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

旅途

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

Internet Explorer 編程簡述(八)實現瀏覽歷史菜單

關鍵字:ITravelLogStg, IEnumTravelLogEntry, ITravelLogEntry

 

1、概述

Internet Explorer的瀏覽歷史菜單在4.0版本開始出現,但直到5.5之前,微軟都未公布用于訪問瀏覽歷史的COM接口,如今已是IE6.0大行其道的年代,用于訪問瀏覽歷史的接口也早已公布多時,本文的目的則是試圖拋磚引玉,簡單介紹用于訪問瀏覽歷史的Travel Log接口,并用一個小小的類CIETravelLog來實現對Travel Log的封裝。

 

2、IOmHistory接口

在早些時候的MSDN中,我們能夠查閱到關于瀏覽歷史的接口僅有IOmHistory,而該接口實際上對應的是瀏覽器中可以通過腳本訪問的“history”對象。對于“history”對象,MSDN中是這樣說的:

 

For security reasons, the history object does not expose the actual URLs in the browser history. It does allow navigation through the browser history by exposing the back, forward, and go methods. A particular document in the browser history can be identified as an index relative to the current page. For example, specifying -1 as a parameter for the go method is the equivalent of clicking the Back button.

 

This object is available in script as of Microsoft Internet Explorer 3.0.

 

即為了安全的原因,IOmHistory接口僅提供了有限的幾個方法來完成在瀏覽器中前進、后退等操作,并沒有提供訪問歷史列表Url的能力。這也難怪,該接口在IE 3.0時代已經存在,而當時IE并不成熟,可編程能力也不甚強大。一直到IE 4.0通過與Windows 98捆綁銷售一統天下之后,相關的文檔才逐漸豐富,多窗口瀏覽器等基于Internet Explorer/WebBrowser Control的應用軟件也才鋪天蓋地開來。但在IE 5.5接口公布之前,要完全模擬IE的Travel Log行為,并不是一件容易的事。最容易想到的方法就是在BeforeNavigate、DocumentComplete等事件發生之時記錄/修改Url并加以保存(我在早些時候也這樣做過),但是效果不甚理想,尤其是瀏覽包含Frame的網頁時,處理更是麻煩。當然,要完全模擬亦非難事,只不過開發人員都知道微軟公布接口是早晚的事,所以也沒有人花大力氣在模擬IE的Travel Log行為上。

 

3、Travel Log簡介

