来自 CreateWindow/CreateDialog 的 HWND 可以从另一个线程获取消息吗?
Posted
技术标签:
【中文标题】来自 CreateWindow/CreateDialog 的 HWND 可以从另一个线程获取消息吗?【英文标题】:Can the HWND from CreateWindow/CreateDialog be GetMessage'd from another thread? 【发布时间】:2010-10-11 15:52:53 【问题描述】:使用 Win32 API,是否可以在一个线程中创建一个窗口或对话框,然后从另一个线程为它收集事件?
HWND 是否与线程绑定?
尝试下面的人为示例,我从来没有看到 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); ...但在这里,我愿意。
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); ...谁能解释一下我看到了什么?
【问题讨论】:
【参考方案1】:没有。
GetMessage 在当前线程的输入队列中返回消息。 HWND 参数是一个过滤器,因此 GetMessage 只返回当前线程的输入队列中用于该窗口的消息。
Windows 具有线程关联性 - 用于窗口的消息在创建并因此拥有该窗口的线程上得到处理。
【讨论】:
【参考方案2】:来自MSDN:
GetMessage 函数检索一个 来自调用线程的消息 消息队列
所以不,你描述的不是直接可能的。
【讨论】:
【参考方案3】:在您的第一个示例中,Dialog 和GetMessage 位于不同的线程中。文档说:
GetMessage 函数从调用线程的消息队列中检索消息。
第二个例子有效,因为调用线程(对于GetMessage
)也拥有Dialog
。
【讨论】:
【参考方案4】:使用AttachThreadInput。
【讨论】:
在 Windows CE/Mobile 上不可能。 推荐使用危险的 API,甚至没有提及后果,这是严重疏忽。 -1.【参考方案5】:在您的示例程序中创建窗口后完成。
但无论如何,在 win32 中,所有线程都有自己的消息队列。
所有消息队列都会为在这个线程中创建的窗口获取消息。
见:
http://msdn.microsoft.com/en-us/library/ms644928(VS.85).aspx(使用消息和消息队列)
http://msdn.microsoft.com/en-us/library/ms644936(VS.85).aspx(GetMessage 函数)
【讨论】:
【参考方案6】:您当然可以更改为任何窗口处理消息的窗口过程。检查 SetWindowLong 函数 - http://msdn.microsoft.com/en-us/library/ms633591(VS.85).aspx - 关于新 proc 的地址空间有一些规则。我建议使用 dll。另一种方法是对窗口消息队列进行子类化。
【讨论】:
【参考方案7】:当然可以!
只需使用远程代码注入! (非常经典!)
【讨论】:
哈!如果您将“可能”定义为“完全做其他事情”,那么是的,一切皆有可能。以上是关于来自 CreateWindow/CreateDialog 的 HWND 可以从另一个线程获取消息吗?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 WCF 服务能够处理来自不同进程的调用而不是来自线程的调用
来自 viewDidAppear 的 Segue 调用有效,但不是来自 viewWillAppear