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

隨筆-250  評(píng)論-20  文章-55  trackbacks-0
一、引言
  最近,由于工作的要求,我需要在 IE 上做一些開發(fā)工作。于是在 MSDN 上翻閱了一些資料,根據(jù) MSDN 上的說明我用 ATL 勝利完成了“資本家老板”分配的任務(wù)。
(并且在白天睡覺的過程中夢(mèng)到了老板給我加工資啦......)
現(xiàn)在,我把 MSDN 上的原文資料,經(jīng)過翻譯整理并把一個(gè) ATL 的實(shí)現(xiàn)奉賢給 VCKBASE 上的朋友們。

二、概念
  在翻譯的過程中,有兩個(gè)詞匯非常不好理解。第一個(gè)詞是 Band 對(duì)象,詞典中翻譯為“鑲邊、裙子邊、帶子、樂隊(duì)......”我的英文水平有限,實(shí)在不知道應(yīng)該翻譯為什么詞匯更合適。于是我毅然決然地決定:在如下的論述中,依然使用 band 這個(gè)詞!(什么?沒聽明白?我的意思就是說,我不翻譯這個(gè)詞了)但到底 Band 對(duì)象應(yīng)該如何理解那?請(qǐng)看圖一:


圖一

  圖一中畫紅圈的地方,分別稱作“垂直的瀏覽器欄”、“水平的瀏覽器欄”、“工具欄”和“桌面工具欄”。這些“欄”,都可以在 IE 的“查看”菜單中或鼠標(biāo)右鍵的上下文快捷方式菜單中顯示或隱藏起來。這些界面窗口的實(shí)現(xiàn),其實(shí)就是實(shí)現(xiàn)一種 COM 接口對(duì)象,而這個(gè)對(duì)象叫 band。這個(gè)概念實(shí)在是只能意會(huì)而無法言傳的,我總不能在文章中把它翻譯為“總是靠在 IE 主窗口邊上的對(duì)象”吧?^_^
  另外,還有一個(gè)詞叫 site。這個(gè)很好翻譯,叫“站點(diǎn)”!。呵呵,我敢打包票,如果你要能理解這個(gè)翻譯在計(jì)算機(jī)類文章中的含義,那就只能恭喜你了,你的智慧太高了。(都是學(xué)計(jì)算機(jī)軟件的人,做人的差距咋就這么大呢?)在本篇文章中,site 可以這樣理解:IE 的主框架四周,就好比是“汽車站”,那些 band 對(duì)象,就好比是“汽車”。band 汽車總是可以停靠在“汽車站”上。所以,site 就是“站點(diǎn)”,它也是 COM 接口的對(duì)象(IObjectWithSite、IInputObjectSite)。

三、原理

3.1 基本 band 對(duì)象
  Band 對(duì)象,從 Shell 4.71(IE 5.0) 開始提供支持。Band 是一個(gè) COM 對(duì)象,必須放在一個(gè)容器中去使用,當(dāng)然使用它們就好象使用普通窗口是一樣的。IE 就是一個(gè)容器,桌面 Shell 也是一個(gè)容器,它們提供不同的函數(shù)功能,但基本的實(shí)現(xiàn)是相似的。
  Band 對(duì)象分三種類型,瀏覽器欄 band(Explorer bands)、工具欄 band(Tool Bands)和桌面工具欄(Desk bands),而瀏覽器欄 band 又有兩種表現(xiàn)形式:垂直和水平的。那么 IE 和 Shell 如何區(qū)分并加載這些 bands 對(duì)象呢?方法是:你要對(duì)不同的 band 對(duì)象,在注冊(cè)表中注冊(cè)不同的組件類型(CATID)。

Band 樣式

組件類型

CATID

垂直的瀏覽器欄CATID_InfoBand00021493-0000-0000-C000-000000000046
水平的瀏覽器欄CATID_CommBand00021494-0000-0000-C000-000000000046
桌面的工具欄CATID_DeskBand00021492-0000-0000-C000-000000000046

  IE 工具欄不使用組件類型注冊(cè),而是使用在注冊(cè)進(jìn)行 CLSID 的登記方式。詳細(xì)情況見 3.3。
  在例子程序中,實(shí)現(xiàn)了全部四個(gè)類型的 band 對(duì)象,垂直瀏覽器欄(CVerticalBar)顯示了一個(gè) HTML 文件,并且實(shí)現(xiàn)了對(duì) IE 主窗口瀏覽網(wǎng)頁(yè)的導(dǎo)航等功能;水平的瀏覽器欄(CHorizontalBar)是一個(gè)編輯窗,它同步顯示當(dāng)前網(wǎng)頁(yè)的 BODY 源文件內(nèi)容;IE 工具欄(CToolBar)最簡(jiǎn)單,只是添加了一個(gè)空的工具欄;桌面工具欄(CDeskBar)實(shí)現(xiàn)了一個(gè)單行編輯窗口,你可以在上面輸入命令行或文件名稱,回車后它會(huì)執(zhí)行 Shell 的打開動(dòng)作。

3.2 必須實(shí)現(xiàn)的 COM 接口
  Band 對(duì)象是 IE 或 Shell 的進(jìn)程內(nèi)服務(wù)器,所以它被包裝在 DLL 中。而作為 COM 對(duì)象,它必須要實(shí)現(xiàn) IUnknown 和 IClassFactory 接口。(大家可以不同操心,因?yàn)槲覀冇?ATL 寫程序,這兩個(gè)接口是不用我們自己寫代碼的。)另外,Band 對(duì)象還必須實(shí)現(xiàn) IDeskBand、IObjectWithSite 和 IPersistStream 三個(gè)接口:
  IPersistStream 是持續(xù)性接口的一種。當(dāng) IE 加載 band 對(duì)象的時(shí)候,它通過這個(gè)接口的 Load 方法傳遞屬性值給對(duì)象,讓其進(jìn)行初始化;而當(dāng)卸載前,IE 則調(diào)用這個(gè)接口的 Save 方法保存對(duì)象的屬性。用 ATL 實(shí)現(xiàn)這個(gè)接口很簡(jiǎn)單:
class ATL_NO_VTABLE Cxxx : 
	......
	public IPersistStreamInitImpl, // 添加繼承
	......
{
public:
	BOOL m_bRequiresSave; // IPersistStreamInitImpl 所必須的變量
......
BEGIN_COM_MAP(CVerticalBar)
	......
	COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
	COM_INTERFACE_ENTRY2(IPersistStream, IPersistStreamInit)
	COM_INTERFACE_ENTRY(IPersistStreamInit)
	......
END_COM_MAP()

BEGIN_PROP_MAP(Cxxx)
...... // 添加需要持續(xù)性的屬性
END_PROP_MAP()		
  上面的代碼,其實(shí)實(shí)現(xiàn)的是 IPersistStreamInit 接口,不過沒有關(guān)系,因?yàn)?IPersistStreamInit 派生自 IPersistStream,實(shí)例化了派生類,自然就實(shí)例化了基類。在例子程序中,我只在桌面工具欄對(duì)象中添加了持續(xù)性屬性,用來保存和初始化“命令行”。另外 COM_INTERFACE_ENTRY2(A,B)表示的含義是:如果想查詢A接口的指針,則提供B接口指針來代替。為什么可以這樣那?因?yàn)锽接口派生自A接口,那么B接口的前幾個(gè)函數(shù)必然就是A接口的函數(shù)了,自然B接口的地址其實(shí)和A接口的地址是一樣的了。
  IObjectWithSite 是 IE 用來對(duì)插件進(jìn)行管理和通訊用的一個(gè)接口。必須要實(shí)現(xiàn)這個(gè)接口的2個(gè)函數(shù):SetSite() 和 GetSite()。當(dāng) IE 加載 band 對(duì)象和釋放 band 對(duì)象的時(shí)候,都要調(diào)用 SetSite()函數(shù),那么在這個(gè)函數(shù)里正好是寫初始化和釋放操作代碼的地方:
STDMETHODIMP Cxxx::SetSite(IUnknown *pUnkSite)
{
	if( NULL == pUnkSite )	// 釋放 band 的時(shí)候
	{
		// 如果加載的時(shí)候,保存了一些接口
		// 那么現(xiàn)在:釋放它
	}
	else	// 加載 band 的時(shí)候
	{
		m_hwndParent = NULL;	// 裝載 band 的父窗口(就是帶有標(biāo)題的那個(gè)框架窗口)

		// 這個(gè)窗口的句柄,是調(diào)用 IUnknown::QueryInterface() 得到 IOleWindow
		// 然后調(diào)用 IOleWindow::GetWindow() 而獲得的。
		CComQIPtr< IOleWindow, &IID_IOleWindow > spOleWindow(pUnkSite);
		if( spOleWindow )	spOleWindow->GetWindow(&m_hwndParent);
		if( !m_hwndParent )	return E_FAIL;
		
		// 現(xiàn)在,正好是建立子窗口的時(shí)機(jī)。
		// 注意,子窗口建立的時(shí)候,不要使用 WS_VISIBLE 屬性
		... ...
		// 在例子程序中,用 CAxWindow 實(shí)現(xiàn)了一個(gè)能包容ActiveX的容器窗口(垂直瀏覽器欄)
		// 在例子程序中,用 WIN API 函數(shù) CreateWindow 實(shí)現(xiàn)了標(biāo)準(zhǔn)窗口(水平瀏覽器欄、工具欄)
		// 在例子程序中,用 CWindowImpl 實(shí)現(xiàn)了一個(gè)包容窗口(桌面工具欄)

		/*********************************************************/
		   以下部分,根據(jù) band 對(duì)象特有的功能,是可以選擇實(shí)現(xiàn)的
		**********************************************************/		
		// 如果子窗口實(shí)現(xiàn)了用戶輸入,那么必須實(shí)現(xiàn) IInputObject 接口,
		// 而該接口是被 IE 的 IInputObjectSite 調(diào)用的,因此在你的對(duì)象
		// 中,應(yīng)該保存 IInputObjectSite 的接口指針。
		// 在類的頭文件中,定義:
		// CComQIPtr< IInputObjectSite, &IID_IInputObjectSite > m_spSite;

		m_spSite = pUnkSite;	// 保存 IInputObjectSite 指針
		if( !m_spSite )		return E_FAIL;

		// 你需要控制 IE 的主框架嗎?
		// 那么在類的頭文件中,定義:
		// CComQIPtr< IWebBrowser2, &IID_IWebBrowser2 > m_spFrameWB;
		// 然后,先取得 IServiceProvider,再取得 IWebBrowser2

		CComQIPtr < IServiceProvider, &IID_IServiceProvider> spSP(pUnkSite);
		if( !spSP )	return E_FAIL;
		spSP->QueryService( SID_SWebBrowserApp, &m_spFrameWB );
		if( !m_spFrameWB)	return E_FAIL;

		// 如果你取得了 IE 主框架的 IWebBrowser2 指針
		// 那么,當(dāng)它發(fā)生了什么事情,你難道不想知道嗎?
		// 定義:CComPtr m_spCP;

		CComQIPtr< IConnectionPointContainer,
			&IID_IConnectionPointContainer> spCPC( m_spFrameWB );
		if( spCPC )
		{
			spCPC->FindConnectionPoint( DIID_DWebBrowserEvents2, &m_spCP );
			if( m_spCP )
			{
				m_spCP->Advise( reinterpret_cast< IDispatch * >( this ), &m_dwCookie );
			}
		}

		// 咳~~~ 不說了,看源碼去吧。這里能干的事情太多了... ...
	}
	return S_OK;
}		
IDeskBand 是一個(gè)特殊的 band 對(duì)象接口,有一個(gè)方法函數(shù):GetBarInfo();
IDockingWindow 是 IDeskBank 的基類,有3個(gè)方法函數(shù):ShowDW()、CloseDW()、ResizeBorderDW();
IOleWindow 又是 IDockingWindow 的基類,有2個(gè)方法函數(shù):GetWindow()、ContextSensitiveHelp();

  首先聲明 IDeskBand ,然后要實(shí)現(xiàn) IDeskBand 接口的共6個(gè)函數(shù),這些函數(shù)比較簡(jiǎn)單,不同類型的 band 對(duì)象,其實(shí)現(xiàn)方法也都基本一致:
class ATL_NO_VTABLE Cxxx : 
	......
	public IDeskBand,
	......
{
......
BEGIN_COM_MAP(Cxxx)
	......
	COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand)
	......
END_COM_MAP()



// IOleWindow
STDMETHODIMP Cxxx::GetWindow(HWND * phwnd)
{	// 取得 band 對(duì)象的窗口句柄
	// m_hWnd 是建立窗口時(shí)候保存的
	*phwnd = m_hWnd;	
	return S_OK;
}

STDMETHODIMP Cxxx::ContextSensitiveHelp(BOOL fEnterMode)
{	// 上下文幫助,參考 IContextMenu 接口
	return E_NOTIMPL;
}

// IDockingWindow
STDMETHODIMP CVerticalBar::ShowDW(BOOL bShow)
{	// 顯示或隱藏 band 窗口
	if( m_hWnd )
		::ShowWindow( m_hWnd, bShow ? SW_SHOW : SW_HIDE);

	return S_OK;
}

STDMETHODIMP CVerticalBar::CloseDW(DWORD dwReserved)
{	// 銷毀 band 窗口
	if( ::IsWindow( m_hWnd ) )
		::DestroyWindow( m_hWnd );

	m_hWnd = NULL;

    return S_OK;
}

STDMETHODIMP CVerticalBar::ResizeBorderDW(LPCRECT prcBorder, IUnknown* punkToolbarSite, BOOL fReserved)
{	// 當(dāng)框架窗口的邊框大小改變時(shí)
	return E_NOTIMPL;
}

// IDeskBand
STDMETHODIMP CVerticalBar::GetBandInfo(DWORD dwBandID, DWORD dwViewMode,  DESKBANDINFO* pdbi)
{	
         // 取得 band 的基本信息,你需要填寫 pdbi 參數(shù)作為返回
	if( NULL == pdbi )		return E_INVALIDARG;

	// 如果將來需要調(diào)用 IOleCommandTarget::Exec() 則需要保存這2個(gè)參數(shù)
	m_dwBandID = dwBandID;
	m_dwViewMode = dwViewMode;

	if(pdbi->dwMask & DBIM_MINSIZE)
	{	// 最小尺寸
		pdbi->ptMinSize.x = 10;
		pdbi->ptMinSize.y = 10;
	}

	if(pdbi->dwMask & DBIM_MAXSIZE)
	{	// 最大尺寸 (-1 表示 4G)
		pdbi->ptMaxSize.x = -1;
		pdbi->ptMaxSize.y = -1;
	}

	if(pdbi->dwMask & DBIM_INTEGRAL)
	{
		pdbi->ptIntegral.x = 1;
		pdbi->ptIntegral.y = 1;
	}

	if(pdbi->dwMask & DBIM_ACTUAL)
	{
		pdbi->ptActual.x = 0;
		pdbi->ptActual.y = 0;
	}

	if(pdbi->dwMask & DBIM_TITLE)
	{	// 窗口標(biāo)題
		wcscpy(pdbi->wszTitle,L"窗口標(biāo)題");
	}

	if(pdbi->dwMask & DBIM_MODEFLAGS)
	{
		pdbi->dwModeFlags = DBIMF_VARIABLEHEIGHT;
	}

	if(pdbi->dwMask & DBIM_BKCOLOR)
	{	// 如果使用默認(rèn)的背景色,則移除該標(biāo)志
		pdbi->dwMask &= ~DBIM_BKCOLOR;
	}

	return S_OK;
}		
3.3 選擇實(shí)現(xiàn)的 COM 接口
  有兩個(gè)接口不是必須實(shí)現(xiàn)的,但也許很有用:IInputObject 和 IContextMenu。如果 band 對(duì)象需要接收用戶的輸入,那么必須實(shí)現(xiàn) IInputObject 接口。IE 實(shí)現(xiàn)了 IInputObjectSite 接口,當(dāng)容器中有多個(gè)輸入窗口時(shí),它調(diào)用 IInputObject 接口方法去負(fù)責(zé)管理用戶的輸入焦點(diǎn)。
在瀏覽器欄中需要實(shí)現(xiàn)3個(gè)函數(shù):UIActivateIO()、HasFocusIO()、TranslateAcceleratorIO()。
當(dāng)瀏覽器欄激活或失去活性的時(shí)候,IE 調(diào)用 UIActivateIO 函數(shù),當(dāng)激活的時(shí)候,瀏覽器欄一般調(diào)用 SetFocus 去設(shè)置它自己窗口的焦點(diǎn)。當(dāng) IE 需要判斷哪個(gè)窗口有焦點(diǎn)的時(shí)候,它調(diào)用 HasFocusIO 。當(dāng)瀏覽器欄的窗口或其子窗口有輸入焦點(diǎn)時(shí),則應(yīng)返回 S_OK,否則返回 S_FALSE。TranslateAcceleratorIO 允許對(duì)象處理加速鍵,例子程序中沒有實(shí)現(xiàn),所以直接返回 S_FALSE。
STDMETHODIMP CExplorerBar::UIActivateIO(BOOL fActivate, LPMSG pMsg)
{
    if(fActivate)
        SetFocus(m_hWnd);

    return S_OK;
}

