派生CDialog类的问题

lswandym_888 2010-06-10 08:41:09
在Project中有很多Dialog,且背景色及响应回车键、ESC键的方法都一样,故想先从CDialoog类派生出一个MyDialog类。对此对进行相关设置,然后将那些很多对话框的基类都修改为MyDialog,有以下问题没有解决,请高手们帮帮忙。
1、MyDialog是否可以不绑定对话框ID.
2、我在MyDialog可改变了背景颜色,但在MyDialogEx中怎么没变。
...全文
216 24 打赏 收藏 转发到动态 举报
写回复
用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)
常用MFC和API函数 索引 CArchive:用于二进制保存档案 CBitmap:封装Windows的图形设备接口(GDI)位图 CBrush:封装图形设备接口(GDI)中的画刷 CButton:提供Windows按钮控件的功能 CByteArray:该支持动态的字节数组 CCmdUI:该仅用于ON_UPDATE_COMMAND_UI处理函数中 CColorDialog:封装标准颜色对话框 CDC:定义设备环境对象 CDialog:所有对话框(模态或非模态)的基 CDocument:提供用户定义的文档的基本功能 CEdit:是一个用于编辑控件的 CFile:该是基本文件的基 CFileDialog:封装了打开和保存文件的标准对话框 CFindReplaceDialog:封装了标准查找/替换对话框 CFont:封装了Windows图形设备接口(GDI)中的字体对象 CFontDialog:封装了字体选择对话框 CGdiObject:GDI绘图工具的基 CIPAddressCtrl:提供了IP地址控件的功能 CImageList:管理大小相同的图标或位图集 CMenu:封装应用程序菜单栏和弹出式菜单 CPen:封装了Windows图形设备接口(GDI)中的画笔对象 CPoint:操作CPoint和POINT结构 CRect:封装了一个矩形区域及相关操作 CRgn:封装用于操作窗口中的椭圆、多边形或者不规则区域的GDI区域 CSize:用于表示相对坐标或位置 CSpinButtonCtrl:旋转控件Spin的控制 CStatusBar:状态栏窗口的基 CString:处理字符串 CStringList:支持CString对象的列表 CWinApp派生的程序对象的基 CWnd:提供所有窗口的基本函数 API函数 CArchive:用于二进制保存档案 CArchive::CArchive 建立一个CArchive对象 CArchive(CFile* pFile,UINT nMode,int nBufSize=4096,void* lpBuf=NULL); 参数:pFile 指向CFile对象的指针,这个CFile对象
CWnd提供了微软基础库中所有窗口的基本功能。 CWnd对象与Windows的窗口不同,但是两者有紧密联系。CWnd对象是由CWnd的构造函数和析构函数创建或销毁的。另一方面,Windows的窗口是Windows的一种内部数据结构,它是由CWnd的Create成员函数创建的,而由CWnd的虚拟析构函数销毁。DestroyWindow函数销毁Windows的窗口,但是不销毁对象。 CWnd和消息映射机制隐藏了WndProc函数。接收到的Windows通知消息通过消息映射被自动发送到适当的CWnd OnMessage成员函数。你可以在派生中重载OnMessage成员函数以处理成员的特定消息。 CWnd同时还使你能够为应用程序创建Windows的子窗口。先从CWnd继承一个,然后在派生中加入成员变量以保存与你的应用程序有关的数据。在派生中实现消息处理成员函数和消息映射,以指定当消息被发送到窗口时应该如何动作。 你可以经过两个步骤来创建一个子窗口。首先,调用构造函数CWnd以创建一个CWnd对象,然后调用Create成员函数以创建子窗口并将它连接到CWnd对象。 当用户关闭你的子窗口时,应销毁CWnd对象,或者调用DestroyWindow成员函数以清除窗口并销毁它的数据结构。 在微软基础库中,从CWnd派生了许多其它以提供特定的窗口型。这些中有许多,包括CFrameWnd,CMDIFrameWnd,CMDIChildWnd,CView和CDialog,被用来进一步派生。从CWnd派生的控件,如CButton,可以被直接使用,也可以被进一步派生出其它来。

16,471

社区成员

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

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

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