ウィンドウが表示されたことをリアルタイムで知りたいと思いました。そこで、Microsoft Active Accessibility (MSAA)のAPIとUI Automationのそれぞれでやってみました。今回はMSAA編です。

MSAAでは、SetWinEventHook関数を使います。SetWinEventHookは、特定のイベントが発生したときにコールバック関数を呼び出すようにする効果があります。イベントの指定は、1番目の実引数から2番目の実引数で指定した範囲の値のIDというやり方で行います。

#include <iostream>
#include <windows.h>
 
void CALLBACK WinEventProc(
  HWINEVENTHOOK hWinEventHook,
  DWORD event,
  HWND hwnd,
  LONG idObject,
  LONG idChild,
  DWORD dwEventThread,
  DWORD dwmsEventTime)
{
  if (idObject == OBJID_WINDOW && idChild == CHILDID_SELF)
  {
    char text[256]{};
    GetWindowText(hwnd, text, ARRAYSIZE(text));
    std::cout << text << std::endl;
  }
}
 
namespace {
  DWORD mainThreadId;
}
 
int main()
{
  mainThreadId = GetCurrentThreadId();
  SetConsoleCtrlHandler([](DWORD controlType)
  {
    PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);
    return TRUE;
  }, TRUE);
 
  auto e = SetWinEventHook(EVENT_OBJECT_SHOW, EVENT_OBJECT_SHOW, nullptr,
    WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
  if (!e)
  {
    std::clog << "SetWinEventHook failed" << std::endl;
    return 1;
  }
 
  MSG msg;
  while (GetMessage(&msg, nullptr, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  UnhookWinEvent(e);
  std::cout << "exit" << std::endl;
}

なお、今回の例はウィンドウの表示を意図した指定となっています。ウィンドウの作成やフォアグラウンドウィンドウの変化などではありません(それらは別のIDが用意されています)。

スポンサード リンク

この記事のカテゴリ

  • ⇒ ウィンドウの表示のイベント通知を受け取る(MSAA編)
  • ⇒ ウィンドウの表示のイベント通知を受け取る(MSAA編)