2011-02-24 6 views
5

MSHTMLで新しい要素がDOMに追加または削除されたかどうかを検出しようとしています。そのような出来事がありますか?DOMがMSHTML IE8で修正されたときに発生するイベントはありますか?

IE9では

http://msdn.microsoft.com/en-us/library/aa741877(v=VS.85).aspx

IDOMMutationEventがある:: initMutationEvent

http://msdn.microsoft.com/en-us/library/ff975905(v=vs.85).aspx

+0

を取得する可能性がありますどのようにあなたはMSHTMLオブジェクトセットは、WBCから取得された状態で作業していますか? – abatishchev

答えて

5

はい、MSHTMLイベント構造の一部ではありませんが、アクセシビリティはIE8では可能です。

トリガー(EVENT_OBJECT_REORDER)はIE8の新機能です - 私たちは、アウトBHOでそれを使用しますが、あなたが選択した場合も同様にIEの外をフックできhttp://blogs.msdn.com/b/ie/archive/2008/12/10/new-accessibility-features-in-ie8.aspx?PageIndex=7

を参照してください。

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); 
} 
} 

そして、ここであなたは、アクセシビリティを見て、文書/ブラウザ

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); 
} 
} 
+0

これは少し遅れますが、JavaScriptでこのイベントをフックする方法はありますか? – thednp

0

ありませんが、あなたはjQueryのyou can fake the event by yourselfのようなクラスライブラリを経由してDOMを変更する場合。

+0

DOMを変更しようとしていません。私はJavaScriptがなく、DOMが変更されたときを検出しようとしています。私はMSHTMLをアプリケーションでホストしています。 – GeorgeU

+0

コンテナがデザインモードの場合、IMarkupContainer2 :: CreateChangeLogを使用できます。そうしないと、IDispatchExを使用して各要素のすべてのDOM変更メソッド/プロパティ(appendchild、outerhtml、innerhtml、text、styleなど)をオーバーライドできます。 –