Delphi Programming / Object Pascal  
                     
                [掲載 2020年08月02日] [更新 2020年08月26日] Delphi 一般・その他  
             
           
        
        
        
          
            
              マウスカーソルの移動とフォーム上の位置 
             
            
               動作確認等  
              Windows 7 U64(SP1) + Delphi XE5(UP2) Pro  VCL-32 
             
           
        
        
         
         
        
         
         
         
         
         
        
         
         
        
          
            
               フォーム上のマウスカーソルの位置の取得と移動に関するサンプルです. 
                  このような場合,マウスのローカルフックの利用が考えられます.マウスのローカルフックであれば,非アクティブなフォームやコモンダイアログ等でもマウスカーソルの位置が取得できます. 
                  本ページのサンプルでは,TApplicationEvents コンポーネントの OnMessage イベントを使用して,アプリケーションが表示するアクティブなフォームだけを対象にしています.また,OnMouseMove イベントを共有する方法もテストしています.  
                  その他にも,マウスカーソルの座標と移動に関するサンプルを掲載しています. 
                 本ページのサンプルの方法を利用すれば,マウスカーソル下のコントロールの判定ができます. 
                  マウスドラック操作によってコントロールがキャプチャ (マウスキャプチャ) されている時は,マウスカーソル下のコントロールの取得方法によって結果が異なる場合ががあります. 
 
             
           
        
         
        
         
        
          
            
               [備考] 
                  マウスのドラッグ操作は,ウィンドウとしてのフォームの移動やリサイズ等,オブジェクトの Drag & Drop (ドラッグ・アント・ドロップ) による操作や処理が必要な場合の操作です.文字列の選択や,画像の領域選択操作等でもマウスドラッグが使われます. 
 
             
           
        
         
        
         
         
         
        
          
            
              01_ TApplicationEvents.OnMessage でマウスカーソル位置を取得 
             
           
        
         
         
        
          
            
               TApplicationEvents コンポーネントの OnMessage イベントを使用して,アプリケーションが発行するメッセージ WM_MOUSEMOVE と  WM_NCMOUSEMOVE を検出します.WM_NCXXX は,非クライアント領域関係のメッセージです.このメッセージを受信することによって,TMemo 等のスクロールバー部分や,フォームのタイトル部分等のマウスカーソル位置の取得も可能にしています. 
                 WM_MOUSEMOVE メッセージfは.マウスキャプチャの状態 (マウスボタンが押されている状態) でも送信されてきます.コントロールの
                  OnMouseMove イベントも,マウスキャプチャの状態でも発生します. 
                 TApplicationEvents.OnMessage
                  イベントは,名前の通り,アプリケーションレベルのメッセージ捕捉用です.このサンプルでは,別のフォームがアクティブになると,そのアクティブなフォームでのマウスカーソルの移動メッセージを受信します.  
                  アクティブなフォームは,TScreen.ActiveForm, TApplication.ActiveFormHandleプロパティ等を使用して確認できます.
 
             
           
        
         
        
         
        
          
            
               
              図1  
                設計時の画面
                
                  以下のコンポーネントを配置 
                    TMemo 
                    TApplicationEvents ([Additional] タブ)  
                   
                  
             
           
        
         
        
          
            
               このサンプルでは,マウスカーソル下のコントロールを,コントロールのウィンドウハンドルの値で判定しています.したがって,TWinControl の派生コントロールでないと判定できません. 
             
           
        
         
         
        
          
            
               
              図2  
                マウスカーソルが,フォーム上の Memo1 以外の位置にある時
                
                  座標値はフォーム上の値 
                  この座標値はフォームの左上が (0, 0) 
                  
             
            
               
              図3  
                マウスカーソルが Memo1 上にある時
                 
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   TApplicationEvents の OnMessage イベント処理 
//   フォーム上のマウスカーソル位置の取得 
//   マウスカーソル下のコントロールをそのコントロールのハンドル値で判定 
// ============================================================================= 
procedure  TForm1.ApplicationEvents1Message(var  Msg: tagMSG; 
  var  Handled: Boolean); 
var  
  LText : string ; 
