You should handle readystatechange
event on the document
object. In JavaScript, it would look like this:
<body>
<body>Hi, this is going to be replaced!</body>
<script>
window.onload = function()
{
document.open("text/html");
document.onreadystatechange = function() {
if (document.readyState == "complete")
alert("Done!");
}
document.write("<b>Hello again!</b>");
document.close();
}
</script>
</body>
To get it done with C++ or C#, probably the easiest way would be to provide an implementation of IDispatch
interface to IHTMLDocument2::put_readystatechange
. Then IDispatch::Invoke(DISPID_VALUE)
will be called back upon readystatechange
event.
I might be able to help with a code sample if you specify the language in use.
[EDITED] You can grab the complete example (C++/ATL/VS2012) from here. The code does it asynchronously by posting a custom message to the main window. It's too long to cite here, below are the relevant parts.
IDispatch implementation, for onreadystatechange Event Sink:
class CEventSink:
public CComObjectRoot,
public IDispatch
{
private:
HWND m_hwnd;
UINT m_message;
public:
CEventSink()
{
m_hwnd = NULL;
m_message = NULL;
}
BEGIN_COM_MAP(CEventSink)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// Init
void Init(HWND hwnd, UINT message)
{
m_hwnd = hwnd;
m_message = message;
}
// IDispatch
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo) {
return E_NOTIMPL; }
STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {
return E_NOTIMPL; }
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) {
return E_NOTIMPL; }
STDMETHODIMP Invoke(
DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pvarResult,
EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if ( dispidMember != NULL )
return DISP_E_MEMBERNOTFOUND;
// Just post a message to notify the main window
::PostMessage(m_hwnd, m_message, 0, 0);
return S_OK;
}
};
Using it:
CComObject<CEventSink>* p = NULL;
hr = CComObject<CEventSink>::CreateInstance(&p);
if ( FAILED(hr) )
return 0;
p->Init(m_hWnd, WM_DOCUMENTREADYSTATECHANGE);
m_eventSink = p; // does AddRef
// ...
m_htmlDocument2->put_onreadystatechange(CComVariant(m_eventSink));
For more details, get the sources and look at WebOcHost.cpp
. The error checks are very basic, for brevity.