救命:MFC怎么防止非模态对话框被重复创建??

avigdkwynw 2008-12-15 01:09:19
很多书上创建非模态对话框的代码都是这样,在某个菜单的响应命令中添加:
CMyDialog *dlg = new CMyDialog;
dlg->Create(IDD_DIALOG1,this);
dlg->ShowWindow(SW_SHOW);

可是这样的话,每次执行这个菜单命令都会创建一次这个非模态对话框,于是我将它改为:
CMyDialog *dlg = new CMyDialog;
if(!IsWindow(dlg->m_hWnd)) //如果m_hwnd存在,就不创建
{
dlg->Create(IDD_DIALOG1,this);
dlg->ShowWindow(SW_SHOW);
}
发现效果还是一样,原来是dlg指针又重新分配了一次地址,于是我又把它改为静态的,防止重新分配:
static CMyDialog *dlg = new CMyDialog;
if(!IsWindow(dlg->m_hWnd))
{
dlg->Create(IDD_DIALOG1,this);
dlg->ShowWindow(SW_SHOW);
}
这样就不会重新创建了,可是问题又来了,当我关闭对话框,然后再打开时,程序就出错了,
因为在销毁非模态对话框时需要销毁这个对象:
void CMyDialog::PostNcDestroy()
{
delete this;
CDialog::PostNcDestroy();
}
我调试了一下,发现代码执行到"dlg->Create(IDD_DIALOG1,this);"
时出错的,错误提示为:assess violation。
唉,实在搞不懂了,请各位高手救救小弟吧,55555!!!


...全文
998 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
bolischou 2011-03-25
  • 打赏
  • 举报
回复
这个。。。。你把
if(!IsWindow(dlg->m_hWnd)) //如果m_hwnd存在,就不创建
{
dlg->Create(IDD_DIALOG1,this);
dlg->ShowWindow(SW_SHOW);
}
改成
if(!IsWindow(dlg->m_hWnd)) //如果m_hwnd存在,就不创建
{
dlg->Create(IDD_DIALOG1,this);
}
dlg->ShowWindow(SW_SHOW);
应该就行了吧。。。
lhdzwkk4 2011-01-11
  • 打赏
  • 举报
回复
以上做法错误,
应该是定义static CMyDialog *dlg = new CMyDialog;在cpp文件中,即函数外却不是.h中
然后一切照旧
if(!IsWindow(pdlg1a->m_hWnd))
....

去掉static 则可以打开n个,可以用if(!(FindWindow(0,"XXX"))判断
lhdzwkk4 2011-01-11
  • 打赏
  • 举报
回复
可能被n个人搜索这个文章,我来解释下楼主的代码
把static CMyDialog *dlg = new CMyDialog;
定义在类成员变量里,别static就没问题了,
汗一个
其实二楼是正解
最简单的测试代码:
CDLG1 *pdlg1a;
//--------------------------------
pdlg1a=new CDLG1;
if(!IsWindow(pdlg1a->m_hWnd))
{
pdlg1a->Create(IDD_DIALOG1);
pdlg1a->ShowWindow(SW_SHOW);
pdlg1a->DestroyWindow();
//pdlg1a->CenterWindow();
}
unwritewolf 2010-12-25
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 avigdkwynw 的回复:]

1、类成员变量不好销毁吧?
2、全局对象尽量少用吧?
3、还是harry330说得好,每次要创建之前通过FindWindow查找是否已经存在,存在就BringWindowToTop,或者SetForgroundWindow将窗口带到前台窗口。
4、我总结一下:
C/C++ code

