Javascript communication with System.Form?
-
I want an html page inside a WebBrowser control to communicate with the csharp Form around it. What is the best way to do this, can javascript raise an event that C# can see? I can't just have the javascript navigate to some special url that my BeforeNavigate event catches, because doing so would cause the page to dissapear. "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
-
I want an html page inside a WebBrowser control to communicate with the csharp Form around it. What is the best way to do this, can javascript raise an event that C# can see? I can't just have the javascript navigate to some special url that my BeforeNavigate event catches, because doing so would cause the page to dissapear. "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
You will need to define three interfaces. IDocHostUIHandler, ICustomDoc and an interface that will define methods you will reference through your JavaScript. Your form will inherit the IDocHostUIHandler interface as well as the interface your define. Take a look on google for example on how to do this. If you have problems please drop me an email and I can send you some code. Catch the NavigateComplete2 event that will be fired after loading a web page in your browser control. You can cast the 'sender' argument to an object of type ICustomDoc and then call SetUIHandler. Pass the 'this' pointer to the method call. Once you've done all of this you should be able to make calls into your form from your JavaScript. Of course these calls can't be made until after you have made the call to SetUIHandler. (ie. If your Javascript is catching some event that occurs before you get the NavigateComplete2 event then it won't work. BTW: Your JavaScript should look something like this: window.external.AMethodInYourCustomInterface() Hope this helps and wasn't too confusing. :)
-
You will need to define three interfaces. IDocHostUIHandler, ICustomDoc and an interface that will define methods you will reference through your JavaScript. Your form will inherit the IDocHostUIHandler interface as well as the interface your define. Take a look on google for example on how to do this. If you have problems please drop me an email and I can send you some code. Catch the NavigateComplete2 event that will be fired after loading a web page in your browser control. You can cast the 'sender' argument to an object of type ICustomDoc and then call SetUIHandler. Pass the 'this' pointer to the method call. Once you've done all of this you should be able to make calls into your form from your JavaScript. Of course these calls can't be made until after you have made the call to SetUIHandler. (ie. If your Javascript is catching some event that occurs before you get the NavigateComplete2 event then it won't work. BTW: Your JavaScript should look something like this: window.external.AMethodInYourCustomInterface() Hope this helps and wasn't too confusing. :)
Thanks, I think I've almost got it. I'm actually pretty close to what you describe already. I already have A IDocHostUIHandler assigned with setuihandler. I made an interface with my method, and my form inherits from both IDocHostUIHandler and IMyInterface. I loaded a page that has a script tag with: window.external.causeShift(); and all I have causeShift doing in my (extended) Form is Console.Writeline("wohoo"); What happens is, I just a get a javascript error: "window.external is null or not an object". I think somewhere don't I need to connect up imyinterface with the ICustomDoc? I know I'm doing for IDocHostUIHandler as you said (and I know it's working because I have error handlers printing to console for it), but what do I do with imyinterface? Thanks very much King Rufus, "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
-
Thanks, I think I've almost got it. I'm actually pretty close to what you describe already. I already have A IDocHostUIHandler assigned with setuihandler. I made an interface with my method, and my form inherits from both IDocHostUIHandler and IMyInterface. I loaded a page that has a script tag with: window.external.causeShift(); and all I have causeShift doing in my (extended) Form is Console.Writeline("wohoo"); What happens is, I just a get a javascript error: "window.external is null or not an object". I think somewhere don't I need to connect up imyinterface with the ICustomDoc? I know I'm doing for IDocHostUIHandler as you said (and I know it's working because I have error handlers printing to console for it), but what do I do with imyinterface? Thanks very much King Rufus, "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
I think I'm figuring out the gap between your instructions and what I'm doing wrong: My definition of ICustomDoc is like this: public interface ICustomDoc { [PreserveSig] void SetUIHandler(IDocHostUIHandler pUIHandler); } Is that bad? So when I call SetUIHandler I have to cast my Form ("this") into an IDocHostUIHandler. It works fine, and I can trap events through the IDocHostUIHandler. In your instructions you said to just pass it "this". So you see what I'm saying, because I have to do the cast, my ICustomDoc has no knowledge of IMyInterface. How should I change my definition of SetUIHandler so that I can just give it my form? Seems to me from reading the docs on SetUIHandler, that it only accepts an IDocHostUIHandler, so I don't think I can interop my way out of this bag. I tried to make it just accept "object" and then pass it my Form ("this") but that didn't work. "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
-
I think I'm figuring out the gap between your instructions and what I'm doing wrong: My definition of ICustomDoc is like this: public interface ICustomDoc { [PreserveSig] void SetUIHandler(IDocHostUIHandler pUIHandler); } Is that bad? So when I call SetUIHandler I have to cast my Form ("this") into an IDocHostUIHandler. It works fine, and I can trap events through the IDocHostUIHandler. In your instructions you said to just pass it "this". So you see what I'm saying, because I have to do the cast, my ICustomDoc has no knowledge of IMyInterface. How should I change my definition of SetUIHandler so that I can just give it my form? Seems to me from reading the docs on SetUIHandler, that it only accepts an IDocHostUIHandler, so I don't think I can interop my way out of this bag. I tried to make it just accept "object" and then pass it my Form ("this") but that didn't work. "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
Here is my code for ICustomDoc [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("3050f3f0-98b5-11cf-bb82-00aa00bdce0b")] public interface ICustomDoc { [PreserveSig] void SetUIHandler(IDocHostUIHandler pUIHandler); } I make this call in my 'NavigateComplete2' event handler. That code looks like this: private void StartPage_NavigateComplete2(object sender, AxSHDocVw.DWebBrowserEvents2_NavigateComplete2Event e) { AxSHDocVw.AxWebBrowser wb = (AxSHDocVw.AxWebBrowser)sender; IHTMLDocument2 hDoc = (IHTMLDocument2)wb.Document; ((ICustomDoc)hDoc).SetUIHandler((IDocHostUIHandler)this); } Let me know if that does it for you.
-
Here is my code for ICustomDoc [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), GuidAttribute("3050f3f0-98b5-11cf-bb82-00aa00bdce0b")] public interface ICustomDoc { [PreserveSig] void SetUIHandler(IDocHostUIHandler pUIHandler); } I make this call in my 'NavigateComplete2' event handler. That code looks like this: private void StartPage_NavigateComplete2(object sender, AxSHDocVw.DWebBrowserEvents2_NavigateComplete2Event e) { AxSHDocVw.AxWebBrowser wb = (AxSHDocVw.AxWebBrowser)sender; IHTMLDocument2 hDoc = (IHTMLDocument2)wb.Document; ((ICustomDoc)hDoc).SetUIHandler((IDocHostUIHandler)this); } Let me know if that does it for you.
No, it still doesn't work, I get the same javascript error. I guess fundamentally I don't understand how it even could work this way. I don't understand how the JS even could call a method in IMyInterface. How can it see it? We glued IDocHostUIHandler to the page, but that interface doesn't have my IMyInterface methods. How could the JS see IMyInterface methods. I don't get it. There has to be someplace where I pass IMyInterface to ICustomDoc or something right? thanks tho "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
-
No, it still doesn't work, I get the same javascript error. I guess fundamentally I don't understand how it even could work this way. I don't understand how the JS even could call a method in IMyInterface. How can it see it? We glued IDocHostUIHandler to the page, but that interface doesn't have my IMyInterface methods. How could the JS see IMyInterface methods. I don't get it. There has to be someplace where I pass IMyInterface to ICustomDoc or something right? thanks tho "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
Give me a couple of days here. I'll try to throw together a simple DEMO application and if I have enough time I'll even throw it out there as an article. I know that this doesn't help you right now but there is a way for this to work. I guarantee since it's a major piece of an app I've done for one client and will be for my current one. Sometimes I need prompting so if you don't hear from me by Wednesday please give me a shout. I would send you code now but it's way to big. (and currently doesn't belong to me.) Let me know if this will work for you. King Rufus
-
Give me a couple of days here. I'll try to throw together a simple DEMO application and if I have enough time I'll even throw it out there as an article. I know that this doesn't help you right now but there is a way for this to work. I guarantee since it's a major piece of an app I've done for one client and will be for my current one. Sometimes I need prompting so if you don't hear from me by Wednesday please give me a shout. I would send you code now but it's way to big. (and currently doesn't belong to me.) Let me know if this will work for you. King Rufus
King Rufus, I see it has been more than a couple of days. :-D I am interested in your sample application as well. I have a need to do just this thing in my next application. Condor _____________________________________________ The world is a dangerous place.
Not because of those that do evil,
but because of those who look on and do nothing. -
I want an html page inside a WebBrowser control to communicate with the csharp Form around it. What is the best way to do this, can javascript raise an event that C# can see? I can't just have the javascript navigate to some special url that my BeforeNavigate event catches, because doing so would cause the page to dissapear. "Outside of a dog, a book is Man’s best friend. And inside of a dog, it’s too dark to read." -Groucho Marx
Bog, I got to the same point that you did. I have IDocHostUIHandler implemented as well as ICustomDoc and my IPageClickHandler interface. I am also getting the 'not an instance of an object' error from my javascript. I pulled my test page into VS7 and it does not expose a window.external method within the window object. Did you figure out how to bind the javascript to the external interface? King Rufus seems to have fallen off the face of the earth and is not responding. MJ _____________________________________________ The world is a dangerous place.
Not because of those that do evil,
but because of those who look on and do nothing.