对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post a reply


In an effort to prevent automatic submissions, we require that you complete the following challenge.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 25 Sep 2016, 04:02

tmplinshi wrote:SetWinEventHook 的最后一个参数可以设置为 WINEVENT_SKIPOWNPROCESS,然而我测试并没有效果。

你用快捷键能成功,是因为你按快捷键的时候 GUI 界面处于非激活状态。

如果 GUI 界面处于非激活状态,按钮和快捷键都能成功:

Code: Select all

Button确认:
f12::
	WinActivate, ahk_class IEFrame
	Pwb := WBGet()
	Pwb.document.getElementById("saveButton").click()
return
确实如此 :thumbup: :thumbup: :thumbup:

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 25 Sep 2016, 03:27

对于本问题解决确实是使用excScript改写confirm函数最完美的解决方案,简单高效快速,我只是对大神提供的方案很感兴趣想研究一下多向您讨教几招呵呵,多谢您的热心指教,除了感谢还是感谢了 :lol: :lol:

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 25 Sep 2016, 03:11

注意:我刚修改了上面的代码一处值的错误 —— BN_CLICKED 的值应该是 0,不是 245。

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 25 Sep 2016, 01:04

用这个 CbtHook_32.dll 可以解决

Code: Select all

#NoEnv
#Persistent
SetBatchLines, -1
DetectHiddenWindows, On
#SingleInstance, force
OnExit, QUIT

Gui, Add, Button, w400 h100, 确认
Gui, Show

sMsg := "CYRUZ_CBTHOOK_MSG_HCBT_ACTIVATE"
nMsg := DllCall( "RegisterWindowMessage", Str,sMsg )
OnMessage(nMsg, "test")

hDll := DllCall( "LoadLibrary", Str,"CbtHook_32.dll" )
DllCall( "CbtHook_32.dll\SetCbtHook", Ptr,A_ScriptHwnd, UInt,0 )
Return

test(wParam, lParam, msg, hWnd) {
	static WM_COMMAND := 0x0111
	     , BN_CLICKED := 0
	     , IDOK := 1

	Critical
	WinGetTitle, sTitle, ahk_id %wParam%
	if (sTitle = "来自网页的消息") {
		PostMessage, WM_COMMAND, (BN_CLICKED << 16) | IDOK, 0,, ahk_id %wParam%
	}
}

Button确认:
	Pwb := WBGet()
	Pwb.document.getElementById("saveButton").click()
return

GuiClose:
ExitApp

QUIT:
	DllCall( "CbtHook_32.dll\UnsetCbtHook" )
ExitApp
其实改写 confirm 函数的方法最适合你啊,一句话就搞定。

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 24 Sep 2016, 23:35

SetWinEventHook 的最后一个参数可以设置为 WINEVENT_SKIPOWNPROCESS,然而我测试并没有效果。

你用快捷键能成功,是因为你按快捷键的时候 GUI 界面处于非激活状态。

如果 GUI 界面处于非激活状态,按钮和快捷键都能成功:

Code: Select all

Button确认:
f12::
	WinActivate, ahk_class IEFrame
	Pwb := WBGet()
	Pwb.document.getElementById("saveButton").click()
return

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 24 Sep 2016, 21:57

tmplinshi,是不是WinEventHook 只能监测其他进程的消息,不能监测自己进程发出的消息,才会出现代码合在一起不能成功的原因,但WinEventHook代码 和 F2::热键代码合在一个脚本可以自动检测到弹出对话框并确认,把F2热键改为 gui 定义的一个按钮调用就不成功了,怎么解释呢?

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 20:13

好奇怪,我测试也是这样。。

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 23 Sep 2016, 11:07

我的F2快捷键代码是放在脚本最后的,就是不能成功,分开就可以了,很奇怪

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 23 Sep 2016, 11:00

使用execScript("function confirm(){return true}")脚本测试成功,开始没有理解execScript语句的原理,经过tmplinshi大神的解释和演示的例子的理解,已经成功可以对弹出的对话框自动确认,就是调用完exceScript语句后再执行getElementById("saveButton").click()就行了,脚本如下:

Code: Select all

F2::
	Pwb := WBGet()
	pwb.document.parentWindow.execScript("function confirm(){return true}")
	sleep,100
	Pwb.document.getElementById("saveButton").click()
