3

我正在使用 AutoIt3,我需要一种方法让用户选择一个窗口。在我看来,最快的方法是让它们指向一个窗口。所以问题是,我如何查看鼠标指针下方的窗口?

4

2 回答 2

6

我从我为选择屏幕上的区域而放置的一些代码中推断出这一点。这只会弹出鼠标下方的窗口标题(按 Escape 退出循环):

#include <WinAPI.au3>
#include <Misc.au3>

Func _WindowFromPoint($iX,$iY)
    Local $stInt64,$aRet,$stPoint=DllStructCreate("long;long")
    DllStructSetData($stPoint,1,$iX)
    DllStructSetData($stPoint,2,$iY)
    $stInt64=DllStructCreate("int64",DllStructGetPtr($stPoint))
    $aRet=DllCall("user32.dll","hwnd","WindowFromPoint","int64",DllStructGetData($stInt64,1))
    If @error Then Return SetError(2,@error,0)
    If $aRet[0]=0 Then Return SetError(3,0,0)
    Return $aRet[0]
EndFunc

Local $hControl, $hWin, $hOldWin, $aMousePos
$hOldWin = ""
While Not _IsPressed("1B")
    $aMousePos = MouseGetPos()
    $hControl=_WindowFromPoint($aMousePos[0],$aMousePos[1])
    ; Since _WindowFromPoint() can return 'sub' windows, or control handles, we should seek the owner window
    $hWin=_WinAPI_GetAncestor($hControl,2)
    If $hWin <> $hOldWin Then
        TrayTip("Window Info","Window under mouse = " & WinGetTitle($hWin), 1)
        $hOldWin = $hWin
    EndIf
    Sleep(10)
WEnd
于 2012-06-30T01:00:57.993 回答
4

这是一个完整的全屏 GUI 示例,显示实际屏幕和鼠标指针下方窗口周围的边框。该函数用于将窗口的标题写入控制台。

#include <Misc.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WindowsConstants.au3>

HotKeySet("{Esc}", "_Exit")
Func _Exit()
    Exit 0
EndFunc

Global $xPosReminder, $yPosReminder
$dll = DllOpen("user32.dll")

$allWindows = WinList()
; exclude invisible windows from winlist
Dim $windows[1]
$windows[0] = 0
For $i = 1 to $allWindows[0][0]
    ; only fetches visible windows
    If BitAnd(WinGetState($allWindows[$i][1]), 2) Then;AND $allWindows[$i][0] <> "" Then
        ReDim $windows[$windows[UBound($windows) - 1] + 2]
        $windows[UBound($windows) - 1] = $windows[UBound($windows) - 2] + 1
        $windows[UBound($windows) - 2] = $allWindows[$i][1]
    EndIf
Next
ReDim $windows[$windows[UBound($windows) - 1]]
_ArrayReverse($windows)

; capture screen without cursor
$pos = MouseGetPos()
MouseMove(@DesktopWidth, @DesktopHeight, 0)
$hBitmap = _ScreenCapture_Capture ("")
MouseMove($pos[0], $pos[1], 0)

; create and show new fullscreen gui
$hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP)
GUISetState(@SW_SHOW)

; Initialize GDI+ library
_GDIPlus_StartUp()
$hImage = _GDIPlus_BitmapCreateFromHBITMAP ($hBitmap)
$hGraphics = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
$hPen = _GDIPlus_PenCreate(0xFFFF0000, 3, 2)
$iX = _GDIPlus_ImageGetWidth($hImage)
$iY = _GDIPlus_ImageGetHeight($hImage)

_GDIPlus_GraphicsDrawImage($hGraphics, $hImage, 0, 0)

Global $oldWindow = 0
; Wait for Click
While True
    If _IsPressed("01", $dll) Then ; left mouse button
        $xPos = MouseGetPos(0)
        $yPos = MouseGetPos(1)
        ExitLoop
    EndIf
    If __MouseMoved() Then
        ; Erzeugt eine Kopie einer 24 bit Bitmap
        $hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iX, $iY, $GDIP_PXF24RGB)

        $currentWindow = __GetWindowByMousePosition($windows, MouseGetPos(0), MouseGetPos(1))
        If $currentWindow <> $oldWindow Then
            $windowPosition = WinGetPos($currentWindow)

            ; reduce position and size to desktop space
            $windowPosition[0] = _Iif($windowPosition[0] < 0, 0, $windowPosition[0])
            $windowPosition[1] = _Iif($windowPosition[1] < 0, 0, $windowPosition[1])
            $windowPosition[2] = _Iif($windowPosition[2]  > @DesktopWidth, @DesktopWidth, $windowPosition[2])
            $windowPosition[3] = _Iif($windowPosition[3] > @DesktopHeight, @DesktopHeight, $windowPosition[3])

            _GDIPlus_GraphicsDrawImage($hGraphics, $hClone, 0, 0)
            _GDIPlus_GraphicsDrawRect($hGraphics, $windowPosition[0], $windowPosition[1], $windowPosition[2], $windowPosition[3], $hPen)
            $oldWindow = $currentWindow
        EndIf
    EndIf
    Sleep(1)
WEnd

; Free Ressources
_GDIPlus_PenDispose($hPen)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGraphics)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_ShutDown()
DllClose($dll)

GUISetState(@SW_HIDE)

Func __GetWindowByMousePosition($windows, $xPos, $yPos)
    Local $currentWindow = 0
    For $i = 0 to UBound($windows) - 1
        $pos = WinGetPos($windows[$i])
        If $xPos >= $pos[0] AND $xPos <= $pos[0] + $pos[2] AND $yPos >= $pos[1] AND $yPos <= $pos[1] + $pos[3] Then
            $currentWindow = $windows[$i]
        EndIf
    Next
    Return $currentWindow
EndFunc

Func __MouseMoved()
    Local $actualPos = MouseGetPos()
    If $xPosReminder <> $actualPos[0] OR $yPosReminder <> $actualPos[1] Then
        $xPosReminder = $actualPos[0]
        $yPosReminder = $actualPos[1]
        Return True
    Else
        Return False
    EndIf
EndFunc

ConsoleWrite(WinGetTitle(__GetWindowByMousePosition($windows, $xPos, $yPos)) & @CR)
于 2012-06-29T10:41:02.107 回答