MiniMiniSpy-- <TOP>
ウインドウクラスの情報を取得します。名付けて MiniMiniSpy--(かくいう私は、本物のSpy++を拝んだことがありません(^^;)
GetWindowRect ウィンドウの座標をスクリーン座標系で取得
GetCursorPos カーソルの現在のスクリーン座標の取得
WindowFromPoint 指定の座標位置にあるウィンドウハンドルを取得
GetClassName ウィンドウのクラス名を取得
GetWindowText ウインドウのタイトル文字列を取得
SendMessage ウィンドウにメッセージを送信
MoveToEx 現在位置を受け取るバッファを参照で指定
LineTo 現在の位置から終点までを直線で描画
GetWindowDC ウィンドウ全体のデバイスコンテキストを取得
GetPixel 指定された座標のピクセルのRGB値を取得
SelectObject 指定されたデバイスコンテキストのオブジェクトを選択
CreatePenIndirect LOGPEN構造体を定義して論理ペンを作成
DeleteObject システムリソースを解放
カーソル位置のクラス名を取得し、そのハンドル・矩形領域値・そのサイズ値を表示するとともにその矩形領域枠を指定色(現在・赤)で描画します。
図は、右図のアドレス欄にカーソルを合わせた時の情報です。例では、その位置が赤枠で点滅します。
※経緯
最初は、Form2を用意し、そのサイズを選択矩形領域に合わせ、内部を透明処理しました。これでは動作が遅いため、デバイスコンテキストに枠を描画することにしました。
Focusの移動があった場合、その枠を消さなければならないので、領域確保したときの左上座標色を記憶しておき、枠を描画し適当なWait処理後、その枠を記憶した元の色で再描画しています。
※チョット便利そうなのでF-Basicを使っていない方のために独立型でEXEにしました。
フォームレイアウトを変えただけです
関連
MiniMiniSpy--は、領域を赤枠で描画していますが、DrawFocusRectで点線で描画する方法もあります。
'================================================================ '= ウインドウクラス情報取得 '= (MiniMiniSpy--.bas) '================================================================ #include "Windows.bi" Type POINTAPI x As Long y As Long End Type Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Type LOGPEN lopnStyle As Long lopnWidth As POINTAPI lopnColor As Long End Type ' ウィンドウの座標をスクリーン座標系で取得 Declare Function Api_GetWindowRect& Lib "user32" Alias "GetWindowRect" (ByVal hWnd&, lpRect As RECT) ' カーソルの現在のスクリーン座標の取得 Declare Function Api_GetCursorPos& Lib "user32" Alias "GetCursorPos" (lpPoint As POINTAPI) ' 指定の座標位置にあるウィンドウハンドルを取得 Declare Function Api_WindowFromPoint& Lib "user32" Alias "WindowFromPoint" (ByVal xPoint&, ByVal yPoint&) ' ウィンドウのクラス名を取得する関数の宣言 Declare Function Api_GetClassName& Lib "user32" Alias "GetClassNameA" (ByVal hWnd&, ByVal lpClassName$, ByVal nMaxCount&) ' ウインドウのタイトル文字列を取得 Declare Function Api_GetWindowText& Lib "user32" Alias "GetWindowTextA" (ByVal hWnd&, ByVal lpString$, ByVal cch&) ' ウィンドウにメッセージを送信。この関数は、指定したウィンドウのウィンドウプロシージャが処理を終了するまで制御を返さない Declare Function Api_SendMessage& Lib "user32" Alias "SendMessageA" (ByVal hWnd&, ByVal wMsg&, ByVal wParam&, lParam As Any) ' 現在位置を受け取るバッファを参照で指定 Declare Function Api_MoveToEx& Lib "gdi32" Alias "MoveToEx" (ByVal hDC&, ByVal x&, ByVal y&, ByVal lpPoint As Any) ' 現在の位置から終点までを直線で描画 Declare Function Api_LineTo& Lib "gdi32" Alias "LineTo" (ByVal hDC&, ByVal x&, ByVal y&) ' ウィンドウ全体のデバイスコンテキストを取得 Declare Function Api_GetWindowDC& Lib "user32" Alias "GetWindowDC" (ByVal hWnd&) ' 指定された座標のピクセルのRGB値を取得 Declare Function Api_GetPixel& Lib "gdi32" Alias "GetPixel" (ByVal hDC&, ByVal X&, ByVal Y&) ' 指定されたデバイスコンテキストのオブジェクトを選択 Declare Function Api_SelectObject& Lib "gdi32" Alias "SelectObject" (ByVal hDC&, ByVal hObject&) ' LOGPEN構造体を定義して論理ペンを作成 Declare Function Api_CreatePenIndirect& Lib "gdi32" Alias "CreatePenIndirect" (lpLogPen As LOGPEN) ' ペン、ブラシ、フォント、ビットマップ、リージョン、パレットのいずれかの論理オブジェクトを削除し、そのオブジェクトに関連付けられていたすべてのシステムリソースを解放。オブジェクトを削除した後は、指定されたハンドルは無効になる Declare Function Api_DeleteObject& Lib "gdi32" Alias "DeleteObject" (ByVal hObject&) #define WM_GETTEXT &HD 'コントロールのキャプション・テキストをバッファにコピー Var Shared Timer1 As Object Var Shared Text(9) As Object Var Shared Edit1 As Object Timer1.Attach GetDlgItem("Timer1") For i = 0 To 9 Text(i).Attach GetDlgItem("Text" & Trim$(Str$(i + 1))) Text(i).SetFontSize 14 Next Edit1.Attach GetDlgItem("Edit1") : Edit1.SetFontSize 14 '================================================================ '= Chr$(0)を取り除く '================================================================ Declare Function TrimNull (item As String) As String Function TrimNull(item As String) As String Var ePos As Integer ePos = InStr(item, Chr$(0)) If ePos Then TrimNull = Left$(item, ePos - 1) Else TrimNull = item End If End Function '================================================================ '= '================================================================ Declare Sub MainForm_Start edecl () Sub MainForm_Start() Timer1.SetInterval 50 Timer1.Enable -1 End sub '================================================================ '= '================================================================ Declare Sub Timer1_Timer edecl () Sub Timer1_Timer() Var pa As POINTAPI Var rc As RECT Var hWnd As Long Var Buff As String * 128 Var Caption As String Var hDC As Long Var hNewPen As Long Var hOldPen As Long Var NewPen As LOGPEN Var ColorMe As Long Var rgbRed As Long Var rgbGreen As Long Var rgbBlue As Long Var Ret As Long 'カーソル位置のスクリーン座標を取得 Ret = Api_GetCursorPos(pa) '座標を含むウィンドウのハンドルを取得 hWnd = Api_WindowFromPoint(pa.x, pa.y) '矩形領域を取得 Ret = Api_GetWindowRect(hWnd, rc) 'デバイスコンテキストを取得 hDC = Api_GetWindowDC(hWnd) '選択したデバイスの左上の色を記憶 ColorMe = Api_GetPixel(hDC, 0, 0) 'RGBに分解 rgbRed = Abs(ColorMe Mod &H100) ColorMe = Abs(ColorMe \ &H100) rgbGreen = Abs(ColorMe Mod &H100) ColorMe = Abs(ColorMe \ &H100) rgbBlue = Abs(ColorMe Mod &H100) ColorMe = RGB(rgbRed, rgbGreen, rgbBlue) 'ウィンドウのハンドルを取得できたとき If hWnd <> 0 Then NewPen.lopnColor = Rgb(255, 0, 0) Gosub *FrameDraw Wait 10 'ペンの作成 NewPen.lopnColor = ColorMe Gosub *FrameDraw 'カーソル座標を表示 Text(4).SetWindowText "(" & Trim$(Str$(pa.x)) & "," & Trim$(Str$(pa.y)) & ")" '矩形座標を表示 Text(5).SetWindowText "(" & Trim$(Str$(rc.Left)) & "," & Trim$(Str$(rc.Top)) & ")-(" & Trim$(Str$(rc.Right)) & "," & Trim$(Str$(rc.Bottom)) & ")" '矩形サイズを表示 Text(6).SetWindowText Trim$(Str$(rc.Right - rc.Left)) & "x" & Trim$(Str$(rc.Bottom - rc.Top)) 'ウィンドウのハンドルを表示 Text(7).SetWindowText "&&H" & Hex$(hWnd) 'ウィンドウのクラス名を取得 Ret = Api_GetClassName(hWnd, Buff, Len(Buff)) Text(8).SetWindowText TrimNull(Buff) 'キャプション取得 Caption = Space$(250) Ret = Api_GetWindowText(hWnd, Caption, Len(Caption)) Ret = Api_SendMessage(hWnd, WM_GETTEXT, Len(Caption), Caption) Edit1.SetWindowText TrimNull(Caption) End If Ret = Api_DeleteObject(hNewPen) Exit Sub *FrameDraw 'ペンの作成 NewPen.lopnWidth.x = 1 hNewPen = Api_CreatePenIndirect(NewPen) 'ペンを持ち替える hOldPen = Api_SelectObject(hDC, hNewPen) Ret = Api_MoveToEx(hDC, 0, 0, ByVal 0) '┏ 左上(始点) Ret = Api_LineTo(hDC, rc.Right - rc.Left - 1, 0) ' ━ 右上 Ret = Api_LineTo(hDC, rc.Right - rc.Left - 1, rc.Bottom - rc.Top - 1) ' ┃ 右下 Ret = Api_LineTo(hDC, 0, rc.Bottom - rc.Top - 1) ' ━ 左下 Ret = Api_LineTo(hDC, 0, 0) '┃ 左上(終点) hNewPen = Api_SelectObject(hWnd, hOldPen) Return End Sub '================================================================ '= '================================================================ While 1 WaitEvent Wend Stop End