走進PIMShell(3)–實現TabNew行為(Behavior)

來源:互聯網
上載者:User

IE7實現了多標籤(Tab)的特性。我們可以通過target屬性指示連結在某個視窗中開啟,卻無法通過類似的屬性指示連結在新的標籤中開啟。現在我們實現一個行為(Behavior),附加到元素a,從而實現點選連結時自動在新的標籤開啟。效果如下

  1. <a style="behavior:url(#default#TabNewDemo);" tabNewActive="true" href="http://www.pimshell.com">test</a>
  2. tabNewActive:指示新的標籤是否啟用

也可以這樣

  1. .TabNewDemo{behavior:url(#default#TabNewDemo);}
  2. <a class="TabNewDemo" href="http://www.pimshell.com">goto my homepage</a>

我們看一下IE是如何處理這個TabNewDemo行為的。

  1. IE發現元素a附加的行為名稱是“#default#TabNewDemo”,default說明這個是登入的預設行為。在登錄機碼HKLM/SOFTWARE/Microsoft/Internet Explorer/Default Behaviors中尋找TABNEWDemo對應的行為工廠組件的ClassId。
  2. 建立行為工廠組件的執行個體,然後調用行為工廠的方法FindBehavior,從而得到行為的執行個體。
  3. 調用行為執行個體的方法Init,傳遞環境參數。
  4. 調用行為執行個體的方法Notify,在這裡行為綁定當前a元素的onclick事件
  5. 準備就緒。當使用者點擊a元素時,行為響應onclick事件,通過調用WebBrowser.Navigate2實現在新標籤中開啟連結
  6. 頁面關閉時,調用行為執行個體的方法Detach,在這裡清理資源。

下面是TabNewDemo行為的實現步驟

 

第一步:建立一個ATL Com,名稱為TabNew,

並在PIMShellDemo.rgs加入如下登錄機碼

  1. HKLM
  2. {
  3.     NoRemove SOFTWARE
  4.     {
  5.         NoRemove Microsoft
  6.         {
  7.             NoRemove 'Internet Explorer'
  8.             {   
  9.                 NoRemove 'Default Behaviors'
  10.                 {
  11.                     val TABNEWDemo = s 'CLSID:E785D34B-7C76-4FC2-B6FE-E2A2AABEEDD9'
  12.                 }
  13.             }
  14.         }
  15.     }
  16. }

第二步:繼承介面IElementBehaviorFactory,實現方法FindBehavior:

  1. // IElementBehaviorFactory
  2. STDMETHODIMP CTabNew::FindBehavior(BSTR bstrBehavior, BSTR bstrBehaviorUrl,
  3.     IElementBehaviorSite* pSite, IElementBehavior** ppBehavior)
  4. {
  5.     HRESULT hr; 
  6.     
  7.     //check
  8.     if(!CVB::_StrCmpI(bstrBehavior,DF_Behavior_Name))
  9.         return E_FAIL;
  10.     //create
  11.     CComObject<CTabNew>* pTabNew;
  12.     hr=CComObject<CTabNew>::CreateInstance(&pTabNew);
  13.     if(FAILED(hr))
  14.         return hr;
  15.     //ok
  16.     return pTabNew->QueryInterface(IID_IElementBehavior, (void**)ppBehavior);
  17. }

第三步:繼承介面IElementBehavior,實現三個方法:

  1. // IElementBehavior
  2. STDMETHODIMP CTabNew::Init(IElementBehaviorSite* pBehaviorSite)
  3. {
  4. __SAFECALL_BEGIN;
  5.     // Cache the IElementBehaviorSite interface pointer.
  6.     m_pSite = pBehaviorSite;
  7.     // Cache the IElementBehaviorSiteOM interface pointer.
  8.     m_pOMSite = m_pSite;
  9.     //
  10.     m_pOMSite->RegisterName(DF_Behavior_Name);
  11. __SAFECALL_END;
  12. }
  13. //
  14. STDMETHODIMP CTabNew::Notify(LONG lEvent, VARIANT* pVar)
  15. {
  16. __SAFECALL_BEGIN;
  17.     switch(lEvent)
  18.     {
  19.     case BEHAVIOREVENT_CONTENTREADY:
  20.         //attachevents
  21.         this->__attachEvents(true);
  22.         break;
  23.     }
  24. __SAFECALL_END;
  25. }
  26. //
  27. STDMETHODIMP CTabNew::Detach()
  28. {
  29. __SAFECALL_BEGIN;
  30.     //detach events
  31.     this->__attachEvents(false);
  32.     //
  33.     this->m_pSite=NULL;
  34.     this->m_pOMSite=NULL;
  35. __SAFECALL_END;
  36. }

第四步:實現綁定onclick事件的方法__attachEvents

  1. //
  2. void CTabNew::__attachEvents(bool bAttach)
  3. {
  4.     //element
  5.     MSHTML::IHTMLElementPtr pElement=this->m_pSite->GetElement();
  6.     MSHTML::IHTMLElement2Ptr pElement2=pElement;
  7.     //
  8.     if(bAttach)
  9.     {
  10.         //pSystem 
  11.         //          should install PIMShell (http://www.pimshell.com)
  12.         PIMShellCore::IAjaxSystem_helperPtr pSystem;
  13.         pSystem.CreateInstance(__uuidof(PIMShellCore::CAjaxSystem));
  14.         //this
  15.         IUnknownPtr pThis=this;
  16.         //delegate
  17.         m_pDelegate_onevents=pSystem->CreateDelegateVC1(pThis,(LONGLONG)&Sink_onevents);
  18.         //attach event of onclick
  19.         pElement2->attachEvent(L"onclick",m_pDelegate_onevents);
  20.     }
  21.     else
  22.     {
  23.         if(m_pDelegate_onevents!=NULL)
  24.         {
  25.             //detach event of onclick
  26.             pElement2->detachEvent(L"onclick",m_pDelegate_onevents);
  27.             //
  28.             m_pDelegate_onevents=NULL;
  29.         }
  30.     }
  31. }

第五步:響應onclick事件

  1. //
  2. HRESULT CTabNew::Sink_onevents(VARIANT vEvent,VARIANT vContext,IUnknown* pInstance,VARIANT* pvarResult)
  3. {
  4. __SAFECALL_BEGIN;
  5.     //init
  6.     CTabNew* pThis=dynamic_cast<CTabNew*>(pInstance);
  7.     MSHTML::IHTMLEventObjPtr e=vEvent.pdispVal;
  8.     //
  9.     CString sType=e->type;
  10.     //
  11.     if(sType==L"click")
  12.     {
  13.         pThis->__onclick(e);
  14.     }
  15. __SAFECALL_END;
  16. }
  17. //
  18. void CTabNew::__onclick(const MSHTML::IHTMLEventObjPtr& e)
  19. {
  20.     //shift or ctrl may by pressed by code.
  21.     VARIANT_BOOL bShift,bCtrl,bAlt;
  22.     
  23.     bShift=e->shiftKey;
  24.     bCtrl=e->ctrlKey;
  25.     bAlt=e->altKey;
  26.     //if shift or ctrl then return
  27.     if(bShift || bCtrl || bAlt)
  28.     {   
  29.         return;
  30.     }
  31.     //element
  32.     MSHTML::IHTMLElementPtr pElement=this->m_pSite->GetElement();
  33.     //pSystem 
  34.     //          should install PIMShell (http://www.pimshell.com)
  35.     PIMShellCore::IAjaxSystemPtr pSys;
  36.     pSys.CreateInstance(__uuidof(PIMShellCore::CAjaxSystem));
  37.     //tabNewActive href
  38.     bool bTabNewActive=pSys->GetAttribute(pElement,L"tabNewActive",false);
  39.     _bstr_t bstrHref=pSys->GetAttribute(pElement,L"href",L"");
  40.     //webbrowser
  41.     CComPtr<IWebBrowser2> pWebBrowser;
  42.     __CCuteGeneric::__GetWebBrowser(this->m_pOMSite,&pWebBrowser);
  43.     //url
  44.     _variant_t vURL=bstrHref;
  45.     //flag
  46.     LONG nFlags=bTabNewActive?(navOpenInNewTab):(navOpenInBackgroundTab);
  47.     _variant_t vFlag=nFlags;
  48.     //navigate
  49.     pWebBrowser->Navigate2(&vURL,&vFlag,NULL,NULL,NULL);
  50.     
  51.     //ok
  52.     e->returnValue=false;
  53.     e->cancelBubble=true;
  54. }

* 源碼下載:http://www.pimshell.com/pimshell/downloads/PIMShellDemo.zip

* System繫結元素onclick事件的機制,請參考:http://blog.csdn.net/pimshell/archive/2008/08/05/2773717.aspx

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.