MFC 父子窗口传递消息及显示问题

cky77 2018-11-07 04:23:09
父窗口类A
B* pDlg;
pDlg = new B();
//B pDlg;
pDlg->Create(IDD_DIALOG_LOGIN,this);
pDlg->ShowWindow(SW_SHOW);


BOOL A::DestroyWindow()
{
// TODO: 在此添加专用代码和/或调用基类
delete pDlg;
pDlg = NULL;
return CDialogEx::DestroyWindow();
}


子窗口类B
void B::OnBnClickedBnCancel()
{
CDialogEx::OnCancel();
AfxGetMainWnd()->PostMessageA(WM_CLOSE);
//AfxGetApp()->GetMainWnd()->PostMessageA(WM_CLOSE);
}


问题1:子窗口B是父窗口A中new出来的,我在B中按钮事件给A发个关闭消息delete pDlg。这不符合逻辑吧?抛开逻辑讲,我发送WM_CLOSE消息后,A的DestroyWindow()函数断点没触发是为啥?A窗口类就是程序主窗口类。
问题2:在A里,如果我B b;b.create(IDD,this);b.showwindow(SW_SHOW);这时候B窗口是没有的,屏幕没有窗口,显示程序在运行。这是为啥?只能new才显示
...全文
200 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2018-11-09
  • 打赏
  • 举报
回复
不用new创建非模态对话框方法如下:

int DoEvents()
{
    MSG msg;
    // Process existing messages in the application's message queue.
    // When the queue is empty, do clean up and return.
    while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
    {// has msg
        if(msg.message== WM_APP) return 1;
        if (!AfxGetThread()->PumpMessage()) break;
    }
    return 0;
}
//
WNDPROC g_OldProc=0;
LRESULT CALLBACK NewProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    switch(message) 
    { 
    case WM_CLOSE: 
        PostMessage(GetParent(hwnd),WM_APP,0,0);
    break;
    case WM_COMMAND: // 0x0111
        if(LOWORD(wParam)==IDOK)
        {   
            PostMessage(GetParent(hwnd),WM_APP,0,0);
        }
    break;   
    } 
    return CallWindowProc(g_OldProc, hwnd, message, wParam, lParam);

//
void CxxxxDlg::OnButton1() 
{
    CAboutDlg dlg;// modeless dlg , not use new !!!
    dlg.Create(IDD_ABOUTBOX);
    dlg.ShowWindow(SW_SHOW);
    g_OldProc = (WNDPROC)SetWindowLong(dlg.m_hWnd, GWL_WNDPROC, (LONG)NewProc);
//
    while (!DoEvents());
    dlg.DestroyWindow();
    afxDump << "Dlg closed()\n";
}
cky77 2018-11-09
  • 打赏
  • 举报
回复
嗯嗯,我5楼和8楼的说法不对,各位不要参考。请参考9楼和12楼
绿色盒子 2018-11-08
  • 打赏
  • 举报
回复

class A;//声明A
//需要关闭的地方
A dlg;
dlg.pDlg=NULL;//pDlg是父对话框中声明的B的指针
DestroyWindow();

//重载B PostNcDestroy()消息
void B::PostNcDestroy()
{
CDialogEx::PostNcDestroy();
delete this;
}
绿色盒子 2018-11-08
  • 打赏
  • 举报
回复
你需要在B中关闭自己应该这么写(B是非模态对话框)

class B;//声明B
//需要关闭的地方
B dlg;
dlg.pDlg=NULL;//pDlg是父对话框中声明的B的指针
DestroyWindow();

//重载B PostNcDestroy()消息
void B::PostNcDestroy()
{
CDialogEx::PostNcDestroy();
delete this;
}
schlafenhamster 2018-11-08
  • 打赏
  • 举报
回复
B b;b.create(IDD,this);b.showwindow(SW_SHOW);这么写 不是不对,而是 B b; 不能是 局部 变量 ,要 是 模态变量
(B m_b; 在头文件 里),因为 ;b.create(IDD,this); 不是 模态的 不 堵塞,程序 执行完后 ,局部 变量 B b 会被 销毁、
再 showwindow(SW_SHOW) 已不可能 。

windows 对象 创建 分2 步 1 构造 一个 对象 (包括 B b 和 B *pB=new B)。
第2步 Create 。创建 该 对象 !
cky77 2018-11-08
  • 打赏
  • 举报
回复
引用 7 楼 schlafenhamster 的回复:
b.create(IDD,this) 是 modeless 对话框


嗯嗯,用create时候要b=new B(),用B b就不行,我两个用混了。
schlafenhamster 2018-11-08
  • 打赏
  • 举报
