zoukankan      html  css  js  c++  java
  • Windows 窗体—— 键盘输入工作原理

          

    方法

    注释

    PreFilterMessage

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

    PreProcessMessage

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

    WndProc

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

    DefWndProc

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

    OnNotifyMessage

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

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

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

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

    // true:将不调度键消息,而且将不发生键事件
    // false:将调用IsInputKey
    [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:表示该控件为常规字符,将引发 KeyDown 事件
    // false:表示还没有做处理,将会调用ProcessDialogKey进行处理
    [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.检查它是否为应引发KeyDown 事件并且被调度到某个控件的普通字符键
    //
    IsHandleCreated 指示控件是否有与它关联的句柄
    return (this.IsHandleCreated && ((((int) ((long) this.SendMessage(0x87, 0, 0))) & num) != 0));
    }

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

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

    // true:将完成预处理,而且将不生成按键事件。
    // false:将发生 KeyDown 事件
    [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)); }

         处理键盘消息

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

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

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

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

    ProcessKeyEventArgs:此方法根据需要引发 KeyDownKeyPress 和 KeyUp 事件。

    [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 = ''; 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] != '') { ch = lpWideCharStr[0]; num2 += 2; } else if ((lpWideCharStr[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; }

    来源:键盘输入工作原理

     

  • 相关阅读:
    Ubuntu16安装GPU版本TensorFlow(个人笔记本电脑)
    python读取shp
    python汉字转拼音
    通过Places API Web Service获取兴趣点数据
    通过修改然后commit的方式创建自己的镜像
    centos安装postgis
    centos下mongodb备份(dump)与还原(restore)
    mysql-5.7.12安装
    Buuctf-misc-snake
    Buuctf-misc-刷新过的图片 (F5刷新)
  • 原文地址:https://www.cnblogs.com/niaomingjian/p/4586644.html
Copyright © 2011-2022 走看看