afan 发表于 2021-8-6 11:00:20

ttmv2019sx 发表于 2021-8-6 10:53
好的,A版,,是的这个问题,弄了快2个月了,哎,不知道为什么楼下的电脑时灵时不灵的,奇了怪了,对了, ...

用句柄操作会忽略文本参数。所以,需要再 WinGetText(窗口句柄) 来获取文本来判断。

ttmv2019sx 发表于 2021-8-6 11:15:05

afan 发表于 2021-8-6 11:00
用句柄操作会忽略文本参数。所以,需要再 WinGetText(窗口句柄) 来获取文本来判断。

主要是,我上面用到的工具,他用你写的窗口工具,或者是自带的,都只有少数几个界面才会有可见文本,唯一可以区分每一个界面不同之处,只有控件ID上的文本,如果用句柄,依文本来判断,由于可见文本不太有,是不是只能是用,ControlGetText ( "窗口标题", "窗口文本", 控件ID)这个来判断作为依据了。    还有,是不是句柄的查窗口,比用标题,类名,,这一些都要来的准 ?我是想到了找到这个工具的进程PID,然后转成句柄,来测试的,,只是一直不清楚问题在哪里,有了你上面的代码,我去好好的看看,到底是什么引起的,再一次先谢谢A大了,,感谢你

afan 发表于 2021-8-6 13:23:15

ttmv2019sx 发表于 2021-8-6 11:15
主要是,我上面用到的工具,他用你写的窗口工具,或者是自带的,都只有少数几个界面才会有可见文本,唯一 ...

只要是窗口文本为参数的必须是windows标准控件,如WinGetText、窗口探测工具可获取的。你若填写该参数当然要有可捕获的文本,否则没意义。
句柄是唯一的,也是不会改变的。但是标题、文本不一定是唯一的,且可能改变。因此,句柄肯定更准确。

ttmv2019sx 发表于 2021-8-19 08:55:51

afan 发表于 2021-8-6 13:23
只要是窗口文本为参数的必须是windows标准控件,如WinGetText、窗口探测工具可获取的。你若填写该参数当 ...

A大,刚好,哪边有空位,找到了机会,去测试了一下你所写的代码,发现如下问题,就是在原来正常的电脑上的,都是可以打开这个OFFICE卸载工具后,运行你的代码,立马是可以发现窗口,而有故障的电脑中,运行了工具后,再运行你的代码,是无法发现窗口的,但是在列表中,又是存在的,怪不得,不能自动操作下去,这个是什么情况引起的。真神奇。

我提供一下图片,请A大,你帮忙分析一下是什么原因,谢谢。




afan 发表于 2021-8-19 09:38:47

ttmv2019sx 发表于 2021-8-19 08:55
A大,刚好,哪边有空位,找到了机会,去测试了一下你所写的代码,发现如下问题,就是在原来正常的电脑上 ...

那就再增加调试
#include <Array.au3>

Local $hWin = _WinListWait('Uninstall Microsoft Office', '下一步(&N)', 10) ;10秒内检测等待
If Not @error Then MsgBox(0, '已检测到窗口', $hWin)

Func _WinListWait($sTitle, $sText = '', $iTimeout = 0)
        Opt('WinTitleMatchMode', -1)
        Local $hWin, $aTtList, $iTs = TimerInit()
        If $iTimeout > 0 Then
                $iTimeout *= 1000
                Do
                        $hWin = WinGetHandle($sTitle, $sText)
                        If $hWin Then Return $hWin
                        Sleep(100)
                        If TimerDiff($iTs) >= $iTimeout Then
                                Local $aList = WinList(), $aWShow, $ix = 0
                                For $i = 1 To $aList
                                        If $aList[$i] <> '' And BitAND(WinGetState($aList[$i]), 2) Then
                                                $ix += 1
                                                $aWShow[$ix] = $aList[$i]
                                                $aWShow[$ix] = $aList[$i]
                                                $aWShow[$ix] = ($aList[$i] = $sTitle)        ;测试是否与标题一致
                                        EndIf
                                Next
                                If Not $ix Then Return SetError(2, 0, 0)
                                $aWShow = $ix
                                ReDim $aWShow[$ix + 1]
                                _ArrayDisplay($aWShow, '已超时,未检测到窗口.当前可见窗口')
                                Return SetError(1, 0, 0)
                        EndIf
                Until 0
        Else
                Do
                        $hWin = WinGetHandle($sTitle, $sText)
                        If $hWin Then Return $hWin
                        Sleep(100)
                        $aTtList = WinList($sTitle, $sText)
                        If $aTtList Then
                                MsgBox(0, '用 WinList 检测到窗口', $aTtList)
                                Return $aTtList
                        EndIf
                Until 0
        EndIf
        Return $hWin
