关于动态链接库中创建非模态对话框出现的问题

每天学习总结 专栏收录该内容
14 篇文章 0 订阅
 
MFC扩展dll:
extern "C" AFX_API_EXPORT BOOL CommOpen(CChannel* pChannel,BOOL bOpen)//主框架调用的第一个导出函数
{
    //创建的非模态对话框    
    AfxGetThread()->PostThreadMessage(CM_TEST1,0,0);//调用主框架的现成发消息
    MSG msg;
    CDirCheckDemoDlg* p = NULL;
    while (::GetMessage(&msg,NULL,0,0))
    {
        //不是非模态对话框则看看是否是其他消息
        if (!::IsWindow(p->GetSafeHwnd()) || !::IsDialogMessage(p->GetSafeHwnd(),&msg) )
        {           
            if (msg.message == CM_TEST1)
            {
                p = new CDirCheckDemoDlg;
                p->Create(IDD_DIRCHECK_DIALOG,AfxGetApp()->m_pMainWnd);
                p->CenterWindow();
                p->ShowWindow(SW_NORMAL);
                p->UpdateWindow();
            }
            //删除消息
            ::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
        }
    }        
    return TRUE;//主框架自动调用第二个导出函数
}
extern "C" AFX_API_EXPORT int Poll(CDevice* pDevice)//主框架调用的第二个导出函数
{

}


发现主框架调用第一个导出函数后,不会调用第二个导出函数。
问题:怎么主框架调用第一个导出函数后,(只要第一个导出函数返回true就)自动调用第二个导出函数?
分析:开始在动态链接库中创建非模态对话框代码是这样的
extern "C" AFX_API_EXPORT BOOL CommOpen(CChannel* pChannel,BOOL bOpen)
{
    //创建的非模态对话框
    AFX_MANAGE_STATE(AfxGetAppModuleState());
     CDirCheckDemoDlg *pDlg=new CDirCheckDemoDlg;
     pDlg->Create(IDD_DIRCHECK_DIALOG,AfxGetApp()->m_pMainWnd);
    pDlg->CenterWindow();
     pDlg->ShowWindow(SW_SHOW);
    pDlg->UpdateWindow();
    return TRUE;//主框架自动调用第二个导出函数
}
extern "C" AFX_API_EXPORT int Poll(CDevice* pDevice)//主框架调用的第二个导出函数
{

}


这里这样写,运行后会造成主框架和非模态对话框卡起,无法响应,分析了下原因好像是非模态对话框一直响应WM_PAINT消息,导致对话框一直画,最终导致看起来卡起,实际上主框架会自动调用第二个导出函数。由于卡起无法向对话框中输入内容。如改成了while循环接受消息的写法,但是另一个问题出现了,一直处理接受消息,即while()循环无法退出(自己试过跳出while后会造成主框架和非模态对话框卡起,无法响应),该怎么改才能使第一个函数返回true?
发现这个问题是矛盾题目,很有意思。。。有遇到这种问题的老鸟发表下解决方法,这个问题关键在分析为什么主框架和非模态对话框卡起,无法响应

完美解决方法:

这个方法也凝聚了云飞 (用户名:sky101010ws) ,感谢他,虽然不是全对。下面给出我的解决方案:

只贴代码了:

CWinThread *cWinThread;
UINT Fun1Pro(LPVOID lpParameter);//线程调用函数
extern "C" AFX_API_EXPORT BOOL CommOpen(CChannel* pChannel,BOOL bOpen)
{
	//主框架暂停和运行进行处理
 	if (bOpen)
 	{
  		if (cThread==NULL)
  		{   
   		//开始一个线程
   		cThread=::AfxBeginThread(Fun1Pro,(LPVOID)pChannel);
  		} 
 	}
 	else
 	{  
  		//结束一个线程,在线程外面不该用afxEndThread()函数
  		TerminateThread(cThread->m_hThread,0);
  		p->DestroyWindow();
  		PostQuitMessage(0);
  		delete p;  
 }
 return TRUE;
}

UINT Fun1Pro(LPVOID lpParameter)
{
	MSG msg;
	p = new CDirCheckDemoDlg;    
	cWinThread->PostThreadMessage(CM_TEST1,0,0);//线程发送消息
	while (::GetMessage(&msg,NULL,0,0))
    {
        //不是非模态对话框则看看是否是其他消息
        if (!::IsWindow(p->GetSafeHwnd()) || !::IsDialogMessage(p->GetSafeHwnd(),&msg) )
        {           
			switch (msg.message)
			{
			case CM_TEST1:
				p->Create(IDD_DIRCHECK_DIALOG,AfxGetApp()->m_pMainWnd);
				p->CenterWindow();
				p->ShowWindow(SW_NORMAL);
				p->UpdateWindow();
				break;
			case WM_CLOSE:
				{
					p->DestroyWindow();
					delete p;
					break;
				}
			case WM_DESTROY:
				{
					::PostQuitMessage(0);
					break;
				}
			}
        }
		::TranslateMessage(&msg);//接受键盘消息
		::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
    }
	return 0;
}

extern "C" AFX_API_EXPORT int Poll(CDevice* pDevice)
{
}

主要思路是创建一个子线程(如果用主线程的话会导致extern "C" AFX_API_EXPORT BOOL CommOpen(CChannel* pChannel,BOOL bOpen)无法返回true)发送消息。

最后是一个对于线程外结束线程的问题,用函数TerminateThread(cThread->m_hThread,0);

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值