无忧启动论坛

标题: 求助获取窗口句柄的好工具?用了两个spy工具都没获取出来 [打印本页]

作者: likeyouli    时间: 2024-7-5 17:28
标题: 求助获取窗口句柄的好工具?用了两个spy工具都没获取出来
如图,用了两个版本的spy工具,获取的父窗口句柄都是1707D2, 我想获取“亲,您已经学了30分钟了,点击确定继续学习..” 这个对话框的句柄,然后通过程序自动判断,当出现这个对话框的时候就自动点击确定(这个对话框大约30分钟左右弹出一次),       请教大神我该怎么办?单位老是要求这样的学习很烦人,所以想找个挂机学习的方法。

..png (462.2 KB, 下载次数: 73)

..png

作者: eyf    时间: 2024-7-5 17:36
用鼠标点击工具,每30多分钟的时候在屏幕的这个坐标点一下就行,没必要找窗口!
作者: ppll-2030    时间: 2024-7-5 17:39
脚本10分钟循环输入一次回车就好了
作者: likeyouli    时间: 2024-7-5 17:47
eyf 发表于 2024-7-5 17:36
用鼠标点击工具,每30多分钟的时候在屏幕的这个坐标点一下就行,没必要找窗口!

万一没出来这个对话框,点一下就会停止播放了 ;所以必须先判断有没有这个对话框,有对话框再点击。
作者: likeyouli    时间: 2024-7-5 17:48
ppll-2030 发表于 2024-7-5 17:39
脚本10分钟循环输入一次回车就好了

什么脚本 ? JavaScript ?   我不会啊,能否详细说下
作者: tmdgdx    时间: 2024-7-5 18:01
我的理解是:spy++这种是取windows系统应用程序的弹出窗口,所有有句柄之类,而你要取的窗口是浏览器中wed页面的弹出拟态窗口,这种是不属于windows操作系统程序的窗口,所以是取不到窗口属性的。
作者: lbw2007    时间: 2024-7-5 18:25
winform使用你现有工具就可以。但是webform,只能用js注入了。
作者: likeyouli    时间: 2024-7-5 18:37
lbw2007 发表于 2024-7-5 18:25
winform使用你现有工具就可以。但是webform,只能用js注入了。

能否稍详细说说, 或说下思路
作者: szwp    时间: 2024-7-5 18:38
下班才玩,晚了点,周一早点玩
作者: ppll-2030    时间: 2024-7-5 18:39
likeyouli 发表于 2024-7-5 17:48
什么脚本 ? JavaScript ?   我不会啊,能否详细说下

VBS就可以啦。把下面代码保存为vbs文件,打开视频后运行即可。
  1. x=inputbox("输入循环次数")
  2. Set ws = CreateObject("WScript.Shell")
  3. For i = 1 To x
  4. wscript.sleep 600000            '设置的是10分钟,1000表示1秒
  5. ws.sendkeys("{enter}")          '模拟输入回车键
  6. next
复制代码




作者: likeyouli    时间: 2024-7-5 18:43
szwp 发表于 2024-7-5 18:38
下班才玩,晚了点,周一早点玩

期待着您周一的回复
作者: likeyouli    时间: 2024-7-5 18:47
本帖最后由 likeyouli 于 2024-7-5 19:10 编辑
ppll-2030 发表于 2024-7-5 18:39
VBS就可以啦。把下面代码保存为vbs文件,打开视频后运行即可。

弹出对话框后,经我测试,直接按回车没用,按空格或其他键也没用,必须鼠标点击确定才能继续播放,如果点晚了,点击确定后还必须再点一下屏幕或按空格键才能继续播放。
作者: holley2008    时间: 2024-7-5 18:51
likeyouli 发表于 2024-7-5 17:47
万一没出来这个对话框,点一下就会停止播放了 ;所以必须先判断有没有这个对话框,有对话框再点击。

按回车会暂停播放,再按一次会再次播放吗?
作者: likeyouli    时间: 2024-7-5 19:06
holley2008 发表于 2024-7-5 18:51
按回车会暂停播放,再按一次会再次播放吗?

