我正在使用另一个进程中注入的DLL。在这个DLL中,我创建了一个Thread,其中包括设置2个Timers并执行KeyboardHook(SetWindowsHookEx WH_KEYBOARD_LL)...为了使这个钩子和2个定时器工作,我需要创建一个Message Pump过程。我将这个消息泵称为我的线程中的最后一个东西,正如你在我的Thread.Execute中看到的那样:
procedure MyMainThread.Execute;
begin
while not Terminated do
begin
MyThread:= Self;
StartKeyboardHook;
StartUp;
SetTimer(0, 0, 60000, @MyMainThread.ContactHome);
SetTimer(0, 0, 40000, @MyMainThread.MapProc);
CreateMessagePump;
Terminate;
end;
end;
好的,在CreateMessagePump调用之后,我做了一个Terminate,因为我相信Message Pump是一个无限循环,如果我从中退出,会发生错误,所以我需要终止我的Thread。 CreateMessagePump就是这个:
procedure MyMainThread.CreateMessagePump;
var
AppMsg: TMsg;
begin
while GetMessage(AppMsg, 0, 0, 0) do
begin
TranslateMessage(AppMsg);
DispatchMessage(AppMsg);
end;
//if needed to quit this procedure use PostQuitMessage(0);
end;
我这样做是正确的吗?我的意思是,相信这个循环是无限的是正确的吗?
答案 0 :(得分:2)
Execute
方法中的循环毫无意义。由于循环体的最后一个动作是调用Terminate
,因此循环体只能运行一次。写得像这样:
procedure MyMainThread.Execute;
begin
MyThread:= Self;
StartKeyboardHook;
StartUp;
SetTimer(0, 0, 60000, @MyMainThread.ContactHome);
SetTimer(0, 0, 40000, @MyMainThread.MapProc);
CreateMessagePump;
end;
你的消息循环很好。有些人可能会警告您更密切地检查GetMessage
的返回值,但您的使用情况确实很好。请参阅Raymond对此主题的讨论:http://blogs.msdn.com/b/oldnewthing/archive/2013/03/22/10404367.aspx
目前尚不清楚,但似乎有理由认为您作为计时器程序传递的内容与所需的功能签名不兼容。 SetTimer
单元中Windows
的声明导致不会对您传递的回调执行类型检查。这意味着你可以绝对传递任何东西。编译器迫使您使用@
运算符的事实是您遇到问题的警告信号。
出路是停止使用@
运算符,并使用SetTimer
的固定声明。您应该使用Sertac在之前的一个问题中提供的代码:Using Process32First/Next inside DLL procedure。