3131210 发表于 2019-2-23 05:51:52

【已解决】怎么实现外部窗口移动后,自动跟随

本帖最后由 3131210 于 2019-3-15 18:49 编辑

不想用定时类的,可不可以用全局钩子监听某某窗口移动后,才触发跟随代码?

比如运行AU3窗口出来后,设置跟随的是notepad记事本。
记事本移动后,自动跟随在相对记事本的坐标,比如x=1,y=1

gzh888666 发表于 2019-2-23 13:49:27

本帖最后由 gzh888666 于 2019-2-23 13:56 编辑

感觉还是需要用定时器类的监控。

3131210 发表于 2019-2-23 14:21:23

全局钩子好像可以,不想用定时器之类的,不好

xyx115 发表于 2019-2-25 11:07:12

有方法,创建定时器,可以检测窗口是否置顶,置顶时,检测位置是不是发生变化,发生变化后,需要不需要窗口跟随。

xyx115 发表于 2019-2-25 11:21:34



;此程序需要先打开跟随的窗口,再运行。否则会导致出错。
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



具体的代码。可以配合你自己的程序,适当测试和调整。

3131210 发表于 2019-2-25 18:19:30

xyx115 发表于 2019-2-25 11:21
具体的代码。可以配合你自己的程序,适当测试和调整。

谢谢楼上的,可是我不想用定时的,有没有办法全局钩子

zhiguang123 发表于 2019-3-4 22:17:24

进来学习,谢谢分享

tubaba 发表于 2019-3-14 21:59:09

本帖最后由 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 18:49:06

本帖最后由 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]
查看完整版本: 【已解决】怎么实现外部窗口移动后,自动跟随