天天看點

VC實作頂層視窗的透明與實作子視窗的透明【重點:子視窗透明處理】

          本人在vc開發過程中,多次因視窗透明而煞費苦心,在本人的前一文章《UpdateLayeredWindow與SetLayeredWindowAttributes》中已經指明實作視窗的透明方法,在過往實際的開發過程中我也一直沿襲這一做法,但也并不是屢試不爽,實際應用過程中的缺陷暴露如下:

(1)SetLayeredWindowAttributes和UpdateLayeredWindow兩個API函數隻能适用于層級視窗,也就是非子視窗;

(2)UpdateLayeredWindow方法效率比SetLayeredWindowAttributes效率高,但是它是通過繪制到某一個記憶體中間裝置上下文後,将裝置上下文拷貝到指定層級視窗上實作的,也就是所有的繪制都必須在記憶體裝置上下文實作,甚至包括所有子控件,是以通過它實作透明,父視窗上的所有子控件“不見了”,是以應特别注意[這也是經驗總結,切記!],但好處是指定不透明度為255時候,它自動從使用的png的alpha[當然不一定是png貼圖,隻要貼圖有alpha通道]通道去透明視窗,也就是透明度就是圖檔的透明度,否則不使用貼圖情況當然可以使用const 透明常亮指定透明度;SetLayeredWindowAttributes透明也有兩種方式,第一種是通過指定COLORREF crKey, 掩碼色,也就是參數2指定為要剔除的掩碼色【視窗自動将所有背景中為crkey的掩碼色的背景完全透明】,當然使用掩碼色方法的時候必須指定 DWORD dwFlags為LWA_COLORKEY,即使用掩碼色透明;第二種方式就是不使用掩碼色,而是使用透明度去透明而不關心你背景顔色到底如何,隻是将整個視窗加上一層透明度,這時crkey忽略填寫0,将bAlpha不透明度指定成0-255的任意值,0指完全透明,255指完全不透明,此時指定 DWORD dwFlags為LWA_ALPHA.

BOOL SetLayeredWindowAttributes(      

    HWND hwnd,
    COLORREF crKey,
    BYTE bAlpha,
    DWORD dwFlags
);通過對比可以知道SetLayeredWindowAttributes中第一種透明方法是逐個去掉掩碼色位置的像素,而UpdateLayeredWindow是通過二進制與操作實作的,是以UpdateLayeredWindow效率要高很多很多;      
(3)由于是層級視窗,在實際應用中将透明視窗都設定為透明視窗導緻的問題是,切換到其他頁面的時候,必須手動去隐藏改層級視窗,如果手動SetParent這層級視窗就失效,調用後自動帶上WS_CHILD屬性導緻層級視窗透明無法實作;      
(4)最小化後再顯示,透明視窗顯示比其他視窗快,感覺覆寫在其他視窗上的透明視窗“不是一夥的”,失聯了一般;      
(5)透明視窗單獨跑到桌面上去了,應用程式最小化不可見;      
以上是使用層級視窗透明的方法以及使用該方法暴露的若幹問題,針對以上問題,為了完善或避免以上方法,我一直在尋找使得子視窗透明的方法,不巧,偶然中使用中空畫刷,這才讓我恍然大悟:中空HOLLOW_BRUSH就等于NULL_BRUSH,含義就是不使用畫刷,也就是不做畫刷填充,不填充其實就是透明,提到這邊不知道各位網友是否已經想到實作子視窗透明的方法?算了,不賣關子了,聽我細細道來:首先視窗以及視窗上的子控件繪制成什麼樣的背景是通過什麼方法告知視窗的,這裡提的字很關鍵, 是告知不是讓你代碼實作,對!就是通過OnCtlColor的傳回值來告知父視窗到底将本視窗或本視窗子控件背景預設繪制成啥顔色,置于具體是傳回本視窗還是本視窗子控件是通過OnCtlColor的參數UINT nCtlColor類型指定的,當為CTLCOLOR_DLG時就是指定視窗的背景色,當是CTLCOLOR_EDIT時告知編輯框的背景色,CTLCOLOR_BUTTON告知按鈕預設的背景色...      
通過以上指點分析,我們隻要截獲ON_WM_CTLCOLOR消息,然後在該處理函數不論是什麼類型都傳回空畫刷也就是return (HBRUSH)GetStockObject(HOLLOW_BRUSH);即可,這時候該視窗就透明了【該視窗指定為其他視窗的子視窗後,則子視窗也透明】,如果還想再該透明子視窗上劃線、畫矩形等實作OnLbuttonDown、OnLbuttonup和OnMouseMove消息函數,在OnEraseBkGround處理函數中繪制即可!簡單吧?      
好,以上就是實作視窗透明的3種方法(内行4種透明方式,包括setlayeredwindowattributes的兩種),如果還是不明白子視窗透明,我這裡有相應的Demon,大家可以去下載下傳,希望各位都有收獲,這才是我共享的力量!      
子視窗透明:http://download.csdn.net/detail/lixiang987654321/8846755      
層級視窗透明以及子視窗透明:http://download.csdn.net/detail/lixiang987654321/8847067