欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
打造個(gè)性化的internet explorer

作者:孫輝

  在Microsoft的軟件哲學(xué)中,框架窗口是一個(gè)十分重要的角色,這類(lèi)窗口簡(jiǎn)直無(wú)處不在。所謂框架窗口,就是四個(gè)窗口邊上具有??繉ο竽芰Φ拇翱趯ο?,從現象上看,框架窗口有十分特別的“邊”,Microsoft構造的許許多多的東西都可以在其邊上“靠泊”,這就是所謂的“Docking”,Internet Explorer是Microsoft的一個(gè)典型的運用框架窗口的代表作品。今天的IE,在不知不覺(jué)中,你會(huì )發(fā)現工具欄中會(huì )多出一些東西來(lái),這一切的緣由歸根到底都是“邊”在作祟,本文試圖拋磚引玉,將你帶入豐富多彩的IE擴展世界。

Band,IE擴展的利器

  Band,是Windows Shell對象,當Microsoft將Internet Explorer與Windows Shell徹底集成時(shí),Band對象就成為Windows Shell的一個(gè)活躍對象,典型的Band對象有IE的搜索欄、收藏欄、歷史欄以及IE的各種工具欄等等。Microsoft公開(kāi)的Band對象有四類(lèi),一類(lèi)是桌面Band,如位于任務(wù)欄上的“快速啟動(dòng)”、“Windows Media Player”等工具條。而其他三種Band,則均出現在IE之中,包括工具欄Band(如MSN Search工具欄)、Explorer Band(如歷史、媒體等出現在IE左側的窗口)和通訊Band(如位于用戶(hù)區下方的“討論”窗口)。

  Band對象??吭趯贗E的框架窗口的四周,因此,給IE的界面提供了靈活的擴張機制。由于IE的用戶(hù)區基本上用于HTML對象的瀏覽,因此現在流行的B/S結構不能充分地運用IE靈活、強大的擴展機制,一旦可以將具有C/S結構特征的自定義子窗口掛接到IE的四周,將可以將IE打造成同時(shí)具備B/S、C/S體系優(yōu)勢的開(kāi)發(fā)框架?,F在,Microsoft已經(jīng)在Office系列產(chǎn)品中體現類(lèi)似的思路,例如在Microsoft Word以及Excel中,Microsoft引進(jìn)了Actions Pane對象,使得位于中心的Office文檔可以與??吭谝贿叺腁ctions Pane對象進(jìn)行通訊、交互操作等等,如圖1所示。


圖1  Word右側的“任務(wù)窗格”對象是個(gè)典型的Docking對象,這里體現了Microsoft最新的Smart Document技術(shù)

開(kāi)發(fā)你的Band對象,讓IE因你而變

  從IE4開(kāi)始,Band對象就已經(jīng)存在了,但其復雜的接口使大多數開(kāi)發(fā)人員望而卻步。一個(gè)典型的Band對象是一個(gè)COM對象,需要實(shí)現如下幾個(gè)接口:

  1. IDeskBand
  2. IObjectWithSite
  3. IPersistStream
  4. IInputObject

  每個(gè)接口各自包含一些列方法。接口IDeskBand決定了Band對象的基本行為,接口IObjectWithSite提供了Band對象與IE的通訊渠道,接口IInputObject提供了Band對象的輸入消息處理,特別該接口是處理對話(huà)框消息的關(guān)鍵所在,當需要實(shí)現桌面Band對象時(shí),接口IPersistStream提供實(shí)現相關(guān)的信息存儲(如Band對象的位置)。關(guān)于Band對象的一般介紹,可以參考Microsoft Internet SDK技術(shù)文檔,由于Microsoft僅提供了很少的文檔與范例,因此Band對象基本上被廣大開(kāi)發(fā)者忽略了。事實(shí)上,IE內部的擴展性十分強大(當然,強大也意味著(zhù)危險),就其擴展編程接口而言,IE的擴展性并不輸給FireFox。

  理論上,只要支持COM技術(shù)的開(kāi)發(fā)工具,都可以用來(lái)構造Band對象,然而對于更深層的COM技術(shù)細節而言,ATL/MFC類(lèi)庫還是最佳的選擇。毋庸置疑,MFC具備強大的界面構造能力,然而,由于缺乏一個(gè)有效的銜接,MFC類(lèi)庫與深層COM技術(shù)開(kāi)發(fā)一直被一層很薄的“紙”隔開(kāi)了,這一點(diǎn)不能不說(shuō)是個(gè)遺憾。

