0

So, I have a main thread that captures an existing IE browser and saves the HTMLDocument in a variable. I attached an event handler to the "onload" event of this document because I need a frame that is located inside it. If I capture the frame in the main thread, everything is fine, but when the event is raised, I get an exception when I access the document:

For I = 0 To MyHTMLDocument.frames.length - 1

I have tried invoking the main thread, I tried making sure that the main document was fully loaded, but nothing seems to work. I always get a "Specified cast is not valid."

Putting MyHTMLDocument.frames into the Watch window in Visual Studio also gives the same exception "Specified cast is not valid." I'm not casting anything, am I? Some websites suggested using <STAThread()> _ which I tried for the heck, but to no avail. I also tried TryCast(MyHTMLDocument.frames, FramesCollection).

All I need to do is recapture a frame's document with a specific name when the document is refreshed. I assume that it's a problem with threading, but invoking doesn't even work... A funny thing is that I can access other things like Title, GetElementsByName, etc. Just not the darn frames...

Apachi
  • 32
  • 5
  • And what happens if you try to iterate that on the UI thread? Have you tried placing a breakpoint on the `For I = 0 ...` line and inspecting the `frames` collection/array? – Visual Vincent Jul 19 '16 at 00:01
  • The iteration works as expected from the UI thread. No problems whatsoever. It looks for the frame with the name that I want, casts it as an `IHTMLWindow2`, and I'm able to click an element located IN the frame. But should the main document get reloaded, of course, I lose everything and have to get the handle again. That's my problem. – Apachi Jul 19 '16 at 13:04
  • Perhaps you should try to get the collection via invocation. If you call `Me.Invoke()` you can get the return value from that as your collection. What .NET Framework version are you targeting? – Visual Vincent Jul 20 '16 at 11:47
  • I'm targeting 4.5. What I ended up doing is creating a shared function with a name like `getFrame` that grabs all the components/elements as they are at the moment. No need for Invokes. It works. I will leave the question open in case people have solutions. At this point, it's more curiosity on WHY I was having the issue... By the way, do you mean `Me` is in reference to the UI thread? – Apachi Jul 21 '16 at 16:13
  • `Me` would be the current form, yes. -- Though you say you attach an event handler to the document's `OnLoad` event. Perhaps that is the issue (or part of it)? Load events are usually fired before the object is done rendering/showing. – Visual Vincent Jul 21 '16 at 23:00
  • Ahh... Now maybe that is it. I did wait for the frame to load in a `Do...Until` loop, but I suppose when speaking about embedded frames, it doesn't work like I thought. The page was actually loaded because I could physically see it in the IE window, but maybe it didn't captured the page before the frame was loaded? I don't know enough about COM's to answer that. I'll do some testing and see what I can come up with. You might be right. – Apachi Jul 22 '16 at 13:48
  • 1
    Otherwise try something like this for thread-safety: `Dim frames = Me.Invoke(Function() Return MyHTMLDocument.frames)`. – Visual Vincent Jul 22 '16 at 16:59
  • I had this same issue when running in a C# class project. I created a Winforms project and ran the same code and all is well. – chdev77 Jul 22 '16 at 21:53
  • mshtml is STA thus expect its methods to be called from the same thread. – Sheng Jiang 蒋晟 Aug 06 '16 at 23:24

0 Answers0