PostThreadMessage 揭秘
如何以及在哪里使用它!
引言
揭秘多线程中一个鲜为人用但功能强大的 API! 此处提供的代码仅用于学习/演示目的,**不应**直接用于生产环境。
Using the Code
多年来在多线程环境工作,我一直想知道 PostThreadMessage
有什么用? 它可以用于工作线程吗(尽管我已经在从 CWinThread
派生的 UI 线程中使用过它)?
我相信提供的每个 API 都有其用途,否则微软的程序员不会提供一个无法正常工作的 API 库的一部分。 因此,我创建了一个测试程序,并在使用工作线程时,传递了一个 HWND
参数作为 NULL
的消息循环。
// Window MSG Structure
MSG msg;
// Window blocking Message Loop
while(GetMessage(&msg,0,0,0))
{
DispatchMessage(&msg);
}
这意味着 GetMessage
可以收集当前线程的消息,无论是线程消息还是窗口消息。 以下是 MSDN 中的摘录。
“如果
hWnd
为NULL
,GetMessage
将检索属于当前线程的任何窗口的消息,以及当前线程消息队列中的任何消息,其 hwnd 值为 NULL(请参阅 MSG 结构)。 因此,如果hWnd
为NULL
,则将处理窗口消息和线程消息。”
现在,我在消息循环中添加了一个消息处理程序,它会等待一个线程消息(WM_APP+1)来执行某些操作,否则它将继续其工作。 我们的完全加载的线程函数看起来像这样
DWORD threadProc(LPVOID lParam)
{
MSG msg;
while(GetMessage(&msg,0,0,0))
{
if(msg.message == WM_APP+1)
{
MessageBoxA(NULL,"Hello","From Thread",MB_OK);
}
DispatchMessage(&msg);
}
MessageBoxA(NULL,"Thread will closed On pressing OK","From Thread",MB_OK);
return 0;
}
现在,你可能仍然想知道我们的 PostThreadMessage
API 在哪里以及如何使用它? 现在 PostThreadMessage
API 使用线程 ID 而不是 HWND
或窗口句柄。 以下是 MSDN 中 PostThreadMessage
的一个小摘录
“将消息发布到指定线程的消息队列。 它返回而不等待线程处理该消息。
BOOL WINAPI PostThreadMessage( __in DWORD idThread, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam );”
现在,要获取线程 ID,在创建线程时,必须通过引用传递一个 DWORD
变量来收集新创建的工作线程的线程 ID,如下所示
DWORD m_idThread;// in Main Class
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadProc,0,0,&m_idThread);
同样在 _beginthreadex
() API 中,但是 _beginthread
() API 中没有这样的安排来检索线程 ID。 虽然有其他方法,但我不会在这里讨论它们,即偏离主题。 现在你有了工作线程的线程 ID,可以使用 PostThreadMessage
将消息发布到线程,例如,打个招呼
PostThreadMessage(m_idThread,WM_APP+1,0,0);
并指示线程退出
PostThreadMessage(m_idThread,WM_QUIT,0,0);
以下是正在运行的应用程序的外观
关注点
我更希望将其发布为技巧和窍门; 但是,我认为将其发布为一篇文章可以覆盖更广泛的受众。
历史
- 2013 年 6 月 21 日 - 更新
- 2011 年 7 月 14 日:发布于 CodeProject