Problem with frames using .NET & webbrowser control
-
Hello, I am currently porting a webbrowser application from C++ to C#/.NET. I already struggled with the beforenavigate2 bug everybody was talking about and I can't wait for the .NET SP3. My current problem is when trying to traverse the DOM tree after a documentcomplete event. It works properly for non framed document but not for framed pages. Everytime a documentcomplete event is fired I always get the same document (the top level one). It should mean that I am always getting the same document, but I must be missing something because I don't know how to get a specific frame document. Here is the C# piece of code:
private void documentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e){ AxSHDocVw.AxWebBrowser Frame; IHTMLDocument3 Doc; IHTMLDOMChildrenCollection Tags; IHTMLElement Tag; int NumTags; Console.WriteLine("URL: "+e.uRL); // Good frame URL try{ Frame=(AxSHDocVw.AxWebBrowser)sender; // Is it really the frame ? if(Frame!=null){ Doc=(IHTMLDocument3)Frame.Document; // Top level document ??? if(Doc!=null){ Tags=(IHTMLDOMChildrenCollection)Doc.childNodes; if(Tags!=null){ NumTags=Tags.length; for(int i=0;i Another question is: what is e.pDisp ? How to cast it ? It tried to cast it into an AxSHDocVw.AxWebBrowser and I got an error. Regards, R. L.
-
Hello, I am currently porting a webbrowser application from C++ to C#/.NET. I already struggled with the beforenavigate2 bug everybody was talking about and I can't wait for the .NET SP3. My current problem is when trying to traverse the DOM tree after a documentcomplete event. It works properly for non framed document but not for framed pages. Everytime a documentcomplete event is fired I always get the same document (the top level one). It should mean that I am always getting the same document, but I must be missing something because I don't know how to get a specific frame document. Here is the C# piece of code:
private void documentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e){ AxSHDocVw.AxWebBrowser Frame; IHTMLDocument3 Doc; IHTMLDOMChildrenCollection Tags; IHTMLElement Tag; int NumTags; Console.WriteLine("URL: "+e.uRL); // Good frame URL try{ Frame=(AxSHDocVw.AxWebBrowser)sender; // Is it really the frame ? if(Frame!=null){ Doc=(IHTMLDocument3)Frame.Document; // Top level document ??? if(Doc!=null){ Tags=(IHTMLDOMChildrenCollection)Doc.childNodes; if(Tags!=null){ NumTags=Tags.length; for(int i=0;i Another question is: what is e.pDisp ? How to cast it ? It tried to cast it into an AxSHDocVw.AxWebBrowser and I got an error. Regards, R. L.
This article [^]might help you. I have included frame events. GriffonRL wrote: what is e.pDisp ? How to cast it ? It tried to cast it into an AxSHDocVw.AxWebBrowser and I got an error. This one should not really appear in public interfaces, but anyway, that's the instance of the underlying web browser control. You can't do much with C# about it, and in fact you don't need since the public IE interfaces are all available to you.
She's so dirty, she threw a boomerang and it wouldn't even come back.
-
This article [^]might help you. I have included frame events. GriffonRL wrote: what is e.pDisp ? How to cast it ? It tried to cast it into an AxSHDocVw.AxWebBrowser and I got an error. This one should not really appear in public interfaces, but anyway, that's the instance of the underlying web browser control. You can't do much with C# about it, and in fact you don't need since the public IE interfaces are all available to you.
She's so dirty, she threw a boomerang and it wouldn't even come back.
Hello Stephane, Thanks for your answer :). I am looking at the article. But this pDisp is not clear for me. You wrote: This one should not really appear in public interfaces, but anyway, that's the instance of the underlying web browser control. You can't do much with C# about it, and in fact you don't need since the public IE interfaces are all available to you. Since I used to write webbrowser applications with VC++, I was actually getting the frame browser control instance in pDisp. What I can't understand, is why e.pDisp exists if we can't cast it ? Regards, R. L.
-
Hello Stephane, Thanks for your answer :). I am looking at the article. But this pDisp is not clear for me. You wrote: This one should not really appear in public interfaces, but anyway, that's the instance of the underlying web browser control. You can't do much with C# about it, and in fact you don't need since the public IE interfaces are all available to you. Since I used to write webbrowser applications with VC++, I was actually getting the frame browser control instance in pDisp. What I can't understand, is why e.pDisp exists if we can't cast it ? Regards, R. L.
GriffonRL wrote: What I can't understand, is why e.pDisp exists if we can't cast it ? the IE namespace you use once you have imported the IE web control ocx (drag&drop, add reference, ...) is actually the result of an automated type-library import which simply creates a thin wrapper around the idl interfaces. Because the IDispatch *pDisp appears in some members of some of the interfaces, it thus appears in the resulting wrapper. But as I have said already, this is a case where it's not useful : IDispatch* is seen as a raw untyped
object
. Furthermore, the namespace already provides interfaces from which you can invoke the methods you would with a C++ ptr on the web control. So, you don't lose power by using C# or other .NET languages. The thing you lose is that the marshaller (at the heart of all the interop stuff) is not able to comply with all kind of variant subtypes (limitation known by MS people). As long as MS doesn't fix it, whevener we import a type-library, we may or may not for any reason be able to call certain methods depending on the parameter types. That's it. We'll have to live with it. And by the way, the article I have suggested bypasses the standard tlbimp.
She's so dirty, she threw a boomerang and it wouldn't even come back.
-
GriffonRL wrote: What I can't understand, is why e.pDisp exists if we can't cast it ? the IE namespace you use once you have imported the IE web control ocx (drag&drop, add reference, ...) is actually the result of an automated type-library import which simply creates a thin wrapper around the idl interfaces. Because the IDispatch *pDisp appears in some members of some of the interfaces, it thus appears in the resulting wrapper. But as I have said already, this is a case where it's not useful : IDispatch* is seen as a raw untyped
object
. Furthermore, the namespace already provides interfaces from which you can invoke the methods you would with a C++ ptr on the web control. So, you don't lose power by using C# or other .NET languages. The thing you lose is that the marshaller (at the heart of all the interop stuff) is not able to comply with all kind of variant subtypes (limitation known by MS people). As long as MS doesn't fix it, whevener we import a type-library, we may or may not for any reason be able to call certain methods depending on the parameter types. That's it. We'll have to live with it. And by the way, the article I have suggested bypasses the standard tlbimp.
She's so dirty, she threw a boomerang and it wouldn't even come back.
Yep ! Here is the solution working with frames ;):
private void documentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e){ SHDocVw.IWebBrowser2 Frame; IHTMLDocument3 Doc; IHTMLDOMChildrenCollection Tags; IHTMLElement Tag; int NumTags; Console.WriteLine("URL: "+e.uRL); try{ Frame=(SHDocVw.IWebBrowser2)e.pDisp; if(Frame!=null){ Doc=(IHTMLDocument3)Frame.Document; Console.WriteLine("Document URL: " (IHTMLDocument2)Doc).location.href); if(Doc!=null){ Tags=(IHTMLDOMChildrenCollection)Doc.childNodes; if(Tags!=null){ NumTags=Tags.length; for(int i=0;i Enjoy, R. L.
-
Yep ! Here is the solution working with frames ;):
private void documentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e){ SHDocVw.IWebBrowser2 Frame; IHTMLDocument3 Doc; IHTMLDOMChildrenCollection Tags; IHTMLElement Tag; int NumTags; Console.WriteLine("URL: "+e.uRL); try{ Frame=(SHDocVw.IWebBrowser2)e.pDisp; if(Frame!=null){ Doc=(IHTMLDocument3)Frame.Document; Console.WriteLine("Document URL: " (IHTMLDocument2)Doc).location.href); if(Doc!=null){ Tags=(IHTMLDOMChildrenCollection)Doc.childNodes; if(Tags!=null){ NumTags=Tags.length; for(int i=0;i Enjoy, R. L.
I haven't run it, but I don't buy it. Why ? Not only MS clearly says in MSDN that frame events are signaled within their own frame space, but I know that there are 3 frame related events which actually get signaled on individual frames : that's FrameBeforeNavigate(dispid=200), FrameNavigateComplete(dispid=201) and FrameNewWindow(dispid=204). That said, whatever the code you have, if it does what you are looking for, then it's probably because it's fine.:cool:
She's so dirty, she threw a boomerang and it wouldn't even come back.
-
Hello, I am currently porting a webbrowser application from C++ to C#/.NET. I already struggled with the beforenavigate2 bug everybody was talking about and I can't wait for the .NET SP3. My current problem is when trying to traverse the DOM tree after a documentcomplete event. It works properly for non framed document but not for framed pages. Everytime a documentcomplete event is fired I always get the same document (the top level one). It should mean that I am always getting the same document, but I must be missing something because I don't know how to get a specific frame document. Here is the C# piece of code:
private void documentComplete(object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e){ AxSHDocVw.AxWebBrowser Frame; IHTMLDocument3 Doc; IHTMLDOMChildrenCollection Tags; IHTMLElement Tag; int NumTags; Console.WriteLine("URL: "+e.uRL); // Good frame URL try{ Frame=(AxSHDocVw.AxWebBrowser)sender; // Is it really the frame ? if(Frame!=null){ Doc=(IHTMLDocument3)Frame.Document; // Top level document ??? if(Doc!=null){ Tags=(IHTMLDOMChildrenCollection)Doc.childNodes; if(Tags!=null){ NumTags=Tags.length; for(int i=0;i Another question is: what is e.pDisp ? How to cast it ? It tried to cast it into an AxSHDocVw.AxWebBrowser and I got an error. Regards, R. L.
GriffonRL- Have you had success in trapping the navigation events in the browser? -AC
-
GriffonRL- Have you had success in trapping the navigation events in the browser? -AC
Hi, At least for DocumentComplete() it works. I also applied the "patch" to get BeforeNavigate2 events (until we get .NET SP3 :(). Everything else seems to work like in VC++/COM so far. But who knows ? I am starting with .NET and it took me 1 day to learn C# and the .NET basics. But the marshalling system was not clear and I spent 2 days on problems. Regards, R. L.
-
Hi, At least for DocumentComplete() it works. I also applied the "patch" to get BeforeNavigate2 events (until we get .NET SP3 :(). Everything else seems to work like in VC++/COM so far. But who knows ? I am starting with .NET and it took me 1 day to learn C# and the .NET basics. But the marshalling system was not clear and I spent 2 days on problems. Regards, R. L.
Unfortunately, there is no .NET SP3 coming this fall. .NET 1.1 is in beta, and this issue is not among the things that have been fixed (see gotdotnet.com for further details).
She's so dirty, she threw a boomerang and it wouldn't even come back.