回复
"B b;b.domodel()就好了"是因为 domodel 是 模态的 ,要等 对话框 退出,domodel 才退出,
期间 B b; 一直有效到 对话框退出。
schlafenhamster 2018-11-07
  • 打赏
  • 举报
回复
b.create(IDD,this) 是 modeless 对话框
cky77 2018-11-07
  • 打赏
  • 举报
回复
然后A里面的DestroyWindow()函数也不要重写。添加A的析构函数在里面加一句DestroyWindow();就好了。
cky77 2018-11-07
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
问题1: SendMessage
问题2:先要 显示 主窗口 见 App InitInstance


我犯了一个好低级的错误....
模态窗口 B b;b.domodel()就好了。。我B b;b.create(IDD,this);b.showwindow(SW_SHOW);这么写不对
cky77 2018-11-07
  • 打赏
  • 举报
回复
	CXMLParseDlg dlg;
m_pMainWnd = &dlg;
//INT_PTR nResponse = dlg.DoModal();
INT_PTR nResponse = dlg.Create(CXMLParseDlg::IDD);
dlg.ShowWindow(SW_HIDE);
dlg.RunModalLoop();

我主窗口 InitInstance是这样写的。
当时因为,因为啥我也忘了。反正就是主窗口不显示,直接显示子窗口。导致现在看着好乱
zgl7903 2018-11-07
  • 打赏
  • 举报
回复

// DlgTest10Dlg.h : header file
#include "SubDlg.h"

class CDlgTest10Dlg : public CDialog
{
public:
CSubDlg m_SubDlg;
void ParentProcessSubClose(UINT nID);
protected:
afx_msg void OnShowhideSub();
……
};




// DlgTest10Dlg.cpp : implementation file
BEGIN_MESSAGE_MAP(CDlgTest10Dlg, CDialog)
//{{AFX_MSG_MAP(CDlgTest10Dlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_SHOWHIDE_SUB, OnShowhideSub)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//显示/隐藏子窗口
void CDlgTest10Dlg::OnShowhideSub()
{
// TODO: Add your control notification handler code here
if(m_SubDlg.m_hWnd == NULL)
{
if(m_SubDlg.Create(this))
{
m_SubDlg.ShowWindow(SW_SHOW);
}
}
else
{
m_SubDlg.DestroyWindow();
m_SubDlg.m_bModelessCreate = FALSE;
}
}

//处理子窗口关闭
void CDlgTest10Dlg::ParentProcessSubClose(UINT nID)
{
if(m_SubDlg.m_hWnd)
{
m_SubDlg.DestroyWindow();
}
CString szMsg;
szMsg.Format(_T("Sub dialog select %u"), nID);
AfxMessageBox(szMsg);
}



// SubDlg.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CSubDlg dialog

class CSubDlg : public CDialog
{

public:
virtual BOOL Create(CWnd* pParentWnd);
BOOL m_bModelessCreate;

protected:
virtual void OnOK();
virtual void OnCancel();
void EndMyDialog(int nResult);
……
};




CSubDlg::CSubDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSubDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSubDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_bModelessCreate = FALSE; //初始化非模态指示
}
// CSubDlg message handlers

BOOL CSubDlg::Create(CWnd* pParentWnd)
{
m_bModelessCreate = TRUE; //非模态方式创建
return CDialog::Create(m_lpszTemplateName, pParentWnd);
}

#include "DlgTest10Dlg.h"

void CSubDlg::EndMyDialog(int nResult)
{
CDlgTest10Dlg *pDlg = (CDlgTest10Dlg*)GetParent();
if(m_bModelessCreate && pDlg) //非模态方式关闭
{
pDlg->ParentProcessSubClose(nResult); //调用父类处理关闭
}
else
{
EndDialog(nResult); //结束模态对话框
}

m_bModelessCreate = FALSE; //清除非模态标记
}

void CSubDlg::OnOK()
{
EndMyDialog(IDOK);
}
void CSubDlg::OnCancel()
{
EndMyDialog(IDCANCEL);
}

cky77 2018-11-07
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
问题1: SendMessage
问题2:先要 显示 主窗口 见 App InitInstance

1.sendmessage我试过了,断点不触发
2.我开始主窗口确实是隐藏的,但是改成可见后。子窗口如果用B b;b.create(IDD,this);b.showwindow(SW_SHOW);还是没有
schlafenhamster 2018-11-07
  • 打赏
  • 举报
回复
问题1: SendMessage
问题2:先要 显示 主窗口 见 App InitInstance

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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