2017-02-21 16 views
1

私は、左側にTTreeview、右側にTGroupboxというフォームを持っています。右端をドラッグしてフォームのサイズを変更すると、Groupboxを適切に拡大または縮小したい。フォームが左にドラッグされると、ツリービューのサイズを変更します。私は以下のコードを試して、右のサイズ変更はうまく動作します。しかし、左にリサイズすると、ツリービューは必要以上に長くなります。これを達成する正しい方法は何でしょうか?ドラッグ領域に基づいて動的にサイズを変更するコントロール

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の値は、ウィンドウのどの辺がサイズ変更されているかを正確に示します。

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

左のウィンドウのサイズを変更すると、グループボックスを右に固定するのを忘れてしまいます。

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; 

は、私はそれを試してみましたが、あなたがやりたいように思わ

EDIT:

あなたはまたして、順番に注意してください(コンポーネントを合わせプロパティを使用することができます "最後に「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; 

EDIT 2:マウスの左ボタンの時刻

WinapiのGetAsyncKeyState(vKey)関数を使用して、ボタンまたはキーの状態をチェックすることができます。 ボタンが押されているかどうかを確認し、ビット15 0/1のSmallIntのボタンの状態を返します。

GetAsyncKeyState

+0

いいえ、左と右に数回ドラッグすると、最終的にグループボックスが消えます。これを使用して、Anchorsを適切に調整することができます。ここで何か奇妙なことが起こっている。 – fullerm

+0

@fullerm 'GroupBox1.Anchors'に' akRight'を追加すると、Delphi 10.1 Berlinで問題なく動作しているようです。それがあなたにとってうまくいかない場合は、テストケースに、あなたが私たちに言わなかった何か他のものがなければなりません。 –

+0

私はXEを使用しており、空のプロジェクトでこのコードをテストしました。左側をずっと前後にドラッグすると、ツリービューはグループボックスにオーバーラップします。たぶん、XEにバグがあります。 – fullerm