【已解决】怎么实现外部窗口移动后,自动跟随
本帖最后由 3131210 于 2019-3-15 18:49 编辑不想用定时类的,可不可以用全局钩子监听某某窗口移动后,才触发跟随代码?
比如运行AU3窗口出来后,设置跟随的是notepad记事本。
记事本移动后,自动跟随在相对记事本的坐标,比如x=1,y=1
本帖最后由 gzh888666 于 2019-2-23 13:56 编辑
感觉还是需要用定时器类的监控。 全局钩子好像可以,不想用定时器之类的,不好 有方法,创建定时器,可以检测窗口是否置顶,置顶时,检测位置是不是发生变化,发生变化后,需要不需要窗口跟随。
;此程序需要先打开跟随的窗口,再运行。否则会导致出错。
Opt("WinTitleMatchMode", 4)
Global $wbcwebSend = WinGetHandle($wbcwebclass, "网页同步");获取要跟随的窗口的句柄
Global $pos1 = WinGetPos($wbcwebSend, "");获取要跟随的窗口的初始位置
Global $mouse3 = ;初始窗口的位置
Global $Auxiliary = GUICreate("Form1", 520, 27, $pos1 + $mouse3, $pos1 + $mouse3, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_TOOLWINDOW)
GUISetState(@SW_SHOWNA);显示窗口但是不激活
WinSetOnTop($Auxiliary, "", 1)
AdlibRegister("__WM_MOVE", 20)
Func __WM_MOVE()
;假设要跟随的窗口名称为“网页同步”
;$Auxiliary为当前程序的窗口句柄
Local $iState = WinGetState($wbcwebclass, "网页同步");获取窗口的状态
Switch $iState
Case 15;检测到要跟随的窗口可见
GUISetState(@SW_SHOWNA)
Local $temppos = WinGetPos($wbcwebclass, "网页同步")
If $temppos <> $pos1 Or $temppos <> $pos1 Then
WinMove($Auxiliary, "", $temppos + $mouse3, $temppos + $mouse3)
EndIf
Case 7;检测到要跟随的窗口处于隐藏状态时候
If WinGetState($Auxiliary) <> 15 Then GUISetState(@SW_HIDE);隐藏自身
Case Else;检测到要跟随的窗口处于其他状态时候
GUISetState(@SW_HIDE);隐藏自身
EndSwitch
EndFunc ;==>__WM_MOVE
具体的代码。可以配合你自己的程序,适当测试和调整。
xyx115 发表于 2019-2-25 11:21
具体的代码。可以配合你自己的程序,适当测试和调整。
谢谢楼上的,可是我不想用定时的,有没有办法全局钩子 进来学习,谢谢分享 本帖最后由 tubaba 于 2019-3-14 22:04 编辑
给个提示,用_WinAPI_SetWinEventHook,如何使用查看帮助
Global $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword')
_WinAPI_SetWinEventHook($EVENT_SYSTEM_MOVESIZESTART, $EVENT_SYSTEM_MINIMIZEEND, DllCallbackGetPtr($hEventProc));钩子函数关联当前桌面上所有现有的进程.或者也可只勾目标窗口,这样的话要先取得目标的PID
在Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime)
#forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime
Switch $iEvent
Case $EVENT_SYSTEM_MOVESIZEEND
Switch $hWnd;如果是目标窗口句柄
写下移动你自己的窗口代码
endswith
endswith
endfunc
效果可参见签名 myscitejump,自动吸附到scite
本帖最后由 3131210 于 2019-3-15 21:00 编辑
tubaba 发表于 2019-3-14 21:59
给个提示,用_WinAPI_SetWinEventHook,如何使用查看帮助
Global $hEventProc = DllCallbackRegister('_Ev ...
完美解决 谢谢了
#include <WinAPISys.au3>
#include <WindowsConstants.au3>
$hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword')
$hProc = _WinAPI_SetWinEventHook($EVENT_SYSTEM_FOREGROUND, $EVENT_SYSTEM_MINIMIZEEND, DllCallbackGetPtr($hEventProc))
Dim $hGuiMain = GUICreate(1, 200, 22, 0, 0, $WS_popup, $WS_EX_TOOLWINDOW)
GUISetState()
WinSetOnTop($hGuiMain, '', 1)
While GUIGetMsg() <> -3
Sleep(1)
WEnd
Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime)
Switch $iEvent
Case $EVENT_SYSTEM_FOREGROUND, $EVENT_SYSTEM_SWITCHEND, $EVENT_SYSTEM_MOVESIZEEND
Local $aHWnd = _WinAPI_GetClassName(WinGetHandle(''))
Local $aPos = WinGetPos(WinGetHandle(''))
Switch $aHWnd
Case 'Notepad'
WinMove($hGuiMain, '', $aPos, $aPos)
Case 'AutoIt v3 GUI'
Return
Case Else
WinMove($hGuiMain, '', -1000, -1000)
EndSwitch
EndSwitch
EndFunc ;==>_EventProc
页:
[1]