return
另外还想请教一下,WinEventHook代码 和 F2::热键代码合在一个脚本可以自动检测到弹出对话框并确认,把F2热键改为 gui 定义的一个按钮调用就不成功了什么原因?

Code: Select all

Gui, Add, Button,x266 y6 w48 h26,确认 
...
Button确认:
	try{
		Pwb := WBGet()
		Pwb.document.getElementById("saveButton").click()
	}
return

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 10:36

gongnl wrote:
tmplinshi wrote:你顶楼的代码还要加上等待“来自网页的消息”窗口出现才能成功。

32772 是 HSHELL_RUDEAPPACTIVATED 事件,在窗口激活时产生。最好是用另外一个消息 HSHELL_WINDOWCREATED,从名字可知道是窗口创建时产生。

Code: Select all

#NoEnv
#Persistent
SetBatchLines, -1

DllCall("RegisterShellHookWindow", "ptr", A_ScriptHwnd)
msgNum := DllCall("RegisterWindowMessage", "str", "SHELLHOOK")
OnMessage(msgNum, "ShellProc")
return

ShellProc(wParam, lParam) {
	if (wParam = 1) { ; HSHELL_WINDOWCREATED = 1
		WinGetClass, className, ahk_id %lParam%
		if (className = "Alternate Modal Top Most") {
			WinWait, 来自网页的消息
			ControlSend,, {Enter}
		}
	}
}
个人认为这个方法没有 WinEventHook 的方法好,毕竟这是监测窗口创建,而 WinEventHook 可以只监测 EVENT_SYSTEM_ALERT 消息。
图片可以上传到 http://upload.otar.im/
如果我把上面的代码和

Code: Select all

F2::
	Pwb := WBGet()
	Pwb.document.getElementById("saveButton").click()
return
放在一个脚本,就不能自动确认弹出对话框,分别运行就可以了,有办法能合在一起吗?
我猜你是把快捷键这段代码放在顶部了吧,这样的话,后面的代码就不会在脚本启动时执行了。
解决方法:把快捷键的代码放在文件尾部即可。

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 10:33