begin  
  //  非クライアント領域の座標も検出 
  if  (Msg.message = WM_MOUSEMOVE) or  (Msg.message = WM_NCMOUSEMOVE) then  begin  
    //  スクリーン座標をフォームの座標に変換 
    LText := IntToStr(Msg.pt.X - Screen.ActiveForm.Left) + ' , '  
           + IntToStr(Msg.pt.Y - Screen.ActiveForm.Top); 
    //  特定のウィンドウコントロールを検索する例 
    if  Msg.hwnd = Memo1.Handle then  begin  
      Memo1.Lines.Text := LText + '  on Memo1' ; 
    end  else  begin  
      Memo1.Lines.Text := LText + '  out of Memo1' ; 
    end ; 
  end ; 
end ; 
         
         
         
        
          
            
               上のサンプルでは,マウスカーソルの位置を,左上を (0, 0) としたフォームの座標で表示しています.以下のようにすると,フォームのクライアント領域における座標表示となります. 
 
             
           
        
         
copy code 
        
              //  スクリーン座標をフォームのクライアント座標に変換 
    LText := IntToStr(Msg.pt.X - Screen.ActiveForm.ClientOrigin.X) + ' , '  
           + IntToStr(Msg.pt.Y - Screen.ActiveForm.ClientOrigin.Y);  
         
         
        
         
         
         
        
          
            
              02_ マウスカーソル下のコントロールを FindDragTarget で判定 
             
           
        
         
         
        
          
            
               前項と同じく,ApplicationEvents コンポーネントの OnMessage イベントを使用する例です. 
                  このサンプルでは,マウスカーソル位置のコントロールを判定するのに FindDragTarget 関数を使用しています.  
                  FindDragTarget 関数の戻り値はコントロールのインスタンスでから,コントロールの名前でコントロールを判定できます.したがって,TImage コントロール等の TGraphicControl の派生クラスのコントロールも検出できます. 
                 Enabled プロパティが False のコントロールの場合,FindDragTarget 関数は,そのコントロールの親コントロールのオブジェクトを返します.
 
             
           
        
         
        
         
        
          
            
               
              図4  
                マウスカーソルが,フォーム上の,何もコントロールがない位置にある時
                
                  座標値はフォーム上の値 
                  この座標値はフォームの左上が (0, 0) 
                  
             
            
               
              図5  
                マウスカーソルが Image1 上にある時
                 
             
            
               
              図6  
                マウスカーソルが Memo1 上にある時
                 
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   TApplicationEvents の OnMessage イベント処理 
//   フォーム上のマウスカーソル位置の取得 
//   マウスカーソル下のコントロールをそのコントロールの名前で判定 
//   コントロールの取得に FindDragTarget 関数を使用 
//  
//   FindDragTarget 関数は Enabled = false のコントロールも検索するが, 
//   戻り値はその親コントメールのオブジェクトとなる 
// ============================================================================= 
procedure  TForm1.ApplicationEvents1Message(var  Msg: tagMSG; 
  var  Handled: Boolean); 
var  
  LControl : TControl; 
  LText    : string ; 
begin  
  //  フレーム部分 (タイトル部分等) の位置も検出 
  if  (Msg.message = WM_MOUSEMOVE) or  (Msg.message = WM_NCMOUSEMOVE) then  begin  
    LControl := FindDragTarget(Msg.pt, True); 
    //  フォームの領域外にドラッグすると例外が発生するのでその対策 
    if  LControl = nil  then  Exit; 
    //  スクリーン座標をフォームの座標に変換 
    LText := IntToStr(Msg.pt.X - Screen.ActiveForm.Left) + ' , '  
           + IntToStr(Msg.pt.Y - Screen.ActiveForm.Top); 
    //  特定のコントロールを検索する例 
    if  LControl = Memo1 then  begin  
    end  else  begin  
    end ; 
    Memo1.Lines.Text := LText + '  on '  + LControl.Name; 
  end ; 
end ; 
         
         
        
         
         
         
        
          
            
              03_ OnMouseMove イベントの共有を利用する方法 
             
           
        
         
         
        
          
            
               イベントは,引数の型と形式と順番,引数の数が同じであれば他のコントロールのイベントと共有できます.上のサンプルでは,フォームには Memo1 (TMemo) しかありません.以下のようにイベントを共有すれば,マウスカーソル下のコントロールを判定することができます.
 
             
           
        
         
         
        
