Is there an event that fires when DOM is modified in MSHTML IE8?
Trying to detect if new elements are added or removed f开发者_开发技巧rom the DOM in MSHTML. Is there such event that will fire?
http://msdn.microsoft.com/en-us/library/aa741877(v=VS.85).aspx
In IE9 there is IDOMMutationEvent::initMutationEvent
http://msdn.microsoft.com/en-us/library/ff975905(v=vs.85).aspx
Yes, it is possible now in IE8, though it is not part of the MSHTML event structure, but Accessibility.
Trigger (EVENT_OBJECT_REORDER) is new in IE8 - See http://blogs.msdn.com/b/ie/archive/2008/12/10/new-accessibility-features-in-ie8.aspx?PageIndex=7
We use it with out BHO, but you could equally hook outside of IE if you choose.
BHOClass::BHOClass()
{
if( TrackDHTML ) {
// end event is not used so +1.
// out of process notifications from accessibility
m_eHook = ::SetWinEventHook(EVENT_OBJECT_REORDER, EVENT_OBJECT_REORDER+1, 0, MSAALib_WinEventProc, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT );
// in process injecting the dll into IE
// m_eHook = ::SetWinEventHook(EVENT_OBJECT_REORDER, EVENT_OBJECT_REORDER+1, GetModuleHandle(L"yourhook.dll"), MSAALib_WinEventProc, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_INCONTEXT );
}
}
And here is how you might look at the accessibility and get the document/browser
static void CALLBACK MSAALib_WinEventProc(HWINEVENTHOOK hook,
DWORD event,
HWND hwnd, // this appears to be the hwnd for the tab and not the specific frame
LONG idObject,
LONG idChild,
DWORD dwEventThread, // the thread being watched that triggered this call
DWORD dwmsEventTime)
{
if( hwnd != NULL // exclude most mouse move
&& ( OBJID_WINDOW == idObject ) // || OBJID_CLIENT == idObject )
)
{
switch( event ) {
case EVENT_OBJECT_REORDER: break;
case EVENT_OBJECT_SHOW: break;
case EVENT_OBJECT_HIDE: break;
default:
return;
}
Log(L"Event START - (%ld) object %ld on window(0x%x)%ld thread (0x%x)%ld\n", event, idObject, hwnd, hwnd, dwEventThread, dwEventThread);
CComPtr<IAccessible> acc;
VARIANT varChild;
AccessibleObjectFromEvent(hwnd, idObject, idChild, &acc, &varChild);
if( acc ) {
// step 1 - change from Accessibility interface to html to check we have right type of reorder message
CComPtr<IServiceProvider> provider;
HRESULT hr = acc->QueryInterface(IID_IServiceProvider,(LPVOID *)&provider);
if( SUCCEEDED(hr) && provider ){
CComPtr<IHTMLElement> spElement;
hr = provider->QueryService(IID_IHTMLElement,IID_IHTMLElement,(LPVOID *)&spElement);
if( spElement ) {
// step 2 - for this doc element get the service provider and then the browser element
CComPtr<IServiceProvider> provider2;
HRESULT hr = spElement->QueryInterface(IID_IServiceProvider,(LPVOID *)&provider2);
CComPtr<IServiceProvider> provider3;
if( provider2 )
hr = provider2->QueryService(SID_STopLevelBrowser,IID_IServiceProvider,(LPVOID *)&provider3);
CComPtr<IWebBrowser2> browser;
if( provider3 )
hr = provider3->QueryService(SID_SWebBrowserApp,IID_IWebBrowser2,(LPVOID *)&browser);
if( browser ) {
// step 3 - Do stuff
}
}
}
}
Log(L"Event DONE - (%ld) object %ld on window(0x%x)%ld thread (0x%x)%ld\n", event, idObject, hwnd, hwnd, dwEventThread, dwEventThread);
}
}
No, but if you modify the DOM via a class library like JQuery you can fake the event by yourself.
How about WebBrowser1.Document.AttachEventHandler()
?
精彩评论