找回密码
 加入
搜索
查看: 6141|回复: 7

[GUI管理] 界标线消除问题

  [复制链接]
发表于 2011-3-20 16:02:02 | 显示全部楼层 |阅读模式
本帖最后由 ken0137 于 2011-3-20 16:05 编辑

前几天问了如何画出界标线,得到了很多热心的大侠的帮助,特别是happytc和pusofalse
都是运用API函数,画两个框,重叠后,取得所需要的部分
happytc的看懂了,是直接调用api中的函数,边界的闪烁是依靠变换截取部分窗体的背景色来实现的,所以作为菜鸟就加了注释
请问当鼠标移到一个窗口上如何在这个窗口周围出现一个闪烁的框(界标线)

而pusofalse是使用winapi库实现的,但是看不懂
但是不管是否使用happytc的GUICreateSquare函数,还是pusofalse的_DrawFrame函数,
都有一个问题,就是闪烁的框会留影,不会完全消除,不知道能否像afan的“探测窗口控件工具”一样,移到别的地方原来的那个闪烁的框就完全消失,
能否告知如何做才能让效果像afan的“探测窗口控件工具”一样
留影的状态:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-3-20 20:54:02 | 显示全部楼层
_DrawFrame会留影?我测试不会如此啊,_DrawFrame 调用的是标准的绘制界标线的函数,SPY++、AU3窗口信息工具都是用的此方法,你试下用AU3的窗口信息工具会留影否。
 楼主| 发表于 2011-3-20 22:11:10 | 显示全部楼层
回复 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[0], $aCtrlPos[1], $aCtrlPos[2], $aCtrlPos[3], $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[2], $aPos[3])
        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[0]
EndFunc        ;==>_WinAPI_Rectangle
Func _WinAPI_SetROP2($hDC, $iMode)
        Local $iResult
        $iResult = DllCall("Gdi32.dll", "bool", "SetROP2", "hwnd", $hDC, "dword", $iMode)
        Return $iResult[0]
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[0]
EndFunc        ;==>_WinAPI_FrameRgn

Func _WinAPI_LoadCursorFromFile($sCursor)
        Local $iResult = DllCall("User32.dll", "hwnd", "LoadCursorFromFile", "str", $sCursor)
        Return $iResult[0]
EndFunc        ;==>_WinAPI_LoadCursorFromFile

Func _WinAPI_SetSystemCursor($hCursor, $iSystemCursor)
        Local $iResult = DllCall("User32.dll", "bool", "SetSystemCursor", "hwnd", $hCursor, "dword", $iSystemCursor)
        Return $iResult[0]
EndFunc        ;==>_WinAPI_SetSystemCursor

Func _WinAPI_DestroyCursor($hCursor)
        Local $iResult = DllCall("User32.dll", "bool", "DestroyCursor", "hwnd", $hCursor)
        Return $iResult
EndFunc        ;==>_WinAPI_DestroyCursor
发表于 2011-3-20 22:36:45 | 显示全部楼层
回复 1# ken0137


    啊,你还没有搞定呀。因为你原帖只要个找外框的。所以我都没有写删除外框的。
添加上这个功能就可以了呀。若P版的你用上没有问题,我就不多写帮你加上了。
发表于 2011-3-20 23:06:34 | 显示全部楼层
回复 3# ken0137


你必须要有一个全局变量来记录上次绘制过的窗口的句柄,当用WindowFromPoint检测到鼠标下的窗口不一样时,必须调用两次_DrawFrame函数,第一次调用将_DrawFrame的参数设为 上次绘制过的窗口的句柄,以清除界标线,第二次才是绘制当前窗口。
发表于 2011-3-20 23:46:05 | 显示全部楼层
本帖最后由 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[0], "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[0])
        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[0], $aCtrlPos[1], $aCtrlPos[2], $aCtrlPos[3], 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[0])
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[2], "long", $aWinPos[3])
        $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[0], "long", $Outer_Rgn[0], "long", $Inner_Rgn[0], "int", $RGN_DIFF)
        DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWin, "long", $Combined_Rgn[0], "int", 1)
EndFunc


发表于 2011-3-20 23:48:28 | 显示全部楼层
又忘了,你要的外框闪了,上次给你了,你自己加上吧,我就懒得改上帖了
 楼主| 发表于 2011-3-22 08:41:47 | 显示全部楼层
本帖最后由 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[0], "dword", 0)这个SetWindowsHookEx是什么作用的啊?$WH_MOUSE_LL有什么意思?能不能注释一下啊?
3、那个闪烁我搞来搞去好像也搞不上去
4、那种效果不知道具体怎么样实现:先外框闪烁一下,然后比外框小的框(例如一半)在闪烁一下,最后在鼠标所处位置再亮一下,这种效果怎么做?
谢谢
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-23 13:16 , Processed in 0.085740 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表