ホーム >プログラム >Delphi 6 ローテクTips

Windows APIメモ PtInRegion

Windows APIのメモ。
PtInRegion。

参考サイト

PtInRegionの座標

  1. GetCursorPosでスクリーン座標のマウスカーソルの位置(X, Y)を取得しました。
  2. GetWindowRgnでウィンドウリージョンを取得しました。
  3. 2のウィンドウリージョン中に1の点(X, Y)があるかテストしようとPtInRegionを使おうと思いました。

さて、そのときこの(X, Y)の座標には何を使えばよいのでしょうか。
スクリーン座標でしょうか。
ウィンドウのクライアント座標でしょうか。

テストしてみた結果、そのどちらでもなく、GetWindowRectで得たウィンドウの外接長方形の左上を原点とした座標でした。
フォームだとタイトルバーの左上を(0, 0)とした座標になります。

procedure TForm1.Timer1Timer(Sender: TObject);
var
  lh_Handle:  HWND;
  lpt_Pos:    TPoint;
  lrc_Rect:   TRect;
  lrg_Region: HRGN;
  li_Ret:     Integer;
begin
  //マウスカーソル位置をスクリーン座標で取得
  GetCursorPos(lpt_Pos);
  //とりあえず自身のウィンドウリージョンを調べることにする
  lh_Handle := Self.Handle;

  //ウィンドウリージョン取得のため空のリージョンを作っておく
  lrg_Region := CreateRectRgn(0,0,0,0);
  try
    //ウィンドウリージョン取得
    li_Ret := GetWindowRgn(lh_Handle, lrg_Region);
    if (li_Ret <> ERROR) then begin
      //ウィンドウのRectを取得
      GetWindowRect(lh_Handle, lrc_Rect);
      //スクリーン座標からウィンドウの左上を原点とした座標に変換
      lpt_Pos.X := lpt_Pos.X - lrc_Rect.Left;
      lpt_Pos.Y := lpt_Pos.Y - lrc_Rect.Top;
      //ウィンドウリージョン内にマウスカーソルがあるかテスト
      if (PtInRegion(lrg_Region, lpt_Pos.X, lpt_Pos.Y)) then begin
        Memo1.Lines.Add(Format('OK %d (%d-%d)', [li_Ret, lpt_Pos.X, lpt_Pos.Y]));
      end else begin
        Memo1.Lines.Add(Format('NG %d (%d-%d)', [li_Ret, lpt_Pos.X, lpt_Pos.Y]));
      end;
    end else begin
      Memo1.Lines.Add(Format('ERR %d (%d-%d)', [li_Ret, lpt_Pos.X, lpt_Pos.Y]));
    end;
  finally
    DeleteObject(lrg_Region);
  end;
end;