CTangramBandImpl,一個(gè)Band對象的起點(diǎn)

  首先,我們需要一個(gè)構造Band對象的起點(diǎn),為此我們構造一個(gè)基類(lèi),以實(shí)現上面提到的四個(gè)接口,CTangramBandImpl對象的詳細實(shí)現細節請參考我們提供的源代碼,以下是其基本構造:

class CTangramBandImpl :
    public IDeskBand,
    public IObjectWithSite,
    public IPersistStream,
    public IInputObject
{
public:
    CTangramBandImpl(void);
    virtual ~CTangramBandImpl(void);

// IDeskBand
public:
    STDMETHOD(GetBandInfo)(DWORD dwBandID, DWORD dwViewMode,
    DESKBANDINFO* pdbi);

// IObjectWithSite
public:
    STDMETHOD(SetSite)(IUnknown* pUnkSite);
    STDMETHOD(GetSite)(REFIID riid, void **ppvSite);

// IOleWindow
public:
    STDMETHOD(GetWindow)(HWND* phwnd);
    STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);

// IDockingWindow
public:
    STDMETHOD(CloseDW)(unsigned long dwReserved);
    STDMETHOD(ResizeBorderDW)(const RECT* prcBorder,
    IUnknown* punkToolbarSite, BOOL fReserved);
    STDMETHOD(ShowDW)(BOOL fShow);

// IPersist
public:
    STDMETHOD(GetClassID)(CLSID *pClassID);

// IPersistStream
public:
    STDMETHOD(IsDirty)(void);
    STDMETHOD(Load)(IStream *pStm);
    STDMETHOD(Save)(IStream *pStm, BOOL fClearDirty);
    STDMETHOD(GetSizeMax)(ULARGE_INTEGER *pcbSize);

// IInputObject
public:
    STDMETHOD(HasFocusIO)(void);
    STDMETHOD(TranslateAcceleratorIO)(LPMSG lpMsg);
    STDMETHOD(UIActivateIO)(BOOL fActivate, LPMSG lpMsg);

public:
    BOOL m_bFocus;
    BOOL m_bCommBand;
    void FocusChange(BOOL);

protected:
    virtual BOOL RegisterAndCreateWindow(){return false;};
    virtual void SetBandTitle(DESKBANDINFO* pdbi){};
    CFrameWnd* m_pFrameWnd;
    DWORD m_dwBandID;
    DWORD m_dwViewMode;
    BOOL m_bShow;
    BOOL m_bEnterHelpMode;
    HWND m_hWndParent;
    IInputObjectSite* m_pSite;
};

  對于IE,除了工具欄外,我們將??坑贗E框架左側的Band稱(chēng)為Explorer Band,而將??坑诳蚣艿走叺腂and稱(chēng)為通訊Band(Communication Band),從COM的角度看,這兩類(lèi)對象分別屬于不同的對象范疇(Category),所有這兩類(lèi)對象均被羅列在IE的View菜單的“Explorer Bar”子菜單中。我們實(shí)現的Explorer Band對象的類(lèi)結構如下:

class ATL_NO_VTABLE CBand : public CTangramBandImpl,
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CBand, &CLSID_Band>,
    public IDispatchImpl<IBand, &IID_IBand, &LIBID_TANGRAMBANDLib>
{
public:
    CBand();

    DECLARE_REGISTRY_RESOURCEID(IDR_BAND)

    DECLARE_PROTECT_FINAL_CONSTRUCT()

    BEGIN_CATEGORY_MAP(CBand)
        IMPLEMENTED_CATEGORY(CATID_InfoBand)
        IMPLEMENTED_CATEGORY(CATID_DeskBand)
    END_CATEGORY_MAP()

    BEGIN_COM_MAP(CBand)
        COM_INTERFACE_ENTRY(IBand)
        COM_INTERFACE_ENTRY(IOleWindow)
        COM_INTERFACE_ENTRY(IObjectWithSite)
        COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow)
        COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject)
        COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
        COM_INTERFACE_ENTRY(IPersist)
        COM_INTERFACE_ENTRY(IPersistStream)
        COM_INTERFACE_ENTRY(IDispatch)
    END_COM_MAP()