//第一步,响应菜单命令,创建与显示对话框。
void CXXView::OnXXX()
{
……
[/Quote]
delete this;要放在在窗口销毁之后
zhenxisuiyuan 2010-08-10
  • 打赏
  • 举报
回复
天剑诗仙 方法最好,牛人!!
hestephen 2009-03-11
  • 打赏
  • 举报
回复
楼主啊,你总结的有个问题:那就在else
{
pWnd->BringWindowToTop();
}
里如果要得到这个已经创建的对话框的指针该怎么操作呢?
avigdkwynw 2009-02-07
  • 打赏
  • 举报
回复 1
1、类成员变量不好销毁吧?
2、全局对象尽量少用吧?
3、还是harry330说得好,每次要创建之前通过FindWindow查找是否已经存在,存在就BringWindowToTop,或者SetForgroundWindow将窗口带到前台窗口。
4、我总结一下:

//第一步,响应菜单命令,创建与显示对话框。
void CXXView::OnXXX()
{
// TODO: Add your command handler code here
CWnd* pWnd=FindWindow(0,"XXX");
if(!pWnd)
{
CMyDlg* dlg=new CMyDlg;
dlg->Create(IDD_DIALOG1,this);
dlg->ShowWindow(SW_SHOW);
}
else
{
pWnd->BringWindowToTop();
}
}

//第二步,在所有关闭对话框的地方调用DestroyWindow,如OnOK,OnCancel,OnClose等
void CMyDlg::OnCancel()
{
// TODO: Add extra validation here
DestroyWindow();
//CDialog::OnOK();
}

//第三步,覆盖对话框的虚函数PostNcDestroy,即在销毁非模态对话框后,释放对话框指针
void CMyDlg::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this;
//CDialog::PostNcDestroy();
}
txk1451 2009-01-18
  • 打赏
  • 举报
回复
办法真的是太多
类成员变量、全局对象....
effective100 2009-01-09
  • 打赏
  • 举报
回复
秀一段用消息来做的方法:
CTestDlg dlg; //CTestDlg 使我们用来测试的Dlg类;
//在处理WM_CLOSE消息时做如下动作:
void CTestDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
GetParent()->PostMessage(WM_SETCREATDLGFLAG);//别忘了定义WM_SETCREATDLGFLAG消息;
CDialog::OnClose();
}
//CNoModeDlg_DemoDlg是父窗口类,别忘了在消息泵中注册WM_SETCREATDLGFLAG消息,如下:
BEGIN_MESSAGE_MAP(CNoModeDlg_DemoDlg, CDialog)
...
ON_MESSAGE(WM_SETCREATDLGFLAG, OnSetCreateDlgFlag)
...
END_MESSAGE_MAP()

//创建非模态对话框,m_bCreateDlg 初始化位false;
CTestDlg dlg;
void CNoModeDlg_DemoDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
if ( !m_bCreateDlg )
{
dlg.Create(IDD_DIALOG_ONE,this);
dlg.ShowWindow(SW_SHOW);
m_bCreateDlg = true;
}
}

LRESULT CNoModeDlg_DemoDlg::OnSetCreateDlgFlag(WPARAM wParam, LPARAM lParam)
{
m_bCreateDlg = false;
dlg.DestroyWindow();
return 0;
}
lhsxsh 2009-01-09
  • 打赏
  • 举报
回复
做一个状态判断一下就行了
effective100 2009-01-08
  • 打赏
  • 举报
回复
前段时间项目遇到类似的问题,不过比这复杂多的去了,最后的做法和2楼说的一致
[Quote=引用 2 楼 AAa_tnT 的回复:]
手动添加一个BOOL 变量就行了。。
创建时候 进行判断 为0就创建 然后写1
为1就什么也不做
[/Quote]
wow415411408 2009-01-08
  • 打赏
  • 举报
回复
我自己做的时候麻烦了点 多弄了个BOOL变量控制
声明
private:
BOOL bT;
CDialog *dlg;

构造里
bT=FALSE;

