在子线程中调用AfxGetMainWnd()->m_hWnd
返回NULL
MFC辅助线程向主线程窗口发送消息时,通常需要获取主线程窗口的句柄。获取主窗口句柄一般使用AfxGetMainWnd()->m_hWnd
,但是在子线程中,AfxGetMainWnd()的返回值可能为空。
报错信息大概是: “AfxGetMainWnd(…) 返回nullptr。”
通常认为AfxGetMainWnd()
在程序的任何位置都会返回主窗口的指针。实际上有“前提条件”的。即返回当前调用AfxGetMainWnd()的线程的主窗口指针。
具体地,在子线程/辅助线程
(CreateThread创建的线程)中调用AfxGetMainWnd(),返回的是辅助线程的窗口指针,如果辅助线程没有创建窗口,则返回NULL
。
所以如果在程序的主线程中调用AfxGetMainWnd()
,则可以得到主程序主窗口的指针,可以用它来与主窗口通讯;
如果发现在子线程/辅助线程
中调用AfxGetMainWnd()
,则不能得到主线程窗口的指针,返回值为空或辅助线程的窗口指针。具体参考官方说明。
解决方案1:使用AfxGetApp()->GetMainWnd()
获得主窗口指针
辅助线程中的错误调用:
AfxGetMainWnd()->PostMessage( WM_OUTPUT_MSG,PROC_REOPEN,0 );
函数AfxGetApp()可以在辅助线程中获取最顶层窗口指针,因此可以将上面的错误调用修改为:
AfxGetApp()->GetMainWnd()->PostMessage( WM_OUTPUT_MSG,PROC_REOPEN,0 );
或者
PostMessage( AfxGetApp()->GetMainWnd()->m_hWnd,PROC_REOPEN,0 );
解决方案2
在辅助线程中保存一份主窗口指针,例如叫gs_mWnd
,则在辅助线程中发消息事可直接用:
PostMessage( gs_mWnd,PROC_REOPEN,0 );
用于测试的判定语句
在程序主线程和子线程/辅助线程
中可以加入一下代码段,通过断点调试来体会函数调用情况。
if(AfxGetMainWnd()==NULL)
{
printf("AfxGetMainWnd返回空");
gs_hWnd = AfxGetApp()->GetMainWnd()->m_hWnd;
}
else
{
printf("AfxGetMainWnd可用");
gs_hWnd = AfxGetMainWnd()->m_hWnd;
}