在VC下有時需要製作個人化的視窗介面,用介面庫又比較繁瑣,而且有些介面庫還必須收費才能使用,這裡我提供一個簡單且有效製作個人化介面的方法。
由AppWizard嚮導產生一個基於對話方塊的應用程式架構,把對話方塊模板的Border屬性改為none,也就是沒有邊框和標題列。從CDialog派生一個類,命名為CCustomDlg。首先我們要建立不規則視窗的介面,要用到以下函數,
int
SetWindowRgn( HRGN
hRgn, BOOL
bRedraw );
這個函數用來設定應用程式視窗的視窗地區,在本文的例子中我們使用CreateRoundRectRgn建立一個圓角矩形地區,然後再調用SetWindowRgn設定視窗地區。CreateRoundRectRgn的原型如下:
BOOL
CreateRoundRectRgn( int
x1, int
y1, int
x2, int
y2, int
x3, int
y3 );
具體代碼如下:
BOOL
CCustomDlgDlg::OnInitDialog()
{
CDialog::OnInitDialog();
......
//set valid
region
CRgn rgn;
CRect rectFrame;
GetClientRect(&rectFrame);
rgn.CreateRoundRectRgn(rectFrame.left,rectFrame.top,rectFrame.right+1,rectFrame.bottom+1,30,30);
SetWindowRgn(rgn,TRUE);
//
TODO: Add extra initialization here
return
TRUE; // return
TRUE unless you set the focus to a control
}
因為對話方塊已經設定了none
border屬性,所以GetClientRect(&rectFrame)得到的就為對話方塊模板整個視窗大小,然後再建立圓角矩形,注意建立圓角矩形的時候要注意第三,第四個參數都要加1(後面會講原因)。
接下來,映射WM_ERASEBKGND訊息來改變背景,需手工加入ON_WM_ERASEBKGND(),同時不要忘了在標頭檔中加入
afx_msg BOOL
OnEraseBkgnd(CDC *pDC);
編輯處理函數:
BOOL
CCustomDlgDlg::OnEraseBkgnd(CDC *pDC)
{
CRect rect;
GetClientRect(&rect);
CBrush *pOldBrush =
pDC->SelectObject(&m_brBrush);
pDC->RoundRect(&rect,
CPoint(30,30));
pDC->SelectObject(pOldBrush);
return
TRUE;
}
pDC->RoundRect(&rect, CPoint(30, 30));
預設是用黑筆畫矩形,到這裡應該知道上面的第三,第四個參數為什麼要加1了,因為預設黑筆的寬度就為1個像素單位,RoundRect實際畫出的矩形的長度和寬度都多1,大家可能會想,為什麼不用rectFrame.left減1,和rectFrame.top減1這種方法呢?它也會使長度和寬度都多1啊,問題在於rectFrame.left,
rectFrame.top都為0,減1就都為-1, 用CreateRoundRectRgn建立地區時值又會變為0,這樣長度和寬度還是沒有增加。
再接下來,加入一CBrush類型的成員變數m_brBrush,在建構函式中加入
m_brBrush.CreateSolidBrush(RGB(239,243,255));
用ClassWizard映射WM_CTLCOLOR訊息,並編輯代碼。作用是改變對話方塊中控制項的顏色以使對話方塊背景相符,不過不能用此法改變按鈕的顏色,按鈕用自繪來改變顏色,這方面內容本文就不介紹了,網上有很多此類文章。
HBRUSH
CCustomDlgDlg::OnCtlColor(CDC*
pDC, CWnd* pWnd, UINT
nCtlColor)
{
HBRUSH
hbr = CDialog::OnCtlColor(pDC,
pWnd, nCtlColor);
if
(CTLCOLOR_STATIC==nCtlColor || CTLCOLOR_DLG==nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return
m_brBrush;
}
// TODO: Return a different brush if
the default is not desired
return
hbr;
}
接著,映射WM_NCHITTEST訊息,需手工加入,ON_WM_NCHITTEST(),同時不要忘了在標頭檔加入
afx_msg UINT
OnNcHitTest(CPoint point);
編輯處理函數:
UINT
CCustomDlgDlg::OnNcHitTest(CPoint point)
{
UINT
nHitTest = CDialog::OnNcHitTest (point);
if
(nHitTest == HTCLIENT)
nHitTest = HTCAPTION;
return
nHitTest;
}
這樣之後就可以用滑鼠拖動對話方塊了。
以上內容轉載自:http://blog.csdn.net/World7th/archive/2007/06/13/1650669.aspx