3

Using the Win32 APIs, is it possible to create a Window or Dialog in one thread then collect events for it from another thread?

Are HWNDs tied to threads?

Trying the contrived example below I never see GetMessage() fire.

HWND g_hWnd;

DWORD WINAPI myThreadProc(LPVOID lpParam)
{
    while(GetMessage(&msg, hWnd, 0, 0) > 0)
    {
       ...
    }

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 
{
    hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), 0, myDlgProc);
    CreateThread(NULL, 0 myThreadProc, NULL, 0, NULL);
    ...
}

But here, I do.

HWND g_hWnd;
HINSTANCE g_hInstance;

DWORD WINAPI myThreadProc(LPVOID lpParam)
{
    hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MYDIALOG), 0, myDlgProc);

    while(GetMessage(&msg, hWnd, 0, 0) > 0)
    {
       ...
    }

}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) 
{
    g_hInstance = hInstance;
    CreateThread(NULL, 0 myThreadProc, NULL, 0, NULL);
    ...
}

Can somebody explain what I'm seeing?

Joby Taffey
  • 83
  • 1
  • 6

7 Answers7

5

No.

GetMessage returns messages on the current thread's input queue. The HWND parameter is a filter, so that GetMessage only returns messages in the current thread's input queue intended for that window.

Windows have thread affinity - messages intended for a window get handled on the thread that created and therefore owns the window.

Michael
  • 54,279
  • 5
  • 125
  • 144
2

From the MSDN:

The GetMessage function retrieves a message from the calling thread's message queue

So no, what you describe is not directly possible.

newgre
  • 5,245
  • 4
  • 31
  • 41
2

In your first example the Dialog and GetMessage are in separate threads. And the documentation says:

The GetMessage function retrieves a message from the calling thread's message queue.

The second example works since the calling thread (for GetMessage) also owns the Dialog.

Community
  • 1
  • 1
dirkgently
  • 108,024
  • 16
  • 131
  • 187
2

Use AttachThreadInput.

Valentin Galea
  • 1,084
  • 8
  • 18
0

In your example programm finish after create window.

But anyway in win32 all threads have own message queue.

And all message queues get messages for windows created in this thread.

see:

http://msdn.microsoft.com/en-us/library/ms644928(VS.85).aspx (Using Messages and Message Queues)

http://msdn.microsoft.com/en-us/library/ms644936(VS.85).aspx (GetMessage Function)

bayda
  • 13,365
  • 8
  • 39
  • 48
0

You can of course change the window procedure that handles messages for any window. Check the SetWindowLong function - http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx - there are some rules as to what address space the new proc is. I suggest using a dll. Another way is to sub class the window message queue.

Martlark
  • 14,208
  • 13
  • 83
  • 99
-3

Of course you can !

Just use remote code injection ! (very classic !)

Samuel
  • 315
  • 3
  • 14
  • 2
    HA! If you define "possible" to mean, "by doing something else entirely", then yes, everything is possible. – Shog9 Dec 26 '09 at 19:28