请教有关互斥量和非模式对话框唯一的问题

jackholy 2008-03-29 02:08:31
//点击按钮弹出非模式对话框:
void CMutexTestDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CString strName;
m_edtName.GetWindowText(strName);
CMutexDlg *pdlg = new CMutexDlg(strName);
if(pdlg->GetSafeHwnd() == NULL)
{
if(pdlg->Create() == TRUE)
m_staticMsg.SetWindowText( strName + " 成功创建!");
else
m_staticMsg.SetWindowText( strName + " 已经存在!");
}

}

//非模式对话框内创建互斥量, 使对话框唯一,其中互斥量名为传入参数。

CMutexDlg::CMutexDlg(CString str)
{
//{{AFX_DATA_INIT(CMutexDlg)
m_strName = str;
//}}AFX_DATA_INIT
}

BOOL CMutexDlg::Create()
{
m_hMutex = CreateMutex(NULL,TRUE,m_strName);
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
MessageBox("窗口已存在");
CloseHandle(m_hMutex);
return FALSE;
}
return CDialog::Create(CMutexDlg::IDD);
}

//关闭窗口 释放并关闭互斥量
void CMutexDlg::OnClose()
{
// TODO: Add your message handler code here and/or call default
ReleaseMutex(m_hMutex);
CloseHandle(m_hMutex);
CDialog::OnClose();
}


这样做确实能使非模式对话框唯一,但问题是关闭对话框以后(不能再打开了)并没有释放调互斥量,请问为什么?有什么解决方法没? 还有怎么通知父窗口该非模式对话框已经关闭?
...全文
103 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
jackholy 2008-03-29
  • 打赏
  • 举报
回复
感谢各位,问题已经解决。
果然不要用互斥量。
cnzdgs 2008-03-29
  • 打赏
  • 举报
回复
看你用什么方式关闭,你可以自己调试一下,或者用SPY++跟踪窗口消息。
jackholy 2008-03-29
  • 打赏
  • 举报
回复
嗯, 可以试一下
非模态的对话框关闭的时候触发的是哪个消息啊?
OnClose()
OnDestroy()
DestroyWindow()
DoModal()
还是只触发OnShowWindow(bShow, nStatus)。

cnzdgs 2008-03-29
  • 打赏
  • 举报
回复
你也可以在主对话框类中为每个子对话框定义一个指针变量,初始化为NULL,需要显示的时候判断指针变量是否为NULL,如果是则用new来分配,自对话框关闭销毁后向主窗口发个消息,由主对话框释放其空间,并把指针变量赋值为NULL。
jackholy 2008-03-29
  • 打赏
  • 举报
回复
每次打开一个非模态对话框以后,关闭的时候并没有销毁,只是隐藏起来了。
这样的话会不会很占资源啊,
就像你查看过几十个好友的资料并聊天后,虽然这些对话框都关闭了,但都只是通过ShowWindow隐藏着。
jameshooo 2008-03-29
  • 打赏
  • 举报
回复
每个好友肯定有一个结构,里面能定义一个类似的 CChatDlg* pDlg成员,然后每次像下面这样调用:
if (pDlg==NULL)
{
pDlg = new CChatDlg;
pDlg->Create(...);
pDlg->ShowWindow(SW_SHOW);
}

pDlg->SendMessage(...); // 通知某个聊天消息,或者设置状态,或者直接调用对话框的成员函数
jackholy 2008-03-29
  • 打赏
  • 举报
回复
6楼说的我大概明白了一些,但具体实现还要想一想。
7楼你说的有道理,怎么实现呢。
是不是定义一个结构
{
BOOL bChatDlgOpen;
CChatDlg *pwmd;
}
这种形式?
多谢大家指教,本人刚刚入门,没多少实际经验。
谁能够提供一个简单的实例学习学习。
jameshooo 2008-03-29
  • 打赏
  • 举报
回复
QQ这种唯一窗口根本用不到互斥量,每个好友都有一个对话框属性成员用来指示是否已打开了窗口,如果没打开就创建对话框,如果打开了就直接使用这个对话框。
cnzdgs 2008-03-29
  • 打赏
  • 举报
回复
你用什么方式关闭非模式对话框?如果你点OK/Cancel按钮(或者按Enter/Esc键)是不会有WM_CLOSE消息的。还有你new出来的对话框类要自己执行delete才会析构。

另外提一下,要使子对话框唯一,建议在主对话框类中构造一个子对话框的实例,并在主对话框创建后创建子对话框,然后用ShowWindow控制显示/隐藏子对话框,子对话框类中自己处理关闭时隐藏而不真正关闭。
jackholy 2008-03-29
  • 打赏
  • 举报
回复
3楼的方法我也试过了。还是一样,同一非模态窗口关了以后就再也打不开了。
jackholy 2008-03-29
  • 打赏
  • 举报
回复
我试过放在析构函数中也不行。
谁有这方面的经验啊。
就像用QQ的时候,对一个项(好友),可以弹出发送消息对话框,又可以弹出查看好友资料对话框,这些框都是怎么实现唯一的。
jameshooo 2008-03-29
  • 打赏
  • 举报
回复
m_hMutex = CreateMutex(NULL,FALSE,m_strName);

或者用1楼的方法。
jackholy 2008-03-29
  • 打赏
  • 举报
回复
不是不能要按钮失效。我本来想把问题简化。
原来的问题是一个ListCtrl里面的某项,通过双击或右键菜单要弹出各种非模态窗口的,保证各种窗口唯一。
wltg2001 2008-03-29
  • 打赏
  • 举报
回复
非模态对话框窗口关闭后,这个窗口并不是真正的关闭的,你可以将
ReleaseMutex(m_hMutex);
CloseHandle(m_hMutex);
放在析构函数中不是更好吗?另外用上面的方法让对话框窗口唯一并不是很好吧,不如让按钮失效不是更好.

15,471

社区成员

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

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