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.lzh>

 

フォームレイアウトを変えただけです

 <MiniMiniSpyS.lzh>

 

関連

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