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)//主框架调用的第二个导出函数
{
}
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);