65.9K
CodeProject 正在变化。 阅读更多。
Home

PostThreadMessage 揭秘

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.63/5 (20投票s)

2011年7月14日

CPOL

2分钟阅读

viewsIcon

86221

downloadIcon

3851

如何以及在哪里使用它!

引言

揭秘多线程中一个鲜为人用但功能强大的 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 中的摘录。

“如果 hWndNULLGetMessage 将检索属于当前线程的任何窗口的消息,以及当前线程消息队列中的任何消息,其 hwnd 值为 NULL(请参阅 MSG 结构)。 因此,如果 hWndNULL,则将处理窗口消息和线程消息。”

现在,我在消息循环中添加了一个消息处理程序,它会等待一个线程消息(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 或窗口句柄。 以下是 MSDNPostThreadMessage 的一个小摘录

将消息发布到指定线程的消息队列。 它返回而不等待线程处理该消息。

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);

以下是正在运行的应用程序的外观

posthreadmessage/PostThreadMessage1.JPG

posthreadmessage/posthreadMessage2.JPG

关注点

我更希望将其发布为技巧和窍门; 但是,我认为将其发布为一篇文章可以覆盖更广泛的受众。

历史

  • 2013 年 6 月 21 日 - 更新
  • 2011 年 7 月 14 日:发布于 CodeProject
© . All rights reserved.