检查无窗口应用程序中的消息

Checking for messages in windowless application

我有一个小应用程序需要对添加到系统中或从系统中删除的特定设备做出反应。所以我使用 CreateWindowEx()RegisterDeviceNotification().

监听 WM_DEVICECHANGE

这似乎可行 - 但是,我不确定如何正确检查消息队列。简而言之,这是我目前的做法:

procedure Main();

  procedure HandleMessages(aWndHandle: HWND);
  var
    lpMsg: TMsg;
  begin
    while PeekMessage(lpMsg, aWndHandle, 0, 0, PM_REMOVE) do
      DispatchMessage(lpMsg);  
  end;

begin
  // ...  
  if (RegisterClassEx(wClass) = 0) then System.Exit;
  wndHnd := CreateWindowEx(0, PChar(wClass.lpszClassName), nil, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, HInstance, nil);
  // ...
  notificationHandle := RegisterDeviceNotification(wndHnd, @bcInterface, DEVICE_NOTIFY_WINDOW_HANDLE);

  while True do
  begin
    HandleMessages();
    DoThings();

    HandleMessages();
    DoOtherThings();

    HandleMessages();
    DoYetMoreThings();
  end;

  // ... (cleanup)
end;

重复调用 HandleMessages()while True do 循环是否可行?或者我是否需要担心一些隐藏的问题 - 例如,如果 DoThings() 例程之一需要很长时间才能 return?
这对我来说似乎有点尴尬,而且我(怀疑地...)似乎无法在网上找到任何可比较的示例...

编辑:此应用程序没有 UI 或控制台,也没有交互。它从 HID 扫描仪读取输入,并且需要知道扫描仪是被移除还是添加到系统中。它一直运行到用户注销。

正如评论中所建议的,我已将 window/messaging 功能移动到一个单独的线程,现在使用 TEvent 将设备更改事件发送到主线程。到目前为止,这似乎运作良好。
我已经按照 Remy 的建议 here(以及其他地方)在 Execute() 中创建 window 和队列,并使用 DoTerminate() 进行清理。