Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You probably need full and working event loop - try:</p> <pre><code>MSG msg; while(GetMessage(&amp;msg, NULL, 0, 0) &gt; 0) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } </code></pre> <p>If your app is not a GUI application - or more specifically if you don't need event loop for anything else than hooks - you might either add another thread and use above event loop there (and all the hooking and unhooking as well I suppose), or use <code>PeekMessage</code> in conjunction with <code>GetMessage</code> to create non-blocking event loop and call it regularly.</p> <p>Secondly, you shouldn't remove your hook directly after a call to <code>CreateProcess</code>. Creation of a window happens usually after a program is fully loaded and initialized, and this process can take a while. <code>CreateProcess</code> works asynchronously, which means that it doesn't wait for all this to happen before exiting.</p> <p>Thirdly, to be able to receive any kind of hook messages your message loop needs to be executed between <code>SetWinEventHook</code> and <code>UnhookWinEvent</code> - in any other case you will not get anything.</p> <p>Finally, to avoid messages from other processes being passed to your process, you should probably start you application using <code>CREATE_SUSPENDED</code> flag, start your hook with apropriate process-ID, and then resume process execution by using <code>ResumeThread</code> with main thread handle obtained form <code>CreateProcess</code>.</p> <p>Overall It should look along the lines of:</p> <pre><code>BOOL result = CreateProcess(0, arguments, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &amp;StartupInfo, &amp;ProcessInfo); HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, WinEventProc, ProcessInfo.dwProcessId, 0, WINEVENT_OUTOFCONTEXT ); ResumeThread(ProcessInfo.hThread); // If you don't have an event loop function in your application already, then you could insert a temporary one here. MSG msg; while (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } </code></pre> <p>If you application is not event driven - just regular sequential app, then you should call above event loop regularly until your <code>WinEventProc</code> executes - you probably should add some safeguard variables to see if it was already executed. Another good idea might be including some timeout (2-3 minutes?) in case that no events are posted (app crashing, app creating no objects for some reason). For simplicity I also skipped any error checking.</p> <p>And your hook procedure should do something like that:</p> <pre><code>void CALLBACK WinEventProc( HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { // This will handle the re-entrance problem nicely. UnhookWinEvent(hWinEventHook); // Do wathever you need to do with a window here. [...] } </code></pre> <p><strong>EDIT:</strong></p> <p>As for skipping through the message loop - yes, that's what this message loop is supposed to do.</p> <p>Which message loop is best for you depends on you program construction - if you already have an even loop running (GUI-frameworks like Qt, MFC... usually implement it for you already), then you don't need to add any anyway. If you want your app to wait until WinEvent is delivered then you should do something like that:</p> <pre><code>//Global variable for stop-condition: bool docontinue = false; void CALLBACK WinEventProc( HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { // This will handle the re-entrance problem nicely. UnhookWinEvent(hWinEventHook); // Do wathever you need to do with a window here. [...] docontinue = false; } </code></pre> <p>And the hooking function should do:</p> <pre><code>// In hooking function use: docontinue = true; MSG msg; while (GetMessage(&amp;msg, NULL, 0, 0, PM_REMOVE) &gt; 0) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); if (!docontinue) break; } </code></pre> <p>This is most naive approach, it has several drawbacks, but if you just need to do one simple operation then it will probably be enough for you.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload