派生CDialog类的问题

lswandym_888 2010-06-10 08:41:09
在Project中有很多Dialog,且背景色及响应回车键、ESC键的方法都一样,故想先从CDialoog类派生出一个MyDialog类。对此对进行相关设置,然后将那些很多对话框的基类都修改为MyDialog,有以下问题没有解决,请高手们帮帮忙。
1、MyDialog是否可以不绑定对话框ID.
2、我在MyDialog可改变了背景颜色,但在MyDialogEx中怎么没变。
...全文
223 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
subfly 2010-06-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 nola 的回复:]
1.MyDialog一定要关联对话框ID。
2.MyDialogEx确认是继承了MyDialog吗
[/Quote]
我也觉得应该要绑定一个ID的
zxdlms 2010-06-11
  • 打赏
  • 举报
回复
把代码贴出来让大家给分析下。
lswandym_888 2010-06-11
  • 打赏
  • 举报
回复
结贴前把结果写一下,多谢各位的帮助!!!
void CSetSchoolInfos::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
((CTeachResultGovernSysDlg*)AfxGetMainWnd())->m_SetSchoolInfosDlg=NULL;
}
zxdlms 2010-06-11
  • 打赏
  • 举报
回复
MSDN:
When you implement a modeless dialog box, always override the OnCancel member function and call DestroyWindow from within it. Don't call the base class CDialog::OnCancel, because it calls EndDialog, which will make the dialog box invisible but will not destroy it. You should also override PostNcDestroy for modeless dialog boxes in order to delete this, since modeless dialog boxes are usually allocated with new. Modal dialog boxes are usually constructed on the frame and do not need PostNcDestroy cleanup.

lswandym_888 2010-06-11
  • 打赏
  • 举报
回复
做了,不行,顺序是怎样的,不调用CDialog::OnCancel关闭,那调用什么关闭?
zxdlms 2010-06-11
  • 打赏
  • 举报
回复
非模式对话框关闭不能调用CDialog::OnCancel,要自己在OnCancel中调用DestroyWindow,并重写PostNcDestroy。具体看MSDN。
lswandym_888 2010-06-11
  • 打赏
  • 举报
回复
我的对话框改为非模式,用Create创建(创建前测试指针),关闭后怎么发现没有真正的关闭,我再次创建对话框时测试了指针,居然非空。
zxdlms 2010-06-11
  • 打赏
  • 举报
回复
看你的代码也没啥问题,不过如果你的OnCancel不做什么就不要重写了,CDialog::OnCancel会调用EndDialog关闭对话框的,不需要你自己调用CDialog::DestroyWindow();
lswandym_888 2010-06-11
  • 打赏
  • 举报
回复
基本解决,就是单击对话框标题栏右端的关闭时,总是要多单击几次,请高手帮助解决。(我修改后的代码如下)
//.h
class CDialogCEx : public CDialog
{
DECLARE_DYNAMIC(CDialogCEx)

public:
CDialogCEx(UINT ID,CWnd* pParent = NULL); // 标准构造函数
virtual ~CDialogCEx();
CBrush m_brushBlue;

// 对话框数据
//enum { IDD = IDD_DIALOGCEX };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void OnCancel();
public:
afx_msg void OnPaint();
// 标题文字
CString m_title;
// 打印标题
void PrintTitle(CString title);
};

//.cpp
MPLEMENT_DYNAMIC(CDialogCEx, CDialog)

CDialogCEx::CDialogCEx(UINT ID,CWnd* pParent /*=NULL*/)
: CDialog(ID, pParent)
, m_title(_T(""))
{

}

CDialogCEx::~CDialogCEx()
{
}

void CDialogCEx::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDialogCEx, CDialog)
ON_WM_CTLCOLOR()
ON_WM_PAINT()
END_MESSAGE_MAP()


// CDialogCEx 消息处理程序

BOOL CDialogCEx::OnInitDialog()
{
CDialog::OnInitDialog();

m_brushBlue.CreateSolidBrush(RGB(232,240,236));

return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

HBRUSH CDialogCEx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if(nCtlColor==CTLCOLOR_DLG)//实现改变对话框背景
return m_brushBlue;
if(nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_BTN || nCtlColor == CTLCOLOR_STATIC)//改变控件背景为透明模式
{
pDC->SetBkMode(TRANSPARENT);
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}

return hbr;
}

BOOL CDialogCEx::PreTranslateMessage(MSG* pMsg)
{
if(pMsg-> message==WM_NCLBUTTONDOWN || pMsg->message==WM_KEYDOWN && (pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE))//阻止回车键及ESC键使对话框退出
{
if(pMsg-> message==WM_NCLBUTTONDOWN)
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)//按回车键跳至下一控件
NextDlgCtrl();
return true;
}

return CDialog::PreTranslateMessage(pMsg);
}

void CDialogCEx::OnCancel()
{
CDialog::DestroyWindow();

CDialog::OnCancel();
}

void CDialogCEx::OnPaint()
{
CPaintDC dc(this);
PrintTitle(m_title);
}

void CDialogCEx::PrintTitle(CString title)
{
CRect rect;
GetWindowRect(rect);

CFont * f;
f = new CFont;
f->CreateFont(26, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_BOLD, // nWeight FW_BOLD表粗体;FW_NORMAL表常规
FALSE, // bItalic TRUE时为斜体
TRUE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial")); // lpszFac

CDC *pDC = GetDC();
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,128,64));
pDC->SelectObject(f);
pDC->TextOut(rect.Width()/2-pDC->GetTextExtent(title).cx/2, 12, title);
ReleaseDC(pDC);
delete f;
}

//派生自CDialogCEx的实际对话框类
//.h
class CDia1 : public CDialogCEx
{
DECLARE_DYNAMIC(CDia1)

public:
CDia1(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDia1();

// 对话框数据
enum { IDD = IDD_DIA1 };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

DECLARE_MESSAGE_MAP()
public:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual BOOL OnInitDialog();
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnPaint();
afx_msg void OnBnClickedButton1();
};

//.cpp
IMPLEMENT_DYNAMIC(CDia1, CDialogCEx)

CDia1::CDia1(CWnd* pParent /*=NULL*/)
: CDialogCEx(CDia1::IDD, pParent)
{

}

CDia1::~CDia1()
{
}

void CDia1::DoDataExchange(CDataExchange* pDX)
{
CDialogCEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDia1, CDialogCEx)
ON_WM_CTLCOLOR()
ON_WM_PAINT()
ON_BN_CLICKED(IDC_BUTTON1, &CDia1::OnBnClickedButton1)
END_MESSAGE_MAP()


// CDia1 消息处理程序

HBRUSH CDia1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogCEx::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: 在此更改 DC 的任何属性

// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return hbr;
}

BOOL CDia1::OnInitDialog()
{
CDialogCEx::OnInitDialog();

// TODO: 在此添加额外的初始化

return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

BOOL CDia1::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类

return CDialogCEx::PreTranslateMessage(pMsg);
}

void CDia1::OnPaint()
{
CPaintDC dc(this);
this->PrintTitle("hhhhhh");
}

void CDia1::OnBnClickedButton1()
{
AfxMessageBox("ghood");
}
zxdlms 2010-06-11
  • 打赏
  • 举报
回复
你的构造函数写的有问题,如果对话框类作为基类,是不需要绑定ID的,当时得让派生类把ID传进来啊。

基类的构造函数

CDialogEx(UINT uID, CWnd *pParent = NULL);

CDialogEx::CDialogEx(UINT uID, CWnd *pParent)
: CDialog(uID, pParent)
{

}


派生类的构造函数

CDia1(CWnd *pParent = NULL)

CDia1::CDia1(CWnd *pParent)
: CDialogEx(CDia1::IDD, pParent)
{

}


lswandym_888 2010-06-11
  • 打赏
  • 举报
回复
派生自CDialogCEx的子类

//.h
class CDia1 : public CDialogCEx
{
DECLARE_DYNAMIC(CDia1)

public:
CDia1(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDia1();

// 对话框数据
enum { IDD = IDD_DIA1 };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

DECLARE_MESSAGE_MAP()
public:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual BOOL OnInitDialog();
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnPaint();
afx_msg void OnBnClickedButton1();
};

//.cpp
IMPLEMENT_DYNAMIC(CDia1, CDialogCEx)

CDia1::CDia1(CWnd* pParent /*=NULL*/)
: CDialogCEx(/*CDia1::IDD,*/ pParent)
{

}

CDia1::~CDia1()
{
}

void CDia1::DoDataExchange(CDataExchange* pDX)
{
CDialogCEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDia1, CDialogCEx)
ON_WM_CTLCOLOR()
ON_WM_PAINT()
ON_BN_CLICKED(IDC_BUTTON1, &CDia1::OnBnClickedButton1)
END_MESSAGE_MAP()


// CDia1 消息处理程序

HBRUSH CDia1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogCEx::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: 在此更改 DC 的任何属性

// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return hbr;
}

BOOL CDia1::OnInitDialog()
{
CDialogCEx::OnInitDialog();

// TODO: 在此添加额外的初始化

return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

BOOL CDia1::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类

return CDialogCEx::PreTranslateMessage(pMsg);
}

