博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows 窗体—— 键盘输入工作原理
阅读量:6224 次
发布时间:2019-06-21

本文共 7122 字,大约阅读时间需要 23 分钟。

      

方法

注释

此方法在应用程序级截获排队的(也称为已发送的)Windows 消息。

此方法在 Windows 消息处理前在窗体和控件级截获它们。

此方法在窗体和控件级处理 Windows 消息。

此方法在窗体和控件级执行 Windows 消息的默认处理。 这提供了窗口的最小功能。

此方法在消息处理后在窗体和控件级截获它们。 若要调用此方法,必须设置  样式位。

     KeyDown 事件的预处理相关方法:、、

     KeyPress 事件的预处理相关方法:、

     Control的ProcessCmdKey方法:该方法处理命令键,命令键的优先级高于常规键。命令键的例子包括快捷键和菜单快捷方式

// true:将不调度键消息,而且将不发生键事件 // false:将调用 [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]protected virtual bool ProcessCmdKey(ref Message msg, Keys keyData){    ContextMenu menu = (ContextMenu) this.Properties.GetObject(PropContextMenu);    return (((menu != null) && menu.ProcessCmdKey(ref msg, keyData, this)) || ((this.parent != null) && this.parent.ProcessCmdKey(ref msg, keyData)));}

Control的IsInputKey方法:

