Delphi 是否有其他方法可以在不使用Application.ProcessMessages的情况下加载MSHTML文档?

Delphi 是否有其他方法可以在不使用Application.ProcessMessages的情况下加载MSHTML文档?,delphi,mshtml,Delphi,Mshtml,是否有其他方法可以在不使用Application.ProcessMessages的情况下加载MSHTML文档 要将文档加载到IHTMLDocument中,我需要执行以下操作: while Doc.readyState <> 'complete' do Application.ProcessMessages; 当Doc.readyState“完成”时 Application.ProcessMessages; 我不想在加载过程中处理所有消息队列,因为我会更改我的应用程序流,换

是否有其他方法可以在不使用Application.ProcessMessages的情况下加载MSHTML文档

要将文档加载到IHTMLDocument中,我需要执行以下操作:

while Doc.readyState <> 'complete' do 
   Application.ProcessMessages;
当Doc.readyState“完成”时
Application.ProcessMessages;
我不想在加载过程中处理所有消息队列,因为我会更改我的应用程序流,换句话说,一些应该在加载完成后处理的消息可以更早地处理,甚至在加载结束之前


有一个特殊的消息代码,IHTMLDocument希望在加载过程中前进?或者有另一种加载方式?

调用Application.ProcessMessages很可能只是为了让MSHTML activeX控件有时间完成加载文档。这听起来像是他们在这里使用协作多任务来模拟在后台加载文档——ActiveX向自己发送消息以处理下一个块或任何东西

通常情况下,这不会影响应用程序的流,因为文档加载是正常消息循环的一部分。但是,因为您希望同步加载文档(在文档完全加载之前不要执行任何其他操作),所以您对它通过消息进行后台加载的方式很敏感

一个解决方案:看看是否可以删除同步加载文档的要求。让加载在发生时发生,但将readState=complete的检查移动到计时器中,可能间隔1秒。当计时器发现文档加载完成时,启动下游食物链活动

另一种解决方案:在等待加载文档时显示模式对话框。这样做的好处是禁用用户界面的其余部分,这样您就不会面临重新进入的风险。调用ProcessMessages意味着用户仍然可以与您的窗口、单击按钮、菜单等进行交互。这通常会导致问题。显示模式对话框(“进度对话框?”)通过禁用模式对话框后面的所有内容来避免重入

第三种可能性:用PeekMessage和逻辑替换Application.ProcessMessages,以检查消息以决定是让其通过还是稍后将其放回消息队列。这有点脏,但在非常特殊的情况下可能会起作用


我推荐方法#2,模态对话框。

该组件包含一些辅助函数,如LoadFromFile和LoadFromStream,它们将直接将文档加载到MSHTML控件中。将完整逻辑移到onDocumentComplete事件中。

有一个TEmbeddedWB.onDocumentComplete事件,在文档完成加载时触发。有什么特别的原因不想使用它吗?

我认为在大多数情况下,#2是最好的解决方案。但对我来说,当我需要每秒处理几个文档时,这将大大降低性能。因此,我遵循第三种可能性,但使用TApplicationEvents组件并忽略来自键盘和鼠标的消息。它工作得很好。非常正确。即使使用模式对话框,问题也在于可能会有其他消息(如WM_TIMER)导致问题,因为当函数等待IE完成加载时,它会使应用程序处于非预期状态。@Andreas:你说的是真的,但是与Application.ProcessMessages循环期间发生的菜单和按钮点击的可重入性问题相比,WM_计时器工件的问题要小得多。@Danny:如果计时器执行诸如刷新TWebBrowser之类的操作,则不会,因为有人认为这是一个好主意(您可以看到无限浏览器刷新“循环”)。不幸的是,我是那个必须识别并修复bug的人。我花了一些时间才发现是WM_定时器信息导致了这个问题。在使用ProcessMessages/DoEvents或其他框架中调用的任何调用之前,都应该仔细评估。可悲的是,许多开发人员在使用软件时没有考虑或不知道他们会给软件带来什么副作用。@Andreas:再多的防御性编程也不能防止糟糕的设计。>服务器没有响应。在我开始直接使用TWebBrowser之前,我想使用TEmbbeddedWB,但是我无法访问它。服务器没有响应。在我开始直接使用TWebBrowser之前,我想使用TEmbbeddedWB,但我无法访问它。TWebBrowser具有相同的事件。即使服务器没有响应,浏览器也会发生文档完成事件。