tags:

views:

330

answers:

3

There is another way to load MSHTML documents without use Application.ProcessMessages?

To load a document into a IHTMLDocument I need to do this:

while Doc.readyState <> 'complete' do 
   Application.ProcessMessages;

I want not to process all the message queue during the loading, because I would be changing my application flow, in other words, some messages that should be processed after the loading to be completed can be processed earlier, even before the loading end.

There is a special message code that the IHTMLDocument expect to advance in the loading process? Or there is another way to load?

Thanks.

+4  A: 

The call to Application.ProcessMessages is most likely just needed to allow the MSHTML activeX control time to finish loading the document. It sounds like they're using cooperative multitasking here to simulate loading the doc in the background - the ActiveX posts messages to itself to process the next chunk or whatever.

Normally, this wouldn't affect your app's flow because the doc load would happen as part of your normal message loop. But because you're wanting to load the doc synchronously (not do anything else until the doc is fully loaded), you're sensitive to the way it's doing background loading via messages.

One solution: see if you can remove the requirement to load the doc synchronously. Let the load happen when it happens, but move the check for readState = complete into a timer, perhaps on a 1 second interval. When the timer discovers the doc load is complete, then fire off your downstream food chain activities.

Another solution: Display a modal dialog while waiting for the doc to load. This has the benefit of disabling the rest of your UI so you don't run the risk of reentrancy. Calling ProcessMessages means the user can still interact with your window, click on buttons, menus etc. Usually this will lead to problems. Displaying a modal dialog ("progress dialog?") avoids reentrancy by disabling everything behind the modal dialog.

Third possibility: Replace Application.ProcessMessages with PeekMessage and logic to examine the message to decide whether to let it go through or put it back on the message queue for later. This is a bit dirty but might work in very special cases.

I recommend approach #2, the modal dialog.

dthorpe
+1 The approch #2 is what I agree too.
Fabricio Araujo
I think in most of the cases the #2 is the best solution. But for me, when I need to process several documents per second, this would decrease a lot the performance.So I follow the third possibilty, but using a TApplicationEvents component and ignoring messages from keyboard and mouse. It have worked fine.Very tks.
Douglas Lise
The problem even with a modal dialog is that there may be other messages like WM_TIMER that will cause problems because it can bring your application in a state that it wasn't intended while your function waits for IE to finish loading.
Andreas Hausladen
@Andreas: What you say is true, but WM_TIMER artifacts are a much much smaller class of problem compared to the reentrancy issue of menu and button clicks happening during an Application.ProcessMessages loop.
dthorpe
@Danny: Not if a timer does things like refreshing the TWebBrowser because somebody thought that was a good idea (you see the infinite browser refresh "loop"). Unfortunately I was the person who had to identify and fix the bug. And it took me some time to find out that it was a WM_TIMER message that caused the problem. Every call to ProcessMessages/DoEvents or whatever it is called in other frameworks should be carefully evaluated before using it. Sadly many developers don't think about or know what side effects they introduce into their software when they use it.
Andreas Hausladen
@Andreas: No amount of defensive programming can protect against bad design. ;>
dthorpe
+3  A: 

The component TEmbeddedWB contains some helper functions such as LoadFromFile and LoadFromStream which will load the document into the MSHTML control directly. Move your complete logic into the onDocumentComplete event.

skamradt
The link is broken
Douglas Lise
should be http://www.bsalsa.com/downloads.html
skamradt
The server doesn't response. Before I start using directly the TWebBrowser I thought use TEmbbeddedWB, but I couldn't access it.
Douglas Lise
A: 

There is a TEmbeddedWB.OnDocumentComplete event, fired when a document completes loading. Is there any special reason why you don't want to use that?

r4w8173
The server doesn't response. Before I start using directly the TWebBrowser I thought use TEmbbeddedWB, but I couldn't access it.
Douglas Lise
TWebBrowser has the same event. Even if server don't respond, there will be a document complete event for the browser.
r4w8173