void CDia1::OnPaint()
{
CPaintDC dc(this);
this->PrintTitle("hhhhhh");
}

void CDia1::OnBnClickedButton1()
{
AfxMessageBox("ghood");
}


出现了一件奇怪的事,我对CDia1进行DoModal时,CDia1上的Button1没有显示,是不是绑定资源应改。怎么改。
lswandym_888 2010-06-11
  • 打赏
  • 举报
回复
//.H
class CDialogCEx : public CDialog
{
DECLARE_DYNAMIC(CDialogCEx)

public:
CDialogCEx(CWnd* pParent = NULL); // 标准构造函数
virtual ~CDialogCEx();
CBrush m_brushBlue;

// 对话框数据
enum { IDD = IDD_DIALOGCEX };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持

DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void OnCancel();
public:
afx_msg void OnPaint();
// 标题文字
CString m_title;
// 打印标题
void PrintTitle(CString title);
};

//.CPP
IMPLEMENT_DYNAMIC(CDialogCEx, CDialog)

CDialogCEx::CDialogCEx(CWnd* pParent /*=NULL*/)
: CDialog(CDialogCEx::IDD, pParent)
, m_title(_T("dkjddj"))
{

}

CDialogCEx::~CDialogCEx()
{
}

void CDialogCEx::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CDialogCEx, CDialog)
ON_WM_CTLCOLOR()
ON_WM_PAINT()
END_MESSAGE_MAP()


// CDialogCEx 消息处理程序

BOOL CDialogCEx::OnInitDialog()
{
CDialog::OnInitDialog();

m_brushBlue.CreateSolidBrush(RGB(232,240,236));

return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}

HBRUSH CDialogCEx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if(nCtlColor==CTLCOLOR_DLG)//实现改变对话框背景
return m_brushBlue;
if(nCtlColor == CTLCOLOR_DLG || nCtlColor == CTLCOLOR_BTN || nCtlColor == CTLCOLOR_STATIC)//改变控件背景为透明模式
{
pDC->SetBkMode(TRANSPARENT);
return HBRUSH(GetStockObject(HOLLOW_BRUSH));
}

return hbr;
}

BOOL CDialogCEx::PreTranslateMessage(MSG* pMsg)
{
if(pMsg-> message==WM_NCLBUTTONDOWN || pMsg->message==WM_KEYDOWN && (pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE))//阻止回车键及ESC键使对话框退出
{
if(pMsg-> message==WM_NCLBUTTONDOWN)
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
if(pMsg->message==WM_KEYDOWN && pMsg->wParam==VK_RETURN)//按回车键跳至下一控件
NextDlgCtrl();
return true;
}

return CDialog::PreTranslateMessage(pMsg);
}

void CDialogCEx::OnCancel()
{
CDialog::DestroyWindow();

CDialog::OnCancel();
}

void CDialogCEx::OnPaint()
{
CPaintDC dc(this);
PrintTitle(m_title);
}

void CDialogCEx::PrintTitle(CString title)
{
CRect rect;
GetWindowRect(rect);

CFont * f;
f = new CFont;
f->CreateFont(26, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_BOLD, // nWeight FW_BOLD表粗体;FW_NORMAL表常规
FALSE, // bItalic TRUE时为斜体
TRUE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial")); // lpszFac

CDC *pDC = GetDC();
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(0,128,64));
pDC->SelectObject(f);
pDC->TextOut(rect.Width()/2-pDC->GetTextExtent(title).cx/2, 12, title);
ReleaseDC(pDC);
delete f;
}
weskiter51 2010-06-11
  • 打赏
  • 举报
回复
不懂,up
for0012 2010-06-11
  • 打赏
  • 举报
回复
不懂,up
gz_qmc 2010-06-11
  • 打赏
  • 举报
回复
定义类,不用绑定,创建实例的时候才需要ID
kakaximodo 2010-06-10
  • 打赏
  • 举报
回复
如果只纯做基类,可以不绑定吧
第二个应该是继承的问题了
疯癫小程序 2010-06-10
  • 打赏
  • 举报
回复
顶下,最近比较忙。。。
lswandym_888 2010-06-10
  • 打赏
  • 举报
回复
多谢各位,再试试,等待解决中……
bdzwj 2010-06-10
  • 打赏
  • 举报
回复
这种情况用模板比较合适
lswandym_888 2010-06-10
  • 打赏
  • 举报
回复
还是不行,怎么回事。
是不是要将CMyDialog1的所有基类都改为CMyDialog。
都改了的,但是问题依旧。
加载更多回复(4)

16,548

社区成员

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

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

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