copy code 
        
          uses  
  System.Types; 
{$R *.dfm}  
// ============================================================================= 
//   Form1 の OnMouseMove イベント処理 
//   Form1 と Memo1 の共有イベント 
//  
//   uses に System.Types を追加しておく 
// ============================================================================= 
procedure  TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
var  
  LControl : TControl; 
  LPoint   : TPoint; 
  LText    : string ; 
begin  
  LControl := TControl(Sender); 
  if  LControl = Self then  begin  
    LPoint := Point(X, Y); 
  end  else  begin  
    //  このフォーム (Self) の座標値に変換 
    LPoint := LControl.ClientToParent(Point(X, Y), Self); 
  end ; 
  LText := IntToStr(LPoint.X) + ' , '  + IntToStr(LPoint.Y); 
  //  イベント発生元のコントロールの判定例 
  //  マウスカーソルはこのコントロール上にある 
  if  Sender = Memo1 then  begin  
  end ; 
  Memo1.Lines.Text := LText + '  on '  + LControl.Name; 
end ; 
         
         
         
        
          
            
               イベントは,オブジェクト・インスペクタで設定できますが,以下のように,実行時に設定した方が便利な場合もあります. 
 
             
           
        
         
         
        
copy code 
        
          type  
  TMyControl = class (Vcl.Controls.TControl); 
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
var  
  LIndex : Integer; 
begin  
  for  LIndex := 0  to  Self.ControlCount - 1  do  begin  
    TMyControl(Self.Controls[LIndex]).OnMouseMove := Self.OnMouseMove; 
  end ; 
end ; 
         
         
         
        
          
            
               TPanel 等,コンテナコントロール上に配置しているコントロールも対象にする場合は,上のコードを再帰的に実行するよりも,次のように,フォーム上の TComponent を検索した方が便利です. 
 
             
           
        
         
         
        
copy code 
        
          type  
  TMyControl = class (Vcl.Controls.TControl); 
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
var  
  LCompo : TComponent; 
  LIndex : Integer; 
begin  
  Memo1.Lines.Clear; 
  for  LIndex := 0  to  Self.ComponentCount - 1  do  begin  
    LCompo := Self.Components[LIndex]; 
    if  LCompo is  TControl then  begin  
      TMyControl(LCompo).OnMouseMove := Self.OnMouseMove; 
    end ; 
  end ; 
end ; 
         
         
        
         
         
         
        
          
            
              04_ マウスカーソルの別コントロールへの移動を検出 
             
           
        
         
         
        
          
            
               マウスカーソルがどのコントロール上にあるかが分かれは,マウスカーソルが別のコントロール上に移動したことが検出できます.その例です.  
                  現在のマウスカーソル下のコントロールと,前にマウスカーソルがあったコントロールが異なる場合だけ処理します.そのために,TControl 型のグローバル変数を用意して,それに以前のマウスカーソル下のコントロールを代入して保持するようにします. 
 
             
           
        
         
         
        
          
            
               
              図7  
                実行例
                
                  以下の順番でマウスカーソルを移動 
                  フォームの外側から Button1 へ移動 
                    当然 Form1 を通過する 
                  Button1 から Form1 へ移動 
                  Form1 から Memo1 へ移動 
                  
             
           
        
         
        
copy code 
        
          unit  Unit1; 
interface  
uses  
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.AppEvnts; 
type  
  TForm1 = class (TForm) 
    Memo1: TMemo; 
    ApplicationEvents1: TApplicationEvents; 
    Button1: TButton; 
    procedure  ApplicationEvents1Message(var  Msg: tagMSG; var  Handled: Boolean); 
    procedure  FormCreate(Sender: TObject); 
  private  
    { Private 宣言 }  
  public  
    { Public 宣言 }  
  end ; 
var  
  Form1: TForm1; 
  FPreControl : TControl = nil ; 
implementation  
{$R *.dfm}  
// ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  Memo1.ScrollBars := ssVertical; 
end ; 
// ============================================================================= 
//   TApplicationEvents の OnMessage イベント処理 
//   フォーム上のマウスカーソル位置の取得 
//   マウスカーソル下のコントロールが変わったらそのコントロール名を表示 
//  
//   FPreControl (TControl) はグローバル変数 
// ============================================================================= 
procedure  TForm1.ApplicationEvents1Message(var  Msg: tagMSG; 
  var  Handled: Boolean); 