protected:
    virtual BOOL RegisterAndCreateWindow();
    virtual void SetBandTitle(DESKBANDINFO* pdbi);
};

代碼片斷:

BEGIN_CATEGORY_MAP(CBand)
    IMPLEMENTED_CATEGORY(CATID_InfoBand)
    IMPLEMENTED_CATEGORY(CATID_DeskBand)
END_CATEGORY_MAP()

表明CBand對象隸屬兩個(gè)對象范疇,分別是桌面Band以及Explorer Band,因此,此類(lèi)對象可以??坑赪indows Shell的桌面,同時(shí)也可以??坑贗E框架窗口的左側,當你在桌面的工具欄中點(diǎn)擊鼠標右鍵,選擇Toolbars時(shí),你會(huì )看到創(chuàng )建桌面TangramBand的菜單項:

  Communication Band對象CHBand的類(lèi)結構與CBand的基本一致,最大的區別是:

BEGIN_CATEGORY_MAP(CHBand)
    IMPLEMENTED_CATEGORY(CATID_CommBand)
END_CATEGORY_MAP()

  由于Band對象實(shí)現了接口IObjectWithSite,因此,Band對象可以通過(guò)該接口得到Band對象所從屬的IE實(shí)例。為此,我們注意到CTangramBandImpl中已經(jīng)實(shí)現了IObjectWithSite的方法SetSite,我們可以在其中添加如下代碼:

IOleCommandTarget* pCmdTarget = NULL;
IWebBrowser2* m_pBrowser;
HRESULT hr = pUnkSite->QueryInterface(IID_IOleCommandTarget,
    (LPVOID*)&pCmdTarget);
if(SUCCEEDED(hr))
{
    IServiceProvider* pSP;
    hr = pCmdTarget->QueryInterface(IID_IServiceProvider,
        (LPVOID*)&pSP);

    pCmdTarget->Release();
    if (SUCCEEDED(hr))
    {
        hr = pSP->QueryService(SID_SWebBrowserApp,
            IID_IWebBrowser2, (LPVOID*)&m_pBrowser);
        if(hr==S_OK)
            TRACE(_T("Get m_pBrowser: %x\n"),m_pBrowser);
        pSP->Release();
    }
}

  這樣就可以以得到這個(gè)Band對象對應的IE實(shí)例(即上述代碼中的m_pBrowser)。通過(guò)m_pBrowser,Band對象可以訪(fǎng)問(wèn)當前瀏覽器瀏覽的頁(yè)面、調用網(wǎng)頁(yè)中的腳本代碼以及實(shí)現其他的Band對象與網(wǎng)頁(yè)之間的交互功能。

實(shí)現基于MFC的Band對象

  為了將MFC類(lèi)庫的強大功能自然納入Band對象,我們需要一個(gè)基于MFC的Frame窗口。我們注意到,CTangramBandImpl已經(jīng)包含了一個(gè)成員變量:

CFrameWnd* m_pFrameWnd;

  這個(gè)變量建立了一座銜接Band對象與MFC類(lèi)庫的橋梁,在每個(gè)Band對象的RegisterAndCreateWindow函數中,均包含如下代碼:

BOOL CHBand::RegisterAndCreateWindow()
{
    RECT rect;
    ::GetClientRect(m_hWndParent, &rect);
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    theApp.m_pBand = this;
    m_pFrameWnd = new CTangramBandFrame();
    CCreateContext m_Context;
    m_Context.m_pNewViewClass = RUNTIME_CLASS(TestFormView);
    CWnd* pWnd = CWnd::FromHandle(m_hWndParent);
    m_pFrameWnd->Create(NULL,_T("TangramBand"),
        WS_CHILD, CRect(rect.left, rect.top,
        rect.right - rect.left, rect.bottom - rect.top),
        pWnd, NULL, NULL, &m_Context);
    theApp.m_pBand = NULL;
    return true;
}

  我們注意到,這段代碼創(chuàng )建了一個(gè)MFC CFrameWnd對象m_pFrameWnd。由此,一切關(guān)于MFC的代碼技巧自然而然地盤(pán)活了,我們看到一個(gè)典型的MFC框架被融入IE之中:

