用API函數在Delphi中實現“非典型”窗體
現在的一些共享軟件特別是一些多媒體播放器軟件為了吸引用戶,很注重程序界面的設計。實際上,我們使用API函數也可以實現那些好看又另類的效果。
1.異形窗體
窗體只能是方的嗎?不是,還可以有其他形狀。這要用到兩個Win32 API函數。首先用CreateRoundRectRgn()函數在窗體內界定一個橢圓形區域。這裡所指的區域(region)是一個特殊的API對象,我們可以在區域內部進行填充和剪裁等操作,從而定義窗體的外部特征。然後調用SetWindowRgn()函數繪制,更進一步還可以再用CombineRgn()函數來合並多個區域,例如在Delphi的單元文件中加入以下代碼:
procedure TForm1.FormCreate(Sender: TObject);
var
FRegion1:THandle;
FRegion2:THandle;
begin
FRegion1:=CreateRoundRectRgn(20,20,200,200,300,300);//界定一個橢圓區域
FRegion2:=CreateRectRgn(170,170,400,400);//界定一個矩形區域
CombineRgn(FRegion1,FRegion1,FRegion2,RGN_OR);//將兩個區域連接起來
SetwindowRgn(handle,FRegion1,True);//對連接後的區域進行繪制
end;
程序段中的CreateRoundRectRgn()函數用來創建一個圓角矩形區域,它的原型為:
HRGN CreateRoundRectRgn(
int nLeftRect, // 左上角的X坐標
int nTopRect, // 左上角的Y坐標
int nRightRect, // 右下角的X坐標
int nBottomRect, // 右下角的Y坐標
int nWidthEllipse, //圓角所在橢圓的寬
int nHeightEllipse // 圓角所在橢圓的高
);
其他圖形如多邊形、橢圓形等都有對應的API函數,它們的原型如下:
HRGN CreateEllipticRgn(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect)
HRGN CreateEllipticRgnIndirect( CONST RECT *lprc)
HRGN CreatePolygonRgn(CONST POINT *lPPT,int cPoints, int fnPolyFillMode)
HRGN CreatepolypolygonRgn(CONST POINT *lPPT,CONST INT *lpPolyCounts,int nCount,int fnPolyFillMode)
HRGN CreateRectRgn(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect)
HRGN CreateRectRgnIndirect(CONST RECT *lprc)
以上函數的參數很好理解,用來說明圖形內置矩形的坐標或指向該矩形。重點來看一下另外兩個函數:
函數原型:SetWindowRgn(
HWND hWnd, //當前窗體的句柄
HRGN hRgn, //當前區域的句柄
BOOL bRedraw, //重繪標志
)
函數功能:該函數把已創建的區域的句柄作為參數傳遞給當前窗體的句柄,並在該區域范圍內繪制窗體;
函數原型:CombineRgn(
HRGN hrgnDest, // 連接目的區域的句柄
HRGN hrgnSrc1, // 第一個連接源區域的句柄
HRGN hrgnSrc2, // 第二個連接源區域的句柄
int fnCombineMode // 連接模式
)
函數功能:該函數將兩個區域合並為一個新的區域,其中連接模式可取以下值:
參數值 作用
RGN_AND 由區域1與區域2的共有部分即交集創建新的區域
RGN_COPY 創建區域1的副本作為新的區域
RGN_DIFF 連接屬於區域1但不屬於區域2的部分為新的區域
RGN_OR 連接區域1和區域2的所有部分即並集
RGN_XOR。 連接區域1和區域2的所有部分即並去掉共有部分
2.空心窗體
這種窗體的特點是好端端的一個窗體,中間被挖了一部分。例如在Delphi的單元文件中加入以下代碼:
procedure TForm1.FormCreate(Sender: TObject);
var
FRegion3:THandle;
begin
Canvas.Font.Name:='華文行楷';//設置字體
Canvas.Font.Size:=100;//設置字號
BeginPath(Canvas.Handle); //得到vanvas上繪制的輪廓
TextOut(form1.Canvas.Handle,0,20,'程序春秋',8);//將“程序春秋”四個字所占區域摳掉
EndPath(Canvas.Handle);
FRegion3:=PathToRegion(Canvas.Handle);//將以上區域賦給窗體
SetwindowRgn(Handle,FRegion3,True);//開始繪制
end;
這裡主要用到了三個API函數:
函數原型:BOOL BeginPath(HDC hdc //設備環境的句柄)
函數功能:開始接收當前設備環境的路徑軌跡;
函數原型:BOOL EndPath(HDC hdc //設備環境的句柄)
函數功能:停止接收並將已接收的路徑軌跡賦給當前設備環境的句柄
函數原型 BOOL TextOut(
HDC hdc, // handle of device context
int nXStart, // 起始位置的X坐標
int nYStart, // 起始位置的Y坐標
LPCTSTR lpString, // 字符串地址
int cbString //字符串所包含字符數(注意一個漢字占兩個字符)
)
函數功能:在指定位置繪制給定字符串。
小結:學會熟練使用API進行編程,是一項很重要的技能,有時可以達到意想不到的效果。以上幾種技巧旨在拋磚引玉,希望大家充分運用各種技巧,發揮自己想像,設計出更炫的窗體,美化自己的程序