STDMETHODIMP CExplorerBar::HasFocusIO(void)
{
    if(m_bFocus)
        return S_OK;

    return S_FALSE;
}

STDMETHODIMP CExplorerBar::TranslateAcceleratorIO(LPMSG pMsg)
{
    return S_FALSE;
}      
  Band 對(duì)象能夠通過包容器的 IOleCommandTarget::Exec() 調(diào)用執(zhí)行命令。而 IOleCommandTarget 接口指針,則可以通過調(diào)用包容器的 IInputOjbectSite::QueryInterface(IID_IOleCommandTarget,...) 函數(shù)得到。CGID_DeskBand 是命令組,當(dāng)一個(gè) band 對(duì)象的 GetBandInfo 被調(diào)用的時(shí)候,包容器通過 dwBandID 參數(shù)指定一個(gè) ID 給 band 對(duì)象,對(duì)象要保存住這個(gè)ID,以便調(diào)用 IOleCommandTarget::Exec()的時(shí)候使用。ID 的命令有:
  • DBID_BANDINFOCHANGED
    Band 的信息變化。設(shè)置參數(shù) pvaIn 為 band ID, 該 ID 就是最近一次調(diào)用 GetBandInfo 所得到的值,容器會(huì)調(diào)用 band 對(duì)象的 GetBandInfo 函數(shù)來更新請(qǐng)求信息。
  • DBID_MAXIMIZEBAND
    最大化 band。設(shè)置參數(shù) pvaIn 為 band ID,該 ID 就是最近一次調(diào)用 ?GetBandInfo ?所得到的值。
  • DBID_SHOWONLY
    打開或關(guān)閉容器中其它的 bands。 設(shè)置參數(shù) pvaIn 為VT_UNKNOWN 類型,它可以是如下的值:
     
    描述
    pUnkband 對(duì)象的 IUnknown 指針,其它的桌面 bands 將被隱藏
    0隱藏所有的桌面 bands
    1顯示所有的桌面 bands

  • DBID_PUSHCHEVRON
    在菜單項(xiàng)左邊顯示“v”的選擇標(biāo)志。容器發(fā)送一個(gè) RB_PUSHCHEVRON 消息,當(dāng) band 對(duì)象接收到通知消息 RBN_CHEVRONPUSHED 提示它顯示一個(gè)"v"的標(biāo)志。設(shè)置 IOleCommandTarget::Exec 函數(shù)中 nCmdExecOpt 參數(shù)為 band ID,該 ID 是最近一次調(diào)用 GetBandInfo ?所得到的值,設(shè)置 IOleCommandTarget::Exec 函數(shù)中 pvaIn 參數(shù)為 VT_I4 類型,這是應(yīng)用程序定義的一個(gè)值,它通過通知消息 RBN_CHEVRONPUSHED 中l(wèi)AppValue 回傳給 band 對(duì)象。

3.4 Band 對(duì)象注冊(cè)
  Band 對(duì)象必須注冊(cè)為一個(gè) OLE 進(jìn)程內(nèi)的服務(wù)器,并且支持 apartment 線程公寓。注冊(cè)表中默認(rèn)鍵的值是表示菜單的文字。對(duì)于瀏覽器欄,它加到 IE 菜單的“查看\瀏覽器欄”中;對(duì)于工具欄 band ,它加到 IE 菜單的“查看\工具欄”中;對(duì)于桌面 band, 它加到系統(tǒng)任務(wù)欄的快捷菜單中。在菜單資源中,可以使用“&”指明加速鍵。

通常,一個(gè)基本的 band 對(duì)象的注冊(cè)表項(xiàng)目是:

HKEY_CLASSES_ROOT
CLSID
{你的 band 對(duì)象的 CLSID}

  (Default) = 菜單的文字
  InProcServer32
   (Default) = DLL 的全路徑文件名
   ThreadingModel= Apartment

工具欄 bands 還必須把它們的 CLSID 注冊(cè)到 IE 的注冊(cè)表中。

HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Toolbar 下給出 CLSID 作為鍵名,而其鍵值是被忽略的。

HKEY_LOCAL_MACHINE
Software
Microsoft
Internet Explorer
Toolbar

  {你的 band 對(duì)象的 CLSID}

  還有幾個(gè)可選的注冊(cè)表項(xiàng)目(例子程序并不是這樣實(shí)現(xiàn)的)。比如,你想讓瀏覽器欄顯示 HTML 的話,必須要如下設(shè)置注冊(cè)表:

