0

我正在另一个进程中使用注入的 DLL。在这个 DLL 中,我创建了一个线程来设置 2 个定时器并执行一个 KeyboardHook (SetWindowsHookEx WH_KEYBOARD_LL)...为了使这个钩子和 2 个定时器工作,我需要创建一个消息泵过程。我将此消息泵称为我的线程上的最后一件事,正如您在我的 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 是一个无限循环,如果我从中退出,就会发生错误,所以我需要终止我的线程。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;

我这样做是正确的方式吗?我的意思是,相信这个循环是无限的是否正确?

4

1 回答 1

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 在您之前的一个问题中提供的代码:在 DLL 过程中使用 Process32First/Next

于 2013-09-24T15:02:07.667 回答