Sign in to follow this  
Followers 0
wisheu

COM & Events (Shell.Explorer.2 object -> MS Webbrowser control)

18 posts in this topic

Hi,

I have here a very simple code example:

#include <GUIConstants.au3>

$oIE = ObjCreate ("Shell.Explorer.2")                                                                           ; create Shell.Explorer.2 object
$GUI = GUICreate ("Embedded IE-Webbrowser", 830, 500, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS); Create a simple GUI
$GUIIE = GUICtrlCreateObj ($oIE, 1, 1 , 829 , 499)                                                              ; embed Shell.Explorer.2 object in GUI
$oIEEvents = ObjEvent ($oIE,"IEEvent","DWebBrowserEvents2")                                                     ; Assign events to functions starting with IEEvent      

$oIE.navigate ("www.microsoft.com")                                                                             ; navigate to www.microsoft.com
While $oIE.busy 
    Sleep (30)                                                                                                  ; Idle around while site is loading
WEnd

Sleep (5000)                                                                                                    ; Sleep vor 5 seconds and then ...
Exit                                                                                                            ; ... exit

And my question is: How could I implement the BeforeNavigate2 event so that I can cancel a navigation?

The reference for the webbrowser control is here: http://msdn.microsoft.com/library/default...._node_entry.asp

and the reference for the BeforNavigate2 event is here: http://msdn.microsoft.com/workshop/browser...renavigate2.asp

I was already able to receive all parameters but when I try to give a parameter back or implement it as ByRef then the script simply crashes!

Here is a example for my event handler:

; Event: Will be called before a navigation starts
Func IEEventBeforeNavigate2 ($IEpDisp, $IEURL, $IEFlags, $IETargetFrameName, $IEPostData, $IEHeaders, ByRef $IECancel)
    $IECancel = False   ; Dummy - Until I add other code
EndFunc

Perhaps now everybody knows what I mean and perhaps somebody knows a solution for my problem...

Thanks in advance

Michael

Share this post


Link to post
Share on other sites



Michael,

It isn't the script that is crashing, it is AutoIt that is crashing with an unhandled error.

You need to put together a code snipet that reproduces the failure (stick your event handler in the code below) and create and entry in the V3 Bugs forum.

Error signature

AppName: autoit3.exe AppVer: 3.1.1.86 ModName: autoit3.exe

ModVer: 3.1.1.86 Offset: 0003d45c

Dale

Hi,

I have here a very simple code example:

#include <GUIConstants.au3>

$oIE = ObjCreate ("Shell.Explorer.2")                                                                            ; create Shell.Explorer.2 object
$GUI = GUICreate ("Embedded IE-Webbrowser", 830, 500, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS); Create a simple GUI
$GUIIE = GUICtrlCreateObj ($oIE, 1, 1 , 829 , 499)                                                                ; embed Shell.Explorer.2 object in GUI
$oIEEvents = ObjEvent ($oIE,"IEEvent","DWebBrowserEvents2")                                                     ; Assign events to functions starting with IEEvent        

$oIE.navigate ("www.microsoft.com")                                                                                ; navigate to www.microsoft.com
While $oIE.busy 
    Sleep (30)                                                                                                

    ; Idle around while site is loading
WEnd

Sleep (5000)                                                                                                

    ; Sleep vor 5 seconds and then ...
Exit                                                                                                

            ; ... exit

And my question is: How could I implement the BeforeNavigate2 event so that I can cancel a navigation?

The reference for the webbrowser control is here: http://msdn.microsoft.com/library/default...._node_entry.asp

and the reference for the BeforNavigate2 event is here: http://msdn.microsoft.com/workshop/browser...renavigate2.asp

I was already able to receive all parameters but when I try to give a parameter back or implement it as ByRef then the script simply crashes!

Here is a example for my event handler:

; Event: Will be called before a navigation starts
Func IEEventBeforeNavigate2 ($IEpDisp, $IEURL, $IEFlags, $IETargetFrameName, $IEPostData, $IEHeaders, ByRef $IECancel)
    $IECancel = False  ; Dummy - Until I add other code
