BeginDeferWindowPos 和 DeferWindowPos、EndDeferWindowPos 是一组一起使用的函数, 可对一组窗口的位置、大小、Z 序等进行调整, 在 ExtCtrls 单元有用到.
下面先用常规方法实现对 Panel1 中的一组 Button 进行调整, 然后再用上面三个函数重新实现.
本例效果图:
代码文件:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
procedure RadioButton1Click(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.RadioButton1Click(Sender: TObject);
var
num,i: Integer;
btn: TButton;
L,T,W,H: Integer;
begin
num := Panel1.ControlCount;
L := 10;
T := 10;
W := (Panel1.ClientWidth - L * (num+1)) div num;
H := (Panel1.ClientHeight - T * (num+1)) div num;
for i := 0 to num - 1 do
begin
if Panel1.Controls[i] is TButton then
begin
btn := TButton(Panel1.Controls[i]);
btn.Left := L;
btn.Top := (H + T) * i + T;
btn.Width := W;
btn.Height := H;
end;
end;
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
var
num,i: Integer;
btn: TButton;
L,T,W,H: Integer;
begin
num := Panel1.ControlCount;
L := 10;
T := 10;
W := (Panel1.ClientWidth - L * (num+1)) div num;
H := (Panel1.ClientHeight - T * (num+1)) div num;
for i := 0 to num - 1 do
begin
if Panel1.Controls[i] is TButton then
begin
btn := TButton(Panel1.Controls[i]);
btn.Left := (W + L) * i + L;
btn.Top := T;
btn.Width := W;
btn.Height := H;
end;
end;
end;
end.
窗体文件:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 220
ClientWidth = 307
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 8
Top = 8
Width = 289
Height = 161
Caption = 'Panel1'
TabOrder = 0
object Button1: TButton
Left = 152
Top = 72
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
end
object Button2: TButton
Left = 160
Top = 80
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 1
end
object Button3: TButton
Left = 168
Top = 88
Width = 75
Height = 25
Caption = 'Button3'
TabOrder = 2
end
object Button4: TButton
Left = 176
Top = 96
Width = 75
Height = 25
Caption = 'Button4'
TabOrder = 3
end
end
object RadioButton1: TRadioButton
Left = 50
Top = 183
Width = 113
Height = 17
Caption = 'RadioButton1'
TabOrder = 1
OnClick = RadioButton1Click
end
object RadioButton2: TRadioButton
Left = 184
Top = 183
Width = 113
Height = 17
Caption = 'RadioButton2'
TabOrder = 2
OnClick = RadioButton2Click
end
end
用 BeginDeferWindowPos、DeferWindowPos、EndDeferWindowPos 重新实现的代码(窗体和运行效果是一样的):
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
procedure RadioButton1Click(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.RadioButton1Click(Sender: TObject);
var
num,i: Integer;
btn: TButton;
L,T,W,H: Integer;
DeferHandle: THandle;
begin
num := Panel1.ControlCount;
L := 10;
T := 10;
W := (Panel1.ClientWidth - L * (num+1)) div num;
H := (Panel1.ClientHeight - T * (num+1)) div num;
DeferHandle := BeginDeferWindowPos(num); {准备调整一组窗口}
for i := 0 to num - 1 do
begin
if Panel1.Controls[i] is TButton then
begin
btn := TButton(Panel1.Controls[i]);
DeferHandle := DeferWindowPos(DeferHandle,
btn.Handle,
HWND_TOP, {此参数决定 Z 序}
L, (H + T) * i + T, W, H, {新的位置与大小}
SWP_NOZORDER {更多控制, 现在是不改变 Z 序}
);
end;
end;
EndDeferWindowPos(DeferHandle); {实施调整}
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
var
num,i: Integer;
btn: TButton;
L,T,W,H: Integer;
DeferHandle: THandle;
begin
num := Panel1.ControlCount;
L := 10;
T := 10;
W := (Panel1.ClientWidth - L * (num+1)) div num;
H := (Panel1.ClientHeight - T * (num+1)) div num;
DeferHandle := BeginDeferWindowPos(num);
for i := 0 to num - 1 do
begin
if Panel1.Controls[i] is TButton then
begin
btn := TButton(Panel1.Controls[i]);
DeferHandle := DeferWindowPos(DeferHandle,
btn.Handle,
HWND_TOP,
(W + L) * i + L, T, W, H,
SWP_NOZORDER
);
end;
end;
EndDeferWindowPos(DeferHandle);
end;
end.