HKEY_CLASSES_ROOT
CLSID
{你的 Band 對(duì)象的 CLSID}
Instance
CLSID
  
(Default) = {4D5C8C2A-D075-11D0-B416-00C04FB90376}

同時(shí),如果要指定一個(gè)本地的 HTML 文件,那么要如下設(shè)置:

HKEY_CLASSES_ROOT
CLSID
{你的 Band 對(duì)象的 CLSID}
Instance
InitPropertyBag
  
Url

  另外,還可以指定瀏覽器欄的寬和高,當(dāng)然,它是依賴于這個(gè)欄是縱向還是橫向的。其實(shí)這個(gè)項(xiàng)目無所謂,因?yàn)楫?dāng)用戶調(diào)整了瀏覽器欄的大小后,會(huì)自動(dòng)保存在注冊(cè)表中的。

HKEY_CURRENT_USER
Software
Microsoft
Internet Explorer
Explorer Bars
{你的 Band 對(duì)象的 CLSID}
  
BarSize

  BarSize 鍵的類型必須是 REG_BINARY 類型,它有8個(gè)字節(jié)。左起前4個(gè)字節(jié),是用16進(jìn)制表示的像素寬度或高度,后4個(gè)字節(jié)保留,你應(yīng)該設(shè)置為0。下面是一個(gè)可以在瀏覽器欄上顯示 HTML 文件的全部注冊(cè)表項(xiàng)目的例子,默認(rèn)寬度為291(0x123)個(gè)像素點(diǎn):

HKEY_CLASSES_ROOT
CLSID
{你的 Band 對(duì)象的 CLSID}

 (Default) = 菜單文字
 InProcServer32
  (Default) = DLL 的全路徑文件名
  ThreadingModel= Apartment
Instance
CLSID

  (Default) = {4D5C8C2A-D075-11D0-B416-00C04FB90376}
InitPropertyBag
  Url= 你的 HTML 文件名

HKEY_CURRENT_USER
Software
Microsoft
Internet Explorer
Explorer Bars
{你的 Band 對(duì)象的 CLSID}

  BarSize= 23 01 00 00 00 00 00 00

  對(duì)于注冊(cè)表的設(shè)置,用 ATL 實(shí)現(xiàn)其實(shí)是異常簡(jiǎn)單的。打開工程的 xxx.rgs 文件,并手工編輯一下就可以了。 下面這個(gè)文件源碼,是例子程序中 IE 工具欄的注冊(cè)表樣式,HKLM 是需要手工添加的,因?yàn)樗皇褂媒M件類型方式注冊(cè)。而對(duì)于其它類型的 band 對(duì)象只要在類聲明中添加:

BEGIN_CATEGORY_MAP(Cxxx)			// 向注冊(cè)表中注冊(cè) COM 類型
	IMPLEMENTED_CATEGORY(CATID_InfoBand)	// 垂直樣式的瀏覽器欄
END_CATEGORY_MAP()		
IE 工具欄類型 band 對(duì)象的“.rgs”文件
HKCR	// 這個(gè)項(xiàng)目是 ATL 幫你生成的,你只要手工修改“菜單上的文字”就可以了
{
	Bands.ToolBar.1 = s ''ToolBar Class''
	{
		CLSID = s ''{ 你的 CLSID }''
	}
	Bands.ToolBar = s ''ToolBar Class''
	{
		CLSID = s ''{ 你的 CLSID }''
		CurVer = s ''Bands.ToolBar.1''
	}
	NoRemove CLSID
	{
		ForceRemove { 你的 CLSID } = s ''用在菜單上的文字(&T)''
		{
			ProgID = s ''Bands.ToolBar.1''
			VersionIndependentProgID = s ''Bands.ToolBar''
			ForceRemove ''Programmable''
			InprocServer32 = s ''%MODULE%''
			{
				val ThreadingModel = s ''Apartment''
			}
			''TypeLib'' = s ''{xxxx-xxxx-xxxxxxxxxxxxxxx}''
		}
	}
}

HKLM	// 這個(gè)項(xiàng)目是手工添加的IE工具欄所特有的
{
	Software
	{
		Microsoft
		{
			''Internet Explorer''
			{
				NoRemove Toolbar
				{
					ForceRemove val { 你的 CLSID } = s ''隨便給個(gè)說明性文字串''
				}
			}
		}
	}
}		
四、 ATL 實(shí)現(xiàn)
  下載代碼后(VC 6.0 工程),請(qǐng)參照前面的說明仔細(xì)閱讀,代碼中也有一些關(guān)鍵點(diǎn)的注釋。如果想運(yùn)行,則可以用 regsvr32.exe 進(jìn)行注冊(cè),然后打開 IE 瀏覽器或資源瀏覽器就可以看到效果了。如果想自己實(shí)踐一下,可以按照如下的步驟構(gòu)造工程:

4.1 建立一個(gè) ATL DLL 工程
4.2 添加 New ATL Object...,選擇 Internet Explorer Object,選這個(gè)類型的目的是讓向?qū)Ыo我們添加 IObjectWithSite 的支持。如果你使用的是 .net 環(huán)境,則不要忘記選擇支持這個(gè)接口。



4.3 輸入對(duì)象名稱,比如我想建立一個(gè)垂直的瀏覽器欄,不妨叫它 VerBar



4.4 線程模型必須選擇 Apartment,接口類型的選擇無所謂,看你想不想支持 IDispatch 接口功能了。在例子程序中的垂直瀏覽器欄中,由于想更簡(jiǎn)單的操縱 IE 和從 IE 中接受事件(連接點(diǎn)),選擇 Dual 是必要的。聚合選項(xiàng),你只要?jiǎng)e選擇 Only 就可以了。



4.5 展現(xiàn)你無窮的智慧,開始輸入程序吧。如果是 Debug 方式編譯,可能會(huì)出現(xiàn)一個(gè)連接錯(cuò)誤,報(bào)告找不到_AtlAxCreateControl,那么你要在菜單 Project\Settings...\Link 中增加對(duì) Atl.lib 的連接。或者使用 #pragma comment ( lib, "atl" )加入連接庫(kù)。
4.6 如果想調(diào)試代碼,在菜單 Project\Settings...\Debug 中輸入 IE 的路徑名稱,比如:“C:\Program Files\Internet Explorer\IEXPLORE.EXE”,然后就可以跟蹤斷點(diǎn)調(diào)試了。 編譯和調(diào)試桌面工具欄的 band 對(duì)象,是非常麻煩的,因?yàn)橛?jì)算機(jī)啟動(dòng)時(shí)自動(dòng)運(yùn)行 Shell,而 Shell 就會(huì)加載活動(dòng)的桌面對(duì)象。

五、結(jié)束語(yǔ)
好了,到這里,就到這里了。祝大家學(xué)習(xí)快樂^_^
posted on 2007-03-11 14:35 jay 閱讀(438) 評(píng)論(0)  編輯 收藏 引用 所屬分類: IE編程
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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成人黄色| 欧美粗暴jizz性欧美20| 久久精品成人一区二区三区蜜臀| 久久精品av麻豆的观看方式 | 久久精品国产免费观看| 亚洲网站在线| 一区二区三区欧美日韩| 亚洲理伦在线| 亚洲中字黄色| 欧美伊人精品成人久久综合97 | 国产精品一区二区三区乱码 | 久久久欧美精品sm网站| 欧美一区二区视频在线| 久久综合中文字幕| 欧美日韩直播| 国产欧美日韩亚洲一区二区三区 | 欧美日韩一区二区免费在线观看| 欧美精品激情在线| 激情视频一区二区三区| 亚洲伦伦在线| 麻豆精品精华液| 在线亚洲精品| 欧美剧在线观看| 樱桃成人精品视频在线播放| 亚洲欧美在线免费观看| 亚洲精品乱码久久久久久久久| 亚洲精品一区二区在线观看| 久久久久久伊人| 在线观看视频一区| 久久亚洲免费| 亚洲欧美日韩综合aⅴ视频| 另类尿喷潮videofree| 亚洲一品av免费观看| 欧美日韩另类视频| 亚洲精品欧美精品| 麻豆9191精品国产| 午夜欧美大尺度福利影院在线看| 美日韩在线观看| 亚洲一区二区av电影| 欧美久久九九| 亚洲日韩视频| 欧美韩日一区二区三区| 久久精品成人| 国产一区二区三区久久久久久久久| 日韩一二三在线视频播| 欧美11—12娇小xxxx| 久久国产天堂福利天堂| 国产亚洲精品激情久久| 欧美一区二区福利在线| 日韩一级精品视频在线观看| 久久视频在线视频| 蜜桃久久av| 亚洲每日更新| 欧美成ee人免费视频| 蜜臀a∨国产成人精品| 亚洲三级影院| 亚洲国内自拍| 欧美日韩综合| 久久精品国产亚洲一区二区| 欧美日韩性视频在线| 亚洲国产精品黑人久久久| 亚洲国产精品日韩| 欧美精品一卡二卡| 欧美一区二区三区视频| 久久综合色影院| 欧美日韩中文字幕日韩欧美| av成人免费在线观看| 久久久久久久综合日本| 小黄鸭视频精品导航| 国产精品视频999| 久久久久久噜噜噜久久久精品| 校园春色国产精品| 亚洲精品日韩一| 欧美在线观看网址综合| 亚洲靠逼com| 久久综合久久久久88| 亚洲一区二区三区四区五区午夜| 欧美在线91| 久久久久五月天| 国产精品日本欧美一区二区三区| 欧美不卡视频一区| 99国内精品久久| 亚洲国产天堂网精品网站| 先锋影音网一区二区| 亚洲一级影院| 欧美日韩大片| 亚洲日本成人| 亚洲天堂网站在线观看视频| 久久中文精品| 久久在线免费观看视频| 国内精品久久久久影院 日本资源| 亚洲精品看片| 99精品欧美一区二区蜜桃免费| 久久久av水蜜桃| 猛男gaygay欧美视频| 亚洲美女毛片| 欧美日韩精品综合| 一区二区电影免费在线观看| 一区二区三区 在线观看视| 欧美成人中文| 欧美成人激情在线| 亚洲一区二区三区精品在线| 亚洲高清激情| 亚洲精品人人| 国产精品高潮呻吟| 亚洲欧美一区二区原创| 久久av一区二区三区漫画| 黑人一区二区| 亚洲视屏在线播放| 久久精品国产v日韩v亚洲 | 国产精品美女www爽爽爽| 午夜精品免费视频| 亚洲福利一区| 国产精品素人视频| 欧美成人免费va影院高清| 亚洲视频在线免费观看| 亚洲国产精品va在线看黑人 | 亚洲精品在线免费| 久久综合国产精品| 久久精品视频一| 亚洲欧美一区二区三区久久| 日韩亚洲在线观看| 91久久精品国产91性色tv| 男人天堂欧美日韩| 久久精品一区二区三区不卡| 亚洲女人av| 久久国产精品久久国产精品| 欧美在线综合| 久久国产精品毛片| 9久re热视频在线精品| 亚洲精品视频一区| 一区二区高清在线| 亚洲综合好骚| 久久精品国产77777蜜臀| 久久九九有精品国产23| 另类国产ts人妖高潮视频| 99在线精品视频在线观看| 国产在线拍偷自揄拍精品| 国产精品国产三级国产普通话99| 久久久久中文| 欧美高清视频| 欧美国产日韩免费| 黄色一区二区在线观看| 国产精品99久久久久久白浆小说 | 亚洲欧美文学| 六十路精品视频| 欧美三级视频在线观看| 国产日韩欧美日韩大片| 亚洲国产精品久久人人爱蜜臀| 亚洲精品一二三区| 久久精品亚洲精品| 99视频在线精品国自产拍免费观看| 亚洲综合首页| 欧美日韩在线播放一区二区| 在线成人激情| 久久久久久久久久久久久9999| 亚洲一区二区三区777| 亚洲国产精品一区二区www在线| 亚洲尤物在线| 国产精品一区二区三区免费观看| 日韩写真视频在线观看| 亚洲婷婷综合色高清在线| 亚洲日本欧美日韩高观看| 久久久久五月天| 一区二区三区无毛| 久久天堂精品| 亚洲综合日韩| 国产日韩欧美中文| 在线观看亚洲a| 美女诱惑一区| 欧美成在线视频| 午夜在线一区| 欧美在线视频日韩| 国产主播一区| 欧美成人免费播放| 欧美va天堂| 久久中文欧美| 99综合视频| 欧美一区二区三区免费看| 国产精品视频免费| 另类成人小视频在线| 欧美三级电影网| 久热国产精品视频| 欧美视频精品一区| 免播放器亚洲| 国产老肥熟一区二区三区| 久久亚洲私人国产精品va| 久久久久网址| 国产欧美一区二区精品婷婷| 亚洲一区二区三区高清不卡| 亚洲一卡久久| 国产精品日韩欧美综合| 亚洲在线免费| 久久久久在线观看| 国产自产精品| 欧美sm视频| 一区二区三区国产精华| 久久精品三级| 亚洲精美视频| 欧美视频在线免费看|