EndFunc

Perhaps now everybody knows what I mean and perhaps somebody knows a solution for my problem...

Thanks in advance

Michael


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

Michael,

It isn't the script that is crashing, it is AutoIt that is crashing with an unhandled error.

You need to put together a code snipet that reproduces the failure (stick your event handler in the code below) and create and entry in the V3 Bugs forum.

Dale

Well I do remember somewhere back in time that I read something about 'DWebBrowserEvents2' is only available to the InternetExplorer.Application.1 com object but I lost track on this one - but with all the browsers around, not every events is available to all and the Shell.Explorer.2 is one of the oldest and basic ones around BUT...

With an com object you could find that an object shows up and works basicly but events is non functional as this particulare language is not in the target area ( basic, C++, net or HTML ) and I don't know what SvenP did target his functions with but it shure looks like basic interface BUT still how he did interface com objects to something as these object always has an target area, he has to answer to that one when he come home from 'south of china', a second com object is needed to interface or simply that the object functions is not available to this particulare object when used in this manner - sniff around the INet is my adwise simple as that...

ActiveX object interface is one of the hardest thing to interface and SvenP did a ereal great job - hope he returns...

kjactive

Share this post


Link to post
Share on other sites

Hi kjactive,

Well I do remember somewhere back in time that I read something about 'DWebBrowserEvents2' is only available to the InternetExplorer.Application.1 com object but I lost track on this one - but with all the browsers around, not every events is available to all and the Shell.Explorer.2 is one of the oldest and basic ones around BUT...

Relying on the documentation of MSDN Shell.Explorer.2 also supports the BeforeNavigate2 event and as long as I didn't try to give a parameter back to the control it works perfect. But in order to get the full functionallity of BeforeNavigate2 I must give the Cancel Parameter back to the control. I've tried this by adding ByRef to the Parameter but when I do that and the event happens AutoIt crashes. It seems that this is a circumstance which is not implementet in AutoIt and so I'll raise a crash.

With an com object you could find that an object shows up and works basicly but events is non functional as this particulare language is not in the target area ( basic, C++, net or HTML ) and I don't know what SvenP did target his functions with but it shure looks like basic interface BUT still how he did interface com objects to something as these object always has an target area, he has to answer to that one when he come home from 'south of china', a second com object is needed to interface or simply that the object functions is not available to this particulare object when used in this manner - sniff around the INet is my adwise simple as that...

I've "sniffed" around the INet and the forum a lot... But I haven't found a solution. But the Webbrowser control is well documentated at MSDN and there is noticed that the Cancel parameter is designed as pointer and to be readable and writeable. I simply have no idea how this could be done with AutoIt and tested the ByRef keyword with my event hanlder. And this ByRef raises a crash. It simply seems that noone had this before. Should I ask SvenP directly?

ActiveX object interface is one of the hardest thing to interface and SvenP did a ereal great job - hope he returns...

I completly belief this!

Best regards

Michael

Share this post


Link to post
Share on other sites

@Dale

Hi Dale,

I will open a bug report with the following code:

; Test script to embed an Shell.Explorer.2 (MS WebBrowser) control into an AutoIt GUI
 ;
; Reference for the control under: http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/browser_control_node_entry.asp
; Reference for the BefroreNavigate2 event under: http://msdn.microsoft.com/workshop/browser/webbrowser/reference/ifaces/dwebbrowserevents2/beforenavigate2.asp
 ;
 ; Error description:
