+ -
当前位置:首页 → 问答吧 → 关于在线程中截取窗口消息的问题

关于在线程中截取窗口消息的问题

时间:2011-12-23

来源:互联网

做了个用于刷新的线程,将窗口的关闭作为线程的终止条件,于是通过PeekMessage函数根据HWND截取消息并判断,但发现截取的消息是个未知量,就算窗口已经创建了依旧如此,各位大神帮我看看~~~
C/C++ code


//OnInitDialog函数中
//...
//创建一个定时刷新屏幕的线程
HANDLE hThd    = ::CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)CFW_111222Dlg::ThdRefrush, (LPVOID)this, 0, NULL);
::CloseHandle(hThd);
//...


//进程函数,把对话框对象作为参数
DWORD WINAPI CFW_111222Dlg::ThdRefrush(LPVOID lpParameter)
{
    CFW_111222Dlg* pThis    = (CFW_111222Dlg*)lpParameter;
    while(true)    {
        MSG msg;
        ::PeekMessage( &msg, pThis->m_hWnd, 0, 0, PM_NOREMOVE);
        if(WM_CLOSE == msg.message)
            break;
        //渲染
        CFWDevice* pDevice    = pThis->m_dlgPkgM.GetGraphDev();
        if(NULL != pDevice)
            if(pDevice->IsInit())
                pDevice->Render();
    }//while true
    return(0);
}

作者: opower   发布时间: 2011-12-23

你这个是后台处理线程,不能截取到UI线程的消息队列的。你应该设置一个BOOL变量,在程序退出的时候置退出标志位为FALSE来退出线程,并且程序退出的时候等待这个线程已经安全退出。

作者: zengwenfu   发布时间: 2011-12-23

不要将MFC中窗口类的指针作为线程函数的参数传递给线程,MFC非线程安全的

作者: VisualEleven   发布时间: 2011-12-23

在MFC中你截获不到WM_CLOSE消息,如果想要验证的话可以尝试一下在PreTranslateMessage中截获WM_CLOSE消息试试,应该是截获不到。

如果你一定要使用WM_CLOSE消息的话,你只能用HOOK。

作者: chayedanwc   发布时间: 2011-12-23

BOOL volatile g_bThreadActived = FALSE;

// MainWindow CreateThread.
g_bThreadActived = TRUE;
CreateThread(...);

// Thread Function
while (g_bThreadActived)
{
// do render.
}

// MainWindow 
// ON WM_DESTRORY
g_bThreadActived = FALSE;

作者: Saleayas   发布时间: 2011-12-23

请教一下,怎么把代码放到代码框内。
像楼主的程序那样?

作者: Saleayas   发布时间: 2011-12-23

给你附上一些参考性质的代码;
C/C++ code

HHOOK m_hHook;

HWND h;
WNDPROC oldProc;
LRESULT CALLBACK HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    LRESULT rc = CallWindowProc( oldProc, hWnd, uMsg, wParam, lParam );
    
    if (uMsg==WM_CLOSE)
    {
        TRACE("Close dlg");
    }
    if (uMsg==WM_NCDESTROY)        
    UnhookWindowsHookEx(m_hHook);

    return rc;
}

LRESULT CALLBACK SetHook(int nCode,WPARAM wParam,LPARAM lParam)
{
    if (nCode==HC_ACTION)[code=C/C++]

  {
  CWPSTRUCT* pwp = (CWPSTRUCT*)lParam;
   
  if (pwp->message==WM_INITDIALOG)
  oldProc=(WNDPROC)SetWindowLong(pwp->hwnd,GWL_WNDPROC,(LONG)HookWndProc); 
  }
  return CallNextHookEx(m_hHook,nCode,wParam,lParam);
}
[/code]

在程序最初始的位置设置HOOK,例如在构造窗体的时候CxxxxDlg(CWnd* pParent = NULL);
C/C++ code

m_hHook = SetWindowsHookEx(WH_CALLWNDPROC,
        (HOOKPROC)SetHook,
        NULL,
        GetCurrentThreadId());



在HOOK截获到了WM_CLOSE消息后,使用PostThreadMessage向你的线程发送消息,例如你可以自定义一个WM_USER+100的消息;然后再线程中截获这个消息,并终止该线程。也可以是WM_QUIT消息直接终止线程。

作者: chayedanwc   发布时间: 2011-12-23

给你附上一些参考性质的代码;
C/C++ code

HHOOK m_hHook;

HWND h;
WNDPROC oldProc;
LRESULT CALLBACK HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    LRESULT rc = CallWindowProc( oldProc, hWnd, uMsg, wParam, lParam );
    
    if (uMsg==WM_CLOSE)
    {
        TRACE("Close dlg");
    }
    if (uMsg==WM_NCDESTROY)        
    UnhookWindowsHookEx(m_hHook);

    return rc;
}

LRESULT CALLBACK SetHook(int nCode,WPARAM wParam,LPARAM lParam)
{
    if (nCode==HC_ACTION)
    {
        CWPSTRUCT* pwp = (CWPSTRUCT*)lParam;
        
        if (pwp->message==WM_INITDIALOG)
        oldProc=(WNDPROC)SetWindowLong(pwp->hwnd,GWL_WNDPROC,(LONG)HookWndProc); 
    }
    return CallNextHookEx(m_hHook,nCode,wParam,lParam);
}



在程序最初始的位置设置HOOK,例如在构造窗体的时候CxxxxDlg(CWnd* pParent = NULL);
C/C++ code

m_hHook = SetWindowsHookEx(WH_CALLWNDPROC,
        (HOOKPROC)SetHook,
        NULL,
        GetCurrentThreadId());

作者: chayedanwc   发布时间: 2011-12-23

while(true) {
  MSG msg;
  ::PeekMessage( &msg, pThis->m_hWnd, 0, 0, PM_NOREMOVE);

这里面要先判断pThis,更好的办法是使用一个信号量。

作者: jennyvenus   发布时间: 2011-12-23