用VC++實現不規則視窗 (轉)

gugu99發表於2007-12-29
用VC++實現不規則視窗 (轉)[@more@]


作者:曾勁峰

  隨著95的推出,在PC中出現了越來越多的應用採用了非矩形外觀的窗體,或者模擬現實中的事物,如鍾、眼睛等;或者創造一個具有三維觀感的非現實物體,這類程式以各種器為代表,甚至一些大腕級的老牌應用程式(如),也開始擁有這種視窗。一來是因為Windows和各類開發工具自身功能的極大提升;二來,也說明開發人員希望透過與眾不同的外觀,來強調使用時的第一映像,以期達到吸引的目的,畢竟,現在的PC是一個充滿圖形(圖象)的世界,充分利用這一特點,也能在一定程度上改善程式介面的可操作性。而且,對於同一型別的應用程式,在功能、相差不大的情況下,使用者也往往願意選擇外觀漂亮的那種。因而,很多文章都在介紹如何建立不規則的視窗,但幾乎千篇一律地基於VB進行說明。而筆者本人一直基於C/C++語言進行開發,因此,研究了一下在VC++5中實現不規則視窗的方法,下面就實現的主要方法進行說明。  
  VC++5提供了CRgn類和SetWindowRgn()來實現不規則的程式視窗。建立一個不規則視窗的過程是:首先定義一個CRgn類,並用各種初始化函式建立CRgn類的具體區域,然後CWnd::SetWindowRgn()函式建立不規則視窗。  
  CRgn是從Cgdi衍生出來的類,用來確定一個多邊形、橢圓或者由多邊形及橢圓合成的範圍,在程式中主要會用到CreateRectRgnIndirect()、CreateEllipticRgnIndirect()、CreatePolygonRgn()三個函式。  
  CreateRectRgnIndirect(LPCRECT   
lpRect)函式建立一個矩形區域,引數lpRect指定所建立的矩形區域在視窗使用者區中的left(左)、top(上)、right(右)、bottom(下)座標。例如:  
CRgn MyRgn;   
RECT m_rect;   
m_rect.left=0; m_rect.top=0; m_rect.right=500; m_rect.bottom=300;   
MyRgn.CreateRectRgnIndirect( &m_rect );   
  CreateEllipticRgnIndirect(LPCRECT   
lpRect)函式建立一個橢圓形區域,引數lpRect指定所建立的橢圓形區域在視窗使用者區中的left(左)、top(上)、right(右)、bottom(下)座標,如果指定right座標與left座標之差等於bottom座標與top座標之差,則建立的區域是一個圓。例如:  
CRgn MyRgn;   
RECT m_rect;   
m_rect.left=0; m_rect.top=0; m_rect.right=500; m_rect.bottom=300;   
MyRgn.CreateEllitpticRgnIndirect( &m_rect );   
  CreatePolygonRgn(LPPOINT lpPoints, int nCount, int   
nMode)函式建立一個多邊形區域,引數lpPoints指向一個POINT結構陣列,在POINT結構陣列中每個POINT結構項,用來確定多邊形頂點在視窗使用者區中的座標;nCount說明POINT結構陣列中POINT結構項的數目,也就是多邊形的頂點數;nMode指定多邊形的填充方式,一般使用ALTERNATE方式。例如建立一個三角形:  
CRgn MyRgn;   
POINT Points[3];   
Points[0].x=Points[0].y=0; Points[1].x=10; Points[1].y=30; Points[2].x=5; Points[2].y=60;   
MyRgn.CreatePolygonRgn(Points, 3, ALTERNATE);   
  利用以上的函式建立區域後,就可以呼叫CWnd::SetWindowRgn(HRGN hRgn, BOOL   
bRedraw)來建立非矩形的視窗了。SetWindowRgn()函式引數說明:hRgn是一個CRgn類的控制程式碼;bRedraw如果被設定成TRUE,那麼,在視窗次序發生變化時,系統會傳送WM_WINDOWPOSCHANGING和WM_WINDOWPOSCHANGED訊息給視窗。  
  如果要建立外形更復雜的視窗,例如mp3Soniq的一個播放介面,就是兩個圓形部分重合形成的。對於這類視窗的建立,還要用到CRgn類另外一個極其重要的函式——CombineRgn()。首先要說明的是:在VC++5的線上幫助中,將這個函式歸入了初始化(Initialization)型別中,實際上,如果定義的CRgn類在沒有使用其它初始化函式初始化之前,就呼叫這個函式的話,程式將會失敗,所以,這個函式似乎應該歸入operation類更恰當。  
  CombineRgn(CRgn* pRgn1, CRgn* pRgn2, int   
nCombineMode)函式用來建立一個由多個多邊形、橢圓合成的不規則區域。pRgn1、pRgn2分別指向參與合成不規則區域的多邊形或橢圓形;nCombineMode說明合成的方式:RGN_AND最後的區域是pRgn1和pRgn2的重疊部分;RGN_DIFF最後的區域是pRgn1中不包含pRgn2的部分;RGN_OR最後的區域同時包含pRgn1和pRgn2;RGN_XOR最後的區域同時包含pRgn1和pRgn2,但不包含pRng1和pRng2重疊的部分。例如,建立一個類似Soniq播放器的介面:  
......   
RECT m_Cyc1;   
RECT m_Cyc2;   
CRgn RgnCyc1;   
CRgn RgnCyc2;   
CRgn RgnDlg;   
m_Cyc1.left=100; m_Cyc1.top=5; m_Cyc1.right=200; m_Cyc1.bottom=105;   
m_Cyc2.left=80; m_Cyc2.top=85; m_Cyc2.right=180; m_Cyc2.bottom=185;   
RgnDlg.CreateEllipticRgnIndirect( &m_Cyc1 );   
RgnCyc1.CreateEllipticRgnIndirect( &m_Cyc1 );   
RgnCyc2.CreateEllipticRgnIndirect( &m_Cyc2 );   
RgnDlg.CombineRgn( &RgnCyc1, &RgnCyc2, RGN_OR );   
MyWin.SetWindowRgn( (HRGN)RgnDlg, TURE );   
......   
  以上就是利用VC++5實現不規則視窗的方法,相信大家看後都能創造出各種希奇古怪的視窗來,但是,有一點應該提請注意:對於Windows作業系統而言,桌面上視窗的形狀在中,所以,視窗外形的複雜程度應該適可而止,不要超過32767╳32767個邏輯單元,或者64K儲存區  
。當然,還有一點很重要:就是給視窗一張漂亮的臉,最好具有三維立體效果。

 

 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-996044/,如需轉載,請註明出處,否則將追究法律責任。

相關文章