我正在另一个进程中使用注入的DLL。在这个DLL中,我创建了一个线程来设置2个计时器并做一个键盘钩(SetWindowsHookEx WH_KEYBOARD_LL(...为了使这个钩子和 2 个计时器工作,我需要创建一个消息泵过程。我把这个消息泵称为我的线程上的最后一件事,正如你在我的线程中看到的那样。
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 调用之后,我执行终止,因为我相信消息泵是一个无限循环,如果我从中退出,就会发生错误,所以我需要终止我的线程。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;
我这样做的方式正确吗?我的意思是,相信这个循环是无限的是正确的吗?
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
的返回值,但你的用法其实没问题。请参阅雷蒙德对这个话题的讨论:http://blogs.msdn.com/b/oldnewthing/archive/2013/03/22/10404367.aspx
目前尚不清楚,但您作为计时器过程传递的内容似乎与所需的函数签名不兼容。在Windows
单元中声明SetTimer
会导致不会对传递的回调执行类型检查。这意味着您绝对可以通过任何东西。编译器强制您使用 @
运算符这一事实是您遇到问题的警告信号。
出路是停止使用 @
运算符,并使用固定的 SetTimer
声明。您应该使用 Sertac 在前面的一个问题中提供的代码:在 DLL 过程中使用 Process32First/Next。