我正在尝试Application.AddMessageFilter
,使用最初由Somebody Else编写的一些代码,所以我不一定了解这里发生的所有事情。
这是代码的样子。在Main()
:
Application.AddMessageFilter(new KeyDownMessageFilter());
在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
,我可以看出键盘上的哪个键被推送了。到目前为止,非常好。
但是 - 我无法弄清楚如何区分 Shift ed键和没有 Shift 的键推 - 例如推%产生字符'5'。更奇怪的是,看看k
的价值,它看起来像是“LButton | MButton | ShiftKey | Space”(无论我是推 5 还是%)。
关于此主题的MSDN文档相当薄。任何人都可以解释如何确切地说出推送的字符,以及奖励标记,解释这个Message
对象应该是什么,以及为什么它使用诸如LParam
和{{WParam
之类的非描述属性1}}携带有用的信息?
答案 0 :(得分:4)
e.g。推动"%"产生角色' 5'
按照设计,WM_KEYDOWN消息在wparam中传递虚拟密钥代码。生成'%'的密钥的虚拟密钥代码和' 5'是相同的,它是键盘上的相同键。在Windows处理WM_KEYDOWN消息并将其转换为WM_CHAR消息之前,它不会变成实际的输入键。这将检查Shift,Ctrl和Alt键的状态并相应地更改生成的字符。生成的实际字符取决于活动的键盘布局。
查看k的值,它显示为" LButton | MButton | ShiftKey |空间"
这是Keys类型的[Flags]属性的副作用。默认的Enum.ToString()方法检查该属性,并在该属性存在时将组合枚举值。 Keys.D5的整数值是0x35,0x01 + 0x04 + 0x10 + 0x20的组合。分别是Keys.LButton,MButton,ShiftKey和Space。显然,这在你的情况下是无用的,在监视表达式中转换为(int)。
嗯,这解释了发生了什么。您实际想要避免的一件事是尝试将虚拟密钥转换为自己的输入密钥。看看ToUnicodeEx() Windows api函数,您必须使用它来正确执行它。您可以使用Control.ModifierKeys属性来检测普通Keys.D5与使用Shift键按下的键之间的区别。
顺便说一句:你还应该捕获WM_SYSKEYDOWN,这是Alt键关闭时生成的消息。消息0x104。
答案 1 :(得分:0)
陷阱WM_CHAR,它已经被转换了,你应该收到%。