Dear José,
today, thanks to your IE Automation tutorial, I finally managed to write program to reboot my router. Thanks a lot :)
But there is one thing I do not get in COM programming with IWebBrowser2, maybe you could explain more on this topic.
To retrieve IHTMLDocument2, I have to do this:
Code #1
LOCAL pDispatch AS IDispatch
LOCAL pIHTMLDocument2 AS IHTMLDocument2
pDisp = pIWebBrowser2.Document
IF ISNOTHING(pDisp) THEN EXIT FUNCTION
pIHTMLDocument2 = pDispatch
IF ISNOTHING(pIHTMLDocument2) THEN EXIT FUNCTION
What is the exact reason I cannot do directly:
Code #2
LOCAL pIHTMLDocument2 AS IHTMLDocument2
pIHTMLDocument2 = pIWebBrowser2.Document
IF ISNOTHING(pIHTMLDocument2) THEN EXIT FUNCTION
What does the following line in original code actually change?:
pIHTMLDocument2 = pDispatch
In Code #1 I retrieve IDispatch reference, then assign it to IHTMLDocument2 object variable. Why do you think this is not possible directly?
To me assigning the reference to dispatch variable and then to IHTMLDocument2 seems just longer way to direct assignment.
Is it like that to make possible compiler check that I am retrieving value to variable of correct type? I would guess this is good for "safe code", but why I am then allowed to assign to IHTMLDocument2 variable?
I am used from OOP programming in other languages, that I can assign object of inherited class to parent class object variable, but not the opposite.
That is:
- IHTMLDocument2( inheriting IDispatch ) to IDispatch -> OK
- IDispatch to IHTMLDocument2( inheriting IDispatch ) -> NO
PB seems to support the second way, which is cool, but I am not sure why it works and how it works :)
Any info on this topic would be highly appreciated!
Thanks,
Petr
In your IE automation thread I found:
Quote
With PowerBASIC, the following assignment performs a call to IUnknown.QueryInterface. It is equivalent to pIHTMLDocument2.QueryInterface (IID_IHTMLDocument3, BYVAL VARPTR(pIHTMLDocument3))
I guess this is the thing PB does during the assignment in my case above too?
Thanks,
Petr
Quote
What is the exact reason I cannot do directly:
LOCAL pIHTMLDocument2 AS IHTMLDocument2
pIHTMLDocument2 = pIWebBrowser2.Document
IF ISNOTHING(pIHTMLDocument2) THEN EXIT FUNCTION
You can. I'm doing that in many of the examples that I have posted.
Quote
What does the following line in original code actually change?:
pIHTMLDocument2 = pDispatch
It calls QueryInterface asking for the IHTMLDocument2 interface.
Hi José,
thanks for the information ... but then I do not understand why does this code GPF with %WANTGPF set to 1:
#COMPILE EXE
#DIM ALL
#INCLUDE "exdisp.inc"
#INCLUDE "mshtml.inc"
%WANTGPF = 1 ' -- Change to 0 for no error
FUNCTION PBMAIN () AS LONG
LOCAL pIWebBrowser2 AS IWebBrowser2
LOCAL pIHTMLDocument2 AS IHTMLDocument2
LOCAL pIHTMLElementCollection AS IHTMLElementCollection
' Create a new instance of Internet Explorer
pIWebBrowser2 = NEWCOM "InternetExplorer.Application"
IF ISNOTHING(pIWebBrowser2) THEN EXIT FUNCTION
' Make it visible
pIWebBrowser2.Visible = 1
' Navigate to Google
pIWebBrowser2.Navigate UCODE$("http://www.google.com")
' Wait until the page is ready
WHILE (pIWebBrowser2.ReadyState <> %READYSTATE_COMPLETE)
apiSleep 3
WEND
#IF %WANTGPF
pIHTMLDocument2 = pIWebBrowser2.Document
IF ISNOTHING(pIHTMLDocument2) THEN EXIT FUNCTION
#ELSE
local pDispatch as IDispatch
pDispatch = pIWebBrowser2.Document
IF ISNOTHING(pDispatch) THEN EXIT FUNCTION
pIHTMLDocument2 = pDispatch
IF ISNOTHING(pIHTMLDocument2) THEN EXIT FUNCTION
#ENDIF
msgbox "Is pIHTMLDocument2 object?: "+iif$(isobject(pIHTMLDocument2), "YES", "NOPE")
' Get all forms
pIHTMLElementCollection = pIHTMLDocument2.Forms ' <- here it will fail if %WANTGPF = 1
IF ISNOTHING(pIHTMLElementCollection ) THEN EXIT FUNCTION
msgbox "All went fine..."
' ... here would follow other code ...
END FUNCTION
Can you confirm problem with the code above or is my PC ill? :) Maybe I overlooked something.
It GPFs, but it works when the WebBrowser Control is embedded.
Who knows what the WebBrowser Controls is doing when we use "InternetExplorer.Application" instead of "Shell.Explorer", used for embedding?
Apparently, it is returning a pointer to the IHTMLDocument interface instead of the IHTMLDocument2 interface, and it GPFs because the Forms property isn't available in IHTMLDocument.
That is odd,
but good to know.
Thank you very much again for explanation :)