天天看點

C#中的鍵盤處理

使用Win32 API進行鍵盤UI設計,代碼較多未整理,相關函數請看注釋,點選 這裡 下載下傳完整代碼。下一篇文章我們将讨論C#的定時器,最後是一篇用這些知識編寫一個基于GDI+的小遊戲的文章,敬請關注。

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace KeyboardDemo

{

      /// <summary>

      /// Description: Keyboard UI design demo.

      ///

      /// Author: Truly

      /// Date: 2006-04-14

      /// </summary>

      public class MainForm : System.Windows.Forms.Form

      {

            private System.ComponentModel.Container components = null;

            // 調用Win32的API

            [DllImport("User32.dll")]

            private static extern int RegisterHotKey(IntPtr hwnd, int id, uint fsModifiers, uint vk);

            [DllImport("User32.dll",SetLastError=true)]

            public static extern bool UnregisterHotKey(IntPtr hwnd, int id);

            protected static extern short GetAsyncKeyState(int vKey);

            public MainForm()

            {

                  InitializeComponent();

            }

            [STAThread]

            static void Main()

                  Application.Run(new MainForm());

            #region Windows Form Designer generated code

            /// <summary>

            /// Clean up any resources being used.

            /// </summary>

            protected override void Dispose( bool disposing )

                  if( disposing )

                  {

                        if(components != null)

                        {

                              components.Dispose();

                        }

                  }

                  base.Dispose( disposing );

            /// Required method for Designer support - do not modify

            /// the contents of this method with the code editor.

            private void InitializeComponent()

                  //

                  // MainForm

                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

                  this.ClientSize = new System.Drawing.Size(292, 266);

                  this.Name = "MainForm";

                  this.Text = "MainForm";

                  this.Load += new System.EventHandler(this.MainForm_Load);

                  this.Closed += new System.EventHandler(this.MainForm_Closed);

            #endregion

            private Graphics g,offGraphics;

            private Bitmap offScreen;           

            private int p1,p2, speed = 5;

            private void MainForm_Load(object sender, System.EventArgs e)

                  for (int i = 0; i < kNumKeys; i++)

                        m_keyStates[i] = 0x00;

                  RegisterAllHardwareKeys();

                  this.Visible = true;

                  InitScreen();                 

            private void InitScreen()

                  // 初始化螢幕

                  p1 = (ClientRectangle.Width -100) / 2;

                  p2 = (ClientRectangle.Height - 40) / 2;

                  g = this.CreateGraphics();

                  offScreen = new Bitmap(this.ClientRectangle.Width , ClientRectangle.Height);

                  offGraphics = Graphics.FromImage(offScreen);

                  offGraphics.Clear(Color.Black);

                  offGraphics.DrawString("按方向鍵控制,Esc退出", new Font("宋體",12), Brushes.Red, 70, ClientRectangle.Height -20);

                  offGraphics.DrawEllipse(Pens.Red, p1,p2,100,30);

                  g.DrawImage(offScreen,this.ClientRectangle);

            public void RegisterKey(Keys key)

                  m_keyStates[(int)key] |= kRegisteredMask;

                  RegisterHotKey(this.Handle, (int)key, 0, (uint)key);

            public void UnregisterKey(Keys key)

                  m_keyStates[(int)key] &= kNotRegisteredMask;

                  UnregisterHotKey(this.Handle, (int)key);

            protected override void WndProc(ref Message msg )

            {

                  const int WM_HOTKEY =  0x0312;

                  if (msg.Msg != WM_HOTKEY)

                        base.WndProc(ref msg);

                  else

                        // 接受到熱鍵時更新按鍵狀态并進行對應處理

                        ProcessKey();

            private void ProcessKey()

                  // 更新按鍵狀态并進行對應處理

                  FreshKeyState();

                  if(KeyPressed(Keys.Up) && p2 > speed)

                        p2 -= speed;

                  if(KeyPressed(Keys.Down) && p2 < this.ClientRectangle.Height - 62)

                        p2 += speed;

                  if(KeyPressed(Keys.Left) && p1 > speed)

                        p1 -= speed;

                  if(KeyPressed(Keys.Right) && p1 < this.ClientRectangle.Width - 102)

                        p1 += speed;

                  if(KeyPressed(Keys.Escape))

                        Application.Exit();

            #region 鍵盤資料聲明

            protected const int kNumKeys = 256;      // 要跟蹤的按鍵數量

            protected byte[] m_keyStates = new byte[kNumKeys]; // 鍵盤狀态數組

            protected const byte kCurrentMask = 0x01;      //屏蔽位檢查按鍵是否被按下

            protected const byte kPreviousMask = 0x02;

            protected const byte kClearMask = 0xfc;      // 清除按鍵資訊的屏蔽

            protected const byte kRegisteredMask = 0x80;      //檢查按鍵是否已注冊的屏蔽

            protected const byte kNotRegisteredMask = 0x7f;

            protected const int kCurToPrevLeftShift = 1;

            public bool KeyPressed(Keys key)

                  if ((m_keyStates[(int)key] & kCurrentMask) != 0)

                        return true;

                  return false;

            public void FreshKeyState()

                        // 隻更新已注冊的按鍵

                        if ((m_keyStates[i] & kRegisteredMask) != 0)

                              // 将目前狀态移動倒前一狀态,并清除目前狀态

                              m_keyStates[i] = (byte)((m_keyStates[i] & kClearMask) | ((m_keyStates[i] << kCurToPrevLeftShift) & kPreviousMask));

                              // 如果有鍵按下,設為目前

                              if ((GetAsyncKeyState(i) & 0x8000) != 0)

                                    m_keyStates[i] |= kCurrentMask;

            public void RegisterAllHardwareKeys()

                  RegisterKey(Keys.Up);

                  RegisterKey(Keys.Down);

                  RegisterKey(Keys.Left);

                  RegisterKey(Keys.Right);

                  RegisterKey(Keys.Escape);