var  
  LControl : TControl; 
  LSrcName : string ; 
  LDstName : string ; 
begin  
  //  フレーム部分 (タイトル部分等) の位置も検出 
  if  (Msg.message = WM_MOUSEMOVE) or  (Msg.message = WM_NCMOUSEMOVE) then  begin  
    LControl := FindDragTarget(Msg.pt, True); 
    //  マウスカーソル下のコントロールが前と異なる場合  
    if  LControl <> FPreControl then  begin  
      if  FPreControl = nil  then  begin  
        LSrcName := 'out of form' ; 
      end  else  begin  
        LSrcName := FPreControl.Name; 
      end ; 
      if  LControl = nil  then  begin  
        LDstName := 'out of form' ; 
      end  else  begin  
        LDstName := LControl.Name; 
      end ; 
      Memo1.Lines.Add(IntToStr(Memo1.Lines.Count) + ' : '  
                      + LSrcName + ' -->  '  + LDstName); 
    end ; 
    //  現在のマウスカーソル下のコントロールを記憶しておく 
    FPreControl := LControl; 
  end ; 
end ; 
end . 
         
         
        
         
         
         
        
          
            
              05_ マウスカーソルの特定コントロール領域内への移動を検出 
             
           
        
         
         
        
          
            
               特定のコントロール上にマウスカーソルが移動してきたことを検出する例です.OnMouseEnter イベントに相当する機能と言えます.手順は上のサンプルコードと同じですが,対象となるコントロールを判定する条件を追加します. 
 
             
           
        
         
         
        
copy code 
        
          // ============================================================================= 
//   TApplicationEvents の OnMessage イベント処理 
//   Memo1 以外から Memo1 上にマウスカーソルが移動した場合のみ処理 
//  
//   FPreControl (TControl) はグローバル変数 
// ============================================================================= 
procedure  TForm1.ApplicationEvents1Message(var  Msg: tagMSG; 
  var  Handled: Boolean); 
var  
  LControl : TControl; 
begin  
  //  フレーム部分 (タイトル部分等) の位置も検出 
  if  (Msg.message = WM_MOUSEMOVE) or  (Msg.message = WM_NCMOUSEMOVE) then  begin  
    LControl := FindDragTarget(Msg.pt, True); 
    //  マウスカーソル下のコントロールが前と異なる場合で, 
    //  マウスカーソルの移動先が Memo1 の場合 
    if  (LControl <> FPreControl) and  (LControl = Memo1) then  begin  
      Memo1.Lines.Add(IntToStr(Memo1.Lines.Count) + ' : '  
                      + FPreControl.Name + ' -->  '  + LControl.Name); 
    end ; 
    //  現在のマウスカーソル下のコントロールを記憶しておく 
    FPreControl := LControl; 
  end ; 
end ; 
         
         
        
         
         
         
        
          
            
              06_ マウスカーソルの特定コントロール領域外への移動を検出 
             
           
        
         
         
        
          
            
               特定のコントロールの領域外へ移動したことを検出する例です.コントロールの OnMouseLeave イベントに相当する機能と言えます.手順は上のサンプルコードと同じですが,対象となるコントロールを判定する条件を変更します. 
 
             
           
        
         
        
         
        
copy code 
        
          // ============================================================================= 
//   TApplicationEvents の OnMessage イベント処理 
//   Memo1 から Memo1 以外の場所にマウスカーソルが移動した場合のみ処理 
//  
//   FPreControl (TControl) はグローバル変数 
// ============================================================================= 
procedure  TForm1.ApplicationEvents1Message(var  Msg: tagMSG; 
  var  Handled: Boolean); 
var  
  LControl : TControl; 
begin  
  //  フレーム部分 (タイトル部分等) の位置も検出 
  if  (Msg.message = WM_MOUSEMOVE) or  (Msg.message = WM_NCMOUSEMOVE) then  begin  
    LControl := FindDragTarget(Msg.pt, True); 
    //  マウスカーソル下のコントロールが前と異なる場合で, 
    //  前にマウスカーソルがあったのが Memo1 の場合 
    if  (LControl <> FPreControl) and  (FPreControl = Memo1) then  begin  
      Memo1.Lines.Add(IntToStr(Memo1.Lines.Count) + ' : '  
                      + FPreControl.Name + ' -->  '  + LControl.Name); 
    end ; 
    //  現在のマウスカーソル下のコントロールを記憶しておく 
    FPreControl := LControl; 
  end ; 