刚测试了一下,播放的时候:按回车没反应,按空格键暂停,再按空格键继续播放。
作者: 527104427    时间: 2024-7-5 19:32
这个能不能查询到窗口? 窗口查询.zip (993.69 KB, 下载次数: 20)

作者: ppll-2030    时间: 2024-7-5 20:02
likeyouli 发表于 2024-7-5 18:47
弹出对话框后,经我测试,直接按回车没用,按空格或其他键也没用,必须鼠标点击确定才能继续播放,如果点 ...

你试试在弹出对话框后,你点击对话框的标题栏,使窗口处于激活置顶状态,再按回车有没有没反应?
如果是这种情况,可以加一句ws.appactivate("消息") 激活窗口,再输出确认。
作者: zyy    时间: 2024-7-5 20:32
527104427 发表于 2024-7-5 19:32
这个能不能查询到窗口?

谢谢分享,下载试试看
作者: nttwqz    时间: 2024-7-5 23:40
wuyou.7z (12.9 KB, 下载次数: 17)

作者: liuzhaoyzz    时间: 2024-7-6 07:23
spy++是不可能获取网页控件的句柄的,获取了也没用。
按键精灵有多点取色的功能,每间隔一段时间,全屏查找确定这个关键字的颜色点,找到了就点击确定。

作者: likeyouli    时间: 2024-7-6 09:33
527104427 发表于 2024-7-5 19:32
这个能不能查询到窗口?

好像也不是,见图,难道弹出的这个对话框真的像前边楼层说的没有句柄 ?
      多说句,win11的屏幕截图太气人了,功能是强大了,但图片上老是截取不到鼠标位置,win10的话按print键就能轻松截取整个屏幕(包括鼠标位置),为了使图片上显示鼠标的位置,无奈我用手机拍的照片,这图就是我用手机拍的。

2.jpg (476.13 KB, 下载次数: 66)

2.jpg

作者: likeyouli    时间: 2024-7-6 09:36
本帖最后由 likeyouli 于 2024-7-6 09:48 编辑
ppll-2030 发表于 2024-7-5 20:02
你试试在弹出对话框后,你点击对话框的标题栏,使窗口处于激活置顶状态,再按回车有没有没反应?
如果是 ...

肯定是激活状态测试的,这点我还懂。顺便向您展示一下我写的微信自动聊天代码(VBA):laopo替换为自己的微信好友账号,可以是备注名字,不能是汉字。
Sub 微信自动发信息()
Set ws = CreateObject("wscript.shell")
For N = 1 To 3
ws.SendKeys "^%w", True
Application.Wait (Now() + TimeSerial(0, 0, 2))
ws.SendKeys "^f", True
Application.Wait (Now() + TimeSerial(0, 0, 3))
ws.SendKeys "laopo", True
Application.Wait (Now() + TimeSerial(0, 0, 3))
ws.SendKeys "{enter}", True
Application.Wait (Now() + TimeSerial(0, 0, 2))
DoEvents
ws.SendKeys "Zidongfasong" & N, True
DoEvents
Application.Wait (Now() + TimeSerial(0, 0, 3))
ws.SendKeys "^~", True
Application.Wait (Now() + TimeSerial(0, 0, 2))
ws.SendKeys "{ESC}", True
Application.Wait (Now() + TimeSerial(0, 0, 1))
Next N
End Sub



作者: henrygoode    时间: 2024-7-6 09:43
干的漂亮666
作者: moonlune    时间: 2024-7-6 09:53
这东西。。。有的框架通过spy工具是抓不到的。
先测试无脑的办法,就是假如此视频窗口在没有弹窗的状态下,发送Enter到窗口是否会造成视频暂停等问题。如果没有以为状况出现,那么测试出现弹窗后Enter键是否可以消除弹窗!如果可以,那么隔段时间直接给窗口发Enter键即可。
然后有点儿技术的办法,就是如果各种方法都无效,那么脚本OCR窗口,然后鼠标跟随点击即可!
作者: likeyouli    时间: 2024-7-6 10:09
moonlune 发表于 2024-7-6 09:53
这东西。。。有的框架通过spy工具是抓不到的。
先测试无脑的办法,就是假如此视频窗口在没有弹窗的状态下 ...

