裝飾你的Title Bar
發(fā)表時(shí)間:2024-02-09 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]Windows 98的發(fā)布給熱衷于UI的用戶帶來(lái)了福音,它內(nèi)嵌的Plus!,動(dòng)態(tài)彈出的菜單與ToolTip,更有那顏色漸變的Title Bar給我們?cè)鎏砹嗽S多的樂(lè)趣。其實(shí)即便是在Windows 95下也能使你的程序的Title Bar更具有個(gè)人魅力,在Norton Utilities for 95...
Windows 98的發(fā)布給熱衷于UI的用戶帶來(lái)了福音,它內(nèi)嵌的Plus!,動(dòng)態(tài)
彈出的菜單與ToolTip,更有那顏色漸變的Title Bar給我們?cè)鎏砹嗽S多的樂(lè)趣。
其實(shí)即便是在Windows 95下也能使你的程序的Title Bar更具有個(gè)人魅力,在
Norton Utilities for 95中就有了顏色漸變的Title Bar,在大量的Delphi 3.0
的第三方控件中更有提供了此類完整功能的控件。當(dāng)然用控件可以快速開發(fā)漂亮的
程序,但對(duì)于爬鍵盤的人來(lái)說(shuō),了解程序內(nèi)核的機(jī)理并且做出更Cool的Title Bar
才是最爽的事!本文列舉了用代碼裝飾你的Title Bar的幾種方法。
1、修改Registry庫(kù)
在Windows 9x的桌面中,進(jìn)入Display Properties對(duì)話框中的Appearance屬性
頁(yè),可以修改Title Bar的字體的寬度與顏色。實(shí)際上所有這些更改都進(jìn)入了
Registry庫(kù)的HKEY-CURRENT-USER/Control Panel下。由于都是單純的數(shù)字,
對(duì)于字體是不好修改的,但若是單純修改顏色值,則在Control Panel的Colors下有
明顯的value Name與value Data的含義。例如在Windows 98中,value Name為
ActiveTitle,value Data為“0 0 128”;value Name為GradientActiveTitle,
value Data為“168 200 240”,即表示活動(dòng)時(shí)的Title Bar顏色由深藍(lán)色漸變到淺
藍(lán)色。值的含義很明顯即為RGB的值。用Win32 SDK中的修改Registry庫(kù)的API修改各
項(xiàng)意義明顯的Color值,別忘了最后發(fā)送WM-SYSCOLORCHANGE消息給自己的窗口,
來(lái)驗(yàn)證改變后的效果。
此種方法的好處是思路簡(jiǎn)單,并且下次重啟Windows后,所有窗口均是改變后的
顏色,但是方法有些勉強(qiáng)且功能不強(qiáng)。
2、利用SetSystem Color函數(shù)
SetSystemColor的解釋請(qǐng)參考相應(yīng)手冊(cè),不再詳述。這里僅列出一段代碼片段,
示意將Windows背景改為黑色,將Windows中的文字改為綠色。
int aiDsp[2];
DWORD aRgb[2];
aiDsp[0]=COLOR-WINDOW;
aRgb[0]=RGB(0, 0, 0);
aiDsp[1]=COLOR-WINDOWTEXT;
aRgb[1]=RGB(0, 255, 0);
SetSysColors(2, aiDsp, aRgb);
SetSysColors會(huì)自動(dòng)給所有Windows發(fā)送WM-SYSCOLORCHANGE消息向所有Window
聲名系統(tǒng)顏色改變,但是并不改變注冊(cè)庫(kù),因?yàn)橄麓沃貑indows后,系統(tǒng)顏色又恢復(fù)原樣。
本方法實(shí)現(xiàn)簡(jiǎn)單,但影響了其他窗口特性,且功能太少。
3、拿起你的刷(brush),握住你的筆(pen),在DC上盡情地想畫什么就畫什么
在Windows 98下用VC 5.0生成小的Demo,在Windows 95下運(yùn)行也正常。 下面先了解一下Windows重畫非客戶區(qū)的過(guò)程。在處理WM-NCPAINT、WM-NCACTIVE、
WM-SYSCOMMAND、WM-SETTEXT消息之后,Windows調(diào)用缺省處理消息函數(shù)DefWindowProc,
在此函數(shù)中將對(duì)非客戶區(qū)進(jìn)行重畫操作,故而在CWnd的虛函數(shù)DefWindowProc中,
重畫Title Bar,就可以達(dá)到我們的目的,但是若不對(duì)消息進(jìn)行一定的過(guò)濾,勢(shì)必引
起過(guò)多的重畫,我們假定Title Bar上沒(méi)有System Menu,即沒(méi)有最大、最小和關(guān)閉按
鈕在Title Bar上(見(jiàn)代碼片段1)。這樣可以簡(jiǎn)化操作。對(duì)消息的過(guò)濾與重畫操作見(jiàn)
代碼片段2。
代碼片段1:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style &=~WS-SYSMENU; //取消Title Bar上的按鈕
return CFrameWnd::PreCreateWindow(cs);
}
代碼片段2:
LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lrst=CFrameWnd::DefWindowProc(message, wParam, lParam);
if (!::IsWindow(m-h(huán)Wnd))
return lrst;
if (message=WM-NCPAINT message=WM-NCACTIVATE message=WM-NOTIFY)
{
CDC pWinDC=GetWindowDC();
if (pWinDC)
DrawTitleBar(pWinDC);
ReleaseDC(pWinDC);
}
return lrst;
}
在DrawTitleBar函數(shù)中,我們將采用乾坤大挪移,將Icon畫到了右邊,將最小、
最大、關(guān)閉按鈕畫到了左邊,并畫上了顏色漸變的Title Bar,在中間寫了“My Own
Cool Title Bar!!!”的標(biāo)題(見(jiàn)代碼片段3)。最后將最小、最大、關(guān)閉按鈕連上
了各自的消息(見(jiàn)代碼片段4)。
代碼片段3:
void CMainFrame::DrawTitleBar(CDC* pDC)
{
if (m-h(huán)Wnd)
{
CRect rtWnd, rtTitle, rtButtons;
GetWindowRect(&rtWnd); //整個(gè)Window的相對(duì)于屏幕的矩形
//取得整個(gè)Title bar的矩形
rtTitle.left=GetSystemMetrics(SM-CXFRAME);
rtTitle.top=GetSystemMetrics(SM-CYFRAME);
rtTitle.right=rtWnd.right-rtWnd.left-GetSystemMetrics(SM-CXFRAME);
rtTitle.bottom=rtTitle.top+GetSystemMetrics(SM-CYSIZE);
//重畫顏色漸變的Title Bar;有DC,有矩形,想怎么畫就怎么畫
DrawGradientBar(pDC, rtTitle); //此函數(shù)源碼因篇幅略去
//重畫icon
HICON hIcon=(HICON)::GetClassLong(m-h(huán)Wnd, GCL-HICON);
m-rtIcon.left=rtTitle.right-GetSystemMetrics(SM-CYSMICON);
m-rtIcon.top=rtTitle.top+1;
m-rtIcon.right=m-rtIcon.left+GetSystemMetrics(SM-CXSMICON);
m-rtIcon.bottom=m-rtIcon.top+GetSystemMetrics(SM-CYSMICON);
::DrawIconEx(pDC->m-h(huán)DC, m-rtIcon.left, m-rtIcon.top,hIcon, GetSystemMetrics
(SM-CXSMICON), GetSystemMetrics(SM-CYSMICON), 0, NULL,
DI-NORMAL);
m-rtIcon.OffsetRect(rtWnd.TopLeft()); //記錄Icon屏幕位置
//重畫最小button
int nButtHeight=GetSystemMetrics(SM-CYSMSIZE)-3;
rtButtons.left=rtTitle.left;
rtButtons.top=rtTitle.top+(GetSystemMetrics(SM-CYSIZE)-nButtHeight)/2;
rtButtons.right=rtButtons.left+GetSystemMetrics(SM-CXSMSIZE);
rtButtons.bottom=rtButtons.top+nButtHeight;
pDC->DrawFrameControl(&rtButtons, DFC-CAPTION, DFCS-CAPTIONMIN);
m-rtButtMin=rtButtons;
m-rtButtMin.OffsetRect(rtWnd.TopLeft()); //記錄最小button屏幕位置
//重畫最大或恢復(fù)button
rtButtons.left=rtButtons.right;
rtButtons.right=rtButtons.left+GetSystemMetrics(SM-CXSMSIZE);
pDC->DrawFrameControl(&rtButtons, DFC-CAPTION, IsZoomed() ?
DFCS-CAPTIONRESTORE : DFCS-CAPTIONMAX);
m-rtButtMax=rtButtons;
m-rtButtMax.OffsetRect(rtWnd.TopLeft());//記錄button屏幕位置
//重畫關(guān)閉button
rtButtons.left=rtButtons.right;
rtButtons.right=rtButtons.left+GetSystemMetrics(SM-CXSMSIZE);
pDC->DrawFrameControl(&rtButtons, DFC-CAPTION, DFCS-CAPTIONCLOSE);
m-rtButtExit=rtButtons;
m-rtButtExit.OffsetRect(rtWnd.TopLeft())//記錄關(guān)閉button屏幕位置;
//重畫caption
int nOldMode=pDC->SetBkMode(TRANSPARENT);
COLORREF clOldText=pDC->SetTextColor(RGB(0, 0, 0));
pDC->SelectStockObject(ANSI-FIXED-FONT); rtTitle.right-=GetSystemMetrics
(SM-CYSMICON); pDC->DrawText((LPSTR)″My Own Cool Title
Bar!!!″, -1, &rtTitle, DT-CENTER);
pDC->SetBkMode(nOldMode);
pDC->SetTextColor(clOldText);
}
}
代碼片段4:
void CMainFrame::OnNcLButtonDown(UINT nHitTest, CPoint point)
{
//處理缺省操作,諸如雙擊Title Bar等其他動(dòng)作
Default();
//檢測(cè)最小,最大和關(guān)閉按鈕是否按到
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) );
}
}
這里需要補(bǔ)充一點(diǎn),若要程序更健壯,需要監(jiān)視WM-WININICHANGED消息,因
為用戶可能在別處動(dòng)態(tài)地改變Title Bar的寬度及其他寬度,此時(shí)需要重新取得Title
Bar的各項(xiàng)新值,使得Title Bar重畫。
實(shí)際上有了DC,有了矩形,的確是可以隨心所欲了,但是有了獨(dú)創(chuàng)就一定有付出。
要完成徹底的乾坤大挪移,還需要在移動(dòng)窗口后,更新最小、最大和關(guān)閉按鈕的位置;
模擬按鈕按下的動(dòng)作;點(diǎn)擊Icon后生成System Menu,并彈出,代價(jià)是大了一些。
有了這種方法后,就完全沒(méi)有必要非要和Windows對(duì)著干了,你可以設(shè)計(jì)自己的
Title Bar、自己的最小、最大和關(guān)閉按鈕,在Title Bar上貼上喜歡的位圖,使
Title Bar完全個(gè)性化,F(xiàn)在握住你的筆(pen),拿起你的刷(brush),盡情地裝飾你
的Title Bar吧!