找回密码
 加入
搜索
查看: 22323|回复: 43

[IE类操作] 内嵌IE不弹出新窗口[新成果+讨论]

 火... [复制链接]
发表于 2010-7-6 16:37:38 | 显示全部楼层 |阅读模式
目前内嵌IE“target=_blank”类型的链接直接点击会跳出Gui的问题尚未得到有效解决
论坛也有几位坛友提出讨论过,也有一定的进展:
传送门:
http://www.autoitx.com/thread-16652-1-3.html
AU3浏览器- 如何不弹出IE窗口-简单试例
http://www.autoitx.com/forum.php?mod=viewthread&tid=14316&sid=VzAdte
触摸屏浏览器!GUI内嵌IE的几个问题
http://www.autoitx.com/forum.php?mod=viewthread&tid=8144&highlight=%C4%DA%C7%B6
点击内嵌IE的链接后,如何指定一定还要在内嵌IE里来打开这个新页面

翻看了一下帮助文件-AutoIt COM 扩展
其中 IE COM 事件有一个例子[附件下载]


我修改了一下如下:
#include "GUIConstantsEx.au3"
#include <IE.au3>
Dim $Text,$EventName, $Text2
$GUIMain=GUICreate              ( "Event Test",       1000,800 )
$GUIEdit=GUICtrlCreateEdit      ( "Test Log:" & @CRLF,  10, 20, 980, 400)
$GUIProg=GUICtrlCreateProgress  (                       10,  5, 580,  10)
GUISetState ()
$oIE = _IECreateEmbedded ()
GUICtrlCreateObj($oIE,0, 421, 980, 350)
$EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents")
if @error then 
   Msgbox(0,"AutoIt COM Test", _ 
    "ObjEvent: Can't use event interface 'DWebBrowserEvents'. Error code: " & hex(@error,8))
   exit
endif
$URL = "http://www.google.com.hk/"
$oIE.Navigate( $URL )           
sleep(1000)            
GUISwitch ( $GUIMain )  
While 1
   $msg = GUIGetMsg()
   If $msg = $GUI_EVENT_CLOSE  Then ExitLoop
Wend
$EventObject.Stop   ; 不再接收事件
$EventObject=0      ; 关闭Event Object
$oIE=0              ; 清除内存
GUIDelete ()       
Exit            
Func IEEvent_BeforeNavigate($URL, $Flags, $TargetFrameName, $PostData, $Headers, $Cancel)
    GUICtrlSetData ( $GUIEdit, "BeforeNavigate: " & $URL & " Flags: " & $Flags & " tgframe: " & $TargetFrameName & " Postdat: " & $PostData & " Hdrs: " & $Headers & " canc: " & $Cancel  & @CRLF  , "append" )
EndFunc
Func IEEvent_ProgressChange($Progress,$ProgressMax)
    If $ProgressMax > 0 Then
        GUICtrlSetData($GUIProg, ($Progress * 100) / $ProgressMax )
    EndIf
EndFunc
Func IEEvent_StatusTextChange($Text)
    GUICtrlSetData ( $GUIEdit, "IE Status text changed to: " & $Text & @CRLF  , "append" )
If $Text<>'' Then $Text2=$Text
      If $EventName ='NewWindow' And $Text<>'' Then
$oIE.Navigate( $Text2 )
EndIf
EndFunc
Func IEEvent_PropertyChange( $szProperty)
    GUICtrlSetData ( $GUIEdit, "IE Changed the value of the property: " & $szProperty & @CRLF  , "append" )
EndFunc
Func IEEvent_DownloadComplete()
    GUICtrlSetData ( $GUIEdit, "IE has finished a navigation operation" & @CRLF  , "append" )
EndFunc
Func IEEvent_NavigateComplete($URL)  
    GUICtrlSetData ( $GUIEdit, "IE has finished loading URL: " & $URL & @CRLF  , "append" )
EndFunc
Func IEEvent_($EventName)  
    GUICtrlSetData ( $GUIEdit, "Uncatched event: " & $EventName & @CRLF  , "append" )
    If $EventName ='NewWindow'  Then;如果发现有IE新窗口生成
WinKill("[active]");将IE弹出激活的新窗口关闭
$oIE.Navigate( $Text2 );然后在Gui激活捕捉到状态栏显示的最后链接
EndIf
EndFunc 