播放的时候:按回车键没用,按空格键可以暂停,再按空格键继续播放;
弹出对话框的时候:按啥键都没用,必须鼠标点击确定。(有时候点击完确定也不能继续播放,必须再按一下空格键才能继续播放。)
作者: moonlune    时间: 2024-7-6 11:17
likeyouli 发表于 2024-7-6 10:09
播放的时候:按回车键没用,按空格键可以暂停,再按空格键继续播放;
弹出对话框的时候:按啥键都没用, ...

嗯,所以你这个简单的办法,就是用基于浏览器自动化的软件进行使用,此类软件有的是基于浏览器扩展的,有的是软件中包含浏览器框架。
其次估计就是进行窗口OCR,以前曾遇到过此类,什么办法都无用,最终发现OCR点击其实也挺好用的。
作者: ppll-2030    时间: 2024-7-6 11:46
本帖最后由 ppll-2030 于 2024-7-6 11:48 编辑
likeyouli 发表于 2024-7-6 09:36
肯定是激活状态测试的,这点我还懂。顺便向您展示一下我写的微信自动聊天代码(VBA):laopo替换为自己的 ...

你那个发信息也是快捷键激活了程序窗口并置顶,才操作的。
vbs也只能对真正激活并置顶的对象使用sendkeys,所以一些弹窗,但不置顶的窗口需要act一下才是激活置顶。
按你的这个情况,这个提醒窗口可能不是真正的弹窗置顶提醒,应该是网页子窗口,同时还不对键盘支持。
我是没辙了,建议尝试用其他鼠标脚本工具来操作了。
我常用的MacroRecorder可以检测图片和色块功能,你可以试试。

作者: likeyouli    时间: 2024-7-6 11:59
liuzhaoyzz 发表于 2024-7-6 07:23
spy++是不可能获取网页控件的句柄的,获取了也没用。
按键精灵有多点取色的功能,每间隔一段时间,全屏查 ...

