Delphi 基于拖动区域动态调整控件大小

Delphi 基于拖动区域动态调整控件大小,delphi,resize,anchor,Delphi,Resize,Anchor,我有一个表单,左边是TTreeview,右边是TGroupbox。通过在右侧边缘拖动来调整窗体大小时,我希望Groupbox相应地增大或缩小。当表单向左拖动时,我希望树视图能够调整大小。我尝试了下面的代码,正确调整大小效果很好。但左调整会导致treeview的长度超出其应有的长度。实现这一目标的正确方法是什么 procedure TForm1.FormResize(Sender: TObject); var p: TPoint; begin P:= ScreenToClient(Mous

我有一个表单,左边是TTreeview,右边是TGroupbox。通过在右侧边缘拖动来调整窗体大小时,我希望Groupbox相应地增大或缩小。当表单向左拖动时,我希望树视图能够调整大小。我尝试了下面的代码,正确调整大小效果很好。但左调整会导致treeview的长度超出其应有的长度。实现这一目标的正确方法是什么

procedure TForm1.FormResize(Sender: TObject);
var
  p: TPoint;
begin
  P:= ScreenToClient(Mouse.CursorPos);
  if(P.X<0) then begin
    Treeview1.Anchors:= [akLeft,akTop,akRight,akBottom];
    Groupbox1.Anchors:= [akTop,akBottom];
  end
  else begin
    Treeview1.Anchors:= [akLeft,akTop,akBottom];
    Groupbox1.Anchors:= [akLeft,akTop,akRight,akBottom];
  end;
end;
过程TForm1.FormResize(发送方:TObject);
变量
p:TPoint;
开始
P:=ScreenToClient(Mouse.CursorPos);

如果(P.X

我认为在调整左侧窗口的大小时,您忘记将Groupbox定位到右侧

procedure TForm1.FormResize(Sender: TObject);
var
  p: TPoint;
begin
  if GetAsyncKeyState(VK_LBUTTON) and $8000 <> 0 then exit;
  P:= ScreenToClient(Mouse.CursorPos);
  if(P.X<0) then begin
    Treeview1.Anchors:= [akLeft, akTop, akRight, akBottom];
    Groupbox1.Anchors:= [akTop, akRight, akBottom];
  end
  else begin
    Treeview1.Anchors:= [akLeft, akTop, akBottom];
    Groupbox1.Anchors:= [akLeft, akTop, akRight, akBottom];
  end;
end;
过程TForm1.FormResize(发送方:TObject);
变量
p:TPoint;
开始
如果GetAsyncKeyState(VK_LBUTTON)和$8000 0,则退出;
P:=ScreenToClient(Mouse.CursorPos);

如果(P.X

我认为在调整左侧窗口的大小时,您忘记将Groupbox定位到右侧

procedure TForm1.FormResize(Sender: TObject);
var
  p: TPoint;
begin
  if GetAsyncKeyState(VK_LBUTTON) and $8000 <> 0 then exit;
  P:= ScreenToClient(Mouse.CursorPos);
  if(P.X<0) then begin
    Treeview1.Anchors:= [akLeft, akTop, akRight, akBottom];
    Groupbox1.Anchors:= [akTop, akRight, akBottom];
  end
  else begin
    Treeview1.Anchors:= [akLeft, akTop, akBottom];
    Groupbox1.Anchors:= [akLeft, akTop, akRight, akBottom];
  end;
end;
过程TForm1.FormResize(发送方:TObject);
变量
p:TPoint;
开始
如果GetAsyncKeyState(VK_LBUTTON)和$8000 0,则退出;
P:=ScreenToClient(Mouse.CursorPos);

如果(P.X

而不是处理

OnResize
事件,则可以拦截消息

发送到用户正在调整大小的窗口。通过处理此消息,应用程序可以监视拖动矩形的大小和位置,并在需要时更改其大小或位置

它的
wParam
值准确地告诉您正在调整窗口的哪些边的大小。您可以使用该值相应地调整
定位,例如:

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    GroupBox1: TGroupBox;
  private
    { Private declarations }
    procedure WMSizing(var Message: TMessage); message WM_SIZING;
  public
    { Public declarations }
  end;

...

procedure TForm1.WMSizing(var Message: TMessage);
var
  TreeViewAnchors: TAnchors;
  GroupBoxAnchors: TAnchors;
begin
  inherited;

  TreeViewAnchors := [akTop, akBottom];
  GroupBoxAnchors := [akTop, akBottom];

  case Message.WParam of
    WMSZ_LEFT, WMSZ_BOTTOMLEFT, WMSZ_TOPLEFT: begin
      TreeViewAnchors := TreeViewAnchors + [akLeft, akRight];
      GroupBoxAnchors := GroupBoxAnchors + [akRight];
    end;
    WMSZ_RIGHT, WMSZ_BOTTOMRIGHT, WMSZ_TOPRIGHT: begin
      TreeViewAnchors := TreeViewAnchors + [akLeft];
      GroupBoxAnchors := GroupBoxAnchors + [akLeft, akRight];
    end;
  end;

  TreeView1.Anchors := TreeViewAnchors;
  GroupBox1.Anchors := GroupBoxAnchors;
end;

您可以截取消息,而不是处理
OnResize
事件

发送到用户正在调整大小的窗口。通过处理此消息,应用程序可以监视拖动矩形的大小和位置,并在需要时更改其大小或位置

它的
wParam
值准确地告诉您正在调整窗口的哪些边的大小。您可以使用该值相应地调整
定位,例如:

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    GroupBox1: TGroupBox;
  private
    { Private declarations }
    procedure WMSizing(var Message: TMessage); message WM_SIZING;
  public
    { Public declarations }
  end;

...

procedure TForm1.WMSizing(var Message: TMessage);
var
  TreeViewAnchors: TAnchors;
  GroupBoxAnchors: TAnchors;
begin
  inherited;

  TreeViewAnchors := [akTop, akBottom];
  GroupBoxAnchors := [akTop, akBottom];

  case Message.WParam of
    WMSZ_LEFT, WMSZ_BOTTOMLEFT, WMSZ_TOPLEFT: begin
      TreeViewAnchors := TreeViewAnchors + [akLeft, akRight];
      GroupBoxAnchors := GroupBoxAnchors + [akRight];
    end;
    WMSZ_RIGHT, WMSZ_BOTTOMRIGHT, WMSZ_TOPRIGHT: begin
      TreeViewAnchors := TreeViewAnchors + [akLeft];
      GroupBoxAnchors := GroupBoxAnchors + [akLeft, akRight];
    end;
  end;

  TreeView1.Anchors := TreeViewAnchors;
  GroupBox1.Anchors := GroupBoxAnchors;
end;

不,当您在左侧向左和向右拖动几次时,Groupbox最终会消失。这里发生了一些奇怪的事情。@fullerm将
akRight
添加到
GroupBox1中。锚定在Delphi 10.1 Berlin中似乎工作得很好。如果它对您不起作用,那么您的测试用例中一定还有其他您没有的东西告诉我们。我正在使用XE,并在一个空白项目中测试了这段代码。在左侧来回拖动了很多次之后,Treeview重叠到Groupbox上。也许XE中有一个bug。我看到了问题:当您调整左侧窗口的大小并将光标拖动到窗口的右侧时,Treeview重叠到组框上pbox,因为我认为OnResize事件会在P.X>0时再次处理。我们必须找到其他解决方案…我找到了一个解决方案:您可以检查鼠标左键的状态。如果单击鼠标左键,请退出该过程,否则请执行该操作。要检查按钮或键的状态,请执行以下操作:GetAsyncKeyState(vKey)-->Winapi.WindowsNo,当您在左侧向左和向右拖动几次时,Groupbox最终会消失。这里发生了一些奇怪的事情。@fullerm将
akRight
添加到
GroupBox1。锚定在Delphi 10.1 Berlin中似乎可以正常工作。如果对您不起作用,您的测试中肯定还有其他内容请注意,您没有告诉我们。我正在使用XE,并在一个空白项目中测试了此代码。在左侧来回拖动了很多次后,Treeview重叠到Groupbox上。XE中可能存在错误。我看到了问题:当您调整左侧窗口的大小,并将光标拖动到窗口的右侧时,Treeview就会出现错误rlaps到Groupbox上,因为我认为OnResize事件会在P.X>0时再次处理。我们必须找到其他解决方案…我找到了一个解决方案:您可以检查鼠标左键的状态。如果单击鼠标左键,请退出该过程,否则请执行该操作。要检查按钮或键的状态,请执行以下操作:GetAsyncKeyState(vKey)-->Winapi.Windows