消息队列上的无限循环



我正在另一个进程中使用注入的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。

最新更新