1. 程式人生 > >循序漸進實現仿QQ介面(一):園角矩形與雙緩衝貼圖視窗

循序漸進實現仿QQ介面(一):園角矩形與雙緩衝貼圖視窗

印象裡仿QQ介面的程式應該有很多,搜了一下,雖然出來一大堆,排除了重複的,卻只有兩三個,沒我想象的好。經常看到CSDN上有人問,QQ這個功能怎麼實現,那個介面怎麼實現,歸納了一下,決定寫這麼一個仿QQ介面程式,實用功能一律不實現,僅仿介面:

異型視窗
貼圖介面
介面可調色,換底紋
仿QQ介面上的各種自繪控制元件

QQ2009介面仔細研究起來,其實還是很複雜的,完全模擬做到一模一樣還是很花工夫的,用API實現是個噩夢,因此這裡是用RingSDK實現。關於RingSDK,請到這個連結http://blog.csdn.net/ringphone/archive/2008/09/11/2911244.aspx,最新版本請用SVN到svn://svnhost.cn/RingSDK下載。RingSDK的圖象庫與介面庫結合,可以實現一些比較酷的介面。這裡就是演示圖象庫與介面庫結合實現QQ2009的介面。OK,Let's go!不過先宣告一下,這裡只是模仿介面,實際QQ的介面不是這麼做的。

QQ2009是園角矩形視窗,不是複雜形狀,因此實現起來很簡單,CreateRoundRectRgn然後SetWindowRgn就行了。不過視窗可以拖動調整大小,因此不是簡單的在開始設定就可以,需要在WM_SIZE訊息裡隨時改變這個RGN:
 

然後需要在WM_NCPAINT的時候描邊,建立QQ邊框顏色的畫筆,用RoundRect就可以畫個圓角邊框。

QQ的標題欄和系統按鈕是自繪的,本來應該在WM_NCPAINT訊息裡繪製,但是發現點選“編輯個性簽名”會出現一個編輯框供輸入,而標題欄是不能放置控制元件的,因此主視窗建立時乾脆不要標題欄,全部客戶區,在客戶區上方模擬一個標題欄區域出來。由於要支援調整視窗尺寸,因此建立視窗時視窗型別是WS_POPUPWINDOW|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,如此預設的視窗邊框並不符合我們的要求,需要在WM_NCCALCSIZE訊息裡設定一下邊框尺寸:

設定邊框尺寸為2。這裡有一個有趣的現象:即使不響應WM_NCCALCSIZE訊息,建立的視窗也是沒有標題欄的,沒有最小/大化,關閉按鈕,但是在工作列上的程式按鈕上按滑鼠右鍵,最小化,移動,大小,關閉的選項一個不少,並且視窗也響應這些命令。如果視窗加上WS_EX_TOOLWINDOW的擴充套件型別,則程式不會出現在工作列上,就跟QQ的表現一樣了,不過目前我們的程式暫時僅實現標題欄的貼圖,不支援實際功能,因此暫時不加這個擴充套件型別,靠在工作列上的程式按鈕上按滑鼠右鍵實現視窗的最小/大化和關閉操作。不過這也太那個了一點,因此還是在系統欄加個圖示為上,怎麼在系統欄加圖示這個應該不成問題了,這裡就不解釋了,RingSDK對此進行了封裝,一句AddInTaskBar(m_hWnd,LoadIcon(GetInstance(),MAKEINTRESOURCE(IDI_QQ)),"仿QQ2009介面");搞定。響應圖示的點選彈出選單這裡也不解釋了,看程式碼就知道了。

接下來就是介面貼圖,實現QQ的上下兩個區域的繪製,這裡就要用到介面庫了。首先就是要準備圖片,QQ資源裡沒找到,懶得研究,就自己截圖搞了,弄了個寬度為1,高95和55的圖片平鋪做上下兩部分的背景,VISTA風格的系統按鈕圖案,因為是圓角,需要有透明色,就做成了GIF格式。底紋,右邊的沙灘海鷗圖案摳圖沒這個本事,另找了一個相似的,做成PNG格式,PS裡面加個蒙板就有了ALPHA通道。圖象庫支援PNG的半透明繪製,只要呼叫AlphaTo就行。還有使用者頭像,隨便截了一個,把這些素材加入資源,算準座標進行雙緩衝繪製,依次繪製到記憶體圖象就可以了。這裡說一下記憶體圖象的建立,是一開始就建立了一個跟螢幕等寬,高95+55的記憶體圖象,這樣就不需要在WM_SIZE裡頻繁釋放再建立了。程式碼如下:

 

至此貼圖視窗完成,看一下程式截圖:

目前的這個程式可拖動,可調整大小,雙擊可最大化,系統欄圖示按右鍵可彈出仿QQ的選單,不過僅“開啟主面板”和“關閉”命令有效。介面上的按鈕只是貼圖,並不會響應滑鼠動作。下一步會實現介面按鈕的三態和功能響應,新增其他功能,下一篇再說了。

補充說明:介面庫是支援MFC的,程式中的貼圖程式碼基本可以照搬到MFC的程式,只需要包含"ringdib.h"即可。不過需要先編譯libsrc/freelib下的zlib,png庫,想支援JPG還需編譯JPG庫。