将消息从工作线程传递到无窗口ActiveX控件中的主线程

时间:2014-01-13 22:40:58

标签: multithreading activex postmessage ocx worker-thread

我需要让第二个线程做一些错误检查,哪个工作正常。主线程是无窗口的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;
}

1 个答案:

答案 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