Internet Explorer 5.5推出以后,Travel Log接口也就開始出現在MSDN中,它是專門為OLE嵌入WebBrowser Control的應用程序設計的,其目的是“提高和加強用戶的訪問日志體驗”(improve and enhance the user's travel log experience)。事實上,稍后我會提到,Travel Log接口正日益成為應用程序中的重要接口之一。

微軟公布的Travel Log共包含三個接口:ITravelLogStg, IEnumTravelLogEntry和ITravelLogEntry。

 

  • ITravelLogStg——該接口提供了用于在Travel Log中添加、刪除、枚舉日志(瀏覽歷史)的方法,本文需要用到的幾個方法列舉如下:

方法名     用途

EnumEntries 為訪問日志項創建枚舉器(IEnumTravelLogEntry接口指針)

GetRelativeEntry 返回一個日志項

TravelTo 訪問一個日志項

  • IEnumTravelLogEntry——該接口提供用于枚舉日志項所必需的方法,本文只用到一個方法:

方法名     用途

Next   枚舉下一個日志項(返回ITravelLogEntry接口指針)

  • ITravelLogEntry——該接口只有兩個方法,分別用于返回日志項的Title和Url:

方法名     用途

GetTitle 返回日志項的Title

GetURL 返回日志項的Url

 

接口準備好了,我們也就很容易得知它們之間的關系:

  • 要得到相對于當前頁面的日志項列表,首先應通過ITravelLogStg接口創建一個枚舉器(IEnumTravelLogEntry接口)。
  • 通過IEnumTravelLogEntry枚舉器的Next方法枚舉出一個個的日志項(ITravelLogEntry接口)。
  • 由ITravelLogEntry接口獲取日志項所代表的網頁的Title和Url并加以處理。
  • 訪問相對于當前頁面的某個日志項時,首先由ITravelLogStg的GetRelativeEntry方法根據與當前頁的距離得到ITravelLogEntry接口,再將后者傳入ITravelLogStg的TravelTo方法以達到訪問日志項的目的(如前進和后退)。

 

也許不是太恰當,我對UML也不熟悉,借用一個偽UML序列圖表示其關系如下:

 

 

 Travel log

 

4、封裝Travel Log

接下來,我們就用一個簡單的類來完成對Travel Log的封裝。如下所示,tlogstg.h包含了Travel Log的相關接口聲明,該頭文件可以在Platform SDK中找到。

 

#include "tlogstg.h"

 

class CIETravelLog

{

private:

ITravelLogStg *m_pTravelLogStg;

IEnumTravelLogEntry *m_pEnumLogEntry;

ITravelLogEntry *m_pTravalLogEntry;

IWebBrowser2* m_pWebBrowser;

public:

CIETravelLog(void);

~CIETravelLog(void);

void SetWebBrowser(IWebBrowser2* pWebBrowser);

void BuildHistoryMenu(CMenu * pMenu, unsigned char nCount, bool bForward);

void TravelTo(int nPosition);

};

 

CIETravelLog::CIETravelLog(void)

: m_pTravelLogStg(NULL), m_pEnumLogEntry(NULL), m_pTravalLogEntry(NULL), m_pWebBrowser(NULL)

{

}

 

CIETravelLog::~CIETravelLog(void)

{

if ( m_pTravelLogStg != NULL )

{

m_pTravelLogStg->Release();

}

if ( m_pEnumLogEntry != NULL )

{

m_pEnumLogEntry->Release();

}

if ( m_pTravalLogEntry != NULL )

{

m_pTravalLogEntry->Release();

}

if ( m_pWebBrowser != NULL )

{

m_pWebBrowser->Release();

}

}

 

//將瀏覽器的IWebBrowser2接口指針賦予CIETravelLog的實例

void CIETravelLog::SetWebBrowser(IWebBrowser2* pWebBrowser)

{

if ( (m_pWebBrowser == pWebBrowser) || (m_pWebBrowser == NULL) )

{

return;

}

if ( m_pWebBrowser != NULL )

{

m_pWebBrowser->Release();

}

m_pWebBrowser = pWebBrowser;

 

IServiceProvider *pSP;

HRESULT hr = m_pWebBrowser->QueryInterface(IID_IServiceProvider, (LPVOID*)&pSP);

m_pWebBrowser->Release();

if (SUCCEEDED(hr))

{

hr = pSP->QueryService(SID_STravelLogCursor, IID_ITravelLogStg, (LPVOID*)&m_pTravelLogStg);

pSP->Release();

}

}

 

//創建瀏覽歷史菜單,bForward指明是前進還是后退菜單

void CIETravelLog::BuildHistoryMenu(CMenu * pMenu, unsigned char nCount, bool bForward)

{

if ( m_pTravelLogStg == NULL )

{

return;

}

TLENUMF eFlag = bForward ? TLEF_RELATIVE_FORE : TLEF_RELATIVE_BACK;

if ( FAILED(m_pTravelLogStg->EnumEntries( eFlag, &m_pEnumLogEntry ) ) )

{

return;

}

 

ULONG uFetched;

int i=0;

if ( m_pEnumLogEntry !=NULL )

{

while ( SUCCEEDED( m_pEnumLogEntry->Next( 1, &m_pTravalLogEntry, &uFetched ) ) &&

m_pTravalLogEntry && i<10 )//我們最多只需要10條歷史菜單,可根據實際情況修改

{

LPOLESTR pszTitle;

m_pTravalLogEntry->GetTitle( &pszTitle );

CString strTitle = pszTitle;

if ( bForward )

{

//ID_IEHISTORY_MIDDLE是預定義的某個菜單項ID,從該ID開始前后可以創建10個菜單項,參見下一節

pMenu->InsertMenu( 0, MF_STRING, ID_IEHISTORY_MIDDLE + ++i, strTitle );

}

else

{

pMenu->InsertMenu( 0, MF_STRING, ID_IEHISTORY_MIDDLE - ++i, strTitle );

}

CoTaskMemFree( pszTitle );

m_pTravalLogEntry->Release();

}

}

}

 

//根據與當前頁面的相對距離來訪問歷史網頁

void CIETravelLog::TravelTo(int nPosition)

{

if ( m_pTravelLogStg == NULL )

{

return;

}

if SUCCEEDED(m_pTravelLogStg->GetRelativeEntry( nPosition, &m_pTravalLogEntry ))

{

m_pTravelLogStg->TravelTo( m_pTravalLogEntry );

}

}

 

5、使用CIETravelLog

假設是在我們自己編寫的多窗口瀏覽器中使用Travel Log。為簡單起見,我們聲明一個CIETravelLog的全局對象g_IETravelLog,以便在任何地方調用。然后在適當的地方,如CMainFrame的TBN_DROPDOWN消息(工具條菜單下拉消息)處理函數OnDropDown中,添加下面的代碼,用以創建瀏覽歷史菜單:

//GetActiveWebBrowserPtr返回活動的瀏覽器IWebBrowser2接口指針

IETravelLog.SetWebBrowser( GetActiveWebBrowserPtr );

//bForward為true則創建“前進”菜單,否則創建“后退”菜單

IETravelLog.BuildHistoryMenu( &Menu, 10, bForward);

 

以下定義為菜單項ID的范圍,前后共可以容納10個菜單項,可根據實際情況修改。

#define ID_IEHISTORY_FIRST  60200

#define ID_IEHISTORY_MIDDLE 60210

#define ID_IEHISTORY_LAST   60220

 

添加命令處理函數OnTravelHistoryUrl用以響應從ID_IEHISTORY_FIRST到ID_IEHISTORY_LAST的菜單命令。

 

ON_COMMAND_RANGE(ID_IEHISTORY_FIRST, ID_IEHISTORY_LAST, OnTravelHistoryUrl)

 

void CMainFrame::OnTravelHistoryUrl(UINT nID /* Command ID */)

{

//nID - ID_IEHISTORY_MIDDLE即為要訪問的瀏覽歷史到當前頁面的距離

g_IETravelLog.TravelTo( nID - ID_IEHISTORY_MIDDLE );

}

 

6、再談Travel Log

前面我提到“Travel Log接口正日益成為應用程序中的重要接口之一”,此處加以說明。從微軟平臺的開發模式及導向來看,基于Internet Explorer/WebBrowser Control的應用勢必會成為主流。在下一代的操作系統Longhorn中,應用程序界面的描述將完全由XML的一個特化——XAML來完成,而XAML的解析將由瀏覽器完成。微軟說未來應用程序的部署將會十分容易,本地應用和基于瀏覽器的應用之間的差異將會被逐漸淡化,而實現這一目標的一個重要表現就是,在將來的操作系統平臺上,應用程序實際上時刻都將運行在Internet Explorer中,Internet Explorer在某種程度上來說變成了一個容器。

于是,扎根于Internet Explorer的Travel Log自然而然地就被整合到了我們的應用程序中。君不見,我們每天在資源管理器和瀏覽器上完成的工作,不就是在Travel Log中來來回回地跑嗎?如果所有的應用程序都嵌入到Internet Explorer中運行,那么我們在應用程序中所作的操作便自然得到了記錄,“前進”和“后退”也就很Easy了。

很多軟件都已經或多或少地開始采用基于Internet Explorer的模式,如Microsoft Money、Microsoft Encarta、Visual Studio.net的安裝程序等等,都是很好的范例。所以,就目前來說,將我們的應用程序按這種模式編寫(可參考《利用瀏覽器實現程序界面與實現的分離》),不是可以早一點獲得“訪問日志的體驗”嗎?

何樂而不為。

 

引用地址:《Internet Explorer 編程簡述(八)實現瀏覽歷史菜單

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


posted on 2007-07-29 15:22 旅途 閱讀(929) 評論(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>
            欧美日韩在线精品一区二区三区| 亚洲午夜女主播在线直播| 狂野欧美激情性xxxx欧美| 国产一区日韩欧美| 欧美大片一区二区三区| 亚洲夫妻自拍| 999亚洲国产精| 亚洲一区视频| 午夜精品久久| 久久激情久久| 老色批av在线精品| 欧美韩国日本一区| 欧美人与性动交cc0o| 欧美激情视频一区二区三区在线播放| 亚洲欧美日韩精品久久奇米色影视| 亚洲电影下载| 亚洲精选中文字幕| 亚洲三级电影全部在线观看高清| 久久久久国产一区二区三区四区 | 久久久午夜视频| 欧美日韩在线不卡| 136国产福利精品导航网址| 亚洲国产成人av在线| 99re66热这里只有精品4| 99国内精品| 久久久精品动漫| 欧美日韩在线观看一区二区三区| 欧美日韩中文| 国产一区二区三区奇米久涩| 影音先锋亚洲视频| 亚洲精品日韩综合观看成人91| 免费中文字幕日韩欧美| 国产农村妇女毛片精品久久麻豆| 樱桃成人精品视频在线播放| 午夜国产精品影院在线观看| 久久精品最新地址| 夜夜嗨av一区二区三区| 欧美一区二区私人影院日本 | 国内精品伊人久久久久av影院| 国产精品成人一区二区三区吃奶| 亚洲伦理精品| 亚洲网站在线| 国产综合亚洲精品一区二| 欧美一区二视频| 日韩一级黄色大片| 欧美国产日韩一区二区在线观看| 国产亚洲欧美日韩日本| 亚洲午夜av电影| 午夜精品久久久久久久久| 欧美精品九九| 国产欧美日韩高清| 亚洲电影免费在线| 国产精品专区第二| 亚洲一区二区三区欧美| 一区二区三区精品| 国产精品免费网站在线观看| 久久久久青草大香线综合精品| 欧美高清不卡| 亚洲精品一区二区三区在线观看| 一区二区三区欧美成人| 亚洲电影av| 中文高清一区| 国产一区二区三区在线观看免费视频| 久久xxxx| 销魂美女一区二区三区视频在线| 好吊色欧美一区二区三区四区| 久久99伊人| 亚洲婷婷在线| 国产情人综合久久777777| 日韩午夜中文字幕| 亚洲欧洲综合| 久久精品男女| 美女免费视频一区| 国产精品久久久久9999高清| 嫩草国产精品入口| 国产精品女主播在线观看 | 久久综合色播五月| 精品二区视频| 久久久久成人网| 久久久久国内| 国产精品黄视频| 亚洲国产清纯| 在线欧美日韩| 欧美在线首页| 久久久久久国产精品mv| 极品日韩久久| 欧美午夜精品久久久久久人妖| 一区二区av在线| 欧美在线免费视屏| 亚洲女优在线| 久久午夜精品| 亚洲欧洲视频在线| 欧美成人精品高清在线播放| 久久国产一区二区| 国产一区二区三区日韩| 亚洲四色影视在线观看| 亚洲精品视频在线| 伊人久久婷婷色综合98网| 久久影院亚洲| 亚洲伦理网站| 欧美一级精品大片| 在线观看不卡av| 美女国内精品自产拍在线播放| 免费91麻豆精品国产自产在线观看| 海角社区69精品视频| 欧美日韩不卡| 亚洲在线成人| 欧美成人激情在线| 亚洲精品在线电影| 韩日欧美一区| 欧美日韩中文字幕在线| 香港久久久电影| 午夜精品久久久久久久| 亚洲精品日韩一| 久久综合久久综合久久综合| 99国产精品久久久| 国产在线精品一区二区夜色| 久久国产精品99精品国产| 亚洲第一天堂av| 91久久夜色精品国产网站| 国产精品你懂的| 欧美伦理在线观看| 亚洲欧美日韩网| 亚洲一区二区三区国产| 麻豆成人在线播放| 亚洲欧美精品suv| 久久综合狠狠| 136国产福利精品导航| 日韩亚洲不卡在线| 欧美激情一区二区三区在线视频观看| 欧美在线视频观看免费网站| 亚洲影院色在线观看免费| 亚洲综合色在线| 欧美大片一区| 在线综合视频| 久久不射电影网| 久久亚洲综合| 欧美人与禽性xxxxx杂性| 欧美成人精品在线观看| 美女日韩欧美| 国产专区精品视频| 黄色精品在线看| 亚洲国产精品电影在线观看| 亚洲风情在线资源站| 亚洲日本久久| 欧美亚洲日本国产| 亚洲男人第一网站| 欧美精品粉嫩高潮一区二区 | 国产精品mv在线观看| 欧美日韩喷水| 国产亚洲精品7777| 欧美久久综合| 在线不卡视频| 久久久久网址| 亚洲综合社区| 国产精品高清网站| 亚洲精品视频中文字幕| 久久综合久久美利坚合众国| 亚洲天堂av综合网| 欧美体内she精视频在线观看| 在线观看日韩国产| 久热精品视频在线| 欧美一区二区女人| 国产亚洲精品v| 久久久国产精品亚洲一区| 亚洲综合另类| 玉米视频成人免费看| 久久免费视频在线观看| 牛牛国产精品| 亚洲三级电影全部在线观看高清| 久久久999| 裸体女人亚洲精品一区| 欧美激情精品久久久久久蜜臀| 久久久九九九九| 亚洲青涩在线| 久久成人一区| 国产精品亚洲综合天堂夜夜 | 美女91精品| 美女免费视频一区| 国产欧美日韩综合| 另类尿喷潮videofree| 欧美一区二区三区在| 国产精品入口尤物| 性久久久久久久久| 久久夜色精品国产亚洲aⅴ| 午夜一区在线| 久久综合九色欧美综合狠狠| 免费视频最近日韩| 久久精品国产第一区二区三区最新章节 | 久久男人资源视频| 欧美 日韩 国产精品免费观看| 亚洲天堂久久| 欧美视频精品一区| 欧美成人综合| 日韩午夜激情av| 欧美精品乱码久久久久久按摩| 欧美一区二区三区在线观看 | 一区二区三区无毛| 久久国产手机看片| 欧美mv日韩mv亚洲|