应用程序.AddMessageFilter -如何准确读取被推送的键

本文关键字:读取 AddMessageFilter 何准确 应用程序 | 更新日期: 2023-09-27 18:17:48

我正在试验Application.AddMessageFilter,使用一些最初由其他人编写的代码,所以我不一定理解这里发生的一切。

下面是代码的样子。In Main():
Application.AddMessageFilter(new KeyDownMessageFilter());

In KeyDownMessageFilter:

internal class KeyDownMessageFilter : IMessageFilter {
    private const int WM_KEYDOWN = 0x0100;
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == WM_KEYDOWN)
        {
            var k = (Keys)m.WParam;
            var c = (char)k;
            // and some other stuff
        }
        return false;
    }
}

我可以看到,通过将m.WParam转换为System.Windows.Forms.Keys类型的变量,然后将其转换为char,我可以告诉键盘上的哪个键被按下了。到目前为止,一切顺利。

BUT -我不知道如何区分Shifted键和没有Shift的键push -例如,按%产生字符'5'。更奇怪的是,查看k的值,它显示为"LButton | MButton | ShiftKey | Space"(无论我是按5还是%)。

关于这个主题的MSDN文档相当单薄。有谁能解释一下如何准确地告诉我们推送了什么字符,并解释一下这个Message对象应该是用来做什么的,以及为什么它使用诸如LParamWParam这样的不可描述的属性来携带有用的信息?

应用程序.AddMessageFilter -如何准确读取被推送的键

。按下"%"得到字符"5"

通过设计,WM_KEYDOWN消息在wparam中传递一个虚拟键代码。产生'%'和'5'的键的虚拟键代码是相同的,它是键盘上的相同键。在Windows处理WM_KEYDOWN消息并将其转换为WM_CHAR消息之前,它不会被转换为实际的键入键。这将检查Shift, Ctrl和Alt键的状态,并相应地改变生成的字符。实际产生的字符取决于活动键盘布局。

查看k的值,它显示为"LButton | MButton | ShiftKey | Space"

这是Keys类型上的[Flags]属性的副作用。默认的枚举. tostring()方法检查该属性,如果该属性存在,则将组合枚举值。Keys的整数值。D5是0x01 + 0x04 + 0x10 + 0x20的组合0x35。分别是钥匙。LButton, MButton, ShiftKey和Space。显然,这对您的情况没有帮助,请在watch表达式中强制转换为(int)。

好吧,这就解释了发生了什么。您真正想要避免的一件事是尝试自己将虚拟键转换为键入键。看一下ToUnicodeEx() Windows api函数,您必须使用它来正确执行此操作。你可以使用控件。ModifierKeys属性来检测普通键之间的差异。按D5键和按下Shift键的键。

顺便说一句:你还应该捕获WM_SYSKEYDOWN,当Alt键被按下时产生的消息。消息0 x104。

捕获WM_CHAR,它已经被平移了,你应该收到%.