EndFunc   ;==>_WinListWait

ttmv2019sx 发表于 2021-8-19 09:56:02

afan 发表于 2021-8-19 09:38
那就再增加调试

好的。A大,我再去试试,,如果依你多年的经验来判断的话,大概会是什么引起的,因为我发现一个问题,哪就是这一些出故障的电脑,在我刚安装好系统后的情况下,都是直接可以用的,但是被他们用一段时间后就这样了,

afan 发表于 2021-8-19 12:25:35

ttmv2019sx 发表于 2021-8-19 09:56
好的。A大,我再去试试,,如果依你多年的经验来判断的话,大概会是什么引起的,因为我发现一个问题,哪 ...

我对这类操作用得很少,似乎没遇到过
上面的没针对超时,要修改下
#include <Array.au3>

Local $hWin = _WinListWait('Uninstall Microsoft Office', '下一步(&N)', 10) ;10秒内检测等待
If Not @error Then MsgBox(0, '已检测到窗口', $hWin)

Func _WinListWait($sTitle, $sText = '', $iTimeout = 0)
        Opt('WinTitleMatchMode', -1)
        Local $hWin, $aTtList, $iTs = TimerInit()
        If $iTimeout > 0 Then
                $iTimeout *= 1000
                Do
                        $hWin = WinGetHandle($sTitle, $sText)
                        If $hWin Then Return $hWin
                        $aTtList = WinList($sTitle, $sText)
                        If $aTtList Then
                                MsgBox(0, '用 WinList 检测到窗口', $aTtList)
                                Return $aTtList
                        EndIf
                        Sleep(100)
                        If TimerDiff($iTs) >= $iTimeout Then
                                Local $aList = WinList(), $aWShow, $ix = 0
                                For $i = 1 To $aList
                                        If $aList[$i] <> '' And BitAND(WinGetState($aList[$i]), 2) Then
                                                $ix += 1
                                                $aWShow[$ix] = $aList[$i]
                                                $aWShow[$ix] = $aList[$i]
                                                $aWShow[$ix] = ($aList[$i] = $sTitle)        ;测试是否与标题一致
                                        EndIf
                                Next
                                If Not $ix Then Return SetError(2, 0, 0)
                                $aWShow = $ix
                                ReDim $aWShow[$ix + 1]
                                _ArrayDisplay($aWShow, '已超时,未检测到窗口.当前可见窗口')
                                Return SetError(1, 0, 0)
                        EndIf
                Until 0
        EndIf
        Do
                $hWin = WinGetHandle($sTitle, $sText)
                If $hWin Then Return $hWin
                Sleep(100)
                $aTtList = WinList($sTitle, $sText)
                If $aTtList Then
                        MsgBox(0, '用 WinList 检测到窗口', $aTtList)
                        Return $aTtList
                EndIf
        Until 0
EndFunc   ;==>_WinListWait

ttmv2019sx 发表于 2021-8-19 14:16:01

afan 发表于 2021-8-19 09:38
那就再增加调试

A大,利用这个代码,再去扫出来的结果如图下:

afan 发表于 2021-8-19 14:27:44

ttmv2019sx 发表于 2021-8-19 14:16
A大,利用这个代码,再去扫出来的结果如图下:

用22#的代码,不要用20#的

ttmv2019sx 发表于 2021-8-19 14:44:08

afan 发表于 2021-8-19 14:27
用22#的代码,不要用20#的

好的。我再去试试。

ttmv2019sx 发表于 2021-8-23 09:00:56

afan 发表于 2021-8-19 14:27
用22#的代码,不要用20#的

A大,现在上了图是22楼,你最后调整过的代码的,请你查看一下,谢谢,但是我发现和20楼的结果显示是一样的,

afan 发表于 2021-8-23 09:28:20

ttmv2019sx 发表于 2021-8-23 09:00
A大,现在上了图是22楼,你最后调整过的代码的,请你查看一下,谢谢,但是我发现和20楼的结果显示是一样 ...

