我需要让第二个线程做一些错误检查,哪个工作正常。主线程是无窗口的ActiveX OCX。
我想做的是让第二个帖子将消息发回主线程。我已经设置了消息映射和消息处理程序。从第二个线程内部,我使用PostMessage来发送消息。我知道我到达那里并且我知道消息被发布,因为PostMessage调用的返回值导致一个(TRUE)。我从来没有看到消息处理程序的任何响应。它似乎没有被引用。
Visual Studio 2012 ActiveX项目的代码片段:
//Message handler definition from the .h file:
protected:
afx_msg LRESULT OnHSAmessage(WPARAM wParam, LPARAM lParam);
//From the .cpp file:
BEGIN_MESSAGE_MAP(CHSAObserver_ActiveXControlCtrl, COleControl)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
ON_MESSAGE(WM_HSAMESSAGE, &CHSAObserver_ActiveXControlCtrl::OnHSAmessage)
END_MESSAGE_MAP()
// thread creation (this works)
HSAWnd *pWnd = new HSAWnd(this);
hwndTarget = pWnd->Create();
HANDLE threadHandle = CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID) hwndTarget, NULL, &dwID);
//thread implementation
LONG ThreadProc(LPVOID pParam)
{
BOOL status;
//I know I get here the Postmessage call does not result
//in the message handler being invoked
MessageBox(_T("inside threadproc"));
CHSAObserver_ActiveXControlCtrl *pCtrl = (CHSAObserver_ActiveXControlCtrl*)pParam;
//post message using global HSAWnd
status = PostMessage(hwndTarget, WM_HSAMESSAGE,(WPARAM)NULL,(LPARAM)NULL);
//post message using Class window (here for testing only)
//status = PostMessage (pCtrl->m_hWnd, WM_HSAMESSAGE,(WPARAM)NULL,(LPARAM)NULL);
return TRUE;
}
afx_msg LRESULT CHSAObserver_ActiveXControlCtrl::OnHSAmessage(WPARAM wParam, LPARAM lParam)
{
//this never happens
MessageBox(_T("message posted"));
return 0;
}
答案 0 :(得分:0)
您没有显示HSAWnd
的代码,但我认为问题是,您的消息地图是在CHSAObserver_ActiveXControlCtrl
类中声明的,那就是您拥有WM_HSAMESSAGE
条目的地方。同时,您将消息发布到由HSAWnd
类的实例创建的窗口,该实例与CHSAObserver_ActiveXControlCtrl
分开,并且与其消息映射没有任何共同之处。
因此,HSAWnd
应该包含WM_HSAMESSAGE
的消息映射条目,而不是CHSAObserver_ActiveXControlCtrl
。我希望它会起作用。
另外,PostMessage
是异步API。当工作线程事件的执行速度超过HSAWnd
可能处理WM_HSAMESSAGE
消息时,您应该考虑这种情况。
如果要将工作线程中的消息异步发布到 UI线程,则隐藏窗口和PostMessage
几乎是唯一的选择。
如果您可以同步执行此操作,则可以使用SendMessage
代替。或者,您可以使用COM线程间编组,在这种情况下,您不需要显式创建隐藏窗口。在ActiveX控件上定义私有接口(例如,IPrivate
,确保它是类型库的一部分),然后使用CoMarshalInterThreadInterfaceInStream
/ CoGetInterfaceAndReleaseStream
将其封送到工作线程并调用任何IPrivate
返回的代理对象上的工作线程内的CoGetInterfaceAndReleaseStream
方法。在网络上有一些很好的例子,例如this one。