; In order to have the full functionallity of the BeforeNavigate2 event it is needed to have the $IECancel paramter read and writeable. This parameter
; is documented as read and writeable but it is nowwhere documented how this is done in AutoIt. So I've tried to the ByRef keyword and this causes a
; crash of AutoIt. The Code below will reproduce this crash and when the ByRef keyword is removed then the code will work but there is still no possibillity
 ; to cancel the navigation.
  
  #include <GUIConstants.au3>
  
 ; Event: Will be called before a navigation starts
 Func IEEventBeforeNavigate2 ($IEpDisp, $IEURL, $IEFlags, $IETargetFrameName, $IEPostData, $IEHeaders, ByRef $IECancel)   ; Remove ByRef and it will work
     $IECancel = True                                                                                                     ; Dummy - Until I add other code
  EndFunc
  
 ; Begin of the main code
 $oIE = ObjCreate ("Shell.Explorer.2")                                                                                 ; create Shell.Explorer.2 object
 $GUI = GUICreate ("Embedded IE-Webbrowser", 830, 500, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS)   ; Create a simple GUI
 $GUIIE = GUICtrlCreateObj ($oIE, 1, 1 , 829 , 499)                                                                    ; embed Shell.Explorer.2 object in GUI
 $oIEEvents = ObjEvent ($oIE,"IEEvent","DWebBrowserEvents2")                                                            ; Assign events to functions starting with IEEvent      
  
 $oIE.navigate ("www.microsoft.com")                                                                                       ; navigate to www.microsoft.com
  While $oIE.busy
     Sleep (30)                                                                                                        ; Idle around while site is loading
  WEnd
  
 Sleep (5000)                                                                                                          ; Sleep vor 5 seconds and then ...
 Exit                                                                                                                  ; ... exit
 ; End of the main code

Best regards

Michael

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

@Dale

Hi Dale,

I will open a bug report with the following code:

Michael,

I think that is a lot more complicated than it needs to be. I get the failure with a much simpler piece of code -- not even using the ActiveX embedding:

$oIE = ObjCreate ("InternetExplorer.Application")
$oIE.visible = 1
$oIEEvents = ObjEvent ($oIE,"IEEvent_","DWebBrowserEvents2")

$oIE.navigate ("www.microsoft.com")

While $oIE.busy 
    Sleep(30)                                                                      
WEnd                                                                                             

Exit                                                                                                



Func IEEvent_BeforeNavigate2 ($IEpDisp, $IEURL, $IEFlags, $IETargetFrameName, $IEPostData, $IEHeaders, ByRef $IECancel)
    ;;;
EndFunc

Error signature
AppName: autoit3.exe     AppVer: 3.1.1.86    ModName: autoit3.exe
ModVer: 3.1.1.86     Offset: 0003d45c

Exception Information
Code: 0xc0000005    Flags: 0x00000000
Record: 0x0000000000000000  Address: 0x000000000043d45c

System Information
Windows NT 5.1 Build: 2600
CPU Vendor Code: 756E6547 - 49656E69 - 6C65746E
CPU Version: 00000673  CPU Feature Code: 0383F9FF
CPU AMD Feature Code: 00B5E824

Module 1
autoit3.exe
Image Base: 0x00400000  Image Size: 0x00000000
Checksum: 0x00000000    Time Stamp: 0x436a8a4b
Version Information


 Signature: feef04bd
 StrucVer:  00010000
 FileVer:   (3.1:1.86)
 ProdVer:   (3.1:1.86)
 FlagMask:  00000017
 Flags:     00000000
 OS:        00000004
 FileType:  00000000
 SubType:   00000000
 FileDate:  00000000:00000000

Don't make the bug report more complex than it needs to be or the devs will spend a lot of unnecessary debugging time.

Dale

Edited by DaleHohm

Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I think that the trouble could be that the "DWebBrowserEvents2" is nonfunctional here for some reason - try to add another simple event like DownloadBegin, this should be fired everytime a navigation operation is beginning if the browser has the cache option set to on ( default ) BUT it don't with "DWebBrowserEvents2" try then to change to "DWebBrowserEvents" and it fires up more than ones...

"DWebBrowserEvents2" is for browsers higher than rev. 3 but for compatible settings "DWebBrowserEvents" is still fired on higher revisions but has some lacks in functions...

I still remember something about "DWebBrowserEvents2" was not available to all browsers / in any conditions for some reason but I don't recall where...

Func IEEvent_DownloadBegin()
    ConsoleWrite('Download done...' & @CR)
EndFunc

