當對話框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派生類對象可以用在任何需基類對象的地方。