AsuYuHomepage
トップページ サイトの説明 子供の成長記録 JM BAR Delphi リンク集
Home>>プログラミング>>Tips&Tricks>>タイトルバーがないウィンドウをドラッグで移動する
Delphi Tips
Delphi Win32API
ダウンロード

Delphi Tips & Tricks

タイトルバーがないウィンドウをドラッグで移動する

 フォームのBorderStyleプロパティをbsNoneにするとマウス操作では移動できなくなってしまいますが、ウィンドウメッセージのWM_NCHITTESTをトラップすることで、フォームの1部分をタイトルバーのようにつまんで移動することができるようになります。
private
    procedure WMNCHITTEST(var Msg: TWMNCHITTEST); message WM_NCHITTEST;
-------------------------------------------------------------------------
procedure TForm1.WMNCHITTEST(var Msg: TWMNCHITTEST);
var
  Pt :TPoint;
begin
  //現在のマウス座標を取得
  GetCursorPos(Pt);
  //フォーム上の座標に変換
  Pt := ScreenToClient(Pt);
    //マウスの左ボタンが押されていて、カーソルがフォームの上半分の位置にあるなら
    if (GetAsyncKeyState(VK_LBUTTON) < 0) and (Pt.Y < Height / 2) then
      //ウィンドウズにタイトル バーで発生することを示すHTCAPTIONを返す
      Msg.Result := HTCAPTION
    else
      //下半分の位置にあるならならそのまま
      Msg.Result := HTCLIENT;
end;

Microsoft Windows がフォームのマウス アクティビティを処理するとき、マウス イベントの発生場所を決定するために、 Windows がフォームに WM NCHITTEST メッセージを送信します。 たとえば、フォームのタイトル バーをクリックすると、マウス イベントがタイトル バーで発生することを示す HTCAPTION の値をフォームが返します。 フォームのクライアント領域をクリックすると、マウス イベントがフォームのクライアント領域で発生することを示す HTCLIENT の値をフォームが返します。~MSDNより引用~

 上の解説を読むとわかるのですが、ウィンドウズがマウスイベントの発生位置を問い合わせる為、フォームにWM_NCHITTESTを送るためこれをトラップします。BorderStyleがbsNoneの場合、ウィンドウ全体がクライアント領域になってしまうため、通常はいくらフォームをつまんでもHTCLIENTしか帰らないのでドラッグできません。
 このサンプルでやっていることはフォーム上のマウス位置を確認してフォームの上半分ならHTCAPTIONをウィンドウズにかえし、下半分ならHTCLIENTを返すということです。
 これで上半分をタイトルバーのようにつまんでドラッグ&ドロップで移動できるようになるはずです。