Local $hWin = _WinListWait('Uninstall Microsoft Office', '', 10) ;10秒内检测等待
这行改成以上再试试

ttmv2019sx 发表于 2021-8-23 09:51:00

afan 发表于 2021-8-23 09:28
Local $hWin = _WinListWait('Uninstall Microsoft Office', '', 10) ;10秒内检测等待
这行改成以上再试 ...

好的A版,,我下午再去试试,,谢谢你

afan 发表于 2021-8-23 09:59:36

本帖最后由 afan 于 2021-8-23 15:15 编辑

ttmv2019sx 发表于 2021-8-23 09:51
好的A版,,我下午再去试试,,谢谢你
如果改了上行仍不行那就试试下面的代码
#include <Array.au3>

Local $hWin = _WinListWait('Uninstall Microsoft Office', '下一步(&N)', 10) ;10秒内检测等待
If Not @error Then MsgBox(0, '已检测到窗口', $hWin)

Func _WinListWait($sTitle, $sText = '', $iTimeout = 0)
        Opt('WinTitleMatchMode', -1)
        Local $hWin, $iTs = TimerInit()
        If $iTimeout > 0 Then
                $iTimeout *= 1000
                Do
                        $hWin = WinGetHandle($sTitle, $sText)
                        If $hWin Then Return $hWin
                        $hWin = __WinListCk($sTitle, $sText)
                        If $hWin Then
                                MsgBox(0, '__WinListCk 已检测到窗口', $hWin)
                                Return $hWin
                        EndIf
                        Sleep(100)
                        If TimerDiff($iTs) >= $iTimeout Then
                                Local $aList = WinList(), $aWShow, $ix = 0
                                For $i = 1 To $aList
                                        If $aList[$i] <> '' And BitAND(WinGetState($aList[$i]), 2) Then
                                                $ix += 1
                                                $aWShow[$ix] = $aList[$i]
                                                $aWShow[$ix] = $aList[$i]
                                                $aWShow[$ix] = ($aList[$i] = $sTitle) ;测试是否与标题一致
                                                If $aWShow[$ix] And $sText <> '' Then
                                                        $aWShow[$ix] = StringInStr(WinGetText($aList[$i]), $sText)
                                                EndIf
                                        EndIf
                                Next
                                If Not $ix Then Return SetError(2, 0, 0)
                                $aWShow = $ix
                                ReDim $aWShow[$ix + 1]
                                _ArrayDisplay($aWShow, '已超时,未检测到窗口.当前可见窗口')
                                Return SetError(1, 0, 0)
                        EndIf
                Until 0
        EndIf
        Do
                $hWin = WinGetHandle($sTitle, $sText)
                If $hWin Then Return $hWin
                $hWin = __WinListCk($sTitle, $sText)
                If $hWin Then
                        MsgBox(0, '__WinListCk 已检测到窗口', $hWin)
                        Return $hWin
                EndIf
                Sleep(100)
        Until 0
EndFunc   ;==>_WinListWait
Func __WinListCk($sTitle, $sText)
        Local $aList = WinList()
        For $i = 1 To $aList
                If $aList[$i] <> '' And BitAND(WinGetState($aList[$i]), 2) Then
                        If StringRegExp($aList[$i], '(?i)^\Q' & $sTitle & '\E') Then
                                If $sText = '' Then Return $aList[$i]
                                If StringInStr(WinGetText($aList[$i]), $sText) Then Return $aList[$i]
                        EndIf
                EndIf
        Next
        Return SetError(1, 0, 0)
EndFunc   ;==>__WinListCk

ttmv2019sx 发表于 2021-8-23 10:00:01

afan 发表于 2021-8-23 09:28
Local $hWin = _WinListWait('Uninstall Microsoft Office', '', 10) ;10秒内检测等待
这行改成以上再试 ...

A版,如果,到时候,还是没有能找到问题所在的话,是否有其它的方法来操作这个自动化呢,因为我这个能过标题名与文字,来判断与操作,可以很有效的等待下一个界面的出现,但是句柄就不太方便,我看到了第一个界面的句柄,与点了下一步后的第二个界面的句柄是不一样的,也就是说,哪个主窗口的句柄都一直在变
页: 1 [2] 3 4
查看完整版本: 关于等窗口获取失败的情况!【已解决】