日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

xp下编程实现窗体透明特效

發布時間:2025/3/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 xp下编程实现窗体透明特效 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文主要介紹了Windows 2000下新增的API函數SetLayeredWindowAttributes()以及通過該函數實現窗體透明特效的一般方法
摘要:本文主要介紹了Windows 2000下新增的API函數SetLayeredWindowAttributes()以及通過該函數實現窗體透明特效的一般方法,并結合代碼給出了具體的編程實現過程。
引言

  Windows 2000操作系統無論是在品質上還是在用戶界面上都有了很大的改善與提高,用戶對系統的操作變的更加簡單、方便,感覺也更加舒適。如果用戶在使用時留意一下,不難發現其中界面上的一些新特性。例如,Windows 2000提供了對帶陰影阿爾法混合光標的支持、提供對菜單、提示框淡入淡出效果的支持以及在外殼拖拽具有阿爾法混合效果圖片等透明特效。所有這些特效看似不同但實際都是通過對Windows 2000新提供的一個分層窗口API函數的調用而實現的。 既然是Windows 2000系統提供的API函數,那么也就意味著在自己的應用程序中同樣能夠實現該函數做做支持的各種特效。

  在程序設計時,有時一些微小的改善就足以增強用戶界面的顯示效果。例如,使用一個具有阿爾法混合效果的光標顯然要比一只普通光標的感覺要好的多,尤其是在大屏幕顯示器或多顯示器系統下這種光標也更容易找到。更進一步,顯示器的屏幕大小是有限的,如果想同時查看多個窗口的內容顯然是不太方便的,盡管采取大屏幕顯示器或多顯示器系統能在一定程度上緩解但遠不如將這些應用程序窗體設置為透明或半透明來的徹底和方便。下圖顯示的兩個應用程序雖然存在覆蓋,但位于前臺的程序窗體顯然沒有影響后臺Word文檔內容的顯示。鑒于分層窗口函數在程序設計中的實用作用,本文將對其作具體的介紹以充分挖掘其潛力并將其應用到程序設計中去。

 
  分層窗口

  在介紹分層窗口函數之前,首先要介紹一下WS_EX_LAYERED擴展窗口風格。該窗口風格也是Windows 2000新增加的,如果使用了該屬性,窗體將具備復合形狀、動畫、阿爾法混合等方面的視覺特效。

  窗口通過被其他窗口的裁剪而在屏幕上以矩形出現。為了實現一個圓形窗體,僅僅簡單繪制一個圓形窗體是不夠的,這樣的話系統還會把窗體按原矩形進行點擊檢測,而且位于該窗體下的窗口仍將被該窗體矩形所裁剪。或許可以考慮在園形窗體顯示出來前取得位于該窗體矩形下可視區域的快照,并在稍后窗體顯示完畢后將其繪制到當前窗體。但由于其他窗口能夠繪制該窗體覆蓋下的區域,而前臺程序無法獲知這種繪制將于何時發生而不會及時獲取下面可視區域的新的快照,因此這種解決方法并不能在多進程、多任務環境下很正常的工作。對于這種情況,在Windows 95/98和Windows NT 4.0下的正確做法是通過SetWindowRgn()API函數指出需要的窗體形狀,但是這種處理在頻繁更改窗體形狀或是在屏幕上拖拽時仍有缺陷存在:前臺窗體將要求位于其下的窗體重繪整個區域,這將生過多的消息和計算量。而且使用SetWindowRgn()只能實現窗體的全透明而無法實現半透明效果。或許這也正是分層窗口被提出的原因。

  分層窗口真正實現了兩個截然不同的概念:分層和重定向。為了能夠去除任何一個層,WS_EX_LAYERED標志位必須要設置,這可以在窗體創建時設置也可以在創建后通過以GWL_EXSTYLE標志調用SetWindowLong()來進行設置。接下來,可以通過UpdateLayeredWindows()函數來更新分層窗口。在具體使用時,需要在位圖中繪制出可視區域,并將其與關鍵色、阿爾法混合參數等一起提供給UpdateLayeredWindows()函數。需要注意的是,在使用UpdateLayeredWindows()函數時,應用程序并不需要響應WM_PAINT或其他繪制消息。

  除此之外,還可以使用傳統的Win32繪制機制來實現,這需要調用另一個API函數SetLayeredWindowAttributes()來完成對關鍵色或阿爾法混合參數值的設定。一旦該函數被調用,系統將開始為分層窗口重定向所有的繪制并自動應用指定的特效。

