2017-02-21 33 views
1

我有一个窗体,左边是一个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; 

回答

2

比处理OnResize事件相反,可以改为拦截WM_SIZING消息,而不是

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

它的wParam值告诉你窗口的哪个边缘被调整大小。你可以用它来相应地调整Anchors,如:

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; 
2

我想你忘了在左边的窗口调整大小时将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; 

我试了一下,似乎做你想做的事

编辑:

您还可以使用对齐财产(注意顺序上,成分与' alClient'值):

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   
    Groupbox1.Align:= alRight; 
    Treeview1.Align:= alClient; 
    end 
    else begin 
    Treeview1.Align:= alLeft; 
    Groupbox1.Align:= alClient; 
    end; 
end; 

编辑2:检查s鼠标左键的状态

您可以使用Winapi函数GetAsyncKeyState(vKey)检查按钮或按键的状态。 如果按钮被按下或没有按下,则返回SmallInt中按钮的状态,位15 0/1。

GetAsyncKeyState

+0

没有,当你在左边拖动到左侧和右侧几次GROUPBOX最终消失。这里有一些奇怪的事情发生。 – fullerm

+0

@fullerm将'akRight'添加到'GroupBox1.Anchors'似乎在德尔福10.1柏林工作正常。如果它不适合你,你的测试用例中肯定还有别的东西没有告诉我们。 –

+0

我正在使用XE并在一个空白项目中测试了这段代码。在左侧来回拖动之后,Treeview重叠到Groupbox上。也许XE有一个错误。 – fullerm