0

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

1 回答 1

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任何方法。网络上有一些这种方法的好例子,比如这个IPrivateCoGetInterfaceAndReleaseStream

于 2014-01-19T09:41:00.273 回答