窗體半透明特效的實現

  前面已經對分層窗口做了較為詳細的介紹。這里將對SetLayeredWindowAttributes()函數及其使用方法做具體的介紹,并在此基礎上實現窗體半透明特效。首先給出SetLayeredWindowAttributes()的函數原形:

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)兩種設置,如果LWA_ALPHA被設置的話,通過bAlpha參數指定窗體的透明度;如果LWA_COLORKEY標志被設置的話,則指定關鍵色為crKey,該顏色所覆蓋的區域將從窗體去除,去除后的區域將不再進行點擊檢測,其他顏色則正常顯示。如果阿爾法混合值設置為0,其窗口區域同樣不進行點擊檢測。

  前面說過,SetLayeredWindowAttributes()函數是Windows 2000新增的一個API函數,它所在的模塊為USER32.DLL。在用GetModuleHandle()裝載USER32.DLL模塊并調用GetProcAddress()得到函數 SetLayeredWindowAttributes()在User32.dll中的指針后就可以通過SetLayeredWindowAttributes()函數將窗體設置為半透明了:

// 全局變量
typedef BOOL (WINAPI *lpfn) (HWND hWnd, COLORREF cr, BYTE bAlpha, DWORD dwFlags);
lpfn g_pSetLayeredWindowAttributes;
……
// 獲取函數 SetLayeredWindowAttributes 在User32.dll中的指針
HMODULE hUser32 = GetModuleHandle(_T("USER32.DLL"));
g_pSetLayeredWindowAttributes = (lpfn)GetProcAddress(hUser32, "SetLayeredWindowAttributes");
if (g_pSetLayeredWindowAttributes == NULL)
::PostQuitMessage(0);

  這段代碼通常在程序初始化時運行以及時將USER32.DLL模塊裝載到內存并獲取得到SetLayeredWindowAttributes()函數指針。在程序退出前需要通過FreeLibrary()函數釋放先前加載的模塊:

// 卸載模塊
if (m_hUser32 != NULL)
FreeLibrary(m_hUser32);

  在將窗體設置為半透明時,首先要獲取得到該窗體的窗口句柄,以指明要操作的是哪一個窗口。如果是對本應用程序中的某個窗口進行設置,可以通過傳遞窗口句柄或是用GetSafeHwnd()來動態獲取。如果要對本程序外的某個程序窗口進行設置,一般的做法是通過對FindWindow()函數的調用來獲取指定窗口標題的窗口句柄。在得到窗口句柄之后并不能直接調用SetLayeredWindowAttributes()進行設置,需要在GetWindowLong()獲取得到當前窗口風格設置后在其基礎之上添加WS_EX_LAYERED擴展風格,并通過SetWindowLong()函數將其設置:

// 半透明
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);

  為了能夠使用該函數,還必須在上述語句之前添加預定義語句:

#define WS_EX_LAYERED 0x00080000

  異形窗體特效的實現

  使用SetLayeredWindowAttributes()創建異形窗體是非常簡單的,具體過程與半透明窗體的實現極為類似,所不同的只是將標志設置為LWA_COLORKEY并指定需要透明顯示的關鍵色:

// 指定關鍵色
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);

  小結

  本文通過對Windows 2000新增API函數SetLayeredWindowAttributes()的使用非常簡單的實現了窗體的半透明設置和異形窗體的創建。除了SetLayeredWindowAttributes()函數,Windows 2000還提供了其他許多類似的特效函數比如用于窗體動態滑動顯示的AnimateWindow()。由于這些函數是系統提供的API函數,因此不會受編程語言的制約,也就是說,并不只在VC++下可以實現上述特效。在C++ Builder、Delphi等其他開發環境下也是可以用類似的方法來實現的。本文所述程序代碼在Windows 2000 Professional下由Microsoft Visual C++ 6.0編譯通過。

總結

以上是生活随笔為你收集整理的xp下编程实现窗体透明特效的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。