Page 2 of 2

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

Posted: 23 Sep 2016, 10:36
by tmplinshi
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及各位大侠指教

Posted: 23 Sep 2016, 11:00
by gongnl
使用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及各位大侠指教

Posted: 23 Sep 2016, 11:07
by gongnl
我的F2快捷键代码是放在脚本最后的,就是不能成功,分开就可以了,很奇怪

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

Posted: 23 Sep 2016, 20:13
by tmplinshi
好奇怪,我测试也是这样。。

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

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

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

Posted: 24 Sep 2016, 23:35
by tmplinshi
SetWinEventHook 的最后一个参数可以设置为 WINEVENT_SKIPOWNPROCESS,然而我测试并没有效果。

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

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

Code: Select all

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

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

Posted: 25 Sep 2016, 01:04
by tmplinshi
用这个 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及各位大侠指教

Posted: 25 Sep 2016, 03:11
by tmplinshi
注意:我刚修改了上面的代码一处值的错误 —— BN_CLICKED 的值应该是 0,不是 245。

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

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

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

Posted: 25 Sep 2016, 04:02
by gongnl
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: