介紹: Layered Windows是windows視窗中的一類,提供類似半透明的效果(阿爾法混合)。半透明效果是字面上有能看出來的,但實際上根據MSND,該類型的視窗還能更好的支持非矩形的視窗,使之顯示效果更平滑流暢(暗地裡猜測是使用了硬體加速而達到的效果)。在win8之前WS_EX_LAYER ...
介紹:
Layered Windows是windows視窗中的一類,提供類似半透明的效果(阿爾法混合)。半透明效果是字面上有能看出來的,但實際上根據MSND,該類型的視窗還能更好的支持非矩形的視窗,使之顯示效果更平滑流暢(暗地裡猜測是使用了硬體加速而達到的效果)。在win8之前WS_EX_LAYERED只能用於頂層視窗,win8及之後版本子視窗也可以使用。
使用:
首先要做的就是在CreateWindowEx()時加入 WS_EX_LAYERED風格。之後調用SetLayeredWindowAttributes()。該函數原型如下:
BOOL WINAPI SetLayeredWindowAttributes(
_In_ HWND hwnd, //視窗句柄
_In_ COLORREF crKey, //設置色彩通道的相對分量 使用RGB巨集
_In_ BYTE bAlpha, //阿爾法值,0-225之間
_In_ DWORD dwFlags //LWA_ALPHA或LWA_COLORKEY,或二者都有
);
/*
*LWA_ALPHA :使用阿爾法值顯示透明效果
LWA_COLORKEY:使用RGB通道過濾顏色
*/
那麼兩種Flag有什麼區別呢,或者說它們分別是什麼效果呢?不多說上圖就明白了。
LWA_COLORKEY有效時參數指定的 LWA_ALPHA 有效時對視窗整體使用半
顏色被視為透明 透明效果,阿爾法值由參數指定。
左側是LWA_COLORKEY,可以看到在視窗 右側是 LWA_ALPHA可以看到整體呈現半透明,而且
上畫的RGB=(255,0,255)的圓形被視 在視窗上繪製的圓形也是半透明的。(也註意到對圓型
為透明 視窗其坐標還是按矩形的左上角算的)
兩種效果可以同時使用效果,其效果就是一個半透明的黑色月亮。
可以使用UpdataLayeredWindow()函數更新Layered Window。比如重新設置其透明度,位置,大小,形狀等。該函數會更新整個視窗。不需要擔心被遮擋的視窗的更新問題,系統會處理好的。(對一個Layered視窗系統總是保存其下麵的圖像,並自動更新,這意味著占用更多記憶體,所以不需要時通過SetWindowLong()刪除WS_LAYERED風格。這在下麵還會說)
對透明的部分(比如上面左圖月牙缺掉的部分或者對右圖設置阿爾法值為0)點擊滑鼠時,滑鼠消息會透過視窗,也就是Layered視窗在此處不接受滑鼠消息。這很符合所看即所得的設計理念,用戶感覺看不到的地方就是沒有,他們不必理解什麼阿爾法混合。
如何設置Layered視窗為普通的視窗
如果不再需要透明效果,儘早去掉Layered屬性可以提高性能,標準的做法如下:
// Remove WS_EX_LAYERED from this window styles SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); // Ask the window and its children to repaint RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
最後說一點,如果視窗已經創建好了也有其他的辦法,調用SetWindowLong(),重新設置視窗風格即可。但是對一個已經顯示在屏幕上的視窗修改其風格為 WS_EX_LAYERED時會發現該視窗不見了,此時調用UpdataLayeredWindow()或SetLayeredWindowAttributes()後會出現你想要的樣子。
另外:一旦 SetLayeredWindowAttributes 被調用了, 之後對 UpdateLayeredWindow 的調用都會失敗直到重新改變了視窗的Layered屬性。