本帖最后由 鸟人 于 2012-11-7 15:36 编辑
最近要帮别人弄个东西,要用到这个,自己琢磨了半天,感觉不是那么回事。
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
Global Const $GW_CHILD = 5
Global Const $GW_HWNDNEXT = 2
Global Const $tagPOINT = "struct;long X;long Y;endstruct"
Global Const $tagRECT = "struct;long Left;long Top;long Right;long Bottom;endstruct"
Global $tStruct = DllStructCreate($tagPOINT)
Global $FindIt = False, $MousePointer = False
$hForm = GUICreate("Form1", 322, 224, 398, 284)
$Pic1 = GUICtrlCreateIcon("3_Au3Info.ico", -1, 16, 6, 32, 32)
GUISetState(@SW_SHOW)
AdlibRegister('_Timer')
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $GUI_EVENT_PRIMARYDOWN
Local $a = GUIGetCursorInfo($hForm)
If $a[4] = $Pic1 Then _MouseDown()
Case $GUI_EVENT_PRIMARYUP
_MouseUp()
EndSwitch
WEnd
Func _MouseUp()
$MousePointer = False
GUICtrlSetImage($Pic1, "3_Au3Info.ico")
_WinAPI_ReleaseCapture()
EndFunc ;==>_MouseUp
Func _MouseDown()
$MousePointer = True
_SetCursor(@ScriptDir & '\cursor.cur') ;鼠标指针变为靶状
GUICtrlSetImage($Pic1, "2_Au3Info.ico") ;此时图片框加载另一无靶图标
_WinAPI_SetCapture($hForm) ;将以后的鼠标输入消息都发送到图片框窗口
EndFunc ;==>_MouseDown
Func _Timer()
If $MousePointer = True Then
AdlibUnRegister('_Timer')
$DeskHwnd = _WinAPI_GetDesktopWindow() ;取得桌面句柄
$DeskDC = _WinAPI_GetWindowDC($DeskHwnd) ;取得桌面设备场景
$oldRop2 = _WinAPI_SetROP2($DeskDC, 10)
DllStructSetData($tStruct, "x", MouseGetPos(0)) ;
DllStructSetData($tStruct, "y", MouseGetPos(1)) ; 取得鼠标坐标
$UnHwnd = _WinAPI_WindowFromPoint($tStruct) ;取得鼠标指针处窗口句柄
$grayHwnd = _WinAPI_GetWindow($UnHwnd, $GW_CHILD)
;因为WindowsFromPoint函数对Disabled的窗口无效,所以写了下面这个循环,否则无法选中“灰色按钮”类窗口
While($grayHwnd)
$tempRc = _WinAPI_GetWindowRect($grayHwnd)
If _WinAPI_PtInRect($tempRc, $tStruct) Then
$FindIt = True
ExitLoop
Else
$grayHwnd = _WinAPI_GetWindow($UnHwnd, $GW_HWNDNEXT)
EndIf
WEnd
If $FindIt = True Then
$FindIt = False
$SnapHwnd = $grayHwnd
Else
$SnapHwnd = $UnHwnd
EndIf
$rc = _WinAPI_GetWindowRect($SnapHwnd) ;获得窗口矩形
ToolTip(DllStructGetData($rc, "Left")&@CRLF & _
DllStructGetData($rc, "Top")&@CRLF & _
DllStructGetData($rc, "Right")&@CRLF & _
DllStructGetData($rc, "Bottom"))
If DllStructGetData($rc, "Left") < 0 Then DllStructSetData($rc, "Left", 0)
If DllStructGetData($rc, "Top") < 0 Then DllStructSetData($rc, "Top", 0)
If DllStructGetData($rc, "Right") > @DesktopWidth / 15 Then DllStructSetData($rc, "Right", @DesktopWidth / 15)
If DllStructGetData($rc, "Bottom") > @DesktopHeight / 15 Then DllStructSetData($rc, "Bottom", @DesktopHeight / 15)
$newPen = _WinAPI_CreatePen(0, 3, 0xFF) ;建立新画笔,载入DeskDC
$oldPen = _WinAPI_SelectObject($DeskDC, $newPen) ;
_WinAPI_Rectangle($DeskDC, $rc) ;在指示窗口周围显示闪烁矩形
Sleep(500)
_WinAPI_SetROP2($DeskDC, $oldRop2)
_WinAPI_SelectObject($DeskDC, $oldPen)
_WinAPI_DeleteObject($newPen)
_WinAPI_ReleaseDC($DeskHwnd, $DeskDC)
$DeskDC = 0
AdlibRegister('_Timer')
EndIf
EndFunc ;==>_Timer
Func _SetCursor($sFile)
Local $Ret = DllCall('user32.dll', 'ptr', 'LoadCursorFromFileW', 'wstr', $sFile)
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Local $aResult = DllCall("user32.dll", "handle", "SetCursor", "handle", $Ret[0])
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc ;==>_SetCursor
Func _WinAPI_DestroyCursor($hCursor)
Local $Ret = DllCall('user32.dll', 'int', 'DestroyCursor', 'ptr', $hCursor)
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return 1
EndFunc ;==>_WinAPI_DestroyCursor
Func _WinAPI_SetCapture($hWnd)
Local $aResult = DllCall("user32.dll", "hwnd", "SetCapture", "hwnd", $hWnd)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc ;==>_WinAPI_SetCapture
Func _WinAPI_ReleaseCapture()
Local $aResult = DllCall("user32.dll", "bool", "ReleaseCapture")
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc ;==>_WinAPI_ReleaseCapture
Func _WinAPI_GetDesktopWindow()
Local $aResult = DllCall("user32.dll", "hwnd", "GetDesktopWindow")
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc ;==>_WinAPI_GetDesktopWindow
Func _WinAPI_GetWindowDC($hWnd)
Local $aResult = DllCall("user32.dll", "handle", "GetWindowDC", "hwnd", $hWnd)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc ;==>_WinAPI_GetWindowDC
Func _WinAPI_SetROP2($hDC, $iMode)
Local $Ret = DllCall('gdi32.dll', 'int', 'SetROP2', 'hwnd', $hDC, 'int', $iMode)
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc ;==>_WinAPI_SetROP2
Func _WinAPI_WindowFromPoint(ByRef $tPoint)
Local $aResult = DllCall("user32.dll", "hwnd", "WindowFromPoint", "struct", $tPoint)
If @error Then Return SetError(1, @extended, 0)
Return $aResult[0]
EndFunc ;==>_WinAPI_WindowFromPoint
Func _WinAPI_GetWindow($hWnd, $iCmd)
Local $aResult = DllCall("user32.dll", "hwnd", "GetWindow", "hwnd", $hWnd, "uint", $iCmd)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc ;==>_WinAPI_GetWindow
Func _WinAPI_GetWindowRect($hWnd)
Local $tRect = DllStructCreate($tagRECT)
DllCall("user32.dll", "bool", "GetWindowRect", "hwnd", $hWnd, "struct*", $tRect)
If @error Then Return SetError(@error, @extended, 0)
Return $tRect
EndFunc ;==>_WinAPI_GetWindowRect
Func _WinAPI_PtInRect(ByRef $tRect, ByRef $tPoint)
Local $aResult = DllCall("user32.dll", "bool", "PtInRect", "struct*", $tRect, "struct", $tPoint)
If @error Then Return SetError(1, @extended, False)
Return Not ($aResult[0] = 0)
EndFunc ;==>_WinAPI_PtInRect
Func _WinAPI_CreatePen($iPenStyle, $iWidth, $nColor)
Local $aResult = DllCall("gdi32.dll", "handle", "CreatePen", "int", $iPenStyle, "int", $iWidth, "dword", $nColor)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc ;==>_WinAPI_CreatePen
Func _WinAPI_SelectObject($hDC, $hGDIObj)
Local $aResult = DllCall("gdi32.dll", "handle", "SelectObject", "handle", $hDC, "handle", $hGDIObj)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc ;==>_WinAPI_SelectObject
Func _WinAPI_Rectangle($hDC, $tRect)
Local $Ret = DllCall('gdi32.dll', 'int', 'Rectangle', 'hwnd', $hDC, 'int', DllStructGetData($tRect, 1), 'int', _
DllStructGetData($tRect, 2), 'int', DllStructGetData($tRect, 3), 'int', DllStructGetData($tRect, 4))
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return 1
EndFunc ;==>_WinAPI_Rectangle
Func _WinAPI_DeleteObject($hObject)
Local $aResult = DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hObject)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc ;==>_WinAPI_DeleteObject
Func _WinAPI_ReleaseDC($hWnd, $hDC)
Local $aResult = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hWnd, "handle", $hDC)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc ;==>_WinAPI_ReleaseDC
不知道A版那个是啥原理,能否指点下。 |