很多編程愛好者都有這樣的經歷,自己寫的程序非常漂亮,但是在Windows平台下開發的程序卻總是逃不出Windows默認風格的約束。標題欄、工具欄,一成不變的風格使得再有創意的作品也黯然失色。下面我們給對話框應用程序進行一次外科手術,旨於向各位讀者介紹一種方法,希望大家在此基礎上有進一步的發展。
本例以對話框應用程序為基礎,自畫非客戶區,完成應用程序美化,代碼運行效果圖如下:
下面我們來探討具體的實現過程
一、定義資源:
添加系統按鈕的位圖資源(本例中使用十個位圖,分別顯示幫助、最小化、最大化、恢復及關閉按鈕的普通狀態和焦點狀態,當然可隨程序的要求自定義添加)
二、定義全局變量及函數:
CRect m_rtButtExit; //關閉按鈕位置
CRect m_rtButtMax; //最大化按鈕位置
CRect m_rtButtMin; //最小化按鈕位置
CRect m_rtButtHelp; //幫助按鈕位置
CRect m_rtIcon; //圖標位置
void DrawTitleBar(CDC *pDC); //畫非客戶區主函數
三、函數實現:
本例需要對以下消息進行重載DefWindowProc、ON_WM_NCMOUSEMOVE、ON_WM_NCLBUTTONDOWN。
函數實現體如下:
//主函數,可根據實際情況進行自繪窗體void CTitleBarDlg::DrawTitleBar(CDC *pDC)
{
if (m_hWnd)
{
CBrush Brush(RGB(0,100,255));
CBrush* pOldBrush = pDC->SelectObject(&Brush);
CRect rtWnd, rtTitle, rtButtons;
GetWindowRect(&rtWnd);
……………………………..
//因代碼過長,未貼,見源程序
……………………………...
}
}
//將消息進行過濾,對可能影響界面初始及更新的消息,產生重畫消息執行DrawTitleBar函數
LRESULT CTitleBarDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lrst=CDialog::DefWindowProc(message, wParam, lParam);
if (!::IsWindow(m_hWnd))
return lrst;
if (message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||
message== WM_NCACTIVATE ||message == WM_NOTIFY)
{
CDC* pWinDC = GetWindowDC();
if (pWinDC)
DrawTitleBar(pWinDC);
ReleaseDC(pWinDC);
}
return lrst;
}
//實現標題欄按鈕的鼠標移動效果
void CTitleBarDlg::OnNcMouseMove(UINT nHitTest, CPoint point)
{
CDC* pDC = GetWindowDC();
if (pDC)
{
……………………………..
//因代碼過長,未貼,見源程序
……………………………...
}
ReleaseDC(pDC);
CDialog::OnNcMouseMove(nHitTest, point);
}
//實現非客戶區,用戶鼠標點擊操作
void CTitleBarDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
//檢測各按鈕是否按到
if (m_rtIcon.PtInRect(point))
AfxMessageBox("歡迎訪問FlySnowStdio主頁");
else if (m_rtButtHelp.PtInRect(point))
SendMessage(WM_HELP);
else if (m_rtButtExit.PtInRect(point))
SendMessage(WM_CLOSE);
else if (m_rtButtMin.PtInRect(point))
SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y));
else if (m_rtButtMax.PtInRect(point))
{
if (IsZoomed())
SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));
else
{
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, MAKELPARAM(point.x, point.y));
Invalidate();
}
}
else if (!IsZoomed())
Default();
}
四、總結
本例為對話框應用程序,單文檔的基本原理也相似。對於包含菜單項的程序,可以采用自畫菜單,將整個程序的界面融為一體,在此不做過多介紹,本人已經完成,請與我聯系。如果你想使你的程序更漂亮,也可以盡情放至貼圖到背景上,願你的程序多姿多彩。本文是在百忙中匆匆完成,錯誤之處希望大家批評指正!
上述程序在Win2000 Advanced Server + VC6 + SP5 2002.3下編譯運行通過。Win98測試順利運行。