DELPHI中使用API函數(shù)完成多態(tài)FORM
發(fā)表時間:2024-02-20 來源:明輝站整理相關軟件相關文章人氣:
[摘要]陳學軍 實現(xiàn)異型FORM并不是一件難事,本文將向您介紹如何利用API函數(shù)實現(xiàn)圓角矩形和橢圓形FORM,并在此基礎之上探討實現(xiàn)TWINcontrol類的后裔的異型的實現(xiàn)。 欲改變FORM的形狀,也就是實現(xiàn)對區(qū)域(region)的控制。在Win32 API程序參考手冊有關區(qū)域(region)的定...
陳學軍
實現(xiàn)異型FORM并不是一件難事,本文將向您介紹如何利用API函數(shù)實現(xiàn)圓角矩形和橢圓形FORM,并在此基礎之上探討實現(xiàn)TWINcontrol類的后裔的異型的實現(xiàn)。
欲改變FORM的形狀,也就是實現(xiàn)對區(qū)域(region)的控制。在Win32 API程序參考手冊有關區(qū)域(region)的定義是這樣描述的:它可以是一個矩形,多邊形,橢圓形(或者是兩者的復合,或者是更多的形狀),這些都可以被填充,畫圖,翻轉,結構化并可以得到焦點執(zhí)行。
由定義得出結論:區(qū)域(region)是可以被改變和操縱的,依據(jù)我們的需求可定義區(qū)域并制作出我們所要求的形狀。
應當指出的是區(qū)域(region)也能對任何TWINcontrol類的后裔定義和控制(不僅僅是FORMS),就是說,可以將區(qū)域(region)的定義運用到向Tpanel或TEdit這樣的對象。在改變TWINcontrol類的后裔控件的形狀時,需要提供一句柄并創(chuàng)建一些改變形狀的函數(shù)。
具體實現(xiàn)方式一般分為兩步:
1.定義所需形狀的區(qū)域邊界形狀(比如:橢圓形)。
2.將已定義的區(qū)域邊界形狀運用到窗口。
這里,我們將通過調用Windows API函數(shù)完成以上兩個步驟,下面就具體函數(shù)的應用予以說明:
實現(xiàn)第一步:定義區(qū)域邊界。
在這里將調用三個WinAPI,這三個函數(shù)是:
CreateEllipticRgn()功能是生成橢圓形區(qū)域;
CreateRoundRectRgn()功能是生成圓角矩形區(qū)域;
CreatePolygonRgn()功能是生成多邊形區(qū)域,Windows要確保使其頂點自動相連形成一封閉的區(qū)域。
這三個函數(shù)通過返回的指針變量標識所生成的區(qū)域將被第二步所應用。這些函數(shù)在Delphi中的函數(shù)聲明及參數(shù)含義說明如下:
。1)橢圓形區(qū)域生成函數(shù):
函數(shù)原形:HRGN CreateEllipticRgn(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect);
參數(shù)含義:
nLeftRect,nTopRect:區(qū)域的左上角坐標;
nRightRect, nBottomRect:區(qū)域的右下角坐標;
。2)圓角矩形區(qū)域生成函數(shù):
函數(shù)原形:HRGN CreateRoundRectRgn(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nWidthEllipse,int nHeightEllipse);
參數(shù)含義:
nLeftRect, nTopRect:區(qū)域的左上角坐標;
nRightRect, nBottomRect:區(qū)域的右下角坐標;
nWidthEllipse, nHeightEllipse:圓角的寬度和高度;
。3)多邊形區(qū)域生成函數(shù):
函數(shù)原形:HRGN CreatePolygonRgn(CONST POINT *lppt,int cPoints, int fnPolyFillMode);
參數(shù)含義:
Lppt:指向一個POINT類型的數(shù)組,該數(shù)組定義多邊形頂點;
CPoints:定義數(shù)組中頂點數(shù);
FnPolyFillMode:定義填充模式,可選值為ALTERNATE或WINDING。
實現(xiàn)第二步:將返回的HRGN類型的區(qū)域值被設置窗口區(qū)域函數(shù)調用。
設置窗口區(qū)域函數(shù):
函數(shù)原形:int SetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw);
參數(shù)說明:
hWnd:指向所操作的窗口的句柄;
hRgn:所給區(qū)域句柄;
bRedraw:是否顯示重畫窗口的標志。
在每一個函數(shù)的最后都需要調用SetWindowRgn函數(shù),然后由Windows操作系統(tǒng)實現(xiàn)區(qū)域的各種形狀的設置并顯示。
以下將測試的FORM的整個源代碼列出,在FORM上添加了四個按鈕分別控制實現(xiàn):橢圓形,圓角矩形,等邊多邊形和星形;一個Tpanel控件為了演示TWINcontrol類的后裔的區(qū)域定義和控制;一個SpinEdit控件定義多邊形和星形的頂點連接數(shù)目。
源程序:
unit form_statue;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Spin;
type
TForm1 = class(TForm)
Button1: TButton;
SpinEdit1: TSpinEdit;
Panel1: TPanel;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure DrawRndRectRegion(wnd : HWND; rect : TRect);
procedure DrawEllipticRegion(wnd : HWND; rect : TRect);
procedure DrawPolygonRegion(wnd : HWND; rect : TRect; NumPoints : Integer; DoStarShape : Boolean);
procedure Button1Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
rgn : HRGN;
rect : TRect;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.DrawRndRectRegion(wnd : HWND; rect : TRect);
begin
rgn := CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom, 30, 30);
SetWindowRgn(wnd, rgn, TRUE);
end;
procedure TForm1.DrawEllipticRegion(wnd : HWND; rect : TRect);
begin
rgn := CreateEllipticRgn(rect.left, rect.top, rect.right, rect.bottom);
SetWindowRgn(wnd, rgn, TRUE);
end;
procedure TForm1.DrawPolygonRegion(wnd : HWND; rect : TRect; NumPoints : Integer; DoStarShape : Boolean);
const
RadConvert = PI/180;
Degrees = 360;
MaxLines = 100;
var
x, y,
xCenter,
yCenter,
radius,
pts,
I : Integer;
angle,
rotation: Extended;
arPts : Array[0..MaxLines] of TPoint;
begin
xCenter := (rect.Right - rect.Left) div 2;
yCenter := (rect.Bottom - rect.Top) div 2;
if DoStarShape then
begin
rotation := Degrees/(2*NumPoints);
pts := 2 * NumPoints;
end
else
begin
rotation := Degrees/NumPoints; //得到每個頂點的度數(shù)
pts := NumPoints ;
end;
radius := yCenter;
for I := 0 to pts - 1 do begin
if DoStarShape then
if (I mod 2) = 0 then
radius := Round(radius/2)
else
radius := yCenter;
angle := ((I * rotation) + 90) * RadConvert;
x := xCenter + Round(cos(angle) * radius);
y := yCenter - Round(sin(angle) * radius);
arPts[I].X := x;
arPts[I].Y := y;
end;
rgn := CreatePolygonRgn(arPts, pts, WINDING);
SetWindowRgn(wnd, rgn, TRUE);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DrawRndRectRegion(Form1.Handle, Form1.ClientRect);
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
DrawPolygonRegion(Panel1.Handle, Panel1.BoundsRect, SpinEdit1.Value, True);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
DrawEllipticRegion(Form1.Handle, Form1.ClientRect);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
DrawPolygonRegion(Panel1.Handle, Panel1.BoundsRect, SpinEdit1.Value, False);
end;
end.
源程序在PWIN98+DELPHI5環(huán)境下調試成功,可以直接引用。