zoukankan      html  css  js  c++  java
  • 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);

                [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) {}
          }
    }
  • 相关阅读:
    选择人员参与游戏的小程序
    Android系统 手机需要用到的命令
    Portal 开发
    又见好书 net4.0面向对象编程漫谈
    IOS UITableView reloadData not respone!
    android开发的注意问题
    BW数据转换中出现的#非法字符错误
    GIT版本控制使用小结
    好书伴我行
    LogMonitorAgent小结
  • 原文地址:https://www.cnblogs.com/top5/p/1634951.html
Copyright © 2011-2022 走看看