views:

127

answers:

1

I've written a multi-threaded WTL util to stress test an in-house service.

Comms threads signal to the main thread that they've quit, so the main thread can delete their corresponding object.

They make the signal as so:

PostThreadMessage(m_dwParentThreadId, WM_THREADQUIT, 1, m_dwNetThreadId);

My problem is how to deal with the custom message I've defined .

WM_THREADQUIT is #define'd as WM_USER + 10

I wanted to use an entry in the message map to call a handler, e.g.:

BEGIN_MSG_MAP(CMainDlg)
  MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
  MESSAGE_HANDLER( WM_THREADQUIT, OnThreadQuit )
  ...
  REFLECT_NOTIFICATIONS()
END_MSG_MAP()

However, OnThreadQuit is never called.

The only way I can handle it is by calling the handler explicitly in PreTranslateMessage:

virtual BOOL CMainDlg::PreTranslateMessage(MSG* pMsg)
{
  if( pMsg->message == WM_THREADQUIT )
  {
    BOOL blHandled;
    OnThreadQuit(pMsg->message, pMsg->wParam, pMsg->lParam, blHandled);
    return TRUE;
  }
  return CWindow::IsDialogMessage(pMsg);
}

I'm sure this isn't the correct way to do it ...

I'd love to know the correct way- can someone help!?

thanks

+1  A: 

As stated in the doc Messages sent by PostThreadMessage are not associated with a window. As a general rule, messages that are not associated with a window cannot be dispatched by the DispatchMessage function.

Set your HWND in pMsg->hwnd and ::DispatchMessage() will deliver it to your WndProc:

virtual BOOL CMainDlg::PreTranslateMessage(MSG* pMsg) 
{ 
  if (pMsg->message == WM_THREADQUIT) 
  { 
    pMsg->hwnd = m_hWnd; 
    return FALSE; // continue processing
  } 
  return CWindow::IsDialogMessage(pMsg); 
}

cheers, AR

Alain Rist