1. 程式人生 > >半透明視窗中顯示標準控制元件(控制元件與文字不透明)的實現方案(附原始碼)

半透明視窗中顯示標準控制元件(控制元件與文字不透明)的實現方案(附原始碼)

原文 http://blog.csdn.net/harbinzju/article/details/7907127

和大家分享一下在半透明視窗中顯示標準控制元件的實現方案。通過層疊視窗可以簡單實現半透明與不規則形狀視窗的效果,但在其上顯示標準控制元件(控制元件與文字不透明)卻是件比較有挑戰的事情,這裡會給出一個可行的解決方案。同時實現了一些可重用的視窗類,有相關需求時可以進行引用。先看一下效果圖:



一、半透明視窗實現原理

繪製半透明視窗的通常做法是為視窗設定WS_EX_LAYERED屬性,通過UpdateLayeredWindow或者SetLayeredWindowAttributes來設定視窗透明度等屬性。這兩種方法有一些區別、適合的場景也不同。

UpdateLayeredWindow:呼叫後窗口的繪製被接管,應用負責主動呼叫這個函式進行繪製,視窗及其控制元件不再能接收到WM_PAINT訊息。可以把帶有透明畫素的PNG圖片直接繪製在視窗上,實現不同程式的透明效果。

SetLayeredWindowAttributes:有兩種模式:1. 指定特定畫素透明。2. 設定整個視窗統一的透明度(包括控制元件)。使用這個函式再設定視窗透明,視窗及控制元件仍可以收到WM_PAINT訊息。


需要特別注意的是UpdateLayeredWindowSetLayeredWindowAttributes的互斥性,在呼叫SetLayeredWindowAttributes

後再呼叫UpdateLayeredWindow都會失敗。

二、實現不規則視窗繪製

不規則的形狀由PNG圖片通過設定透明區域來實現,程式需要實現全透明區域的滑鼠訊息也透明。將需要進行透明處理的區域色彩設定為RGB(r,g,b),可以直接設定為RGB(0,0,0),通過SetLayeredWindowAttributes,將COLORREFcrKey引數設為RGB(r,g,b),即可以實現,這個透明效果不只是視覺上的透明,同時也會透過滑鼠訊息

三、在半透明背景中實現控制元件不透明

有時候我們只希望有透明畫素的圖片來做背景或者希望整個視窗有一定的透明度,但其上的控制元件不想做透明處理,否則控制元件上的文字會變得不明顯,影響使用。這裡提供的是雙層視窗的解決方案。前景視窗作為背景視窗的子視窗,兩個視窗時刻保持同樣尺寸,同時移動,關閉事件關聯處理。


前端視窗窗體全透明,並且透過滑鼠訊息,控制元件放置在前端視窗,不透明。實現方法是對訊息進行處理,視窗畫刷返回m_crKey(比如RGB(0, 255, 0))顏色的畫刷,其它控制元件預設處理。在視窗初始化的時候使用::SetLayeredWindowAttributes(m_hWnd, m_crKey, 0, LWA_COLORKEY); 設定對這個顏色透明。

  1. <span style="font-size:18px;">HBRUSH CStandardDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)    
  2. {    
  3.     if (nCtlColor == CTLCOLOR_DLG)    
  4.     {    
  5.         return CreateSolidBrush(m_crKey);    
  6.     }    
  7.     return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);    
  8. }</span>  

背景視窗使用預設的PNG圖片,通過UpdateLayeredWindow繪製,並設定全透明的區域透過滑鼠訊息。呼叫UpdateLayeredWindow後窗口內容會被系統快取,所以在視窗建立初次繪製後,如果沒有特殊需要是不需要去重畫背景視窗的。

這個方案支援所有標準的控制元件,同時也支援ActiveX控制元件,只要繼承通用的基類,使用起來十分方便,有興趣的朋友可以自己玩一下。附件的Demo主視窗展示了不規則形狀視窗,鏤空效果,控制元件懸浮效果,及ActiveX控制元件的使用;控制元件Demo中羅列了一系列標準控制元件。在Vista及以後的系統,由於有新API的支援可以實現更簡單的半透明視窗(毛玻璃效果),就不用這麼費周折了。

四、參考資料

五、程式碼下載