需求:有時候為了做出好看的UI,不需要使用Windows自帶的最大化最小化和關閉按鈕,那么此時對話框一定的屬性中Border一定就不是Dialog Frame了,應該選擇None,此時沒有邊框,那么就需要給對話框重繪一個邊框。
思想:重繪邊框,主要是對top,left,right和bottom四個邊進行重新繪制。
處理:具體的實現細節和代碼如下:
第一步:重載DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam),並添加以下代碼:
1 LRESULT CPswDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 2 { 3 LRESULT lResult = CDialog::DefWindowProc(message, wParam, lParam); 4 5 CWnd* pWnd = this->GetParent(); 6 m_hWnd = pWnd->m_hWnd; 7 if (!::IsWindow(m_hWnd)) 8 { 9 return lResult; 10 } 11 12 if (message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message==WM_NCACTIVATE ||message == WM_NOTIFY) 13 { 14 CDC* pWinDC = GetWindowDC(); 15 if (pWinDC) 16 { 17 DrawBorder(pWinDC); 18 } 19 ReleaseDC(pWinDC); 20 } 21 return lResult; 22 //return CDialog::DefWindowProc(message, wParam, lParam); 23 }
此處有一個重繪函數需要實現:
1 void CPswDlg::DrawBorder(CDC *pDC) 2 { 3 if (m_hWnd ) 4 { 5 CBrush Brush(RGB(185, 184, 182)); 6 CBrush* pOldBrush = pDC->SelectObject(&Brush); 7 8 CRect rtWnd; 9 GetWindowRect(&rtWnd); 10 11 CPoint point; 12 //填充頂部框架 13 point.x = rtWnd.Width(); 14 point.y = GetSystemMetrics(SM_CYFRAME)+1; 15 pDC->PatBlt(0, 0, point.x, point.y, PATCOPY); 16 //填充左側框架 17 point.x = GetSystemMetrics(SM_CXFRAME); 18 point.y = rtWnd.Height(); 19 pDC->PatBlt(0, 0, point.x, point.y, PATCOPY); 20 //填充底部框架 21 point.x = rtWnd.Width(); 22 point.y = GetSystemMetrics(SM_CYFRAME) + 1; 23 pDC->PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY); 24 //填充右側框架 25 point.x = GetSystemMetrics(SM_CXFRAME); 26 point.y = rtWnd.Height(); 27 pDC->PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY); 28 } 29 }
由於在設置對話框的Border的屬性時選擇的是None,那么此時鼠標點擊對話框拖動就失去了作用,使用如下的代碼是可以實現拖動的:
1 LRESULT CPswDlg::OnNcHitTest(CPoint point) 2 { 3 UINT nh = CDialog::OnNcHitTest(point); 4 return ((nh==HTCLIENT) ? HTCAPTION : nh); 5 6 //return CDialog::OnNcHitTest(point); 7 }
這里是重載了WM_NCHITTEST消息。另外,按照以上重繪的邊框,邊框的四個角都是直角,使用如下代碼,可以將直角變為圓角。
1 void CPswDlg::OnSize(UINT nType, int cx, int cy) 2 { 3 CDialog::OnSize(nType, cx, cy); 4 5 CRgn rgn; 6 CRect rc; 7 GetWindowRect(&rc); //獲得窗口矩形 8 rc -= rc.TopLeft(); 9 rgn.CreateRoundRectRgn(rc.left, rc.top, rc.right, rc.bottom, 15, 15); //根據窗口矩形創建一個圓角矩形最后兩個是形成圓角的大小 10 SetWindowRgn(rgn, TRUE); 11 }
經過以上的幾個函數的重載處理,基本上你想要的功能都實現了。下面是實現的效果圖: