青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

旅途

如果想飛得高,就該把地平線忘掉

Internet Explorer 編程簡述(九)在自己的瀏覽器中嵌入Google工具條

關鍵字:Google Toolbar, Explorer Bars, ToolBands, IObjectWithSite, IDeskBand

 

1、概述

  Internet Explorer強大而方便的可編程能力和可擴展能力為其搶占瀏覽器市場可謂是立下了汗馬功勞。可編程主要體現兩方面:

  • 實現瀏覽功能的部分被包裝成一個控件——WebBrowser Control,開發人員可以在自己的應用程序中嵌入它從而使程序具有訪問Internet上網頁的能力,同時WebBrowser Control也能夠被靈活地自定義以滿足不同的需要。
  • 可對Microsoft Internet Explorer應用程序本身嵌入的瀏覽器控件編程,一般通過BHO(Browser Helper Object)來實現。

 

  可擴展能力則體現在幾個方面:

  • 嵌入式面板型擴展,包括Explorer Bars(如收藏夾、搜索、歷史等嵌入IE主窗口的大型面板), Tool Bands(如Google Toolbar、MSN Toolbar等嵌入IE的工具條), 和Desk Bands(如快速啟動這類嵌入任務欄的面板,實際上是Explorer外殼的擴展)。這幾種面板的編寫方法相差無幾,不同之處主要在于向系統注冊方式的不同。

 

Explorer bars

 

Tool bands

Desk band

 

 

  • 是參數型擴展,包括為瀏覽器增加上下文菜單項(調用腳本)、為瀏覽器主菜單增加菜單項、為瀏覽器“標準按鈕”工具條添加按鈕等。
  • 其他擴展,如文件下載的擴展(Custom Download Manager)、地址欄擴展(搜索擴展)等。

 

  隨著IE的發展,各種類型的擴展遍地開花,其中最為引人注目的,當屬地址欄擴展和工具條擴展(幾乎成了兵家必爭之地)。本文討論的主題,正是工具條的擴展。

 

2、問題的提出

  兩個原因促成了Google Toolbar的流行,一是廣告窗口的泛濫、二是Google Search。Google“簡單”(實則一點都不簡單,沒有搜索引擎的強力支持,Toolbar的用途就大受限制)地抓住了這兩點,迅速占領了市場。

  插件的一大好處在于可以不修改主程序,只需換一個樣子差不多但功能更強的東西就可以使得整個應用程序功能增強,所以IE不升級大家也覺得Google Toobar越來越好用。于是利用WebBroser Control編寫瀏覽器的開發人員就想,如果能像IE一樣支持上述這些擴展,不就能把Google Toolbar拿過來用了嗎?其他的事交給Google去做就行了。這就是我們要討論的問題,“如何在自己的瀏覽器中嵌入Google Toolbar”。

 

3、分析

  微軟并未在MSDN中說明如何將Google Toolbar這類IE的工具條插件嵌入自己的應用程序,但其基于COM的設計方法實際上給予了我們這個能力(創建嵌入式的工具條的方法并不是本文的重點,此處略去,有興趣的朋友可以參考MSDN)。我們知道,除了IUnknown接口外,Bands和Bars(以下簡稱Band對象)還需要實現三個接口:IObjectWithSite,IPersistStream和IDeskBand。當用戶選擇工具條或面板時,其容器(如IE的外殼框架)就會調用Band對象的IObjectWithSite::SetSite方法(該方法僅需要一個IUnknown類型的指針),將自己實現的IUnknown指針傳遞給Band對象。這就是整個插件開始真正激活的入口,也是我們的著手點。

  MSDN中說到,一般來說,Band對象對于SetSite方法的實現需要完成以下幾件事:

  1. 如果當前Band對象持有另外的Site指針,則首先釋放該指針。
  2. 如果容器向SetSite方法傳入的是一個空指針,則表示要刪除該Band對象,此時SetSite返回S_OK即可。
  3. 如果容器傳入的不是空指針,則需要設置新的Site:
    1. 對此IUnknown指針所指的新Site調用QueryInterface查詢得到其IOleWindow接口。
    2. 調用得到的IOleWindow接口的GetWindow方法獲取父窗口的句柄(此窗口即是Band對象的棲身之處)并保存下來。如果以后不會再用到IOleWindow接口的話就對其調用Release。
    3. 現在可以創建Band對象的窗口了,當然,要以第2步得到的窗口為父窗口來創建,并且該窗口目前只能以不可見狀態存在。
    4. 如果Band對象實現了IInputObject接口,即需要接收鍵盤輸入,則還需要向容器傳來的Site查詢(QueryInterface)IInputObjectSite接口,此接口指針也需要保存下來。
    5. 上述步驟完成后即可返回S_OK,否則應返回OLE-defined的error code告知容器什么地方出了錯。

 

  顯然,就我們要討論的問題而言,只需換個角度(編寫IE外殼的的角度)來考慮即可。首先,我們需要一個IUnknown接口(即Band對象所需的Site),其次需要一個IInputObjectSite接口,用以和Band對象的IInputObject接口交互,處理輸入焦點轉移的情況。接下來就可以通過Band對象的IDeskBand接口來顯示、隱藏Band對象了(注意IDeskBand接口派生自IDockingWindow接口,后者又派生自IOleWindow接口)。

 

4、實現

  實現分為兩個部分,其一是一個簡單的類,用以模擬IE外殼,我取名為CIESimulator。其二是一個管理IE擴展的類CIEBandPlugInManager,用以管理Band對象的方方面面。

 

class CIESimulator : public IInputObjectSite

{

private:

IWebBrowser2 *m_pwb; //保存WebBrowser Control的接口指針

public:

CIESimulator(void){};

~CIESimulator(void){};

 

void SetIWebBrowser2(IWebBrowser2* pwb);

 

//IUnknown methods

STDMETHODIMP QueryInterface(REFIID, void **);

STDMETHODIMP_(ULONG) AddRef(void);

STDMETHODIMP_(ULONG) Release(void);

 

//IInputObjectSite specific methods

STDMETHOD(OnFocusChangeIS)(THIS_ IUnknown* punkObj, BOOL fSetFocus);

};

 

//IUnknown methods

STDMETHODIMP CIESimulator::QueryInterface( REFIID riid, void **ppv )

{

if ( riid == IID_IInputObjectSite )  //這個接口需要自己處理

{

*ppv = static_cast<IInputObjectSite*>(this);

}

else if ( m_pwb )  //其它的交給WebBrowser Control去處理

{

m_pwb->QueryInterface( riid, ppv );

}

return S_OK;

}

 

//IInputObjectSite specific methods

STDMETHODIMP CIESimulator::OnFocusChangeIS(IUnknown* punkObj, BOOL fSetFocus)

{

return S_OK;  //此處我們簡單地返回

}

 

void CIESimulator::SetIWebBrowser2(IWebBrowser2* pwb)

{

m_pwb = pwb;

}

 

  注意這里我們并沒有實現IOleWindow接口來向Band對象傳遞父窗口對象(窗口的宿主可以更改,所以Band對象創建的窗口的父窗口我們并不關心,Band對象查詢IOleWindow接口的動作實際上是向WebBrowser Control查詢),而是在稍后的CIEBandPlugInManager類中通過調用IDeskBand的GetWindow方法獲得Band對象的窗口句柄,再手動將其嵌入我們指定的窗口中。

 

  首先我們定義一個結構用以保存Band的信息:

enum eBANDTYPE

{

btVertical = 0,

btHorizontal = 1

};

 

enum eBANDSTATE

{

bsUnInitialized = -1,

bsVisible = 0,

bsInVisible = 1,

bsUnLoaded = 2

};

 

typedef struct tagIEBANDINFO

{

char

 

szCLSID[39];

char

 

szName[MAX_PATH];

IUnknown

*puk;

HWND

 

hBand;

UINT

 

uMinHeight;

UINT

 

uBandID;

eBANDTYPE

eBandType;

eBANDSTATE

eBandState;

} IEBANDINFO, *LPIEBANDINFO;

 

  再用一個函數來獲取所有Band的信息(以下代碼為示例,具體實現是可從注冊表把所有Band的信息一一讀出)

void CIEBandPlugInManager::GetAllBandCLSID(void)

{

LPIEBANDINFO pIEBandInfo;

 

pIEBandInfo = new IEBANDINFO();

strcpy( pIEBandInfo->szCLSID, "{2318C2B1-4965-11d4-9B18-009027A5CD4F}\0");  //Google Toolbar的CLSID

strcpy( pIEBandInfo->szName, GetDisplayName(pIEBandInfo->szCLSID) );

pIEBandInfo->uMinHeight = 22;

pIEBandInfo->uBandID = m_BandCtrlID++;

pIEBandInfo->eBandType = btHorizontal;

pIEBandInfo->eBandState = bsUnInitialized;

m_oaBand.Add( (CObject*)pIEBandInfo );//m_oaBand是一個CObArray

 

//根據CLSID從注冊表獲取Band的名稱

CString CIEBandPlugInManager::GetDisplayName(CString strCLSID)

{

TCHAR

 

sz[MAX_PATH];

HKEY

 

hKey;

DWORD

 

dwSize;

 

strCLSID = "CLSID\\" + strCLSID;

if(RegOpenKey(HKEY_CLASSES_ROOT, strCLSID, &hKey) != ERROR_SUCCESS)

{

return _T("");

}

 

RegQueryValueEx(hKey, NULL, NULL, NULL, (LPBYTE)sz, &dwSize);

RegCloseKey(hKey);

 

return sz;

}

 

//通過Band的CLSID激活Band

bool CIEBandPlugInManager::ActivateBand( CString strCLSID )

{

LPIEBANDINFO pIEBandInfo = GetBandInfo( strCLSID ); //從m_oaBand中找到符合條件的Band的信息

if ( !pIEBandInfo )

{

return false;

}

 

WCHAR wsz[MAX_PATH]; 

::MultiByteToWideChar(CP_ACP, 0, strCLSID, -1, wsz, MAX_PATH);

 

CLSID

clsid;

HRESULT hr2 = CLSIDFromString( wsz, &clsid);

if ( hr2 != NOERROR )

return false;

 

HRESULT hr = ::CoCreateInstance(clsid, NULL, LSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pIEBandInfo->puk); //創建Band對象的實例

IUnknown* puk = pIEBandInfo->puk;

if (FAILED(hr))

return false;

 

DoQueryBandInfo( pIEBandInfo );  //查詢Band對象實例的信息

 

switch( pIEBandInfo->eBandType )

{

case btVertical:

break;

//我們不處理Vertical的面板

case btHorizontal:

{

g_pMainFrame->m_wndReBar.AddBar2( pIEBandInfo->hBand, pIEBandInfo->uBandID, pIEBandInfo->uMinHeight, 0, 0); //將Band嵌入主窗口的ReBar中

 

REBARBANDINFO rbbi;

rbbi.cbSize = sizeof(rbbi);

rbbi.fMask = RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_SIZE;

rbbi.cxMinChild = 0;

rbbi.cyMinChild = pIEBandInfo->uMinHeight;

rbbi.cx = rbbi.cxIdeal = 250;

UINT nCount = g_pMainFrame->m_wndReBar.GetReBarCtrl().GetBandCount();

g_pMainFrame->m_wndReBar.GetReBarCtrl().SetBandInfo(nCount-1, &rbbi);

break;

}

default:

break;

}

pIEBandInfo->eBandState = bsVisible;

return true;

}

 

//查詢Band對象實例的信息

void CIEBandPlugInManager::DoQueryBandInfo(LPIEBANDINFO pIEBandInfo)

{

IObjectWithSite *pOWS;

//查詢IObjectWithSite接口

HRESULT hr = pIEBandInfo->puk->QueryInterface(IID_IObjectWithSite, (void**)&pOWS);

if (SUCCEEDED(hr))

{     //設置Site

pOWS->SetSite( (IUnknown *)&m_IESimulator ); //m_IESimulator是CIESimulator的一個實例對象,對Band對象而言,它就像IE

}

 

IDeskBand *pdb;

hr = pIEBandInfo->puk->QueryInterface(IID_IDeskBand, (void**)&pdb);

if (SUCCEEDED(hr))

{     //查詢得到Band對象窗口的句柄,稍候通過該句柄將Band對象的窗口嵌入我們指定的窗口

pdb->GetWindow(&pIEBandInfo->hBand);

}

 

ShowBand(pIEBandInfo, TRUE);//顯示Band

}

 

bool CIEBandPlugInManager::ShowBand(LPIEBANDINFO pIEBandInfo, bool bShow)

{

IDockingWindow *pdw;

HRESULT hr = pIEBandInfo->puk->QueryInterface(IID_IDockingWindow, (void**)&pdw);

if (SUCCEEDED(hr))

{

pdw->ShowDW(bShow);

}

else

{

return false;

}

return true;

}

 

  下面是我測試的一個截圖,Google的搜索、廣告窗口攔截均可正常工作。

嵌入Google toolbar演示

 

5、總結

  上述的原理看來很簡單,但具體實現的時候仍然需要作較多的測試和考慮,Band對象的管理和緩存、接口的AddRef和Release等。時間有限,代碼也很亂,不過只要原理交待清楚,相信會對有興趣的朋友有所幫助。

 

6、參考資料

MSDN:Creating Custom Explorer Bars, Tool Bands, and Desk Bands

 

引用地址:《Internet Explorer編程簡述(九)在自己的瀏覽器中嵌入Google工具條



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=550698


posted on 2007-07-29 15:25 旅途 閱讀(1032) 評論(0)  編輯 收藏 引用 所屬分類: BHO

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产精品久久久久婷婷老年| 中日韩高清电影网| 一区二区三区国产在线| 久热国产精品| 亚洲国产精品成人综合色在线婷婷 | 欧美成人午夜激情| 影院欧美亚洲| 女仆av观看一区| 91久久久一线二线三线品牌| 销魂美女一区二区三区视频在线| 国产精品theporn| 亚洲视屏一区| 久久伊人一区二区| 99精品视频免费全部在线| 国产精品ⅴa在线观看h| 欧美国产欧美亚州国产日韩mv天天看完整 | 蜜臀av性久久久久蜜臀aⅴ| 亚洲精品日韩激情在线电影| 午夜精品久久久久久久99樱桃| 伊伊综合在线| 在线观看日韩专区| 亚洲成色最大综合在线| 国产精品私拍pans大尺度在线 | 99v久久综合狠狠综合久久| 亚洲人成7777| 亚洲福利国产| 一本一本久久a久久精品综合麻豆| 国产色爱av资源综合区| 免费视频一区| 欧美日韩视频在线一区二区| 欧美一区二区成人| 一区二区三区回区在观看免费视频| 久久av红桃一区二区小说| 日韩视频国产视频| 精品盗摄一区二区三区| 欧美国产一区在线| 国产精品美女诱惑| 欧美日韩xxxxx| 欧美成熟视频| 欧美日韩国产专区| 韩日精品中文字幕| 国产精品v欧美精品v日本精品动漫 | 久久九九热re6这里有精品| 亚洲字幕在线观看| 亚洲一区亚洲二区| 久久久久成人精品| av成人免费观看| 99这里有精品| 欧美一级视频免费在线观看| 欧美日韩另类丝袜其他| 久久九九热免费视频| 亚洲精品人人| 久久伊人免费视频| 亚洲欧美卡通另类91av| 亚洲婷婷综合色高清在线| 久久久久久久久伊人| 在线观看日韩专区| 亚洲欧美日本日韩| 在线欧美日韩| 欧美在线高清视频| 久久成人亚洲| 中文在线一区| 久久精品国产久精国产一老狼| 久久婷婷久久一区二区三区| 国产精品亚洲一区| 亚洲一区三区在线观看| 亚洲精品影视| 欧美日韩亚洲视频一区| 亚洲国产精品va| 久久伊人一区二区| 老司机精品视频网站| 黄色成人精品网站| 欧美激情国产精品| 亚洲手机成人高清视频| 欧美系列电影免费观看| 99视频超级精品| 亚洲美女区一区| 校园春色综合网| 久久资源av| 亚洲国产另类 国产精品国产免费| 亚洲人体偷拍| 欧美国产视频在线| 久久这里有精品视频| 亚洲免费观看| 99视频精品全国免费| 欧美日韩另类字幕中文| 午夜欧美不卡精品aaaaa| 亚洲乱码国产乱码精品精| 欧美理论电影在线观看| 亚洲激情偷拍| 欧美国产欧美综合| 欧美日韩一本到| 香蕉久久精品日日躁夜夜躁| 欧美一级理论性理论a| 国产亚洲欧美一区| 一区在线观看| 亚洲国产91色在线| 亚洲图片欧美午夜| 黑丝一区二区三区| 亚洲欧洲另类| 欧美日韩亚洲91| 蜜桃av一区| 久久在线播放| 羞羞视频在线观看欧美| 免费成人av在线看| 久久都是精品| 欧美日韩在线播放三区四区| 久久网站免费| 久久夜色精品亚洲噜噜国产mv| 欧美特黄一区| 国产一区二区三区在线播放免费观看 | 久久视频精品在线| 亚洲无毛电影| 一区二区三区色| 亚洲第一精品电影| 亚洲一区二区av电影| 国产精品一区二区黑丝| 亚洲欧美综合网| 欧美国产大片| 美女999久久久精品视频| 国产精品看片你懂得| 亚洲日本一区二区| 欧美日韩亚洲一区三区| 亚洲第一页自拍| 国内精品视频在线观看| 亚洲国产你懂的| 有码中文亚洲精品| 亚洲欧美在线网| 91久久国产综合久久91精品网站| 亚洲欧美韩国| 欧美亚洲日本国产| 国产精品成人va在线观看| 久久人人爽国产| 美女国内精品自产拍在线播放| 欧美在线观看视频一区二区三区| 欧美午夜宅男影院| 国产精品99久久久久久www| 一本色道久久综合亚洲精品不| 欧美大片18| 亚洲伦理精品| 亚洲伊人观看| 国产精品久久久亚洲一区 | 亚洲激情视频在线| 99国产成+人+综合+亚洲欧美| 免费中文字幕日韩欧美| 欧美国产日韩一区二区| 日韩亚洲在线| 国产精品久久一区主播| 午夜精品免费| 久久免费99精品久久久久久| 韩日精品视频一区| 欧美www视频| 9久re热视频在线精品| 一区二区三区高清视频在线观看| 欧美日韩精品免费看| 亚洲综合丁香| 美女主播精品视频一二三四| 亚洲国产美女精品久久久久∴| 欧美成年人视频网站| 一二三区精品| 久久最新视频| 国产一区二区三区精品久久久| 久久九九国产精品| 欧美一区在线看| 精品不卡视频| 欧美日韩精品免费| 午夜欧美精品久久久久久久| 久久久免费精品| 日韩视频在线免费观看| 国产精品一级在线| 亚洲天堂久久| 欧美大片国产精品| 亚洲全部视频| 欧美中文在线观看| 亚洲精品网站在线播放gif| 香蕉久久久久久久av网站| 久久久久久有精品国产| 亚洲蜜桃精久久久久久久| 国产乱理伦片在线观看夜一区| 久久亚洲春色中文字幕| 亚洲图片你懂的| 亚洲福利小视频| 欧美一级一区| 99精品国产福利在线观看免费| 国产日韩欧美夫妻视频在线观看| 欧美暴力喷水在线| 欧美一区午夜视频在线观看| 久久久久久久一区| 亚洲美女色禁图| 国产一区二区你懂的| 欧美精品一区二区高清在线观看| 欧美成ee人免费视频| 91久久中文| 激情五月婷婷综合| 国产乱码精品一区二区三| 欧美激情影音先锋| 久久综合伊人77777麻豆| 午夜精品久久久久久| 一区二区三区国产在线| 亚洲精品国产精品国自产观看浪潮 |