当对话框DoModal返回后,对话框句柄被销毁,同时,对话框中的所有控件的句柄都会被销毁,所以所有的控件类型都不可用,但是普通的值类型对象的值还是存在的知道对话框对象生命周期结束。
在VC6.0中将很多控件调整为一样大小的或者对齐排列时候开始总是不知以哪一个为标准,试了几次发现:用CTRL和鼠标左键选中的以最后一个为标准,用鼠标圈住时以第一个进入的为标准。
HWND是Windows系统中对所有窗口的一种标识,即窗口句柄。这是一个SDK概念。
CWnd是MFC类库中所有窗口类的基类。微软在MFC中将所有窗口的通用操作都封装到了这个类中,如:ShowWindow等等,同时它也封装了窗口句柄即m_hWnd成员。
由HWnd得到CWnd*:
CWnd wnd;
HWnd hWnd;
wnd.Attach(hWnd);
通常一个窗口资源已经和一个CWnd类的对象关联起来的,由于一般来说这个类是自己创建的,所以自然知道怎么得到指向这个类的指针。如果没有就创建一个CWnd对象,将这个对象与窗口资源的hWnd句柄关联起来。(如上边的语句)。如果用
static CWnd* CWnd::FromHandle(HWND hWnd) ;
则返回值是一个暂时的CWnd对象,并且我们确保返回值为非空,也就是hWnd是有效的。
static CWnd* CWnd::FromHandlePermanent(HWND hWnd) ;
返回的是一个永久的对象。只有在返回的CWnd在类表里已经存在是返回值为非空。
由CWnd获取HWnd就容易多了,因为它的一个成员m_hWnd就是所对应窗口的句柄。
wnd->m_hWnd。
---- 方法一:调用CWinApp类的成员函数SetDialogBkColor来实现。
---- 其中函数的第一个参数指定了背景颜色,第二个参数指定了文本颜色。
下面的例子是将应用程序对话框设置为蓝色背景和红色文本,步骤如下:
---- ① 新建一个基于Dialog的MFC AppWizard应用程序ExampleDlg。
---- ② 在CExampleDlgApp ::InitInstance()中添加如下代码:
BOOL CExampleDlgApp: : InitInstance ( )
{
…
CExampleDlgDlg dlg;
m_pMainWnd = &dlg;
//先于DoModal()调用,将对话框设置为蓝色背景、红色文本
SetDialogBkColor(RGB(0,0,255),RGB(255,0,0));
int nResponse = dlg.DoModal();
…
}
---- 编译并运行,此时对话框的背景色和文本色已发生了改变。值得注意的
是:在调用DoModal()之前必须先调用SetDialogBkColor,且此方法是将改变
应用程序中所有的对话框颜色,并不能针对某一个指定的对话框。
---- 方法二:重载OnPaint(),即WM_PAINT消息。有关代码如下(以上例工程为准):
void CExampleDlgDlg::OnPaint()
{
if (IsIconic())
…
else
{
CRect rect;
CPaintDC dc(this);
GetClientRect(rect);
dc.FillSolidRect(rect,RGB(0,255,0)); //设置为绿色背景
CDialog::OnPaint();
}
---- 方法三:重载OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor),
即WM_CTLCOLOR消息。具体步骤如下(以上例工程为准):
---- ①在CExampleDlgDlg的头文件中,添加一CBrush的成员变量:
class CExampleDlgDlg : public CDialog
{
...
protected:
CBrush m_brush;
...
};
---- ②在OnInitDialog()函数中添加如下代码:
BOOL CExampleDlgDlg::OnInitDialog()
{
...
// TODO: Add extra initialization here
m_brush.CreateSolidBrush(RGB(0, 255, 0)); // 生成一绿色刷子
...
}
---- ③利用ClassWizard重载OnCtlColor(…),即WM_CTLCOLOR消息:
HBRUSH CExampleDlgDlg::OnCtlColor
(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
/*
** 这里不必编写任何代码!
**下行代码要注释掉
** HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
*/
return m_brush; //返加绿色刷子
}
---- 方法四:还是重载OnCtlColor (CDC* pDC, CWnd* pWnd, UINT nCtlColor),
即WM_CTLCOLOR消息。具体步骤如下(以上例工程为准):
---- 步骤①、②同上方法三中的步骤①、②。
---- 步骤③利用ClassWizard重载OnCtlColor(…)(即WM_CTLCOLOR消息)时则有
些不同:
HBRUSH CExampleDlgDlg::OnCtlColor
(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
//在这加一条是否为对话框的判断语句
if(nCtlColor ==CTLCOLOR_DLG)
return m_brush; //返加绿色刷子
return hbr;
}
原帖见:
http://topic.csdn.net/t/20020821/08/957154.html
在栈上创建CPaintDC对象是良好的编程习惯,这样当OnPaint结束时将自动调用他们的析构函数。如果用new操作符来实例化一个CPaintDC对象,在OnPaint结束之前删除那个对象很重要。否则::EndPaint将不会被调用。
Visual C++有一种简单的方法用来确定是否成功删除了画笔,画刷和其他资源:只要在调试状态下运行程序。在应用程序终止时,没有释放的资源会显示在调试窗口中。
在最新版本的Windows中,允许GDI对象在设备描述表释放的前一刻被删除并没有什么不好的影响,尤其是当你能确保在此期间没有画图程序执行时更是如此。但是通过取消选定选入的对象而实现清除设备描述表仍然是Windows编程中的惯例。同时也是一种好习惯。
当写下:
char ch[5];
ch = "last";
编译提示:error C2106: '=' : left operand must be l-value。所以只能在数组定义的同时用字符串常量来给它赋值。
但是写下:
char *pa;
pa = "last";
就不会有错误。说明数组名字是一个常指针,不能被重新赋值。
引用和指针的的静态类型和动态类型可以不同,这是C++用以支持多态的基石。
在同一虚函数的基类版本和派生类版本使用不同的默认实参几乎一定会引起麻烦!
设计良好的类的层次中,public派生类对象可以用在任何需基类对象的地方。