0

別のプロセス内で挿入された DLL を使用しています。この DLL では、1 つのスレッドを作成して、とりわけ 2 つのタイマーを設定し、KeyboardHook (SetWindowsHookEx WH_KEYBOARD_LL) を実行します... このフックと 2 つのタイマーを機能させるには、1 つのメッセージ ポンプ プロシージャを作成する必要がありました。そして、Thread.Execute でわかるように、この Message Pump を Thread の最後のものとして呼び出します。

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 を実行します。これは、メッセージ ポンプが 1 つの無限ループであると信じているためです。それから抜け出すと、何か問題が発生するため、スレッドを終了する必要があります。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は無意味です。ループ本体の最後の動作は呼び出しであるため、ループ本体はTerminate1 回しか実行できません。次のように書きます。

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。以前の質問の 1 つで Sertac が提供したコードを使用する必要があります: Using Process32First/Next inside DLL procedure

于 2013-09-24T15:02:07.667 に答える