关键是修改了Func IEEvent_($EventName)  这一部分
这样虽然可以在GUi打开弹出的新IE窗口链接,
虽然不完美:弹窗还会一闪而过
但总算向完美又迈进了一小步
在这里,如果有比较熟悉IE event或对此问题有兴趣的朋友,不妨跟帖讨论下,有价值的回帖一律重重加分!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×

评分

参与人数 2金钱 +52 收起 理由
大绯狼 + 22 如此强大,留名备用。
C.L + 30 支持新成果

查看全部评分

发表于 2010-7-6 23:49:48 | 显示全部楼层
#include "GUIConstantsEx.au3"
#include <IE.au3>
#include <Misc.au3>
Dim $Text,$Text2="",$URL = "http://www.baidu.com/"
$dll = DllOpen("user32.dll")
$GUIMain=GUICreate              ( "Event Test",       800,600 )
$GUIEdit=GUICtrlCreateEdit      ( "Test Log:" & @CRLF,  10, 20, 780, 270)
$StateLab = GUICtrlCreateLabel("Label1", 8, 288, 780, 17)
GUISetState ()
$oIE = _IECreateEmbedded ()
GUICtrlCreateObj($oIE,8, 320, 780, 320)
$EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents")
if @error then exit Msgbox(0,"错误!","不可使用COM接口 'DWebBrowserEvents'. 错误代码: " & hex(@error,8))
$Timer = DllCallbackRegister("Timer", "int", "hwnd;uint;uint;dword")
$TimerDLL = DllCall($dll, "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", 10, "ptr", DllCallbackGetPtr($Timer))
$oIE.Navigate( $URL )           
sleep(1000)            
GUISwitch ( $GUIMain )  
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE  Then
                $EventObject.Stop   ; 不再接收事件
                $EventObject=0      ; 关闭Event Object
                $oIE=0              ; 清除内存
                GUIDelete ()  
                DllCall($dll, "int", "KillTimer", "hwnd", 0, "uint", $TimerDLL)
                DllCallbackFree($Timer)
                DllClose($dll)
                Exit  
        EndIf
        ;这里你可以自己检测鼠标点击的是什么控件,按你的要求做相应的响应。
           If _IsPressed("1", $dll) And WinActive($GUIMain) Then
                ;我测试用延迟不管用。必须用MSGBOX断下程序执行。然后才能正常。
        MsgBox(0,"提示", "End Key Pressed",10)
                If $Text2<>"" Then $oIE.Navigate( $Text2 )     
        EndIf
Wend
;其实例子中那么多函数,真正要用到的只有这个。
Func IEEvent_StatusTextChange($Text)
    If $Text<>'' Then GUICtrlSetData ( $GUIEdit, "IE Status text changed to: " & $Text & @CRLF  , "append" )
        If $Text<>'' And StringLeft($Text,4)="http" Then $Text2=$Text
        GUICtrlSetData($StateLab,$Text)
EndFunc
Func Timer($hWnd, $uiMsg, $idEvent, $dwTime)
        If WinExists("提示") Then
                WinMove("提示","",@DesktopWidth,@DesktopHeight,0,0,1)
                Send("{Enter}")
        EndIf
EndFunc
完美解决。

评分

参与人数 1金钱 +100 贡献 +25 收起 理由
lynfr8 + 100 + 25

查看全部评分

发表于 2010-7-6 23:50:47 | 显示全部楼层
用到了一个定时器模拟多线程的函数来检测弹出对话框 并将其移走 点确定。
 楼主| 发表于 2010-7-7 00:17:49 | 显示全部楼层
用到了一个定时器模拟多线程的函数来检测弹出对话框 并将其移走 点确定。
lanfengc 发表于 2010-7-6 23:50



已经非常好了
如果能解决一闪而过的msgbox就更完美了!
 楼主| 发表于 2010-7-7 00:24:11 | 显示全部楼层