// true:表示该控件为常规字符,将引发  事件 // false:表示还没有做处理,将会调用进行处理
[UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows)]protected virtual bool IsInputKey(Keys keyData){
// 1.检查该键是否为需要预处理的特殊键 // Alt需要特殊处理 if ((keyData & Keys.Alt) == Keys.Alt) { return false; } int num = 4; switch ((keyData & Keys.KeyCode)) { case Keys.Left: case Keys.Up: case Keys.Right: case Keys.Down: num = 5; break; case Keys.Tab: num = 6; break; } // 2.检查它是否为应引发 事件并且被调度到某个控件的普通字符键 // IsHandleCreated 指示控件是否有与它关联的句柄 return (this.IsHandleCreated && ((((int) ((long) this.SendMessage(0x87, 0, 0))) & num) != 0)); }

  ※预处理的键包括 Tab、Return、ESC 以及向上键、向下键、向左键和向右键。

      :此方法在控件内实现特殊功能(如在控件及其父级之间切换焦点)的物理按键。 如果中间控件不处理该键,则将调用父控件的 ,直至层次结构中的最顶端控件。

// true:将完成预处理,而且将不生成按键事件。 // false:将发生  事件 [UIPermission(SecurityAction.InheritanceDemand, Window=UIPermissionWindow.AllWindows), UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]protected virtual bool ProcessDialogKey(Keys keyData){    return ((this.parent != null) && this.parent.ProcessDialogKey(keyData));}

     处理键盘消息

:此方法处理由控件的  方法接收的所有键盘消息。

[SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]protected internal virtual bool ProcessKeyMessage(ref Message m){    return (((this.parent != null) && this.parent.ProcessKeyPreview(ref m)) || this.ProcessKeyEventArgs(ref m));}

此方法将键盘消息发送到控件的父控件。 如果  返回 true,则将不生成键事件;否则将调用 。

[SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]protected virtual bool ProcessKeyPreview(ref Message m){    return ((this.parent != null) && this.parent.ProcessKeyPreview(ref m));}

:此方法根据需要引发 、 和  事件。

[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]protected virtual bool ProcessKeyEventArgs(ref Message m){    KeyEventArgs e = null;    KeyPressEventArgs args2 = null;    IntPtr zero = IntPtr.Zero;    if ((m.Msg == 0x102) || (m.Msg == 0x106))    {        int imeWmCharsToIgnore = this.ImeWmCharsToIgnore;        if (imeWmCharsToIgnore > 0)        {            imeWmCharsToIgnore--;            this.ImeWmCharsToIgnore = imeWmCharsToIgnore;            return false;        }        args2 = new KeyPressEventArgs((char) ((ushort) ((long) m.WParam)));         // OnKeyPress        this.OnKeyPress(args2);        zero = (IntPtr) args2.KeyChar;    }    else if (m.Msg == 0x286)    {        int num2 = this.ImeWmCharsToIgnore;        if (Marshal.SystemDefaultCharSize == 1)        {            char ch = '\0';            byte[] lpMultiByteStr = new byte[] { (byte) (((int) ((long) m.WParam)) >> 8), (byte) ((long) m.WParam) };            char[] lpWideCharStr = new char[1];            int num3 = UnsafeNativeMethods.MultiByteToWideChar(0, 1, lpMultiByteStr, lpMultiByteStr.Length, lpWideCharStr, 0);            if (num3 <= 0)            {                throw new Win32Exception();            }            lpWideCharStr = new char[num3];            UnsafeNativeMethods.MultiByteToWideChar(0, 1, lpMultiByteStr, lpMultiByteStr.Length, lpWideCharStr, lpWideCharStr.Length);            if (lpWideCharStr[0] != '\0')            {                ch = lpWideCharStr[0];                num2 += 2;            }            else if ((lpWideCharStr[0] == '\0') && (lpWideCharStr.Length >= 2))            {                ch = lpWideCharStr[1];                num2++;            }            this.ImeWmCharsToIgnore = num2;            args2 = new KeyPressEventArgs(ch);        }        else        {            num2 += 3 - Marshal.SystemDefaultCharSize;            this.ImeWmCharsToIgnore = num2;            args2 = new KeyPressEventArgs((char) ((ushort) ((long) m.WParam)));        }        char keyChar = args2.KeyChar;         // OnKeyPress        this.OnKeyPress(args2);        if (args2.KeyChar == keyChar)        {            zero = m.WParam;        }        else if (Marshal.SystemDefaultCharSize == 1)        {            string wideStr = new string(new char[] { args2.KeyChar });            byte[] pOutBytes = null;            int num4 = UnsafeNativeMethods.WideCharToMultiByte(0, 0, wideStr, wideStr.Length, null, 0, IntPtr.Zero, IntPtr.Zero);            if (num4 >= 2)            {                pOutBytes = new byte[num4];                UnsafeNativeMethods.WideCharToMultiByte(0, 0, wideStr, wideStr.Length, pOutBytes, pOutBytes.Length, IntPtr.Zero, IntPtr.Zero);                int num5 = Marshal.SizeOf(typeof(IntPtr));                if (num4 > num5)                {                    num4 = num5;                }                long num6 = 0;                for (int i = 0; i < num4; i++)                {                    num6 = num6 << 8;                    num6 |= pOutBytes[i];                }                zero = (IntPtr) num6;            }            else if (num4 == 1)            {                pOutBytes = new byte[num4];                UnsafeNativeMethods.WideCharToMultiByte(0, 0, wideStr, wideStr.Length, pOutBytes, pOutBytes.Length, IntPtr.Zero, IntPtr.Zero);                zero = (IntPtr) pOutBytes[0];            }            else            {                zero = m.WParam;            }        }        else        {            zero = (IntPtr) args2.KeyChar;        }    }    else    {        e = new KeyEventArgs(((Keys) ((int) ((long) m.WParam))) | ModifierKeys);        if ((m.Msg == 0x100) || (m.Msg == 260))        {
// OnKeyDown this.OnKeyDown(e); } else {
// OnKeyUp this.OnKeyUp(e); } } if (args2 != null) { m.WParam = zero; return args2.Handled; } if (e.SuppressKeyPress) { this.RemovePendingMessages(0x102, 0x102); this.RemovePendingMessages(0x106, 0x106); this.RemovePendingMessages(0x286, 0x286); } return e.Handled;}

来源:

 

 

 

转载于:https://www.cnblogs.com/niaomingjian/p/4586644.html

你可能感兴趣的文章
Apache Pulsar中的地域复制,第1篇:概念和功能
查看>>
getRealPath()和getContextPath()的区别
查看>>
如何为Linux安装Go语言
查看>>
Hadoop MapReduce编程 API入门系列之wordcount版本2(六)
查看>>
一个页面标题和过滤输出的解决方案(上)
查看>>
Zend Studio 9 汉化教程
查看>>
C#关于委托和事件(基础)
查看>>
automake (>=1.14) error: but option ‘subdir-objects’ is disabled
查看>>
CentOS6.7下安装MySQL
查看>>
Go Main测试实现原理剖析
查看>>
安装本地yum源
查看>>
系统性能调节命令ulimit
查看>>
AS3音效管理
查看>>
LYNC2013部署系列PART1:LYNC2013介绍和基础架构准备
查看>>
ssh公钥登录无效
查看>>
mysql修改密码
查看>>
开放、高效且高性价的Dell GPU解决方案
查看>>
深入理解缓存cache(2):各级缓存测试
查看>>
oltp和olap
查看>>
日常工作小结(三)
查看>>