我正在使用C#,我已经使用SetWindowsHookEx
WH_JOURNALRECORD
成功记录了日记邮件。
我的问题出现了,是时候停下来了。文档显示,如果用户按下CTRL-ESC或CTRL-ALT-DELETE,将发布WM_CANCELJOURNAL
消息,我可以查看该消息何时停止。我的应用程序取消了,但我似乎永远不会得到WM_CANCELJOURNAL
。
我有两个挂钩设置。一个钩子用于记录日志记录,另一个用于检查取消消息:
IntPtr hinstance = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
JournalRecordProcedure = JournalRecordProc;
journalHook = SetWindowsHookEx(WH_JOURNALRECORD, JournalRecordProcedure, hinstance, 0);
GetMessageProcedure = GetMessageProc;
messageHook = SetWindowsHookEx(WH_GETMESSAGE, GetMessageProcedure, hinstance, 0);
------
public static int JournalRecordProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0) return CallNextHookEx(journalHook, nCode, wParam, lParam);
EventMsgStruct msg = (EventMsgStruct) Marshal.PtrToStructure(lParam, typeof (EventMsgStruct));
script.Add(msg); //just a quick way to record for now
return CallNextHookEx(journalHook, nCode, wParam, lParam);
}
public static int GetMessageProc(int code, IntPtr wParam, IntPtr lParam)
{
//it comes here but how do I test if it's WM_CANCELJOURNAL ??
//code always seems to be equal to zero.. I must be missing something
return CallNextHookEx(journalHook, code, wParam, lParam);
}
答案 0 :(得分:1)
我想你在documentation:
中引用了这一部分此角色作为停止日志记录的信号意味着无法记录CTRL + BREAK组合键。由于CTRL + C组合键不具有日记信号的作用,因此可以记录它。还有另外两个无法记录的组合键:CTRL + ESC和CTRL + ALT + DEL。这两个组合键会导致系统停止所有日记活动(记录或回放),删除所有日记记录挂钩,并将
WM_CANCELJOURNAL
消息发布到日记应用程序。
问题是WM_CANCELJOURNAL
message 不已发送到您使用SetWindowsHookEx
安装的回调函数。但与其他WM_*
消息不同,它也不是由窗口过程(WinForms中的WndProc
)处理,因为它被发布到线程的消息队列中,与任何特定窗口无关。
相反,文档建议必须在应用程序的主循环中或使用WH_GETMESSAGE
hook处理它:
此消息不返回值。它应该从应用程序的主循环或GetMessage钩子过程中处理,而不是从窗口过程中处理。
[。 。 。 ]
WM_CANCELJOURNAL
消息具有NULL
窗口句柄,因此无法将其分派给窗口过程。应用程序有两种方法可以查看WM_CANCELJOURNAL
消息:如果应用程序在其自己的主循环中运行,则必须在其对GetMessage
或PeekMessage
的调用与其之间捕获消息致电DispatchMessage
。如果应用程序未在其自己的主循环中运行,则必须设置GetMsgProc
挂钩过程(通过调用SetWindowsHookEx
指定WH_GETMESSAGE
挂钩类型)来监视消息。 / p>
在托管的WinForms代码中,您显然无法访问或控制应用程序的主循环。我不确定您的应用程序adding a message filter是否会让您处理此消息:我没有尝试过。如果它会,那可能是你想要的路线,考虑替代方案,即安装第二个钩子WH_GETMESSAGE
,然后在该钩子程序中,听取{{ 1}}消息。
<强>更新强>
在GetMessageProc
callback function中,WM_CANCELJOURNAL
参数只是告诉您钩子过程是否应该处理消息。几乎所有的时间,它都是0,相当于符号常量code
。如果HC_ACTION
参数小于0,则挂钩过程应该只调用code
函数而不执行任何进一步处理。这与CallNextHookEx
回调函数基本完全相同。
窗口消息将在MSG
structure中找到,指针将作为JournalRecordProc
参数传递给回调函数。但那是Win32的东西。不要乱用.NET中的原始指针,让P / Invoke编组程序为您处理所有这些脏东西。原生lParam
结构等同于托管System.Windows.Forms.Message
structure(与MSG
方法使用的相同),因此如果您声明这样的WndProc
回调函数,事情将会更简单:
GetMessageProc
然后,Windows消息被发现为public delegate int GetMessageProc(int code, IntPtr wParam, ref Message lParam);
结构的Msg
member。这是您要与Message
进行比较的值:
WM_CANCELJOURNAL
请注意,要使public static int GetMessageProc(int code, IntPtr wParam, ref Message lParam)
{
if (code >= 0)
{
if (lParam.Msg == WM_CANCELJOURNAL)
{
// do something
}
}
return CallNextHookEx(messageHook, code, wParam, ref lParam);
}
的上述调用有效,您还必须提供与CallNextHookEx
回调的签名匹配的CallNextHookEx
函数的重载定义功能:
GetMessageProc