有一个方法可以解决恼人的msgbox
看代码32-34这几句:
#include "GUIConstantsEx.au3"
#include <IE.au3>
#include <Misc.au3>
Dim $Text,$Text2="",$URL = "http://www.google.com.hk/"
$dll = DllOpen("user32.dll")
$GUIMain=GUICreate              ( "Event Test",       800,600 )
$GUIEdit=GUICtrlCreateEdit      ( "Test Log:" & @CRLF,  10, 20, 780, 270)
$StateLab = GUICtrlCreateLabel("Label1", 8, 288, 780, 17)
GUISetState ()
$oIE = _IECreateEmbedded ()
GUICtrlCreateObj($oIE,8, 320, 780, 320)
$EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents")
if @error then exit Msgbox(0,"错误!","不可使用COM接口 'DWebBrowserEvents'. 错误代码: " & hex(@error,8))
$Timer = DllCallbackRegister("Timer", "int", "hwnd;uint;uint;dword")
$TimerDLL = DllCall($dll, "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", 10, "ptr", DllCallbackGetPtr($Timer))
$oIE.Navigate( $URL )           
sleep(1000)            
GUISwitch ( $GUIMain )  
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE  Then
                $EventObject.Stop   ; 不再接收事件
                $EventObject=0      ; 关闭Event Object
                $oIE=0              ; 清除内存
                GUIDelete ()  
                DllCall($dll, "int", "KillTimer", "hwnd", 0, "uint", $TimerDLL)
                DllCallbackFree($Timer)
                DllClose($dll)
                Exit  
        EndIf
           If _IsPressed("1", $dll) And WinActive($GUIMain) Then
                WinSetOnTop("Event Test", "", 1);设置置顶
        MsgBox(0,"提示", "End Key Pressed",-1000);这样弹出的MsgBox就看不见了,呵呵
                WinSetOnTop("Event Test", "", 0);解除置顶
                If $Text2<>"" Then $oIE.Navigate( $Text2 )     
        EndIf
Wend
Func IEEvent_StatusTextChange($Text)
    If $Text<>'' Then GUICtrlSetData ( $GUIEdit, "IE Status text changed to: " & $Text & @CRLF  , "append" )
        If $Text<>'' And StringLeft($Text,4)="http" Then $Text2=$Text
        GUICtrlSetData($StateLab,$Text)
EndFunc
Func Timer($hWnd, $uiMsg, $idEvent, $dwTime)
        If WinExists("提示") Then
                WinMove("提示","",@DesktopWidth,@DesktopHeight,0,0,1)
                Send("{Enter}")
        EndIf
EndFunc
不过问题还是存在:msgbox在任务栏还是会一闪而过
依然不够完美
发表于 2010-7-7 08:55:40 | 显示全部楼层
一会上班了测试下用SOUNDPLAY或者INETGET这样 的语句让程序等待返回试试。 或者RUNWAIT。
发表于 2010-7-7 08:58:05 | 显示全部楼层
对了。另外还有个问题。 。昨天发过帖子后发现的。 不管在IE控件内点什么位置,包括输入框,都会重载页面, 我的想法是检测鼠标指针图标的ID, 判断为手形状才执行IE.NAVIGATE操作。
发表于 2010-7-7 08:59:44 | 显示全部楼层
庸手一个,可耻的坐等成果
发表于 2010-7-7 09:04:27 | 显示全部楼层
回复 2# lanfengc
能给出只显示下半部分窗口的代码吗?就是GUI内嵌网页而不至于点击某连接转到浏览器上去!
发表于 2010-7-7 10:10:13 | 显示全部楼层
你说的问题和我自己遇到的问题已解决。 可是又出来个问题。IEEvent_StatusTextChange这个函数对中文支持不好。 链接中含有中文就会出现乱码。我测试的环境是windows 2003 企业版
#include "GUIConstantsEx.au3"
#include <IE.au3>
#include <Misc.au3>
#include <WinAPI.au3>
Global Const $HandCursorID=0X0001001F
Dim $Text,$Text2="",$URL = "http://www.baidu.com/"
$dll = DllOpen("user32.dll")
$GUIMain=GUICreate              ( "Event Test",       800,600 )
$GUIEdit=GUICtrlCreateEdit      ( "Test Log:" & @CRLF,  10, 20, 780, 270)
$StateLab = GUICtrlCreateLabel("Label1", 8, 288, 780, 17)
GUISetState ()
$oIE = _IECreateEmbedded ()
GUICtrlCreateObj($oIE,8, 320, 780, 320)
$EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents")
if @error then exit Msgbox(0,"错误!","不可使用COM接口 'DWebBrowserEvents'. 错误代码: " & hex(@error,8))
$Timer = DllCallbackRegister("Timer", "int", "hwnd;uint;uint;dword")
$TimerDLL = DllCall($dll, "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", 100, "ptr", DllCallbackGetPtr($Timer))
$oIE.Navigate( $URL )           
sleep(1000)            
GUISwitch ( $GUIMain )  
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE  Then
                $EventObject.Stop   ; 不再接收事件
                $EventObject=0      ; 关闭Event Object
                $oIE=0              ; 清除内存
                GUIDelete ()  
                DllCall($dll, "int", "KillTimer", "hwnd", 0, "uint", $TimerDLL)
                DllCallbackFree($Timer)
                DllClose($dll)
                Exit  
        EndIf
        ;这里你可以自己检测鼠标点击的是什么控件,按你的要求做相应的响应。
        $cursor = _WinAPI_GetCursorInfo()
        If $cursor[0]=False Then Exit MsgBox(16,"错误!","获取鼠标信息失败!")
        If $cursor[2]=$HandCursorID Then
                If _IsPressed("1", $dll) And WinActive($GUIMain) Then        
                        ;我测试用延迟不管用。必须用MSGBOX断下程序执行。然后才能正常。
                        WinSetOnTop($GUIMain,"",1)
                        MsgBox(0,"IE内嵌不新建IE窗口", "0",1,WinGetHandle("Program Manager"))
                        WinSetOnTop($GUIMain,"",0)
                        If $Text2<>""  Then $oIE.Navigate( $Text2 )     
                EndIf
        EndIf