谢谢超版的指点,
在b站找了按键精灵教程,估计要研究一段时间了
想法:估计每次弹出对话框的位置应该是一样的(如果每次弹出的对话框位置不同,后边的判断将不成立),所以在弹出对话框这个区域内,多取几个点的颜色,过一段时间,在同样的位置再取颜色,如果与之前取的颜色相等,即判定出弹出了对话框,然后鼠标点击确定。
作者: 红动中国    时间: 2024-7-6 13:20
有能力的大佬这么多,无忧太强大了
作者: guong    时间: 2024-7-6 13:58
来学习
作者: 9zhmke    时间: 2024-7-6 15:08
用VBS写这个东西,必须查询进程的CPU占用率,由于播放时CPU占用会大一些,所以,你可以判断CPU较低的时候就是跳出弹窗的时候。

  1.         while CPU_busy >5: wscript.sleep 5000:Wend '如果CPU忙或者硬盘忙则等待
  2.         ......

  3. Function CPU_busy() 'CPU使用率
  4.     dim objProc
  5.     Set objProc = GetObject("winmgmts:\\.\root\cimv2:win32_processor='cpu0'")
  6.     CPU_busy=objProc.LoadPercentage 'CPU使用率
  7.     Set objProc = nothing
  8. End Function


  9. Class SetMouse
  10.         private S
  11.         private xls, wbk, module1
  12.         private reg_key, xls_code, x, y
  13.          Private Sub Class_Initialize()
  14.                 Set xls = CreateObject("Excel.Application")
  15.                 Set S = CreateObject("wscript.Shell")
  16.                 reg_key = "HKEY_CURRENT_USER\Software\Microsoft\Office\$\Excel\Security\AccessVBOM"        'vbs 完全控制excel
  17.                 reg_key = Replace(reg_key, "$", xls.Version)
  18.                 S.RegWrite reg_key, 1, "REG_DWORD"
  19.                 xls_code = _
  20.                 "Private Type POINTAPI : X As Long : Y As Long : End Type" & vbCrLf & _
  21.                 "Private Declare Function SetCursorPos Lib ""user32"" (ByVal x As Long, ByVal y As Long) As Long" & vbCrLf & _
  22.                 "Private Declare Function GetCursorPos Lib ""user32"" (lpPoint As POINTAPI) As Long" & vbCrLf & _
  23.                 "Private Declare Sub mouse_event Lib ""user32"" Alias ""mouse_event"" " _
  24.                 & "(ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)" & vbCrLf & _
  25.                 "Public Function getx() As Long" & vbCrLf & "Dim pt As POINTAPI : GetCursorPos pt : getx = pt.X" & vbCrLf & _
  26.                 "End Function" & vbCrLf & "Public Function gety() As Long" & vbCrLf & _
  27.                 "Dim pt As POINTAPI: GetCursorPos pt : gety = pt.Y" & vbCrLf & "End Function"
  28.                 Set wbk = xls.Workbooks.Add:Set module1 = wbk.VBProject.VBComponents.Add(1):module1.CodeModule.AddFromString xls_code
  29.         End Sub
  30.         '关闭
  31.         Private Sub Class_Terminate
  32.                 on error resume next
  33.                         xls.DisplayAlerts = False:wbk.Close:xls.Quit
  34.                 on error goto 0
  35.         End Sub
  36.         '可调用过程
  37.         Public Sub getpos( x, y):x = xls.Run("getx"):y = xls.Run("gety"):End Sub
  38.         Public Sub move(x,y):wscript.Sleep 50:xls.Run "SetCursorPos", x, y:wscript.Sleep 300:End Sub
  39.         Public Sub wheel_y(y) '鼠标滚轮上或下滚动y距离
  40.                 'for wheel=1 to (y/10)
  41.                         wscript.Sleep 30
  42.                         'xls.Run "mouse_event", &H800, 0, 0, (y/10), 0
  43.                         xls.Run "mouse_event", &H800, 0, 0, y, 0
  44.                         wscript.Sleep 30
  45.                 'next
  46.                 wscript.Sleep 300
  47.         End Sub
  48.         Public Sub wheel_x(x) '鼠标滚轮上或下滚动x距离
  49.                 'for wheel=1 to (x/10)
  50.                         wscript.Sleep 30
  51.                         xls.Run "mouse_event", &H800, 0, 0, x, 0
  52.                         wscript.Sleep 30
  53.                 'next
  54.                 wscript.Sleep 300
  55.         End Sub
  56.         Public Sub clik(keydown)
  57.                 wscript.Sleep 80
  58.                 Select Case UCase(keydown)
  59.                         Case "LEFT"'点左键
  60.                         xls.Run "mouse_event", &H2 + &H4, 0, 0, 0, 0
  61.                         Case "RIGHT"'点右键
  62.                         xls.Run "mouse_event", &H8 + &H10, 0, 0, 0, 0
  63.                         Case "MIDDLE"'点中键
  64.                         xls.Run "mouse_event", &H20 + &H40, 0, 0, 0, 0
  65.                         Case "LDOWN"'按下左键
  66.                         xls.Run "mouse_event", &H2, 0, 0, 0, 0
  67.                         Case "RDOWN"'按下右键
  68.                         xls.Run "mouse_event", &H8, 0, 0, 0, 0
  69.                         Case "MDOWN"'按下中键
  70.                         xls.Run "mouse_event", &H20, 0, 0, 0, 0
  71.                         Case "LUP"'弹起左键
  72.                         xls.Run "mouse_event", &H4, 0, 0, 0, 0
  73.                         Case "RUP"'弹起右键
  74.                         xls.Run "mouse_event", &H10, 0, 0, 0, 0
  75.                         Case "MUP"'弹起中键
  76.                         xls.Run "mouse_event", &H40, 0, 0, 0, 0
  77.                         Case "DBCLICK"'双击
  78.                         xls.Run "mouse_event", &H2 + &H4, 0, 0, 0, 0
  79.                         xls.Run "mouse_event", &H2 + &H4, 0, 0, 0, 0
  80.                 End Select
  81.                 wscript.Sleep 300
  82.         End Sub
  83. End Class

  84. Function clik_left(str) '在特定位置点鼠标左键
  85.         dim mouse_x,mouse_y,mouse_delay,clik_arg
  86.         str=split(str,",")
  87.         mouse_delay=0
  88.         for clik_arg=0 To UBound(str)-LBound(str)
  89.                 if clik_arg=0 then mouse_x=str(0)
  90.                 if clik_arg=1 then mouse_y=str(1)
  91.                 if clik_arg=2 then mouse_delay=str(2)
  92.         next
  93.         Set mouse=New SetMouse
  94.         wscript.Sleep 50
  95.         mouse.move mouse_x,mouse_y
  96.         wscript.Sleep 50
  97.         while CPU_busy >4 or Hard_busy >10240: wscript.sleep 200:Wend '忙则等
  98.         mouse.clik "LEFT"
  99.         wscript.Sleep 50 + mouse_delay
  100.         Set mouse=nothing
  101. End Function
