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

 
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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是对光盘主要实例的简要说明: 实例2-1:利用向导生成的应用程序框架。源代码在光盘此目录下“\02\实例2-1\HelloMFC”。 实例2-2:介绍应用程序运行过程的实例。源代码在光盘此目录下“\02\实例2-2\hello”。 实例2-3:技巧演示程序。源代码在光盘此目录下“\02\实例2-3\EditApp”。 实例2-4:技巧演示实例。源代码在光盘此目录下“\02\实例2-4\TestMDI”。 实例2-5:改变MDI窗口框架的颜色。源代码在光盘此目录下“\02\实例2-5\TestMDI”。 实例2-6:添加工具栏程序。源代码在光盘此目录下“\02\实例2-6\MyToolBar”。 实例2-7:电子时钟。源代码在光盘此目录下“\02\实例2-7\EClock”。 实例3-1:创建菜单实例。源代码在光盘此目录下“\03\实例3-1\test1”。 实例4-1:创建对话框实例。源代码在光盘此目录下“\04\实例4-1\Sample4_1”。 实例4-2:创建模态对话框实例。源代码在光盘此目录下“\04\实例4-2\Sample4_1”。 实例4-3:创建模态对话框实例。源代码在光盘此目录下“\04\实例4-3\Sample4_1”。 实例4-4:创建向导对话框实例。源代码在光盘此目录下“\04\实例4-4\Sample4_1”。 实例4-5:创建通用对话框实例。源代码在光盘此目录下“\04\实例4-5\GridDemo”。 实例5-1:控件基本使用方法实例。源代码在光盘此目录下“\05\实例5-1\RMB”。 实例5-2:实现列表框的提示条实例。源代码在光盘此目录下“\05\实例5-2\ListTest”。 实例5-3:美化对话框应用程序实例。源代码在光盘此目录下“\05\实例5-3\New_RMB”。 实例6-1:字体和文本输出实例。源代码在光盘此目录下“\06\实例6-1\gundong”。 实例6-2:字体和文本输出实例。源代码在光盘此目录下“\06\实例6-2\HollowFont”。 实例7-1:画笔使用实例实例。源代码在光盘此目录下“\07\实例7-1\CpuUsage”。 实例7-2:画刷使用实例实例。源代码在光盘此目录下“\07\实例7-2\Color”。 实例8-1:个人信息录入实例。源代码在光盘此目录下“\08\实例8-1\PersonData”。 实例8-2:文件操作实例。源代码在光盘此目录下“\08\实例8-2\FileManipulate”。 实例9-1:赛马程序实例。源代码在光盘此目录下“\09\实例9-1\Racing”。 实例9-2:线程之间通信实例。源代码在光盘此目录下“\09\实例9-2\IPCDemog”。 实例9-3:串口通信实例。源代码在光盘此目录下“\09\实例9-3\SComm”。 实例10-1:动态链接库使用资源实例。源代码在光盘此目录下“\10\实例10-1\vcDlgDLL”。 实例10-2:界面汉化实例。源代码在光盘此目录下“\10\实例10-2”。 实例10-3:鼠标钩子应用实例。源代码在光盘此目录下“\10\实例10-3\MouseHook”。 实例10-4:键盘钩子应用实例。源代码在光盘此目录下“\10\实例10-4\KeyBoardHook”。 实例11-1:网络聊天程序实例。源代码在光盘此目录下“\11\实例11-1”。 实例11-2:MSComm控件使用实例。源代码在光盘此目录下“\11\实例11-2\MSComm”。 实例12-1:Access数据库实例。源代码在光盘此目录下“\12\实例12-1”。 实例12-2:ADO使用实例。源代码在光盘此目录下“\12\实例12-2\AdoTest”。
Visual C++从初学到精通 吕兵 高清PDF带书签 《Visual C++从初学到精通》由浅入深:逐步展现VistJal c++开发的核心Wiridows编程机制;重点突出:详细讲解Wiridows编程和数据库开发两个典型方向;实例典型:用52个典型实例讲解VisuJaI c++开发的重点知识;侧重开发:包含数据库、网络通信、Windows组件三大开发方向;注重实战:用2个完整案例展现Visual c++开发应用流程和领域。 光盘内容: 《Visual C++从初学到精通》实例源代码 《Visual C++从初学到精通》多媒体教学视频 《Visual C++从初学到精通》教学PPT 免费赠送的电子图书和视频 《Visual C++从初学到精通》涵盖内容:控制台应用程序、基于对话框的应用程序、单文档应用程序、多文档应用程序、异常处理机制、 Windows应用程序运行机;WinMain()函数、MFC消息映射机制、API文件操作、MFC文件操作、创建位图对象、模态对话框、菜单的创建、工具栏的使用、状态栏的创建、进程和线程的基本概念、Win32的进程处理、Win32的线程处理、MFC的线程处理、线程同步、ODBC组成结构使用ODBC API进行数据库开发、DAO编程方法、ADO对象模型、套接字、客户机/服务器模式、网络字节顺序、半相关与全相关、半双工与全双工、 套接字编程模型、Windows Socket API主要函数、MFC Socket编程、Winlnet编程、创建动态链接库、使用ActiveX控件编写ActiveX控件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值