简而言之,你必须正常地输出所有消息,你不能自己单独输出COM消息(此外,没有记录的消息,你可以自己查看/泵浦,他们只知道COM的内部).
如何使WebBrower.Navigate2同步?
你不能.但是你也不必等待这个OnDocumentComplete
事件.你可以在NavigateToEmpty()
自己内部忙碌循环,直到WebBrowser的ReadyState
属性为止READYSTATE_COMPLETE
,在等待处理消息时抽取消息队列:
procedure TContoso.NavigateToEmpty(WebBrowser: IWebBrowser2); begin WebBrowser.Navigate2('about:blank'); while (WebBrowser.ReadyState <> READYSTATE_COMPLETE) and (not Application.Terminated) do begin // if MsgWaitForMultipleObjects(0, Pointer(nil)^, False, 5000, QS_ALLINPUT) = WAIT_OBJECT_0 then // if GetQueueStatus(QS_ALLINPUT) <> 0 then Application.ProcessMessages; end; end;
如何提取COM消息?
无论如何,你不能,不能自己.泵送一切,并准备好处理由此产生的任何再入问题.
抽COM消息会导致COM事件回调吗?
是.
如何使用CoWaitForMultipleHandles
尝试这样的事情:
procedure TContoso.NavigateToEmpty(WebBrowser: IWebBrowser2); var hEvent: THandle; dwIndex: DWORD; hr: HRESULT; begin // when UseCOMWait() is true, TEvent.WaitFor() does not wait for, or // notify, when messages are pending in the queue, so use // CoWaitForMultipleHandles() directly instead. But you have to still // use a waitable object, just don't signal it... hEvent := CreateEvent(nil, True, False, nil); if hEvent = 0 then RaiseLastOSError; try WebBrowser.Navigate2('about:blank'); while (WebBrowser.ReadyState <> READYSTATE_COMPLETE) and (not Application.Terminated) do begin hr := CoWaitForMultipleHandles(COWAIT_INPUTAVAILABLE, 5000, 1, hEvent, dwIndex); case hr of S_OK: Application.ProcessMessages; RPC_S_CALLPENDING, RPC_E_TIMEOUT: begin end; else RaiseLastOSError(hr); end; end; finally CloseHandle(hEvent); end; end;