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版,如果,到时候,还是没有能找到问题所在的话,是否有其它的方法来操作这个自动化呢,因为我这个能过标题名与文字,来判断与操作,可以很有效的等待下一个界面的出现,但是句柄就不太方便,我看到了第一个界面的句柄,与点了下一步后的第二个界面的句柄是不一样的,也就是说,哪个主窗口的句柄都一直在变