Wend
;其实例子中那么多函数,真正要用到的只有这个。
Func IEEvent_StatusTextChange($Text)
    If $Text<>'' And $Text<>'完成' And $Text<>'完毕' Then GUICtrlSetData ( $GUIEdit, "IE Status text changed to: " & $Text & @CRLF  , "append" )
        If $Text<>'' And StringLeft($Text,4)="http" Then $Text2=$Text
        GUICtrlSetData($StateLab,$Text)
EndFunc
Func Timer($hWnd, $uiMsg, $idEvent, $dwTime)
        If WinExists("IE内嵌不新建IE窗口") Then
                WinMove("IE内嵌不新建IE窗口","",@DesktopWidth,@DesktopHeight,0,0,1)
                Send("{Enter}")
        EndIf
EndFunc

评分

参与人数 2金钱 +130 贡献 +15 收起 理由
lynfr8 + 100 + 15
C.L + 30 很完美,学习了

查看全部评分

发表于 2010-7-7 10:13:16 | 显示全部楼层
主要是用了_WinAPI_GetCursorInfo() 获取鼠标信息,检测鼠标指针ID为手形才执行检测点击链接操作。 另外,MSGBOX可以通过设置它的父窗口句柄为桌面句柄,任务栏就不会出现一闪而过的窗口了。 代码为MsgBox(0,"IE内嵌不新建IE窗口", "0",1,WinGetHandle("Program Manager")),这个对话框的标题尽量设置的复杂点,防止定时器检测的时候把别的窗口也检测到了,一直对别的窗口发按键。

评分

参与人数 1金钱 +5 贡献 +1 收起 理由
lynfr8 + 5 + 1

查看全部评分

发表于 2010-7-7 10:30:45 | 显示全部楼层
回复 9# newuser


    代码就在那放着呢。。自己改了 才有意义呀。。
发表于 2010-7-7 10:32:42 | 显示全部楼层
有一个方法可以解决恼人的msgbox
看代码32-34这几句:不过问题还是存在:msgbox在任务栏还是会一闪而过
依 ...
lynfr8 发表于 2010-7-7 00:24



    如何关闭里边的网页呢??关闭 不是从新打开。。 about:blank
发表于 2010-7-7 14:04:39 | 显示全部楼层
本帖最后由 newuser 于 2010-7-7 14:18 编辑

