グラフィックスまたはマルチメディア アプリケーションを開発している場合、タイトル バーを使用せずにフォームを移動する方法を疑問に思うかもしれません。実際には、フォームのクライアント領域をマウスでドラッグするだけです。
方法 1
上記の機能を実現する最も一般的な方法は次のとおりです。フォームの PRivate ステートメント セクションに次のプロシージャ ステートメントを追加します。
プロシージャ WMNCHitTest(var Msg:TWMNCHitTest);メッセージ WM_NCHITTEST;
次に、実装セクションに次のコードを追加します。
プロシージャ TForm1{または定義したフォーム名}.WMNCHitTest(var Msg:TWMNCHitTest);
始める
DefaultHandler(メッセージ);
Msg.Result = HTCLIENT の場合
メッセージ結果:= HTCAPTION;
終わり;
このメソッドは、マウスがフォームのクライアント領域をクリックしたときに、Windows にタイトル バーがクリックされたと認識させます。
方法 2
ここでは、マウスを使用して通常のフォームを移動する別の方法を紹介します。
プロシージャ TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X、Y: Integer);
始める
if (ssLeft in Shift) then begin
リリースキャプチャ;
SendMessage(Form1.Handle,WM_SYSCOMMAND,SC_MOVE+1,0);
終わり;
終わり;
上記の方法の不完全性
「ドラッグ中にウィンドウの内容を表示する」オプションのチェックを外すとどうなるかを見てみましょう。これは Windows の設定です。このプロパティは、[スタート メニュー --> 設定 --> フォルダ オプション --> 表示 --> 詳細設定] にあります。 Windows95の場合はレジストリの変更が必要です。このプロパティを無効に設定すると、ドラッグするとフォームが正方形のアウトラインに変わります。不規則なフォームを使用している可能性がありますが、それでも輪郭は表示されます。
フォームを画面の端にドッキングしたい場合 (例: WinAmp、フォームを画面上部の特定の位置にドラッグすると、フォームは画面上部近くになります)。上記の 2 番目の手順を使用します。この方法では、マウス ボタンが放されるまでフォームの位置を処理できず、ドッキングの問題も処理できなくなります。
以下では、簡単な方法を使用して 2 つの問題を解決します。
まず、設定に関係なく、フォームをドラッグしてもアウトラインは表示されません。
次に、フォームの移動時に位置検出が行われ、適切な位置になった場合に特定の位置にドッキングされます。
多くの人がこれらの問題を解決しているかもしれませんが、おそらく以下のコードが役立つでしょう。
方法 3
Form1 を uMain.pas として保存し、Form2 を uDock.pas として保存する場合、次のコードを Delphi に直接コピーできます。使用されるイベントは、OnMouseDown、OnMouseMove、OnMouseUp、OnShow (Form1) です。
これは、uMain と uDock (Form1 と Form2) の 2 つのフォームを含む、マウスの動きに基づいてフォームを移動する方法です。 Form2 は Form1 を通じて開かれ、Form1 の下部にドッキングできます。ドッキングすると、Form2 を邪魔にならないように移動するまで、Form2 は Form1 と一緒に移動します。
フォーム1
ユニットuMain;
インタフェース
用途
ウィンドウ、メッセージ、SysUtils、クラス、グラフィックス、コントロール、フォーム、ダイアログ。
タイプ
TForm1 = クラス(TForm)
プロシージャ FormMouseDown(Sender:TObject; Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
プロシージャ FormMouseMove(Sender: TObject; Shift: TShiftState;X,Y: Integer);
プロシージャ FormMouseUp(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y: Integer);
プロシージャ FormShow(Sender: TObject);
プライベート
{プライベート宣言}
公共
DocktoForm: ブール値;
{公的宣言}
終わり;
変数
フォーム1: TForm1;
CanMove、CanMoveX、CanMoveY: ブール値。
OldX、OldY: 整数。
F1X、F1Y、F2X、F2Y: 整数。
ワークエリア : TRect;
実装
uDockを使用します。
{$R *.DFM}
プロシージャ TForm1.FormMouseDown(送信者: TObject; ボタン: TMouseButton;Shift: TShiftState; X、Y: 整数);
始める
CanMoveX := true;
CanMoveY := true;
CanMove := true;
OldX := X;
古いY := Y;
ifDocktoForm then
始める
F1X := フォーム 1.左;
F1Y := フォーム 1.トップ;
F2X := フォーム 2.左;
F2Y := フォーム 2.トップ;
終わり;
終わり;
プロシージャ TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X、Y: Integer);
始める
if (移動できる)
始める
CanMoveX の場合
Form1.Left := Form1.Left + (X - OldX);
CanMoveY なら
Form1.Top := Form1.Top + (Y - OldY);
//このセクションは先頭にラッチされます
if (Form1.Top < WorkArea.Top + 10) および (Form1.Top > WorkArea.Top-10) then
始める
Form1.Top := WorkArea.Top;
if (Y-OldY > 10) または (Y-OldY < -10) then
CanMoveY := true
それ以外
CanMoveY := False;
終わり;
//このセクションは左側にラッチされます
if (Form1.Left < WorkArea.Left+10) および (Form1.Left > WaskArea.Left-10) then
始める
Form1.Left := WorkArea.Left;
if (X-OldX > 10) または (X-OldX < -10) then
CanMoveX := true
それ以外
CanMoveX := False;
終わり;
//このセクションは右側にラッチされます
if (Form1.Left > WorkArea.Right-Form1.Width-10) および (Form1.Left < WorkArea.Right-Form1.Width+10) then
始める
Form1.Left := WorkArea.Right-Form1.Width;
if (X-OldX > 10) または (X-OldX < -10) then
CanMoveX := true
それ以外
CanMoveX := False;
終わり;
//このセクションはタスクバーにラッチされます
ifDocktoForm then
始める
if (Form1.Top > WorkArea.Bottom-Form1.Height-Form2.Height-10) および (Form1.Top < WorkArea.Bottom-Form1.Height-Form2.Height+10) then
始める
Form1.Top := WorkArea.Bottom-Form1.Height-Form2.Height;
if (Y-OldY > 10) または (Y-OldY < -10) then
CanMoveY := true
それ以外
CanMoveY := False;
終わり;
終わり
そうでなければ始まる
if (Form1.Top > WorkArea.Bottom-Form1.Height-10) および (Form1.Top < WorkArea.Bottom-Form1.Height+10) then
始める
Form1.Top := WorkArea.Bottom-Form1.Height;
if (Y-OldY > 10) または (Y-OldY < -10) then
CanMoveY := true
それ以外
CanMoveY := False;
終わり;
終わり;
ifDocktoForm then
始める
Form2.Left := Form1.Left - (F1X-F2X);// + (X-OldX);
Form2.Top := Form1.Top+Form1.Height;
出口;
終わり;
//このセクションは、Form1 の中央にプレイリストをラッチします。
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) および (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Width div 2))+10) および
(Form2.Top > Form1.Top+Form1.Height-10) および (Form2.Top < Form1.Top+Form1.Height+10) の場合
始める
Form2.Left := Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2));
DocktoForm := True;
F1X := フォーム 1.左;
F1Y := フォーム 1.トップ;
F2X := フォーム 2.左;
F2Y := フォーム 2.トップ;
終わり;
終わり;
終わり;
プロシージャ TForm1.FormMouseUp(送信者: TObject; ボタン: TMouseButton; Shift: TShiftState; X、Y: 整数);
始める
CanMove := false;
終わり;
プロシージャ TForm1.FormShow(送信者: TObject);
始める
//ワークエリアパラメータを取得する
SystemParametersInfo(SPI_GETWORKAREA, 0, @WorkArea, 0);
Form2.表示;
終わり;
終わり。
フォーム2
ユニットuDock;
インタフェース
用途
ウィンドウ、メッセージ、SysUtils、クラス、グラフィックス、コントロール、フォーム、ダイアログ。
タイプ
TForm2 = クラス(TForm)
プロシージャ FormMouseDown(送信者: TObject; ボタン: TMouseButton;Shift: TShiftState; X、Y: 整数);
プロシージャ FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
プロシージャ FormMouseUp(送信者: TObject; ボタン: TMouseButton;Shift: TShiftState; X、Y: 整数);
プライベート
{プライベート宣言}
公共
{公的宣言}
終わり;
変数
フォーム 2: TForm2;
CanMove、CanMoveX、CanMoveY、DocktoForm: ブール値;
OldX、OldY: 整数。
実装
uMain を使用します。
{$R *.DFM}
プロシージャ TForm2.FormMouseDown(送信者: TObject; ボタン: TMouseButton; シフト: TShiftState; X、Y: 整数);
始める
CanMoveX := true;
CanMoveY := true;
CanMove := true;
OldX := X;
古いY := Y;
終わり;
プロシージャ TForm2.FormMouseMove(Sender: TObject; Shift: TShiftState; X、Y: Integer);
始める
if (移動できる)
始める
CanMoveX の場合
Form2.Left := Form2.Left + (X - OldX);
CanMoveY なら
Form2.Top := Form2.Top + (Y - OldY);
//このセクションは先頭にラッチされます
if (Form2.Top < WorkArea.Top + 10) および (Form2.Top > WorkArea.Top-10) then
始める
Form2.Top := WorkArea.Top;
if (Y-OldY > 10) または (Y-OldY < -10) then
CanMoveY := true
それ以外
CanMoveY := False;
終わり;
//このセクションは左側にラッチされます
if (Form2.Left < WorkArea.Left+10) および (Form2.Left > WorkArea.Left-10) then
始める
Form2.Left := WorkArea.Left;
if (X-OldX > 10) または (X-OldX < -10) then
CanMoveX := true
それ以外
CanMoveX := False;
終わり;
//このセクションは右側にラッチされます
if (Form2.Left > WorkArea.Right-Form2.Width-10) および (Form2.Left < WorkArea.Right-Form2.Width+10) then
始める
Form2.Left := WorkArea.Right-Form2.Width;
if (X-OldX > 10) または (X-OldX < -10) then
CanMoveX := true
それ以外
CanMoveX := False;
終わり;
//このセクションはタスクバーにラッチされます
if (Form2.Top > WorkArea.Bottom-Form2.Height-10) および (Form2.Top < WorkArea.Bottom-Form2.Height+10) then
始める
Form2.Top := WorkArea.Bottom-Form2.Height;
if (Y-OldY > 10) または (Y-OldY < -10) then
CanMoveY := true
それ以外
CanMoveY := False;
出口;
終わり;
//このセクションはプレーヤーの下部にラッチされます
if (Form2.Top > Form1.Top+Form1.Height-10) および (Form2.Top < Form1.Top+Form1.Height+10) および (Form2.Left > Form1.Left-Form2.Width) および (Form2.Top Left < Form1.Left + Form1.Width) の場合
始める
Form2.Top := Form1.Top+Form1.Height;
(Y-OldY > 10) または (Y-OldY < -10) の場合、開始します
CanMoveY := true;
Form1.DockToForm := False;
終わり
そうでなければ始まる
CanMoveY := False;
Form1.DockToForm := True;
終わり;
終わり;
//このセクションは、Form1 の中央にプレイリストをラッチします。
if (Form2.Left > Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2))-10) および (Form2.Left < Form1.Left + ((Form1.Width div 2)-( Form2.Width div 2))+10) および
(Form2.Top > Form1.Top+Form1.Height-10) および (Form2.Top < Form1.Top+Form1.Height+10) の場合
始める
Form2.Left := Form1.Left + ((Form1.Width div 2)-(Form2.Width div 2));
if (X-OldX > 10) または (X-OldX < -10) または (Y-OldY > 10) または (Y-OldY < -10) then
CanMoveX := true
それ以外
CanMoveX := False;
終わり;
終わり;
終わり;
プロシージャ TForm2.FormMouseUp(送信者: TObject; ボタン: TMouseButton; シフト: TShiftState; X、Y: 整数);
始める
CanMove := false;
終わり;
終わり。
同じような内容で悩んでいる方の参考になれば幸いです。