C#中的鍵盤處理

來源:互聯網
上載者:User

使用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);

            [DllImport("User32.dll")]
            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 );
            }
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            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();
                  }

                  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);
            }
           
            #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;

            #endregion

            public bool KeyPressed(Keys key)
            {
                  if ((m_keyStates[(int)key] & kCurrentMask) != 0)
                        return true;

                  return false;
            }

            public void FreshKeyState()
            {
                  for (int i = 0; i < kNumKeys; i++)
                  {
                        // 只更新登入的按鍵
                        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);
            }

            public void UnregisterAllHardwareKeys()
            {                 
                  UnregisterKey(Keys.Up);
                  UnregisterKey(Keys.Down);
                  UnregisterKey(Keys.Left);
                  UnregisterKey(Keys.Right);
                  UnregisterKey(Keys.Escape);
            }

            private void MainForm_Closed(object sender, System.EventArgs e)
            {
                  UnregisterAllHardwareKeys();
                  Application.Exit();
            }

            // 圖形已經在鍵盤訊息中處理,覆蓋基類的Paint處理
            protected override void OnPaint(PaintEventArgs e) {}
            protected override void OnPaintBackground(PaintEventArgs e) {}
      }
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.