end ; 
         
         
        
         
         
         
        
          
            
              07_ マウスカーソルのコントロール領域外への移動を禁止 
             
           
        
         
         
        
          
            
               Windows API の ClipCursor 関数を使用すると,マウスの移動をクリップして,指定した矩形領域の外側にはマウスカーソルを移動できなくすることができます. 
                  このサンプルでは,マウスの左ボタンを押した状態でマウスを移動した時は,Panel1 の領域外にはマウスカーソルを移動できないようにしています.マウスの左ボタンを押した時にクリップを開始して,ボタンを離すとクリップを解除します. 
 
             
           
        
         
        
         
        
          
            
               
              図8  
                マウスの左ボタンを押した状態の時は,Panel1 の外側にマウスを移動できない 
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   TApplicationEvents の OnMessage イベント処理 
//   マウスカーソル下のコントロールをそのコントロールのハンドル値で判定 
//  
//   特定のコントロールの領域外へのマウスカーソルの移動の禁止と解除 
// ============================================================================= 
procedure  TForm1.ApplicationEvents1Message(var  Msg: tagMSG; 
  var  Handled: Boolean); 
var  
  LRect : TRect; 
begin  
  if  (Msg.hwnd = Panel1.Handle) then  begin  
    if  (Msg.message = WM_LBUTTONDOWN) then  begin  
      //  マウスの移動をクリップ 
      GetWindowRect(Panel1.Handle, LRect); 
      ClipCursor(@LRect); 
    end ; 
    if  (Msg.message = WM_LBUTTONUP) then  begin  
      //  マウスの移動クリップを解除 
      ClipCursor(nil ); 
    end ; 
  end ; 
end ; 
         
         
        
         
         
         
        
          
            
              08_ コントロール上の座標値とフォーム上の座標値の変換 
             
           
        
         
         
        
          
            
               コントロールのクライアント座標値をフォームのクライアント座標値に変換するには,TControl に実装されている ClientToParent メソッドが利用できます.その例です.  
                  この関数は,対象のコントロールの親コントロールにおける座標値を取得するメソッドですが,親の親,そのまた親も指定できます. 
                  逆の変換には,TControl の ParentToClient メソッドが利用できます. 
 
             
           
        
         
        
         
        
          
            
               
              図9  
                Panel2 の座標を Form1 の座標に変換  
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  Panel1.ParentBackground := False; 
  Panel2.ParentBackground := False; 
  Panel1.Color := clSkyBlue; 
  Panel2.Color := clGreen; 
  Panel1.Left := 50 ; 
  Panel1.Top  := 60 ; 
//  
  Panel2.Left := 30 ; 
  Panel2.Top  := 10 ; 
end ; 
// ============================================================================= 
//   Panel2 の OnMouseMove イベント処理 
//   コントロール内の座標値をフォームの座標値に変換 
//   共にクライアント領域の座標 
// ============================================================================= 
procedure  TForm1.Panel2MouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
var  
  LFormPos : TPoint; 
  LText    : string ; 
begin  
  LFormPos := Panel2.ClientToParent(Point(X, Y), Form1); 
  LText := IntToStr(X) + ' , '  + IntToStr(Y) + '  at '  + TControl(Sender).Name 
         + sLineBreak + IntToStr(LFormPos.X) + ' , '  + IntToStr(LFormPos.Y) + '  at Form1' ; 
  Memo1.Lines.Text := LText; 
end ; 
         
         
        
         
         
         
        
          
            
              09_ マウスカーソルをコントロール上の任意の位置に移動 
             
           
        
         
         
        
          
            
               TMouse の CursorPos プロパティを使用すると,マウスカーソルを,フォームあるいはフォーム上のコントロールの任意の位置に移動できます. 
                  このプロパティは,マウスカーソルの位置の設定と取得に使用できまずか,扱う座標値はスクリーン座標です.TControl.ClientToScreen メソッドでスクリーン座標に変換してから代入します. 
 
             
           
        
         
        
         
        
          
            
               
              図10  
                マウスカーソルをフォームまたはコントロール上の任意の位置に移動 
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   フォーム生成時の処理 
// ============================================================================= 
procedure  TForm1.FormCreate(Sender: TObject); 
begin  
  Panel1.ParentBackground := False; 
  Panel2.ParentBackground := False; 
  Panel1.Color := clSkyBlue; 
  Panel2.Color := clGreen; 
  Panel1.Left := 50 ; 
  Panel1.Top  := 60 ; 
