关于同一进程内不同对话框分线程显示的疑问

Fireway2008 Fireway2008 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
各位朋友,本人曾发表过一篇帖子:
关于自封装的消息循环函数的改进问题


虽然承蒙众多高手的指导,但是依旧存在一些小bug。
尤其对于 从主对话框用新线程打开新的对话框S后,在这个对话框S关闭并销毁后,主对话框无法响应鼠标点击的问题,至今依然未找到原因……

对于新的一个基于对话框的MFC工程Test,本人有了新的设想:
1. 这个工程内有3个对话框,主对话框0,启动画面对话框A,初始界面对话框B

2. 本人打算实现这样的效果,
把此工程的主对话框0创建成一个非模式对话框,以便让其创建完成后,不会立即显示;
在CTestApp内,开辟新的线程让启动画面对话框A出现并短暂地停留2s,然后销毁,并打开初始化界面对话框B
因为主对话框0内部处理过程比较繁琐而复杂,所以需要让对话框A和B显示的时候拖延时间给主对话框完成创建,然后点击初始化对话框B上的某个按钮,利用ShowWindow(SW_SHOW)把主对话框0给显示出来,这样看起来显得界面的呈现比较平滑有序。

3. 目前,为了这个目的,本人按如下代码做了如下尝试:

BOOL CTestApp::InitInstance()
{
AfxEnableControlContainer();
//必须新开一线程打开启动页面
::AfxBeginThread(OpenBgPageThread, this, THREAD_PRIORITY_HIGHEST);


// 创建主对话框
m_pMainDlg = new CAdoRWAccessDlg(IDD_ADORWACCESS_DIALOG);
m_pMainWnd = m_pMainDlg;


m_pMainDlg->Create(IDD_ADORWACCESS_DIALOG, CWnd::GetDesktopWindow());

return TRUE;// 声明对话框创建成功
}

UINT CTestApp::OpenBgPageThread(LPVOID lpv)
{
CBeginDlg dlg;
dlg.DoModal();
::AfxEndThread(0);
return 0;
}

在启动画面对话框A内,设 定时器
SetTimer(ID_CLOSE_BEGINDLG, 2000, NULL);

void CBeginDlg::OnTimer(UINT nIDEvent)
{
this->KillTimer(ID_CLOSE_BEGINDLG);
this->OnOK();//销毁此对话框并开启新的对话框B

OpenStPage();

}
void CBeginDlg::OpenStPage()
{
//CFriendBookADODlg* m_pStPageDlg;
m_pStPageDlg = new CFriendBookADODlg; //我是用new创建的


CWinThread* pThread=::AfxBeginThread(OpenStPageThread, (LPVOID)m_pStPageDlg, THREAD_PRIORITY_HIGHEST);
if(pThread)
{
((CFriendBookADOApp*)AfxGetApp())->m_pThreadList.push_back(pThread);
}
}

UINT CBeginDlg::OpenStPageThread(LPVOID lpv)
{
if(lpv == NULL)
{
AfxMessageBox(_T("ERROR"), MB_OK| MB_ICONERROR);
::AfxEndThread(2);
}

CFriendBookADODlg* dlg = (CFriendBookADODlg*)lpv;
// 初始化对话框B为无模式对话框
dlg->Create(IDD_FRIENDBOOKADO_DIALOG, CWnd::GetDesktopWindow());
dlg->ShowWindow(SW_SHOW);

dlg->DoLoop();
// 这里为了测试消息循环是否正常,特地加入了如下语句
AfxMessageBox(_T("quit while!"));

delete dlg;
((CFriendBookADOApp*)AfxGetApp())->m_pThreadList.remove(AfxGetThread());
return 0;
}

4. 然而,程序运行的结果出乎我的意料!
在初始化对话框B出来后,按理应该进入了消息循环,可是,
我并没有给其投入PostQuitMessage(0);


可是它却自动跳出了消息循环,运行到了AfxMessageBox(_T("quit while!"));
接下来 则执行delete dlg;

而我并没有打算让初始化对话框B 这个时候销毁,它还有用的上的地方呢 !


5. 按上一个帖子,我更正了DoLoop为如下代码:
BOOL CFriendBookADODlg::DoLoop()
{
MSG msg;
while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT) //只有当收到这个消息才退出
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}

else
{
//在这里添加空闲任条处理
//之前的代码是
AfxGetApp()->OnIdle(0);
AfxGetApp()->OnIdle(1);
//目前换成如下,但还是有问题……

Sleep(100);
}
}
return TRUE;
}

还请各位朋友看看,我的思路对吗?
为什么依然有那样的缺陷?
...全文
评论 59
收藏 已收藏
分享
返回顶部
Fireway2008
进程/线程/DLL 15,466 成员 49,169 内容