xp下编程实现窗体透明特效
生活随笔
收集整理的這篇文章主要介紹了
xp下编程实现窗体透明特效
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本文主要介紹了Windows 2000下新增的API函數(shù)SetLayeredWindowAttributes()以及通過(guò)該函數(shù)實(shí)現(xiàn)窗體透明特效的一般方法
摘要:本文主要介紹了Windows 2000下新增的API函數(shù)SetLayeredWindowAttributes()以及通過(guò)該函數(shù)實(shí)現(xiàn)窗體透明特效的一般方法,并結(jié)合代碼給出了具體的編程實(shí)現(xiàn)過(guò)程。
引言
Windows 2000操作系統(tǒng)無(wú)論是在品質(zhì)上還是在用戶界面上都有了很大的改善與提高,用戶對(duì)系統(tǒng)的操作變的更加簡(jiǎn)單、方便,感覺(jué)也更加舒適。如果用戶在使用時(shí)留意一下,不難發(fā)現(xiàn)其中界面上的一些新特性。例如,Windows 2000提供了對(duì)帶陰影阿爾法混合光標(biāo)的支持、提供對(duì)菜單、提示框淡入淡出效果的支持以及在外殼拖拽具有阿爾法混合效果圖片等透明特效。所有這些特效看似不同但實(shí)際都是通過(guò)對(duì)Windows 2000新提供的一個(gè)分層窗口API函數(shù)的調(diào)用而實(shí)現(xiàn)的。 既然是Windows 2000系統(tǒng)提供的API函數(shù),那么也就意味著在自己的應(yīng)用程序中同樣能夠?qū)崿F(xiàn)該函數(shù)做做支持的各種特效。
在程序設(shè)計(jì)時(shí),有時(shí)一些微小的改善就足以增強(qiáng)用戶界面的顯示效果。例如,使用一個(gè)具有阿爾法混合效果的光標(biāo)顯然要比一只普通光標(biāo)的感覺(jué)要好的多,尤其是在大屏幕顯示器或多顯示器系統(tǒng)下這種光標(biāo)也更容易找到。更進(jìn)一步,顯示器的屏幕大小是有限的,如果想同時(shí)查看多個(gè)窗口的內(nèi)容顯然是不太方便的,盡管采取大屏幕顯示器或多顯示器系統(tǒng)能在一定程度上緩解但遠(yuǎn)不如將這些應(yīng)用程序窗體設(shè)置為透明或半透明來(lái)的徹底和方便。下圖顯示的兩個(gè)應(yīng)用程序雖然存在覆蓋,但位于前臺(tái)的程序窗體顯然沒(méi)有影響后臺(tái)Word文檔內(nèi)容的顯示。鑒于分層窗口函數(shù)在程序設(shè)計(jì)中的實(shí)用作用,本文將對(duì)其作具體的介紹以充分挖掘其潛力并將其應(yīng)用到程序設(shè)計(jì)中去。
分層窗口
在介紹分層窗口函數(shù)之前,首先要介紹一下WS_EX_LAYERED擴(kuò)展窗口風(fēng)格。該窗口風(fēng)格也是Windows 2000新增加的,如果使用了該屬性,窗體將具備復(fù)合形狀、動(dòng)畫、阿爾法混合等方面的視覺(jué)特效。
窗口通過(guò)被其他窗口的裁剪而在屏幕上以矩形出現(xiàn)。為了實(shí)現(xiàn)一個(gè)圓形窗體,僅僅簡(jiǎn)單繪制一個(gè)圓形窗體是不夠的,這樣的話系統(tǒng)還會(huì)把窗體按原矩形進(jìn)行點(diǎn)擊檢測(cè),而且位于該窗體下的窗口仍將被該窗體矩形所裁剪。或許可以考慮在園形窗體顯示出來(lái)前取得位于該窗體矩形下可視區(qū)域的快照,并在稍后窗體顯示完畢后將其繪制到當(dāng)前窗體。但由于其他窗口能夠繪制該窗體覆蓋下的區(qū)域,而前臺(tái)程序無(wú)法獲知這種繪制將于何時(shí)發(fā)生而不會(huì)及時(shí)獲取下面可視區(qū)域的新的快照,因此這種解決方法并不能在多進(jìn)程、多任務(wù)環(huán)境下很正常的工作。對(duì)于這種情況,在Windows 95/98和Windows NT 4.0下的正確做法是通過(guò)SetWindowRgn()API函數(shù)指出需要的窗體形狀,但是這種處理在頻繁更改窗體形狀或是在屏幕上拖拽時(shí)仍有缺陷存在:前臺(tái)窗體將要求位于其下的窗體重繪整個(gè)區(qū)域,這將生過(guò)多的消息和計(jì)算量。而且使用SetWindowRgn()只能實(shí)現(xiàn)窗體的全透明而無(wú)法實(shí)現(xiàn)半透明效果。或許這也正是分層窗口被提出的原因。
分層窗口真正實(shí)現(xiàn)了兩個(gè)截然不同的概念:分層和重定向。為了能夠去除任何一個(gè)層,WS_EX_LAYERED標(biāo)志位必須要設(shè)置,這可以在窗體創(chuàng)建時(shí)設(shè)置也可以在創(chuàng)建后通過(guò)以GWL_EXSTYLE標(biāo)志調(diào)用SetWindowLong()來(lái)進(jìn)行設(shè)置。接下來(lái),可以通過(guò)UpdateLayeredWindows()函數(shù)來(lái)更新分層窗口。在具體使用時(shí),需要在位圖中繪制出可視區(qū)域,并將其與關(guān)鍵色、阿爾法混合參數(shù)等一起提供給UpdateLayeredWindows()函數(shù)。需要注意的是,在使用UpdateLayeredWindows()函數(shù)時(shí),應(yīng)用程序并不需要響應(yīng)WM_PAINT或其他繪制消息。
除此之外,還可以使用傳統(tǒng)的Win32繪制機(jī)制來(lái)實(shí)現(xiàn),這需要調(diào)用另一個(gè)API函數(shù)SetLayeredWindowAttributes()來(lái)完成對(duì)關(guān)鍵色或阿爾法混合參數(shù)值的設(shè)定。一旦該函數(shù)被調(diào)用,系統(tǒng)將開始為分層窗口重定向所有的繪制并自動(dòng)應(yīng)用指定的特效。
窗體半透明特效的實(shí)現(xiàn)
前面已經(jīng)對(duì)分層窗口做了較為詳細(xì)的介紹。這里將對(duì)SetLayeredWindowAttributes()函數(shù)及其使用方法做具體的介紹,并在此基礎(chǔ)上實(shí)現(xiàn)窗體半透明特效。首先給出SetLayeredWindowAttributes()的函數(shù)原形:
其中dwFlags有LWA_ALPHA(值為2)和LWA_COLORKEY(值為1)兩種設(shè)置,如果LWA_ALPHA被設(shè)置的話,通過(guò)bAlpha參數(shù)指定窗體的透明度;如果LWA_COLORKEY標(biāo)志被設(shè)置的話,則指定關(guān)鍵色為crKey,該顏色所覆蓋的區(qū)域?qū)拇绑w去除,去除后的區(qū)域?qū)⒉辉龠M(jìn)行點(diǎn)擊檢測(cè),其他顏色則正常顯示。如果阿爾法混合值設(shè)置為0,其窗口區(qū)域同樣不進(jìn)行點(diǎn)擊檢測(cè)。
前面說(shuō)過(guò),SetLayeredWindowAttributes()函數(shù)是Windows 2000新增的一個(gè)API函數(shù),它所在的模塊為USER32.DLL。在用GetModuleHandle()裝載USER32.DLL模塊并調(diào)用GetProcAddress()得到函數(shù) SetLayeredWindowAttributes()在User32.dll中的指針后就可以通過(guò)SetLayeredWindowAttributes()函數(shù)將窗體設(shè)置為半透明了:
這段代碼通常在程序初始化時(shí)運(yùn)行以及時(shí)將USER32.DLL模塊裝載到內(nèi)存并獲取得到SetLayeredWindowAttributes()函數(shù)指針。在程序退出前需要通過(guò)FreeLibrary()函數(shù)釋放先前加載的模塊:
在將窗體設(shè)置為半透明時(shí),首先要獲取得到該窗體的窗口句柄,以指明要操作的是哪一個(gè)窗口。如果是對(duì)本應(yīng)用程序中的某個(gè)窗口進(jìn)行設(shè)置,可以通過(guò)傳遞窗口句柄或是用GetSafeHwnd()來(lái)動(dòng)態(tài)獲取。如果要對(duì)本程序外的某個(gè)程序窗口進(jìn)行設(shè)置,一般的做法是通過(guò)對(duì)FindWindow()函數(shù)的調(diào)用來(lái)獲取指定窗口標(biāo)題的窗口句柄。在得到窗口句柄之后并不能直接調(diào)用SetLayeredWindowAttributes()進(jìn)行設(shè)置,需要在GetWindowLong()獲取得到當(dāng)前窗口風(fēng)格設(shè)置后在其基礎(chǔ)之上添加WS_EX_LAYERED擴(kuò)展風(fēng)格,并通過(guò)SetWindowLong()函數(shù)將其設(shè)置:
為了能夠使用該函數(shù),還必須在上述語(yǔ)句之前添加預(yù)定義語(yǔ)句:
異形窗體特效的實(shí)現(xiàn)
使用SetLayeredWindowAttributes()創(chuàng)建異形窗體是非常簡(jiǎn)單的,具體過(guò)程與半透明窗體的實(shí)現(xiàn)極為類似,所不同的只是將標(biāo)志設(shè)置為L(zhǎng)WA_COLORKEY并指定需要透明顯示的關(guān)鍵色:
小結(jié)
本文通過(guò)對(duì)Windows 2000新增API函數(shù)SetLayeredWindowAttributes()的使用非常簡(jiǎn)單的實(shí)現(xiàn)了窗體的半透明設(shè)置和異形窗體的創(chuàng)建。除了SetLayeredWindowAttributes()函數(shù),Windows 2000還提供了其他許多類似的特效函數(shù)比如用于窗體動(dòng)態(tài)滑動(dòng)顯示的AnimateWindow()。由于這些函數(shù)是系統(tǒng)提供的API函數(shù),因此不會(huì)受編程語(yǔ)言的制約,也就是說(shuō),并不只在VC++下可以實(shí)現(xiàn)上述特效。在C++ Builder、Delphi等其他開發(fā)環(huán)境下也是可以用類似的方法來(lái)實(shí)現(xiàn)的。本文所述程序代碼在Windows 2000 Professional下由Microsoft Visual C++ 6.0編譯通過(guò)。
摘要:本文主要介紹了Windows 2000下新增的API函數(shù)SetLayeredWindowAttributes()以及通過(guò)該函數(shù)實(shí)現(xiàn)窗體透明特效的一般方法,并結(jié)合代碼給出了具體的編程實(shí)現(xiàn)過(guò)程。
引言
Windows 2000操作系統(tǒng)無(wú)論是在品質(zhì)上還是在用戶界面上都有了很大的改善與提高,用戶對(duì)系統(tǒng)的操作變的更加簡(jiǎn)單、方便,感覺(jué)也更加舒適。如果用戶在使用時(shí)留意一下,不難發(fā)現(xiàn)其中界面上的一些新特性。例如,Windows 2000提供了對(duì)帶陰影阿爾法混合光標(biāo)的支持、提供對(duì)菜單、提示框淡入淡出效果的支持以及在外殼拖拽具有阿爾法混合效果圖片等透明特效。所有這些特效看似不同但實(shí)際都是通過(guò)對(duì)Windows 2000新提供的一個(gè)分層窗口API函數(shù)的調(diào)用而實(shí)現(xiàn)的。 既然是Windows 2000系統(tǒng)提供的API函數(shù),那么也就意味著在自己的應(yīng)用程序中同樣能夠?qū)崿F(xiàn)該函數(shù)做做支持的各種特效。
在程序設(shè)計(jì)時(shí),有時(shí)一些微小的改善就足以增強(qiáng)用戶界面的顯示效果。例如,使用一個(gè)具有阿爾法混合效果的光標(biāo)顯然要比一只普通光標(biāo)的感覺(jué)要好的多,尤其是在大屏幕顯示器或多顯示器系統(tǒng)下這種光標(biāo)也更容易找到。更進(jìn)一步,顯示器的屏幕大小是有限的,如果想同時(shí)查看多個(gè)窗口的內(nèi)容顯然是不太方便的,盡管采取大屏幕顯示器或多顯示器系統(tǒng)能在一定程度上緩解但遠(yuǎn)不如將這些應(yīng)用程序窗體設(shè)置為透明或半透明來(lái)的徹底和方便。下圖顯示的兩個(gè)應(yīng)用程序雖然存在覆蓋,但位于前臺(tái)的程序窗體顯然沒(méi)有影響后臺(tái)Word文檔內(nèi)容的顯示。鑒于分層窗口函數(shù)在程序設(shè)計(jì)中的實(shí)用作用,本文將對(duì)其作具體的介紹以充分挖掘其潛力并將其應(yīng)用到程序設(shè)計(jì)中去。
分層窗口
在介紹分層窗口函數(shù)之前,首先要介紹一下WS_EX_LAYERED擴(kuò)展窗口風(fēng)格。該窗口風(fēng)格也是Windows 2000新增加的,如果使用了該屬性,窗體將具備復(fù)合形狀、動(dòng)畫、阿爾法混合等方面的視覺(jué)特效。
窗口通過(guò)被其他窗口的裁剪而在屏幕上以矩形出現(xiàn)。為了實(shí)現(xiàn)一個(gè)圓形窗體,僅僅簡(jiǎn)單繪制一個(gè)圓形窗體是不夠的,這樣的話系統(tǒng)還會(huì)把窗體按原矩形進(jìn)行點(diǎn)擊檢測(cè),而且位于該窗體下的窗口仍將被該窗體矩形所裁剪。或許可以考慮在園形窗體顯示出來(lái)前取得位于該窗體矩形下可視區(qū)域的快照,并在稍后窗體顯示完畢后將其繪制到當(dāng)前窗體。但由于其他窗口能夠繪制該窗體覆蓋下的區(qū)域,而前臺(tái)程序無(wú)法獲知這種繪制將于何時(shí)發(fā)生而不會(huì)及時(shí)獲取下面可視區(qū)域的新的快照,因此這種解決方法并不能在多進(jìn)程、多任務(wù)環(huán)境下很正常的工作。對(duì)于這種情況,在Windows 95/98和Windows NT 4.0下的正確做法是通過(guò)SetWindowRgn()API函數(shù)指出需要的窗體形狀,但是這種處理在頻繁更改窗體形狀或是在屏幕上拖拽時(shí)仍有缺陷存在:前臺(tái)窗體將要求位于其下的窗體重繪整個(gè)區(qū)域,這將生過(guò)多的消息和計(jì)算量。而且使用SetWindowRgn()只能實(shí)現(xiàn)窗體的全透明而無(wú)法實(shí)現(xiàn)半透明效果。或許這也正是分層窗口被提出的原因。
分層窗口真正實(shí)現(xiàn)了兩個(gè)截然不同的概念:分層和重定向。為了能夠去除任何一個(gè)層,WS_EX_LAYERED標(biāo)志位必須要設(shè)置,這可以在窗體創(chuàng)建時(shí)設(shè)置也可以在創(chuàng)建后通過(guò)以GWL_EXSTYLE標(biāo)志調(diào)用SetWindowLong()來(lái)進(jìn)行設(shè)置。接下來(lái),可以通過(guò)UpdateLayeredWindows()函數(shù)來(lái)更新分層窗口。在具體使用時(shí),需要在位圖中繪制出可視區(qū)域,并將其與關(guān)鍵色、阿爾法混合參數(shù)等一起提供給UpdateLayeredWindows()函數(shù)。需要注意的是,在使用UpdateLayeredWindows()函數(shù)時(shí),應(yīng)用程序并不需要響應(yīng)WM_PAINT或其他繪制消息。
除此之外,還可以使用傳統(tǒng)的Win32繪制機(jī)制來(lái)實(shí)現(xiàn),這需要調(diào)用另一個(gè)API函數(shù)SetLayeredWindowAttributes()來(lái)完成對(duì)關(guān)鍵色或阿爾法混合參數(shù)值的設(shè)定。一旦該函數(shù)被調(diào)用,系統(tǒng)將開始為分層窗口重定向所有的繪制并自動(dòng)應(yīng)用指定的特效。
窗體半透明特效的實(shí)現(xiàn)
前面已經(jīng)對(duì)分層窗口做了較為詳細(xì)的介紹。這里將對(duì)SetLayeredWindowAttributes()函數(shù)及其使用方法做具體的介紹,并在此基礎(chǔ)上實(shí)現(xiàn)窗體半透明特效。首先給出SetLayeredWindowAttributes()的函數(shù)原形:
| BOOL SetLayeredWindowAttributes( HWND hwnd, // handle to the layered window COLORREF crKey, // specifies the color key BYTE bAlpha, // value for the blend function DWORD dwFlags // action ); |
其中dwFlags有LWA_ALPHA(值為2)和LWA_COLORKEY(值為1)兩種設(shè)置,如果LWA_ALPHA被設(shè)置的話,通過(guò)bAlpha參數(shù)指定窗體的透明度;如果LWA_COLORKEY標(biāo)志被設(shè)置的話,則指定關(guān)鍵色為crKey,該顏色所覆蓋的區(qū)域?qū)拇绑w去除,去除后的區(qū)域?qū)⒉辉龠M(jìn)行點(diǎn)擊檢測(cè),其他顏色則正常顯示。如果阿爾法混合值設(shè)置為0,其窗口區(qū)域同樣不進(jìn)行點(diǎn)擊檢測(cè)。
前面說(shuō)過(guò),SetLayeredWindowAttributes()函數(shù)是Windows 2000新增的一個(gè)API函數(shù),它所在的模塊為USER32.DLL。在用GetModuleHandle()裝載USER32.DLL模塊并調(diào)用GetProcAddress()得到函數(shù) SetLayeredWindowAttributes()在User32.dll中的指針后就可以通過(guò)SetLayeredWindowAttributes()函數(shù)將窗體設(shè)置為半透明了:
| // 全局變量 typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags); lpfn g_pSetLayeredWindowAttributes; …… // 獲取函數(shù) SetLayeredWindowAttributes 在User32.dll中的指針 HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL")); g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32, "SetLayeredWindowAttributes"); if (g_pSetLayeredWindowAttributes == NULL) ::PostQuitMessage(0); |
這段代碼通常在程序初始化時(shí)運(yùn)行以及時(shí)將USER32.DLL模塊裝載到內(nèi)存并獲取得到SetLayeredWindowAttributes()函數(shù)指針。在程序退出前需要通過(guò)FreeLibrary()函數(shù)釋放先前加載的模塊:
| // 卸載模塊 if (m_hUser32 != NULL) FreeLibrary(m_hUser32); |
在將窗體設(shè)置為半透明時(shí),首先要獲取得到該窗體的窗口句柄,以指明要操作的是哪一個(gè)窗口。如果是對(duì)本應(yīng)用程序中的某個(gè)窗口進(jìn)行設(shè)置,可以通過(guò)傳遞窗口句柄或是用GetSafeHwnd()來(lái)動(dòng)態(tài)獲取。如果要對(duì)本程序外的某個(gè)程序窗口進(jìn)行設(shè)置,一般的做法是通過(guò)對(duì)FindWindow()函數(shù)的調(diào)用來(lái)獲取指定窗口標(biāo)題的窗口句柄。在得到窗口句柄之后并不能直接調(diào)用SetLayeredWindowAttributes()進(jìn)行設(shè)置,需要在GetWindowLong()獲取得到當(dāng)前窗口風(fēng)格設(shè)置后在其基礎(chǔ)之上添加WS_EX_LAYERED擴(kuò)展風(fēng)格,并通過(guò)SetWindowLong()函數(shù)將其設(shè)置:
| // 半透明 HWND hWnd = GetSafeHwnd(); LONG lWindowLong = GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED; ::SetWindowLong(hWnd, GWL_EXSTYLE, lWindowLong); g_pSetLayeredWindowAttributes(hWnd, 0, (BYTE)m_sldAlpha.GetPos(), 2); ::RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); |
為了能夠使用該函數(shù),還必須在上述語(yǔ)句之前添加預(yù)定義語(yǔ)句:
| #define WS_EX_LAYERED 0x00080000 |
異形窗體特效的實(shí)現(xiàn)
使用SetLayeredWindowAttributes()創(chuàng)建異形窗體是非常簡(jiǎn)單的,具體過(guò)程與半透明窗體的實(shí)現(xiàn)極為類似,所不同的只是將標(biāo)志設(shè)置為L(zhǎng)WA_COLORKEY并指定需要透明顯示的關(guān)鍵色:
| // 指定關(guān)鍵色 HWND hWnd = GetSafeHwnd(); LONG lWindowLong = GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED; ::SetWindowLong(hWnd, GWL_EXSTYLE, lWindowLong); g_pSetLayeredWindowAttributes(hWnd, RGB(255, 255, 255), 0, 1); ::RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); |
小結(jié)
本文通過(guò)對(duì)Windows 2000新增API函數(shù)SetLayeredWindowAttributes()的使用非常簡(jiǎn)單的實(shí)現(xiàn)了窗體的半透明設(shè)置和異形窗體的創(chuàng)建。除了SetLayeredWindowAttributes()函數(shù),Windows 2000還提供了其他許多類似的特效函數(shù)比如用于窗體動(dòng)態(tài)滑動(dòng)顯示的AnimateWindow()。由于這些函數(shù)是系統(tǒng)提供的API函數(shù),因此不會(huì)受編程語(yǔ)言的制約,也就是說(shuō),并不只在VC++下可以實(shí)現(xiàn)上述特效。在C++ Builder、Delphi等其他開發(fā)環(huán)境下也是可以用類似的方法來(lái)實(shí)現(xiàn)的。本文所述程序代碼在Windows 2000 Professional下由Microsoft Visual C++ 6.0編譯通過(guò)。
總結(jié)
以上是生活随笔為你收集整理的xp下编程实现窗体透明特效的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 程序员与代码之间的搞笑日常,笑的人肚子痛
- 下一篇: C++字符串完全指南(2) - 各种字符