gongnl wrote: 本来对弹出的对话框确认后会执行后面的语句,如果改写后直接会收到【确定】的结果,但confirm()后面的{document.frm.action="….”; document.frm.submit();} 也执行不了,就不是没有意义了吗?
我测试是没有问题的。测试代码:

Code: Select all

Gui, Font, s15, 微软雅黑
Gui, Add, ActiveX, w600 h300 vwb, Shell.Explorer
Gui, Add, Button, w200, 测试
Gui, Show

wb.Navigate("about:tabs")
wb.document.write( html() )
Return

Button测试:
	wb.document.parentWindow.execScript("function confirm(){return true}")
	wb.document.getElementById("saveButton").click()
return

GuiClose:
ExitApp

html() {
	html =
	(
		<html>
			<script>
				function save() {
					if(confirm("确认保存?")){
						document.getElementById('result').innerText = "成功";
					}
				}
			</script>
			
			<input type=button id="saveButton" onclick="save()" value="保存" />
			<p>结果: <span id=result></span>
		</html>
	)
	return html
}

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 23 Sep 2016, 10:28

tmplinshi wrote:你顶楼的代码还要加上等待“来自网页的消息”窗口出现才能成功。

32772 是 HSHELL_RUDEAPPACTIVATED 事件,在窗口激活时产生。最好是用另外一个消息 HSHELL_WINDOWCREATED,从名字可知道是窗口创建时产生。

Code: Select all

#NoEnv
#Persistent
SetBatchLines, -1

DllCall("RegisterShellHookWindow", "ptr", A_ScriptHwnd)
msgNum := DllCall("RegisterWindowMessage", "str", "SHELLHOOK")
OnMessage(msgNum, "ShellProc")
return

ShellProc(wParam, lParam) {
	if (wParam = 1) { ; HSHELL_WINDOWCREATED = 1
		WinGetClass, className, ahk_id %lParam%
		if (className = "Alternate Modal Top Most") {
			WinWait, 来自网页的消息
			ControlSend,, {Enter}
		}
	}
}
个人认为这个方法没有 WinEventHook 的方法好,毕竟这是监测窗口创建,而 WinEventHook 可以只监测 EVENT_SYSTEM_ALERT 消息。
图片可以上传到 http://upload.otar.im/
如果我把上面的代码和

Code: Select all

F2::
	Pwb := WBGet()
	Pwb.document.getElementById("saveButton").click()
return
放在一个脚本,就不能自动确认弹出对话框,分别运行就可以了,有办法能合在一起吗?

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 23 Sep 2016, 10:10

tmplinshi wrote:
gongnl wrote: 我使用execScript("function confirm(){return true}") 试了根本没有 反应,并且 confirm()后面的{document.frm.action="….”; document.frm.submit();} 也执行不了
确实不会有任何反应。这个代码只是改写了 confirm() 函数,只有在网页调用 confirm() 函数时才有效果。比如没有改写之前 confirm("确认保存?") 会弹出一个对话框,而改写后这个对话框就不会弹出来了,直接会收到【确定】的结果。
本来对弹出的对话框确认后会执行后面的语句,如果改写后直接会收到【确定】的结果,但confirm()后面的{document.frm.action="….”; document.frm.submit();} 也执行不了,就不是没有意义了吗?

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 09:58

wb.document.parentWindow.execScript("function confirm(){return true}")
需要注意的是,这个代码是修改网页源码。也就是要等网页打开后再执行,并且如果你刷新了网页也需要再次执行。

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 09:52

gongnl wrote: 我使用execScript("function confirm(){return true}") 试了根本没有 反应,并且 confirm()后面的{document.frm.action="….”; document.frm.submit();} 也执行不了
确实不会有任何反应。这个代码只是改写了 confirm() 函数,只有在网页调用 confirm() 函数时才有效果。比如没有改写之前 confirm("确认保存?") 会弹出一个对话框,而改写后这个对话框就不会弹出来了,直接会收到【确定】的结果。

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 23 Sep 2016, 09:47

tmplinshi wrote:
gongnl wrote:wb.document.parentWindow.execScript("function confirm(){return true}") 我试了好像无效,不会调用 网页内的save()函数
这句代码的作用是改写 confirm 函数,让它直接返回 true。这样当网页调用了 confirm 时就会直接得到选择了【确定】的结果,而达到了你标题“弹出的对话框自动确认”的目的。

我上面写的三种方法都是只实现“弹出的对话框自动确认”。
我使用execScript("function confirm(){return true}") 试了根本没有 反应,并且 confirm()后面的{document.frm.action="….”; document.frm.submit();} 也执行不了

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 09:44

这个脚本可用来查看 ShellHook 消息:
https://autohotkey.com/board/topic/3262 ... -messages/

Image

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 09:39

gongnl wrote:wb.document.parentWindow.execScript("function confirm(){return true}") 我试了好像无效,不会调用 网页内的save()函数
这句代码的作用是改写 confirm 函数,让它直接返回 true。这样当网页调用了 confirm 时就会直接得到选择了【确定】的结果,而达到了你标题“弹出的对话框自动确认”的目的。

我上面写的三种方法都是只实现“弹出的对话框自动确认”。如果要调用 save() 函数,试试这样:

Code: Select all

wb.document.parentWindow.execScript("save()")

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by tmplinshi » 23 Sep 2016, 09:33

你顶楼的代码还要加上等待“来自网页的消息”窗口出现才能成功。

32772 是 HSHELL_RUDEAPPACTIVATED 事件,在窗口激活时产生。最好是用另外一个消息 HSHELL_WINDOWCREATED,从名字可知道是窗口创建时产生。

Code: Select all

#NoEnv
#Persistent
SetBatchLines, -1

DllCall("RegisterShellHookWindow", "ptr", A_ScriptHwnd)
msgNum := DllCall("RegisterWindowMessage", "str", "SHELLHOOK")
OnMessage(msgNum, "ShellProc")
return

ShellProc(wParam, lParam) {
	if (wParam = 1) { ; HSHELL_WINDOWCREATED = 1
		WinGetClass, className, ahk_id %lParam%
		if (className = "Alternate Modal Top Most") {
			WinWait, 来自网页的消息
			ControlSend,, {Enter}
		}
	}
}
个人认为这个方法没有 WinEventHook 的方法好,毕竟这是监测窗口创建,而 WinEventHook 可以只监测 EVENT_SYSTEM_ALERT 消息。
图片可以上传到 http://upload.otar.im/

Re: 对弹出的对话框自动确认,却一直无法成功,请求tmplinshi及各位大侠指教

Post by gongnl » 23 Sep 2016, 09:22

wb.document.parentWindow.execScript("function confirm(){return true}") 我试了好像无效,不会调用 网页内的save()函数

Top