回复 12# woeiwoei
这是我的理解,但还是不懂,我想把EDIT控件给屏蔽了不就看不到EVENT LOG了吗?但该怎么做呢?确实水平有限,他里面的2个函数我都没看懂,能在帮助把该代码的编写思路给理清一下吗?
#include "GUIConstantsEx.au3"
#include "GUIConstantsEx.au3"
#include <IE.au3>
#include <Misc.au3>
#include <WinAPI.au3>
Global Const $HandCursorID=0X0001001F
Dim $Text,$Text2="",$URL = "http://www.baidu.com/"
$dll = DllOpen("user32.dll")  ;打开指定的DLL文件以供DllCall()函数调用
$GUIMain=GUICreate              ( "Event Test",       800,600 );创建主窗口
$GUIEdit=GUICtrlCreateEdit      ( "Test Log:" & @CRLF,  10, 20, 780, 270)  ;在主窗口上创建一个Edit控件 
;这个Edit控件应该是显示事件的日志信息 
$StateLab = GUICtrlCreateLabel("Label1", 8, 288, 780, 17) ;在主窗口上创建一个静态标签控件
;这个标签难道是:当鼠标在不同的连接地址移动时,获得连接地址上的文字?
GUISetState () ;显示当前窗口
$oIE = _IECreateEmbedded ();创建一个适合于内嵌在AU3的图形化界面的浏览器对象,该图形化界面必须是由GUICtrlCreateObj()建立
GUICtrlCreateObj($oIE,8, 320, 780, 320) ;创建适合浏览器对象内嵌的图形化界面
$EventObject=ObjEvent($oIE,"IEEvent_","DWebBrowserEvents") ;包含一个已经得到的对象(object)的事件句柄
;IEEvent  函数前缀,用来处理收到的事件
;DWebBrowserEvents 接口名称
if @error then exit Msgbox(0,"错误!","不可使用COM接口 'DWebBrowserEvents'. 错误代码: " & hex(@error,8))
$Timer = DllCallbackRegister("Timer", "int", "hwnd;uint;uint;dword")
;DllCallbackRegister() 创建一个用户自定义的回调函数
;语法:DllCallbackRegister ( "函数名", "返回类型", "参数" )
$TimerDLL = DllCall($dll, "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", 100, "ptr", DllCallbackGetPtr($Timer))
;DllCall() 调用指定Dll文件里面的函数
;语法 :DllCall ( "dll", "返回值类型", "函数名称" [, "类型1", 参数1[, "类型n", 参数n]] )
;DllCallbackGetPtr($Timer) 返回回调函数的指针,可以用于传递给一个WIN32 API
$oIE.Navigate( $URL ) ;打开指定连接地址          
sleep(1000)            
GUISwitch ( $GUIMain )  ;切换用于GUI函数“当前”的窗口
While 1
    $msg = GUIGetMsg()
        If $msg = $GUI_EVENT_CLOSE  Then
                $EventObject.Stop   ; 不再接收事件
                $EventObject=0      ; 关闭Event Object
                $oIE=0              ; 清除内存
                GUIDelete ()  
                DllCall($dll, "int", "KillTimer", "hwnd", 0, "uint", $TimerDLL)
                DllCallbackFree($Timer) ;清除先前由DllCallbackRegister()创建的句柄
                DllClose($dll) ;将先前打开的User32.dll文件关闭 
                Exit  
        EndIf
        ;这里你可以自己检测鼠标点击的是什么控件,按你的要求做相应的响应。
        $cursor = _WinAPI_GetCursorInfo()
        If $cursor[0]=False Then Exit MsgBox(16,"错误!","获取鼠标信息失败!")
        If $cursor[2]=$HandCursorID Then
                If _IsPressed("1", $dll) And WinActive($GUIMain) Then        
                        ;_IsPressed("1", $dll) 检查按键是否被按下,1表示按下,反之0。
                                                ;我测试用延迟不管用。必须用MSGBOX断下程序执行。然后才能正常。
                        WinSetOnTop($GUIMain,"",1) 
                                                ;设定指定窗口总是在顶层,1表示在顶层
                                                ;语法:WinSetOnTop ( "窗口标题", "窗口文本", 标志 ) 
                        MsgBox(0,"IE内嵌不新建IE窗口", "0",1,WinGetHandle("Program Manager"))
                        WinSetOnTop($GUIMain,"",0)
                        If $Text2<>""  Then $oIE.Navigate( $Text2 )     
                EndIf
        EndIf
Wend
;其实例子中那么多函数,真正要用到的只有这个。
Func IEEvent_StatusTextChange($Text)
    If $Text<>'' And $Text<>'完成' And $Text<>'完毕' Then GUICtrlSetData ( $GUIEdit, "IE Status text changed to: " & $Text & @CRLF  , "append" )
        If $Text<>'' And StringLeft($Text,4)="http" Then $Text2=$Text
        GUICtrlSetData($StateLab,$Text)
EndFunc
Func Timer($hWnd, $uiMsg, $idEvent, $dwTime)
        If WinExists("IE内嵌不新建IE窗口") Then
                WinMove("IE内嵌不新建IE窗口","",@DesktopWidth,@DesktopHeight,0,0,1)
                Send("{Enter}")
        EndIf
EndFunc

评分

参与人数 1金钱 +6 贡献 +2 收起 理由
lynfr8 + 6 + 2

查看全部评分

发表于 2010-7-7 15:23:30 | 显示全部楼层
非常不错,学习了
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-16 18:26 , Processed in 0.093389 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表