Don't you two devoted programmers get a lot of hanging objects, not freeing the objects and events handle processes, I do running your scripts NOTE: that Internetexplorer object has a special quit metrod as it got a IE.Quit function to Close the object while the WebBrowser object ignores this method, overall these two objects look alike but they are not target to the same purpose and one has to be very carefull reading documentation as these two objects are totally mixed together...

About the ByRef - it crashes the script alright but I read that one has to stop the browsing with IE.Stop before changing the Cancel flag but this didn't prevent the crash...

kjactive B)

Edited by kjactive

Share this post


Link to post
Share on other sites

I think that the trouble could be that the "DWebBrowserEvents2" is nonfunctional here for some reason - try to add another simple event like DownloadBegin, this should be fired everytime a navigation operation is beginning if the browser has the cache option set to on ( default ) BUT it don't with "DWebBrowserEvents2" try then to change to "DWebBrowserEvents" and it fires up more than ones...

There are two issues. One is trying to find wisheu a workaround for what he is trying to accomplish. With this issue we can try different event classes and other creative ideas to get it working. The second however is that AutoIt (rather than his script) is crashing. This is not a matter of whether the correct event class is being used or even if it is being used correctly -- AutoIt needs to either correct a problem if it is handling this improperly or it needs to trap the error, give the user an error message and exit gracefully. The bug report that will get filed for this shortly is about this second issue, not the first.

Don't you two devoted programmers get a lot of hanging objects, not freeing the objects and events handle processes, I do running your scripts

No, not when using the InternetExplorer.Application object as in the previous example. Unless the coder make a mistake and leaves it invisible, there is a WebBrowser UI left on the screen with a File->Exit menu function that makes it easy to release everything. You make a valid point about claenup, but that is not what this topic is about.

Dale


Free Internet Tools: DebugBar, AutoIt IE Builder, HTTP UDF, MODIV2, IE Developer Toolbar, IEDocMon, Fiddler, HTML Validator, WGet, curl

MSDN docs: InternetExplorer Object, Document Object, Overviews and Tutorials, DHTML Objects, DHTML Events, WinHttpRequest, XmlHttpRequest, Cross-Frame Scripting, Office object model

Automate input type=file (Related)

Alternative to _IECreateEmbedded? better: _IECreatePseudoEmbedded  Better Better?

IE.au3 issues with Vista - Workarounds

SciTe Debug mode - it's magic: #AutoIt3Wrapper_run_debug_mode=Y Doesn't work needs to be ripped out of the troubleshooting lexicon. It means that what you tried did not produce the results you expected. It begs the questions 1) what did you try?, 2) what did you expect? and 3) what happened instead?

Reproducer: a small (the smallest?) piece of stand-alone code that demonstrates your trouble

Share this post


Link to post
Share on other sites

I sometime use a walkaround with com object that trap some crashes: trap autoit errors events

$Errorhandle = ObjEvent("AutoIt.Error","MyErrFunc"); init the event handle

Func Errorhandle()
    ; one could trap/insert some error messages here
EndFunc

About cleaning up code/free objects and libraries: if one leave a browser unfreed and this is set as target one has a problem and I really don't understand why one don't free an object proper in the script...

A dirty walk around but working...

kjactive B)

Share this post


Link to post
Share on other sites

Michael,

I think that is a lot more complicated than it needs to be. I get the failure with a much simpler piece of code -- not even using the ActiveX embedding:

$oIE = ObjCreate ("InternetExplorer.Application")
$oIE.visible = 1
$oIEEvents = ObjEvent ($oIE,"IEEvent_","DWebBrowserEvents2")

$oIE.navigate ("www.microsoft.com")

While $oIE.busy 
    Sleep(30)                                                                      
WEnd                                                                                             

Exit                                                                                                



Func IEEvent_BeforeNavigate2 ($IEpDisp, $IEURL, $IEFlags, $IETargetFrameName, $IEPostData, $IEHeaders, ByRef $IECancel)
    ;;;
EndFunc

Error signature
AppName: autoit3.exe     AppVer: 3.1.1.86     ModName: autoit3.exe
ModVer: 3.1.1.86     Offset: 0003d45c

Exception Information
Code: 0xc0000005    Flags: 0x00000000
Record: 0x0000000000000000    Address: 0x000000000043d45c

System Information
Windows NT 5.1 Build: 2600
CPU Vendor Code: 756E6547 - 49656E69 - 6C65746E
CPU Version: 00000673  CPU Feature Code: 0383F9FF
CPU AMD Feature Code: 00B5E824

Module 1
autoit3.exe
Image Base: 0x00400000    Image Size: 0x00000000
Checksum: 0x00000000    Time Stamp: 0x436a8a4b
Version Information
 Signature:    feef04bd
 StrucVer:    00010000
 FileVer:    (3.1:1.86)
 ProdVer:    (3.1:1.86)
 FlagMask:    00000017
 Flags:        00000000
 OS:        00000004
 FileType:    00000000
 SubType:    00000000
 FileDate:    00000000:00000000

Don't make the bug report more complex than it needs to be or the devs will spend a lot of unnecessary debugging time.

Dale

Thanks for helping me to found where to fix the crash issue. you will have a solution in 3.1.1.87

Unfornulatly you will never be able to use a byRef. AutoIt cannot make a reference to the data handled by the object. I look at the code of SvenP and I found out a lot of comment that this reference is impossible.

So I decide to throw a fatalerror. That will be the fix in 3.1.1.87

B)

Share this post


Link to post
Share on other sites

So I decide to throw a fatalerror. That will be the fix in 3.1.1.87

B)

Is a fatal error necessary? Isn't there some way to throw a COM error? No run-time errors should be thrown by AutoIt unless it runs out of memory or the syntax of the script is invalid.

Share this post


Link to post
Share on other sites

Is a fatal error necessary? Isn't there some way to throw a COM error? No run-time errors should be thrown by AutoIt unless it runs out of memory or the syntax of the script is invalid.

I know the code it's very complex I am not sure how to do it. So it is a first correction avoinding the crash which is unacceptable. :">

Share this post


Link to post
Share on other sites

I know the code it's very complex I am not sure how to do it. So it is a first correction avoinding the crash which is unacceptable. :

As a user, I see little difference between a fatal crash and a fatal error. In both cases, my script stops unexpectedly. With that in mind, I don't think replacing the fatal crash with a fatal error when a more user-friendly solution is available makes much sense.

Share this post


Link to post
Share on other sites

As a user, I see little difference between a fatal crash and a fatal error. In both cases, my script stops unexpectedly. With that in mind, I don't think replacing the fatal crash with a fatal error when a more user-friendly solution is available makes much sense.

in this particular case the byref is an illegal definition of a function that can be used by the objevent.

There are still other Fatalerror at execution that cannot be detected before execution.

As I say it is a temporary solution. An error message is still better than a crash until SvenP comeback.

Share this post


Link to post
Share on other sites

Hi folks,

thank you for all your help. It's good to know that a new error will be prevented but it's a pity that AutoIt hasn't the abillity to give parameters back in events of an COM control. So now I have to do a little bit brainstorming and perhaps I'll find a solution for my problem or otherwise I have to use C++.

At last I have to excuse me for the 3 threads I opened for this single problem... So please have in mind that I was ill and I know that I shouldn't work when I am ill... ;-)

Best regards

Michael

Share this post


Link to post
Share on other sites

Hi folks,

thank you for all your help. It's good to know that a new error will be prevented but it's a pity that AutoIt hasn't the abillity to give parameters back in events of an COM control. So now I have to do a little bit brainstorming and perhaps I'll find a solution for my problem or otherwise I have to use C++.

At last I have to excuse me for the 3 threads I opened for this single problem... So please have in mind that I was ill and I know that I shouldn't work when I am ill... ;-)

Best regards

Michael

No problem for multiple thread. B)

Share this post


Link to post
Share on other sites

Know this old - but just thought I would throw it out

In this case why not create a wrapper to the webbrowser control.

Share this post


Link to post
Share on other sites

anyone solve this problem yet, any wrapper for webbrowser control?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0