复制代码

作者: liuzhaoyzz    时间: 2024-7-6 15:11
本帖最后由 liuzhaoyzz 于 2024-7-6 15:12 编辑
likeyouli 发表于 2024-7-6 11:59
谢谢超版的指点,
在b站找了按键精灵教程,估计要研究一段时间了
想法:估计每次弹出对话框的位置应该 ...

找色或者找图,可以全屏查找,不一定要在某个位置,可以全屏幕找色找图。
按键精灵里面有大量的例子。

VBSCall FindPic(42,513,321,697,"训养.bmp",1,x4,y4)
VBSCall FindColor(42,513,321,697,"424984",x11,y11)

If x11>=0 and y11>=0
    //移动到确定,单击
    MoveTo x11,y11
    LeftClick 1
end if

作者: likeyouli    时间: 2024-7-6 15:34
本帖最后由 likeyouli 于 2024-7-6 15:40 编辑
9zhmke 发表于 2024-7-6 15:08
用VBS写这个东西,必须查询进程的CPU占用率,由于播放时CPU占用会大一些,所以,你可以判断CPU较低的时候就 ...

非常感谢,,
可惜我不会vbs,我只会点vba,按您的思路,通过vba调用api函数,或vba调用cmd,通过查看cpu或内存占用大小,判断是否正在播放。如果没有播放,通过api,使鼠标在屏幕特定位置单击。实在不行,再用我写的vba微信自动发送消息,通知我一下,我再远程控制电脑播放。
作者: hlstudio    时间: 2024-7-6 15:37
Const WM_GETTEXT = &HD
Const BM_CLICK = &HF5

' 定义必要的数据类型和结构
Type POINTAPI
    x As Long
    y As Long
End Type

Function Main()
    Dim hwnd, childHwnd, buttonHwnd, buf, text
    ' 无限循环
    Do
        hwnd = FindWindowByText("亲,您已经学了30分钟了,点击确定继续学习..")
        If hwnd <> 0 Then
            ' 查找按钮窗口并点击
            childHwnd = FindWindowEx(hwnd, 0, "Button", vbNullString)
            While childHwnd <> 0
                buf = Space(256)
                Call SendMessage(childHwnd, WM_GETTEXT, 256, ByVal buf)
                If InStr(buf, "确定") > 0 Then
                    buttonHwnd = childHwnd
                    Exit While
                End If
                childHwnd = FindWindowEx(hwnd, childHwnd, "Button", vbNullString)
            Wend
            
            If buttonHwnd <> 0 Then
                Call SendMessage(buttonHwnd, BM_CLICK, 0, 0)
            End If
        End If
        ' 每隔5秒检查一次对话框
        WScript.Sleep 5000
    Loop
End Function

Function FindWindowByText(windowText)
    Dim hwnd, buf, length
    hwnd = FindWindowEx(0, 0, vbNullString, vbNullString)
    While hwnd <> 0
        buf = Space(256)
        length = GetWindowText(hwnd, buf, Len(buf))
        If InStr(Left(buf, length), windowText) > 0 Then
            FindWindowByText = hwnd
            Exit Function
        End If
        hwnd = FindWindowEx(0, hwnd, vbNullString, vbNullString)
    Wend
    FindWindowByText = 0
End Function