//  
  Panel2.Left := 30 ; 
  Panel2.Top  := 10 ; 
end ; 
// ============================================================================= 
//   マウスカーソルをフォーム上のコントロールの任意の位置に移動 
//   TMouse.CursorPos を使用 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
var  
  LCtrlPos : TPoint; 
  LFormPos : TPoint; 
  LText    : string ; 
begin  
  //  Panel2 上の座標値を指定して,フォーム上の座標値に変換 
  LCtrlPos := Point(5 , 10 ); 
  LFormPos := Panel2.ClientToParent(LCtrlPos, Form1); 
  LText := IntToStr(LCtrlPos.X) + ' , '  + IntToStr(LCtrlPos.Y) + '  at Panel2'  
         + sLineBreak + IntToStr(LFormPos.X) + ' , '  + IntToStr(LFormPos.Y) + '  at Form1' ; 
  Memo1.Lines.Text := LText; 
  //  実際にマウスカーソルを移動 
  Mouse.CursorPos := Panel2.ClientToScreen(LCtrlPos); 
  //  以下でも同じ 
  //  この場合の Self は Form1.Self は省略できる 
  //  Mouse.CursorPos := Form1.ClientToScreen(LFormPos); 
  //  Mouse.CursorPos := Self.ClientToScreen(LFormPos); 
  //  Mouse.CursorPos := ClientToScreen(LFormPos); 
end ; 
         
         
         
        
          
            
               TControl.ClientOrigin
                  プロパティを使用すると,コントロールのクライアント領域の左上の座標を,スクリーン座標として取得できます.取得したスクリーン座標を使用してマウスカーソルを指定の位置に移動する例です. 
 
             
           
        
         
copy code 
        
          // ============================================================================= 
//   マウスカーソルをフォーム上のコントロールの任意の位置に移動 
//   TMouse.CursorPos を使用 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
var  
  LCtrlPos : TPoint; 
begin  
  //  コントロールのクライアント領域の左上のスクリーン座標を取得 
  LCtrlPos := Panel2.ClientOrigin; 
  //  位置の値を指定してマウスカーソルをそこに移動 
  LCtrlPos.Offset(5 , 10 ); 
  Mouse.CursorPos := LCtrlPos; 
end ; 
         
         
         
        
          
            
               TPanel は TWinControl の派生クラスのコントロールです.Handle プロパティでウィンドウハンドルの値が取得できます.そのウィンドウの矩形領域の座標を基準にした位置にマウスカーソルを移動できます.その例です. 
 
             
           
        
         
copy code 
        
          // ============================================================================= 
//   マウスカーソルをフォーム上のコントロールの任意の位置に移動 
//   TWindControl の派生コントロールの例 
//   TMouse.CursorPos を使用 
// ============================================================================= 
procedure  TForm1.Button1Click(Sender: TObject); 
var  
  LWndRect : TRect; 
begin  
  //  コントロールの矩形領域を取得 
  GetWindowRect(Panel2.Handle, LWndRect); 
  //  位置の値を指定してマウスカーソルをそこに移動 
  Mouse.CursorPos := TPoint.Create(LWndRect.Left + 5 , LWndRect.Top + 10 ); 
