界标线消除问题
本帖最后由 ken0137 于 2011-3-20 16:05 编辑前几天问了如何画出界标线,得到了很多热心的大侠的帮助,特别是happytc和pusofalse
都是运用API函数,画两个框,重叠后,取得所需要的部分
happytc的看懂了,是直接调用api中的函数,边界的闪烁是依靠变换截取部分窗体的背景色来实现的,所以作为菜鸟就加了注释
请问当鼠标移到一个窗口上如何在这个窗口周围出现一个闪烁的框(界标线)
而pusofalse是使用winapi库实现的,但是看不懂
但是不管是否使用happytc的GUICreateSquare函数,还是pusofalse的_DrawFrame函数,
都有一个问题,就是闪烁的框会留影,不会完全消除,不知道能否像afan的“探测窗口控件工具”一样,移到别的地方原来的那个闪烁的框就完全消失,
能否告知如何做才能让效果像afan的“探测窗口控件工具”一样
留影的状态:
_DrawFrame会留影?我测试不会如此啊,_DrawFrame 调用的是标准的绘制界标线的函数,SPY++、AU3窗口信息工具都是用的此方法,你试下用AU3的窗口信息工具会留影否。 回复 2# pusofalse
不知道我这样调用的对不对
#include <ProgressConstants.au3>
#include <GuiConstantsEx.au3>
#include <GuiConstants.au3>
#include <ButtonConstants.au3>
#include <BorderConstants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <TabConstants.au3>
#include <ComboConstants.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <WinApi.au3>
#Include <Misc.au3>
Global $Color = 0x0
While 1
Sleep(500)
;~ If $Color = 0xFFFFFF Then
;~ $Color =0x000000
;~ Else
;~ $Color = 0xFFFFFF
;~ EndIf
;创建一个 C/C++ 样式的数据结构供 DllCall 使用. DllStructCreate ( "数据结构" [,指针] )
Global $Struct = DllStructCreate($tagPoint)
;设置数据结构(struct)中部分元素的数据.DllStructSetData ( 数据结构, 元素, 值 [, 索引 ] )
DllStructSetData($Struct, "x", MouseGetPos(0));获取当前鼠标的屏幕绝对坐标x位置.
DllStructSetData($Struct, "y", MouseGetPos(1));获取当前鼠标的屏幕绝对坐标y位置.
;返回当前坐标windowns窗口的句柄,例如返回值为0x0016035A,这里的窗口为所要捕捉的程序界面中的窗口,即控件
$hWinCtrl = _WinAPI_WindowFromPoint($Struct)
;获取指定窗口的坐标位置(绝对坐标)和大小等属性.WinGetPos ( "窗口标题" [, "窗口文本"] )
;Local $aCtrlPos = WinGetPos($hWinCtrl)
;自定义界标线函数,开始画框
;GUICreateSquare($aCtrlPos, $aCtrlPos, $aCtrlPos, $aCtrlPos, $Color)
_DrawFrame($hWinCtrl)
WEnd
Func _DrawFrame($hWnd)
If ($hWnd = 0) Then Return 0
Local $hDC, $hPen, $hRgn, $aPos
$hDC = _WinAPI_GetWindowDC($hWnd)
$hPen = _WinAPI_CreatePen(6, 3, 0)
$hRgn = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, @DesktopHeight)
_WinAPI_SelectObject($hDC, $hPen)
_WinAPI_SelectObject($hDC, _WinAPI_GetStockObject(5))
_WinAPI_SetROP2($hDC, 6)
If _WinAPI_GetWindowRgn($hWnd, $hRgn) Then
_WinAPI_FrameRgn($hDC, $hRgn, $hPen, 3, 3)
Else
$aPos = WinGetPos($hWnd)
If Not IsArray($aPos) Then Return 0
_WinAPI_Rectangle($hDC, 0, 0, $aPos, $aPos)
EndIf
_WinAPI_DeleteObject($hRgn)
_WinAPI_DeleteObject($hPen)
_WinAPI_ReleaseDC($hWnd, $hDC)
Return 1
EndFunc ;==>_DrawFrame
Func _WinAPI_Rectangle($hDC, $iLeft, $iTop, $iRight, $iBottom)
Local $iResult
$iResult = DllCall("Gdi32.dll", "bool", "Rectangle", "hwnd", $hDC, _
"long", $iLeft, "long", $iTop, "long", $iRight, "long", $iBottom)
Return $iResult
EndFunc ;==>_WinAPI_Rectangle
Func _WinAPI_SetROP2($hDC, $iMode)
Local $iResult
$iResult = DllCall("Gdi32.dll", "bool", "SetROP2", "hwnd", $hDC, "dword", $iMode)
Return $iResult
EndFunc ;==>_WinAPI_SetROP2
Func _WinAPI_FrameRgn($hDC, $hRgn, $hBrush, $iWidth, $iHeight)
Local $iResult
$iResult = DllCall("Gdi32.dll", "bool", "FrameRgn", "hwnd", $hDC, "hwnd", $hRgn, _
"hwnd", $hBrush, "long", $iWidth, "long", $iHeight)
Return $iResult
EndFunc ;==>_WinAPI_FrameRgn
Func _WinAPI_LoadCursorFromFile($sCursor)
Local $iResult = DllCall("User32.dll", "hwnd", "LoadCursorFromFile", "str", $sCursor)
Return $iResult
EndFunc ;==>_WinAPI_LoadCursorFromFile
Func _WinAPI_SetSystemCursor($hCursor, $iSystemCursor)
Local $iResult = DllCall("User32.dll", "bool", "SetSystemCursor", "hwnd", $hCursor, "dword", $iSystemCursor)
Return $iResult
EndFunc ;==>_WinAPI_SetSystemCursor
Func _WinAPI_DestroyCursor($hCursor)
Local $iResult = DllCall("User32.dll", "bool", "DestroyCursor", "hwnd", $hCursor)
Return $iResult
EndFunc ;==>_WinAPI_DestroyCursor
回复 1# ken0137
啊,你还没有搞定呀。因为你原帖只要个找外框的。所以我都没有写删除外框的。
添加上这个功能就可以了呀。若P版的你用上没有问题,我就不多写帮你加上了。 回复 3# ken0137
你必须要有一个全局变量来记录上次绘制过的窗口的句柄,当用WindowFromPoint检测到鼠标下的窗口不一样时,必须调用两次_DrawFrame函数,第一次调用将_DrawFrame的参数设为 上次绘制过的窗口的句柄,以清除界标线,第二次才是绘制当前窗口。 本帖最后由 happytc 于 2011-3-20 23:47 编辑
象下面这样子添加上删除绘的外框,就可以了嘛
#include <ProgressConstants.au3>
#include <GuiConstantsEx.au3>
#include <GuiConstants.au3>
#include <ButtonConstants.au3>
#include <BorderConstants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <TabConstants.au3>
#include <ComboConstants.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <WinApi.au3>
#Include <Misc.au3>
Window()
Func Window()
Local $sImgFile
Local $hUser32Dll = DllOpen("user32.dll")
Local $hLast_Control = -1
Local $hWinCtrl = -1
Local $IsCapture = False
Local Const $WH_MOUSE_LL = 14
Local $hKey_Proc = DllCallbackRegister("_Mouse_Handler", "int", "int;ptr;ptr;int")
Local $hModule = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "int", 0)
Local $hHook = DllCall($hUser32Dll, "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hModule, "dword", 0)
Local $Frame_Width = 3
Local $hSquare_GUI = -1
While 1
Check_Highlight_Controls_Proc($hSquare_GUI, $hLast_Control)
If _IsPressed("0D", $hUser32Dll) Or _IsPressed("01", $hUser32Dll) Then ;0D ENTER, 01 Primary Key
GUIDeleteSquare($hSquare_GUI)
$hWinCtrl = $hLast_Control
If $hWinCtrl <= 0 Then $hWinCtrl = _Get_Hovered_Handle()
$IsCapture = True
ExitLoop
EndIf
If _IsPressed("1B", $hUser32Dll) Or _IsPressed("02", $hUser32Dll) Then ;1B ESC 键
GUIDeleteSquare($hSquare_GUI)
ExitLoop
EndIf
WEnd
DllCall($hUser32Dll, "int", "UnhookWindowsHookEx", "hwnd", $hHook)
DllCallbackFree($hKey_Proc)
DllClose($hUser32Dll)
EndFunc
Func Check_Highlight_Controls_Proc(ByRef $hSquare_GUI, ByRef $hLast_Control)
Local $hWinCtrl = _Get_Hovered_Handle()
If $hWinCtrl <> 0 And $hWinCtrl <> $hLast_Control And $hWinCtrl <> $hSquare_GUI Then
$hLast_Control = $hWinCtrl
Local $aCtrlPos = WinGetPos($hWinCtrl)
If @error Then Return
GUIDeleteSquare($hSquare_GUI)
GUICreateSquare($hSquare_GUI, $aCtrlPos, $aCtrlPos, $aCtrlPos, $aCtrlPos, 0xFF0000)
EndIf
EndFunc
Func GUIDeleteSquare(ByRef $hSquare_GUI)
If IsHWnd($hSquare_GUI) Then
GUIDelete($hSquare_GUI)
$hSquare_GUI = -1
EndIf
EndFunc
Func _Get_Hovered_Handle()
Local $aRet = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
If Not IsArray($aRet) Then Return SetError(1, 0, 0)
Return HWnd($aRet)
EndFunc
Func GUICreateSquare(ByRef $hSquare_GUI, $i_X=-1, $i_Y=-1, $i_W=-1, $i_H=-1, $sColor=0x0)
$hSquare_GUI = GUICreate("", $i_W, $i_H, $i_X, $i_Y, $WS_POPUP, $WS_EX_TOPMOST+$WS_EX_TOOLWINDOW)
Local $Frame_Width = 3
GUISetBkColor($sColor)
_GUISetHole($hSquare_GUI, $Frame_Width, $Frame_Width, $i_W - ($Frame_Width * 2), $i_H - ($Frame_Width * 2))
GUISetState(@SW_SHOWNOACTIVATE, $hSquare_GUI)
EndFunc
Func _GUISetHole(ByRef $hWin, $i_X, $i_Y, $i_SizeW, $i_SizeH)
Local $aWinPos, $Outer_Rgn, $Inner_Rgn, $Wh, $Combined_Rgn
Local Const $RGN_DIFF = 4
$aWinPos = WinGetPos($hWin)
$Outer_Rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", $aWinPos, "long", $aWinPos)
$Inner_Rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $i_Y, "long", $i_Y, "long", $i_Y + $i_SizeW, "long", $i_Y + $i_SizeH)
$Combined_Rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
DllCall("gdi32.dll", "long", "CombineRgn", "long", $Combined_Rgn, "long", $Outer_Rgn, "long", $Inner_Rgn, "int", $RGN_DIFF)
DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWin, "long", $Combined_Rgn, "int", 1)
EndFunc
又忘了,你要的外框闪了,上次给你了,你自己加上吧,我就懒得改上帖了 本帖最后由 ken0137 于 2011-3-22 09:19 编辑
回复 7# happytc
谢谢happytc的回答,
1、请问Local $hKey_Proc = DllCallbackRegister("_Mouse_Handler", "int", "int;ptr;ptr;int")中的_Mouse_Handler应该是自定义的回调函数吧,但是却没有看见这个函数在哪里?
2、Local $hHook = DllCall($hUser32Dll, "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, "ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hModule, "dword", 0)这个SetWindowsHookEx是什么作用的啊?$WH_MOUSE_LL有什么意思?能不能注释一下啊?
3、那个闪烁我搞来搞去好像也搞不上去
4、那种效果不知道具体怎么样实现:先外框闪烁一下,然后比外框小的框(例如一半)在闪烁一下,最后在鼠标所处位置再亮一下,这种效果怎么做?
谢谢
页:
[1]