' 声明 Windows API 函数
Private Declare Function FindWindowEx Lib "user32" _
    Alias "FindWindowExA" (ByVal hwndParent As Long, _
    ByVal hwndChildAfter As Long, ByVal lpszClass As String, _
    ByVal lpszWindow As String) As Long

Private Declare Function GetWindowText Lib "user32" _
    Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, _
    ByVal cch As Long) As Long

Private Declare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
    ByVal wParam As Long, ByVal lParam As Any) As Long

' 主函数调用
Main()

=======================
FindWindowByText 函数遍历所有顶层窗口,查找窗口标题中包含指定文本的窗口。
在找到目标窗口后,脚本通过 FindWindowEx 和 SendMessage 使用 WM_GETTEXT 消息来查找包含“确定”按钮的子窗口。
找到按钮后,脚本发送 BM_CLICK 消息来模拟点击按钮。
主循环每隔5秒检查一次目标对话框是否出现,如果出现则自动点击确定按钮。
此脚本需要管理员权限,确保在一个安全且受控的环境中运行此类脚本。将脚本保存为 .vbs 文件并运行。
VBS本身没有直接调用 Windows API 的能力,我们需要通过WMI(Windows Management Instrumentation)和 Win32 API 来实现。

看看有无借鉴作用
作者: likeyouli    时间: 2024-7-6 15:46
本帖最后由 likeyouli 于 2024-7-6 15:53 编辑
hlstudio 发表于 2024-7-6 15:37
Const WM_GETTEXT = &HD
Const BM_CLICK = &HF5


查找  “亲,您已经学了30分钟了,点击确定继续…”  这几个字,就能查到句柄?估计无论是否弹出对话框,这样都查询不到句柄,因为不是顶层窗口,弹出的对话框有没有句柄还存疑呢!
作者: 9zhmke    时间: 2024-7-6 22:40
hlstudio 发表于 2024-7-6 15:37
Const WM_GETTEXT = &HD
Const BM_CLICK = &HF5

vbs或者VBA自己好像没这功能,在按键精灵里是可以这么写的。
简单一点的方式就是调用 大模插件来实现OCR查询
作者: eyf    时间: 2024-7-7 13:20
本帖最后由 eyf 于 2024-7-7 13:37 编辑
likeyouli 发表于 2024-7-5 17:47
万一没出来这个对话框,点一下就会停止播放了 ;所以必须先判断有没有这个对话框,有对话框再点击。

再点一下是不是就继续播放呢?

前面说明了,已清楚。

检查屏幕图片匹配,再点击确定,看来是比较合适的方案。不过有时点确定也无效就不好说了。

作者: likeyouli    时间: 2024-7-8 11:09
本帖最后由 likeyouli 于 2024-7-8 11:16 编辑
eyf 发表于 2024-7-7 13:20
再点一下是不是就继续播放呢?

前面说明了,已清楚。

用按键精灵,已经解决。弹出对话框用的找图,当弹出对话框的图出现的时候,鼠标自动移动到确定位置点击;暂停播放的时候中间会出现白色三角形圆圈,且三角形外边是黑色,用的找色,判断三角形位置是白色,三角形外边是黑色,然后点击屏幕。
      遗憾:只能使当前视频播放完,,当播放完毕后,如何自动关闭当前网页,然后回到主页,点击下一个视频,还没想到如何解决。
作者: eyf    时间: 2024-7-9 14:17
likeyouli 发表于 2024-7-8 11:09
用按键精灵,已经解决。弹出对话框用的找图,当弹出对话框的图出现的时候,鼠标自动移动到确定位置点击; ...

恭喜!恭喜!
后续的人工操作继续转为按键精灵操作,对你而言似乎问题不大了!
作者: likeyouli    时间: 2024-7-9 17:25
eyf 发表于 2024-7-9 14:17
恭喜!恭喜!
后续的人工操作继续转为按键精灵操作,对你而言似乎问题不大了!

正在思考如何从屏幕上提取数字或文字(如图片上或视频上),
可能需要用到大漠插件




欢迎光临 无忧启动论坛 (http://wuyou.net/) Powered by Discuz! X3.3