windows CreateWindow/CreateDialog 中的 HWND 可以从另一个线程获取 GetMessage 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/617248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:07:06  来源:igfitidea点击:

Can the HWND from CreateWindow/CreateDialog be GetMessage'd from another thread?

c++cwindowsmultithreadingwinapi

提问by Joby Taffey

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

使用 Win32 API,是否可以在一个线程中创建一个窗口或对话框,然后从另一个线程为它收集事件?

Are HWNDs tied to threads?

HWND 是否与线程相关联?

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

尝试下面的人为示例,我从未看到 GetMessage() 火。

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?

有人可以解释一下我所看到的吗?

回答by Michael

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.

GetMessage 在当前线程的输入队列上返回消息。HWND 参数是一个过滤器,因此 GetMessage 只返回当前线程的输入队列中用于该窗口的消息。

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

Windows 具有线程关联性 - 用于窗口的消息在创建并因此拥有该窗口的线程上得到处理。

回答by newgre

From the MSDN:

MSDN

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

GetMessage 函数从调用线程的消息队列中检索消息

So no, what you describe is not directly possible.

所以不,你所描述的不是直接可能的。

回答by Valentin Galea

回答by dirkgently

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

在您的第一个示例中,Dialog 和GetMessage位于不同的线程中。并且文档说:

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

GetMessage 函数从调用线程的消息队列中检索消息。

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

第二个示例有效,因为调用线程(for GetMessage)也拥有Dialog.

回答by bayda

In your example programm finish after create window.

在您的示例程序中,在创建窗口后完成。

But anyway in win32 all threads have own message queue.

但无论如何在 win32 中所有线程都有自己的消息队列。

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/ms644928(VS.85) .aspx(使用消息和消息队列)

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

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

回答by Martlark

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.

您当然可以更改处理任何窗口消息的窗口过程。检查 SetWindowLong 函数 - http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx- 关于新 proc 的地址空间有一些规则。我建议使用dll。另一种方法是将窗口消息队列子类化。

回答by Martlark

Of course you can !

当然可以 !

Just use remote code injection ! (very classic !)

只需使用远程代码注入!(非常经典!)