天天看點

VC個性化視窗界面設計

在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;
}
            

這樣之後就可以用滑鼠拖動對話框了。

繼續閱讀