BOOL CTangramBandFrame::OnCreateClient(LPCREATESTRUCT lpcs,
    CCreateContext* pContext)
{
    if(!m_pBand->m_bCommBand)
    {
        m_SplitterWnd.CreateStatic(this, 2, 1);
        m_SplitterWnd.CreateView(0, 0, RUNTIME_CLASS(TestFormView),
            CSize(0, 100), NULL);
        m_SplitterWnd.CreateView(1, 0, RUNTIME_CLASS(TestFormView2),
            CSize(0, 100), NULL);
    }
    else
    {
        m_SplitterWnd.CreateStatic(this, 1, 2);
        m_SplitterWnd.CreateView(0, 0, RUNTIME_CLASS(TestFormView),
            CSize(150, 100), NULL);
        m_SplitterWnd.CreateView(0, 1, RUNTIME_CLASS(TestFormView2),
            CSize(0, 0), NULL);
    }
    return true;
}

  由于Band對象存在于一個(gè)動(dòng)態(tài)鏈接庫中,故創(chuàng )建MFC對象時(shí)要注意在合適的位置調用代碼:

AFX_MANAGE_STATE(AfxGetStaticModuleState());

以使得MFC能夠正確處理消息。

輸入消息處理

  接口IInputObject用于管理Band對象的輸入以及對話(huà)框、加速鍵消息,關(guān)于MFC消息,由于Band對象本質(zhì)上是一種IE插件,故消息隊列由IE控制,因此MFC窗口的消息處理是個(gè)關(guān)鍵問(wèn)題。當Band對象捕獲輸入焦點(diǎn)時(shí),我們必須保證MFC窗口消息被正確處理,下述代碼:

STDMETHODIMP CTangramBandImpl::TranslateAcceleratorIO(LPMSG lpMsg)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    if(m_bFocus&&theApp.m_pWnd)
    {
        theApp.m_pWnd->PreTranslateMessage(lpMsg);
        TRACE(_T("TranslateAcceleratorIO\n"));
        return S_OK;
    }
    return S_FALSE;
}

用來(lái)處理當前具有輸入焦點(diǎn)的MFC窗口theApp.m_pWnd的相關(guān)消息,因此具有輸入焦點(diǎn)的MFC窗口必須重載函數PreTranslateMessage,特別是CFormView的派生對象,在范例代碼中我們給出了重載該函數的例子。

調試與中文處理

  Band對象的調試例程是IE,因此需要修改工程配置,使得調試過(guò)程定向到IE。為使得Band對象能夠正確接受中文輸入,代碼工程必須是基于UNICODE的。

  您可以到雜志的站點(diǎn)(http://mag.csdn.net/msdn)上下載本刊附帶的源代碼,其中的MsdnJxControl解決方案中有本文所提到的項目的完整實(shí)現。該解決方案已經(jīng)為您做好了所有的配置工作,但還是希望您能夠通過(guò)屬性面板仔細觀(guān)察該解決方案的具體設置。

小結

  正如Microsoft系列的其他產(chǎn)品一樣,Internet Explorer中存在著(zhù)豐富的擴展空間。對于Microsoft而言,框架窗口的四周存在著(zhù)可??繉ο蟮目诎?,因此你可以在這些岸邊開(kāi)拓你的軟件空間以展示你的軟件魅力,如果你讀到了本文,那么你就開(kāi)始吧,充滿(mǎn)誘惑的海岸,等待你去開(kāi)拓。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
IE內核瀏覽器開(kāi)發(fā)筆記
ATL 實(shí)現定制的 IE 瀏覽器欄、工具欄和桌面工具欄
瀏覽器的定制與擴展
Mozilla ActiveX control
Popup Window Blocker
Internet Explorer 8 使用技巧
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久