应用程序.AddMessageFilter -如何准确读取被推送的键
本文关键字:读取 AddMessageFilter 何准确 应用程序 | 更新日期: 2023-09-27 18:17:48
我正在试验Application.AddMessageFilter
,使用一些最初由其他人编写的代码,所以我不一定理解这里发生的一切。
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
对象应该是用来做什么的,以及为什么它使用诸如LParam
和WParam
这样的不可描述的属性来携带有用的信息?
。按下"%"得到字符"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,它已经被平移了,你应该收到%.