然后
void CMyView::OnMyWindow()
{
if(!bT)
{
dlg=new Dialog_Setsize_Result;
dlg->Create(IDD_DIALOG1);
dlg->ShowWindow(SW_SHOW);
bT=TRUE;
}else{
if(dlg!=NULL)
{
dlg->DestroyWindow();
delete dlg;
dlg=NULL;
bT=FALSE;
OnMyWindow();
}
}
}
StartDay 2008-12-23
  • 打赏
  • 举报
回复
在非模态对话框的PostNcDestroy里面,给显示这个非模态对话框的窗体send一个自定义消息,
之后delete this;

消息处理函数里面把指向非模态对话框的指针赋值为NULL。

每次show的时候记得判断指向非模态对话框的指针是否为空。
用户 昵称 2008-12-23
  • 打赏
  • 举报
回复
用一个全局变量,当对话框成功创建后,变量在对话内部变成1,在销毁时变成0.
congyu888 2008-12-23
  • 打赏
  • 举报
回复
4楼的方法,控制dialog的创建和释放都比较方便!
baoyz 2008-12-23
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 AAa_tnT 的回复:]
手动添加一个BOOL 变量就行了。。
创建时候 进行判断 为0就创建 然后写1
为1就什么也不做
[/Quote]
对,这个最可靠,最简单。

关闭对话框时再写0。
sixbusy 2008-12-22
  • 打赏
  • 举报
回复
写一个单例模式,就可以了!
构造函数私有!参数可以设置为父类的ID。
miao120550 2008-12-22
  • 打赏
  • 举报
回复
把这个指针保存为成员变量就好办了。创建之间先判断句柄是否有效,否则就创建,然后再显示,退出的时候删除指针,OK。
yc_8301 2008-12-22
  • 打赏
  • 举报
回复
来晚了,作为成员变量,在new之前判断是否为NULL就OK了。
ZWHLOVEPRO 2008-12-22
  • 打赏
  • 举报
回复
if(dlg->GetSafeHanle() == NULL)
{
plg->Create(...);
....
}
加载更多回复(4)
学习计划:每天学习2小时,1个月可以学习完本套(上部)课程。课程目标:掌握虚拟现实房产领域的开发重点与难点,对商业开发的进度与质量保障起到事半功倍的效用。课程简介: 一:本套课程商业价值:        1:“三维数字房产互动展示”项目,是采用三维数字图像技术,将数字全景沙盘、虚拟样板房、数字三维户型透视、宣传片等内容包含其中。 其强大的三维图型界面使销售人员更能直观方便地向外界表达项目热点。        2: 本项目开发的最终目的是彻底解决了楼盘销售前置、规划展示单一和展示时间受限等问题,以更逼真、互动、高效的特点,将现有运营式取而代之。 二:本套课程(上中下)功能点概况:       1:数字全景沙盘展示(上部):            提供手工互动漫游、自动漫游、拍照留念、多语种、多分辨率支持。       2:虚拟样板房展示(中部):           提供样板房互动漫游、语音讲解、文字展示、样板房虚拟测距、样板房三维透视等功能展示。       3:样板房虚拟装修(中部):           提供样板房室墙壁不同材质、家私不同摆设、不同风格的预装修体验。       4:  项目整体介绍(下部):           包括项目地理位置、交通环境、整体项目效果图、楼盘整体介绍等。       5: 项目VR头盔展示(下部):          使用PICO头盔,激光线或贝塞尔曲线方式,对虚拟数字世界进行访问与交互。  三: 本教学项目特点:       1:本教学视频课程从企业真实房产项目中,提取核心技术要点,总结必须开发功能要素,多面而细致的讲解虚拟现实之三维数字房产项目中,需要开发的各个功能块、开发要点等。       2: 本作从项目环境搭建、环境素材导入、大型(超大型)项目整体优化策略分析与实现、自主漫游中各语音与NPC检测、自动漫游路线规划与实现、多摄像机管理、对话框、拍照留念、语言国际化等多个方面,给出详细的解决方案。本课程的细致学习将有助于,虚拟现实房产领域的高水平高效研发之目的!

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