end ; 
         
         
        
         
         
         
        
          
            
              10_ OnMouseMove イベントはそのコントロール専用 
             
           
        
         
         
        
          
            
               多くの TControl の派生クラスには OnMouseMove イベントが実装されています. OnMouseMove イベントに限らず,他のコントロールとイベントを共有しなければ,それらのコントロール (クラス) のメンバとしてのイベントは,そのコントロール専用です.OnMouseMove イベントの場合,そのコントロールの領域内でないと OnMouseMove  イベントは発生しません.  
                  コントロール (クラス) のメンバとしての
                  WM_MOUSEMOVE メッセージも同じです. 
                 下に示すコードは TMemo の OnMouseMove イベント処理の例です.このイベントのコードは,マウスカーソルが Memo1
                  の領域内にないと実行されません.したがって,マウスカーソルが Memo1 の領域外へ移動したか,Memo1 の領域内へ移動したかを検出することはできません. 
 
             
           
        
         
         
        
          
            
               
              図11  
                マウスカーソルを Memo1 から Memo1 以外の位置
                に移動した時
                
                  かなりの勢いで Memo1 の外にマウスカーソルを移動した結果 
                  OnMouseMove イベントは発生していない 
                  表示されている座標値は,マウスカーソルが Memo1 領域内にあった時の値 
                  
             
            
               
              図12  
                マウスカーソルを Memo1 以外の別の位置に移動した場合
                
                  OnMouseMove イベントは発生していない 
                  表示されている座標値が上の図と同じ 
                  この座標値は,マウスカーソルが Memo1 領域内にあった時の値 
                  
             
           
        
         
        
          
            
               マウスの左ボタンを押した状態でマウスカーソルを移動すると,マウスのドラッグ操作となります.マウスのドラッグ操作の場合は,コントロールのキャプチャ (マウスキャプチャ) が行われます.コントロールがキャプチャされると,マウスはそのコントロール上にあるのと同じとなります.その結果,ドラッグ中はこのイベントが発生します.  
                  TMemo におけるマウスの左ボタン押下状態のマウスドラッグの操作は,文字列 (テキスト) の選択操作となります. 
 
             
           
        
         
         
        
          
            
               
              図13  
                マウスドラッグの場合
                
                  Memo1 から Form1 へドラッグ操作でマウスを移動 
                  座標値は Memo1 における値 
                  マウスカーソルも Memo1 領域内の時と同じ 
                  
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   Memo1 の OnMouseMove イベント処理 
// ============================================================================= 
procedure  TForm1.Memo1MouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
var  
  LCurPos  : TPoint; 
  LLeftTop : TPoint; 
  LInRect  : TRect; 
  LText    : string ; 
begin  
  //  TMemo の領域外も検出のため現在のスクリーンカーソル位置を取得 
  GetCursorPos(LCurPos); 
  LLeftTop := Self.ClientToScreen(Point(Memo1.Left, Memo1.Top)); 
  LInRect  := TRect.Create(LLeftTop, Memo1.Width, Memo1.Height); 
  LText := IntToStr(X) + ' , '  + IntToStr(Y); 
  if  PtInRect(LInRect, LCurPos) then  begin  
    Memo1.Lines.Text := LText + '  on Memo1' ; 
  end  else  begin  
    //  ここはドラッグ操作でないと実行されない 
    Memo1.Lines.Text := LText + '  out of Memo1' ; 
  end ; 
end ; 
         
         
        
          
            
               コントロールがマウスキャプチャされている状態の時,つまり,マウスドラッグの場合に,マウスカーソル下のコントロールを FindDragTarget 関数を使用して取得する例です.この場合は,ドロップ先であるかも知れない,マウスカーソルがある位置のコントロールが取得できます.上のコードのような矩形領域による判定は必要ありません. 
 
             
           
        
         
         
        
          
            
               
              図14  
                マウスドラッグ時のマウスカーソル下のコントロールを FindDragTarget 関数で判定
                
                  Memo1 から Form1 へマウスドラッグ 
                  表示座標は Form1 のクライアント座標 
                  
             
           
        
         
        
copy code 
        
          // ============================================================================= 
//   Memo1 の OnMouseMove イベント処理 
// ============================================================================= 
procedure  TForm1.Memo1MouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
var  
  LControl : TControl; 
  LCurPos  : TPoint; 
  LPos     : TPoint; 
  LText    : string ; 
begin  
  //  イベントの引数はクライアント座標なのでスクリーン座標に変換 
  LCurPos := Mouse.CursorPos; 
  //  マウスカーソル位置のコントロールを取得 
  LControl := FindDragTarget(LCurPos, True); 
  if  LControl <> nil  then  begin  
    //  マウスカーソルのクライアント座標を取得して表示 
    LPos  := LControl.ScreenToClient(LCurPos); 
    LText := IntToStr(LPos.X) + ' , '  + IntToStr(LPos.Y) + '  on '  + LControl.Name; 
        Memo1.Lines.Text := LText; 
  end  else  begin  
    Memo1.Lines.Text := '' ; 
  end ; 
end ;