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

旅途

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

COM 組件設(shè)計與應(yīng)用(十七) ---持續(xù)性

作者:楊老師

下載源代碼

一、前言

  我們寫程序,經(jīng)常需要實現(xiàn)這樣的需求:
例一、程序運行產(chǎn)生一個窗口,用戶關(guān)閉的時候需要記錄窗口的位置,以便下次運行時保持位置不變;
例二、由于程序運行時間很長,今天執(zhí)行一部分,明天繼續(xù)執(zhí)行。那么在下次運行前要恢復(fù)前次的狀態(tài);
... ... ... ...

智慧的老師:以上這些需求,如何實現(xiàn)呢?
懵懂的學生:這個簡單,只要在程序退出前提取必要的信息保存到文件中,下次運行時再從文件中讀出來,設(shè)置一下就OK了。
智慧的老師:恩,不錯,這位同學的思想值得表揚。
懵懂的學生:不好意思,這都要感謝老師的栽培,我對您的景仰如滔滔江水......
智慧的老師:別臭P了,我話還沒有說完那......如果你需要提取和保存的信息很多,結(jié)構(gòu)很復(fù)雜......怎么辦?
懵懂的學生:也好辦,我設(shè)計一個結(jié)構(gòu)來記錄這些信息。
智慧的老師:恩......不錯。但如果這些信息提供方是別人寫的模塊,并且隨著版本的不同還經(jīng)常變化,你怎么辦?
懵懂的學生:... ...
智慧的老師:解決這些問題的方法是---持續(xù)性。

二、原理
  持續(xù)性,也叫永久性。組件方提供 IPersistXXX 接口,調(diào)用者(容器)提供存儲介質(zhì),比如文件啦、內(nèi)存啦、注冊表啦、流啦、文本啦......啦啦拉。需要保存的時候,調(diào)用者通過 IPersistXXX::Save() 接口函數(shù)讓組件去自己存儲屬性信息,而調(diào)用者根本不用關(guān)心存儲格式和存儲內(nèi)容;需要還原狀態(tài)的時候,調(diào)用者打開存儲介質(zhì),然后同樣調(diào)用 IPersistXXX::Load() 接口函數(shù)讓組件自己去讀取屬性信息并完成初始化的設(shè)置。
  目前,微軟定義了如下各種類型的持續(xù)性接口,足夠滿足你的需求了。我們只要在自己寫的組件中實現(xiàn)其中一個或幾個持續(xù)性接口,那么調(diào)用者就可以按照統(tǒng)一的方式和我們的組件協(xié)商完成屬性信息的保存和狀態(tài)還原了。
 
持續(xù)性接口 簡要說明
IPersist    所有持續(xù)性接口的根,下面的接口大多從它派生出來。這個接口很簡單,只有一個函數(shù) GetClassID()它返回組件的 CLSID 號,以便調(diào)用者能保存這個號為將來 CoCreateInstance() 啟動組件用。
   實現(xiàn)這個函數(shù)也很簡單,只要返回你組件中的 CLSID_XXX 即可,或者比較省事的方法是返回 GetObjectCLSID() 。
IPersistStream

派生自 IPersist,并增加了4個函數(shù),從流(IStream)中讀寫組件屬性信息。

IsDirty() 組件內(nèi)部屬性是否發(fā)生了變化。為調(diào)用者是否需要保存信息提供依據(jù)
Load() 從 IStream 中讀入信息,初始化組件屬性
Save() 把屬性信息保存到 IStream 中
GetSizeMax() 返回信息尺寸,以便調(diào)用者事先開辟空間
IPersistStreamInit 派生自 IPersistStream,并再增加了一個函數(shù) InitNew() 用來完成一個默認的組件屬性初始化。
這個持續(xù)性接口是最常用的,本文示例中就實現(xiàn)了該接口。
IPersistMemory 和 IPersistStreamInit 類似,但使用的是內(nèi)存塊,而不是大小可變化的 IStream 流。
IPersistStorage 和 IPersistStream 類似,但保存屬性信息使用的是存儲 IStorage,一個 IStorage 中可以有多個 IStream。
IPersistFile 和 IPersistStream 類似,但存儲介質(zhì)為文件。
IPersistPropertyBag    使用屬性包(屬性名、屬性值)的文本方式保存信息。在 IE 瀏覽器中,HTML 嵌入 ActiveX 控件通常使用這個方法。
   在 HTML 中插入控件,<param name="屬性名稱" value="值"> 這樣的形式你應(yīng)該見過吧?!
   在下一回的文章中,我們介紹這個接口。因為在 ActiveX 中,它太常用了。
IPersistPropertyBag2 擴展了 IPersistPropertyBag 接口。提供了更豐富一些的屬性管理用函數(shù)。
IPersistMoniker 用于命名(moniker)存儲和讀取狀態(tài)的持續(xù)性接口。
IPersistHistory 運行于 IE 上,想在用戶瀏覽 WEB 頁面時存儲和讀取狀態(tài)的持續(xù)性接口。

三、持續(xù)性接口組件的實現(xiàn)
  示例程序分別在 vc6.0 和 vc.net 上實現(xiàn)了 IPersistStreamInit 接口的 COM 組件和調(diào)用舉例。組件完成的功能是計算素數(shù),你第一次運行的時候,會得到第一個素數(shù)2,然后是3,5,7,11......下班時間到了,今天就運行到這里。于是調(diào)用者開辟一個流來保存組件的屬性信息。明天繼續(xù)運行的時候,從流中原換組件狀態(tài),開始了新的計算 13,17,19,23......
  這個示例應(yīng)用完全是假設(shè)性的,其實沒有什么實用價值,只是演示了 IPersistStreamInit 接口的實現(xiàn)方法。另外,關(guān)于建立流(IStream)的方法,請參閱COM 組件設(shè)計與應(yīng)用(一)》

1、建立一個 ATL 工程項目。
2、增加 ATL 組件類,vc.net 使用者注意不要選擇“屬性化編程”方式,其它的設(shè)置全部使用默認方法。當然你愿意適當?shù)馗淖冞x擇也無所謂。
3、設(shè)計完成你的組件功能。
   示例程序中,實現(xiàn)了一個接口函數(shù) GetNext() 負責計算下一個素數(shù)。
4、添加IPersistStreamInit 接口。

class ATL_NO_VTABLE Cxxx : 	public CComObjectRootEx<...> ,	public CComCoClass<...>,	......	public IPersistStreamInit	// 手工添加持續(xù)性接口{......BEGIN_COM_MAP(Cxxx)	......		// 手工添加接口映射表入口	COM_INTERFACE_ENTRY(IPersistStreamInit)		// 表示如果要取得 IPersistStream 指針,則返回 IPersistStreamInit 指針	COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStreamInit)		// 表示如果要取得 IPersist 指針,則返回 IPersistStremInit 指針	COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersistStreamInit)END_COM_MAP()
5、完成 IPersistStreamInit 接口函數(shù)。
手工在 h 頭文件中增加函數(shù)聲明:
public:// IPersist	STDMETHOD(GetClassID)(/*[out]*/CLSID * pClassID);// IPersistStream	STDMETHOD(IsDirty)(void);	STDMETHOD(Load)(/*[in]*/IStream *pStm);	STDMETHOD(Save)(/*[in]*/IStream *pStm,/*[in]*/BOOL fClearDirty);	STDMETHOD(GetSizeMax)(/*[out]*/ULARGE_INTEGER *pcbSize);// IPersistStreamInit	STDMETHOD(InitNew)(void);
手工在 cpp 文件中增加函數(shù)實現(xiàn):
// IPersistSTDMETHODIMP Cxxx::GetClassID(/*[out]*/CLSID * pClassID){	*pClassID = GetObjectCLSID();	return S_OK;}// IPersistStreamSTDMETHODIMP Cxxx::IsDirty(void){	if( 數(shù)據(jù)已經(jīng)改變,需要保存 )	return S_OK;	else			return S_FALSE;}STDMETHODIMP Cxxx::Load(/*[in]*/IStream *pStm){	return pStm->Read( 讀到哪里, 讀多長字節(jié), NULL);}STDMETHODIMP Cxxx::Save(/*[in]*/IStream *pStm,/*[in]*/BOOL fClearDirty){	if( fClearDirty )	清除內(nèi)部表示數(shù)據(jù)變化的變量;	return pStm->Write( 需要保存的數(shù)據(jù)指針, 寫多長字節(jié), NULL );}STDMETHODIMP Cxxx::GetSizeMax(/*[out]*/ULARGE_INTEGER *pcbSize){	pcbSize->LowPart = 需要保存數(shù)據(jù)長度的低位;	pcbSize->HighPart = 需要保存數(shù)據(jù)長度的高位;// 一般都是0,難道你的數(shù)據(jù)長度都超過了 4G?	return S_OK;}// IPersistStreamInitSTDMETHODIMP Cxxx::InitNew(void){	內(nèi)部屬性數(shù)據(jù)默認初始化;	設(shè)置或清除內(nèi)部表示數(shù)據(jù)變化的變量;	return S_OK;}
四、小結(jié)
  下載示例程序后,結(jié)合本文仔細閱讀代碼,并試著運行看看效果。如果你理解了,那么你能自己實現(xiàn) IPersistFile 接口嗎?你能自己實現(xiàn) IPersistStorage 接口嗎?你實現(xiàn)的持續(xù)性接口越多,別人使用你的組件就越方便,也就是說你的組件就能大賣特賣啦,祝你為中國軟件事業(yè)做貢獻的同時多多賺錢:-)下回我們用 IPersistPropertyBag 接口實現(xiàn)持續(xù)性屬性包功能,別忘了看呦......

posted on 2007-07-30 15:59 旅途 閱讀(407) 評論(0)  編輯 收藏 引用 所屬分類: COM+/DCOM

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一区二区自拍| 国产精品99久久久久久www| 性欧美video另类hd性玩具| 亚洲国产老妈| 亚洲欧美日韩久久精品 | 久久综合伊人77777麻豆| 欧美日韩国产欧美日美国产精品| 一区二区精品在线| 欧美一区二区三区视频免费播放| 一级日韩一区在线观看| 久久综合网色—综合色88| 亚洲电影视频在线| 午夜久久一区| 欧美mv日韩mv国产网站| 国产欧美日韩精品专区| 亚洲三级视频| 亚洲国产精品ⅴa在线观看| 香蕉成人久久| 欧美国产在线电影| 在线日韩中文字幕| 久久久久九九九| 久久精品一二三| 国产精品久久久久久久一区探花| 亚洲黄色性网站| 99国产精品| 欧美精品aa| 亚洲国产91| 欧美一区二区私人影院日本| 国产精品国产三级国产专播精品人 | 亚洲美女电影在线| 六月天综合网| 欧美91大片| 欧美亚洲一区| 国产亚洲精品自拍| 亚洲免费中文字幕| 欧美一区2区三区4区公司二百 | 亚洲国产日韩在线| 国产香蕉97碰碰久久人人| 欧美一级视频精品观看| 日韩视频精品| 亚洲午夜女主播在线直播| 欧美久久电影| 在线一区二区三区四区五区| 欧美肥婆bbw| 日韩亚洲视频| 在线观看欧美黄色| 欧美日韩国产精品专区| 久久久人成影片一区二区三区| 亚洲尤物在线视频观看| 久久精品一区二区三区中文字幕| 一本久道久久综合狠狠爱| 亚洲电影免费| 国产午夜精品在线| 国产伦精品一区二区三区视频孕妇| 欧美有码在线视频| 亚洲第一综合天堂另类专| 久久久久中文| 99国产精品99久久久久久| 亚洲国产成人av| 一区二区三区在线不卡| 国产欧美亚洲视频| 国产欧美短视频| 国产精品视频专区| 久久综合狠狠综合久久激情| 久久不射中文字幕| 亚洲精品一品区二品区三品区| 亚洲欧美日本视频在线观看| 狠狠干狠狠久久| 欧美日韩专区| 欧美综合国产精品久久丁香| 亚洲欧美日韩一区二区| 久久不射中文字幕| 亚洲精品一区二区三区樱花| 国产精品国产精品国产专区不蜜| 欧美剧在线免费观看网站| 欧美风情在线| 亚洲综合视频网| 亚洲欧美国产视频| 午夜精品久久| 久久国产精品久久国产精品 | 亚洲国产日韩精品| 欧美综合国产精品久久丁香| 午夜一级在线看亚洲| 久久激情视频久久| 亚洲免费观看在线观看| 日韩一级大片在线| 一本色道久久综合亚洲精品小说| 中文一区在线| 亚洲国产一区二区a毛片| 亚洲国产综合在线| 亚洲免费观看视频| 亚洲影院在线观看| 亚洲精品乱码久久久久| 99热这里只有精品8| 亚洲午夜精品福利| 欧美一区亚洲二区| 久久中文字幕一区| 亚洲女爱视频在线| 久久九九热re6这里有精品| 蜜桃av一区二区| 亚洲欧美综合v| 亚洲精品永久免费| 亚洲欧美99| 久久久久久久高潮| 亚洲国产成人久久| 一区二区三区欧美激情| 亚洲人成小说网站色在线| 在线视频免费在线观看一区二区| 性8sex亚洲区入口| 欧美mv日韩mv国产网站app| 久久久久久久久岛国免费| 欧美成人免费播放| 久久综合九色综合网站| 欧美日韩999| 国产三级欧美三级| 亚洲美女毛片| 久久精品青青大伊人av| 亚洲人体1000| 欧美一区二区三区免费观看视频| 欧美 日韩 国产精品免费观看| 国产精品久久久久一区二区| 国语自产在线不卡| 亚洲网站视频| 免费在线看一区| 亚洲一区二区久久| 欧美jizzhd精品欧美喷水| 国产精品网站视频| 亚洲精品国产精品国自产观看| 欧美伊人久久| 亚洲伦理中文字幕| 久久婷婷成人综合色| 老司机精品福利视频| 国产精品色午夜在线观看| 亚洲精品免费看| 久久久久五月天| 亚洲影音先锋| 欧美日韩视频在线观看一区二区三区| 欧美日韩一区综合| 亚洲国产精品久久久| 欧美在线视频a| 日韩天天综合| 欧美黄色小视频| 亚洲高清不卡av| 久久久999成人| 亚洲午夜精品视频| 午夜精品成人在线| 欧美色图天堂网| 亚洲美女福利视频网站| 美女视频黄免费的久久| 亚洲欧美三级伦理| 欧美日韩一二区| 一本色道久久综合亚洲精品高清| 亚洲电影免费在线| 欧美77777| 亚洲国产影院| 欧美国产精品| 久久综合色播五月| 欧美va亚洲va国产综合| 精品91视频| 久久麻豆一区二区| 欧美一区二区视频在线观看| 国产精品影音先锋| 亚洲综合99| 亚洲午夜激情在线| 国产精品国产a| 亚洲性图久久| 一本色道久久综合亚洲精品不卡| 欧美精品一区二区三区蜜臀| 亚洲精品乱码久久久久久黑人| 亚洲国产精品小视频| 欧美国产日韩一区二区三区| 亚洲精品美女免费| 亚洲精品在线视频| 欧美丝袜一区二区三区| 国产精品99久久不卡二区| 亚洲免费高清| 欧美日韩系列| 亚洲在线视频一区| 亚洲男人第一网站| 国产一区二区三区观看| 久久久www成人免费精品| 久久九九99视频| 国产精品v欧美精品∨日韩| 在线成人h网| 欧美国产第一页| 欧美成人免费va影院高清| 一二三区精品| 亚洲在线中文字幕| 国内精品久久国产| 亚洲综合色视频| 亚洲一区二区在线视频| 国产欧亚日韩视频| 蜜桃av综合| 欧美激情精品久久久六区热门 | 亚洲日本欧美在线| 9色精品在线| 免费久久久一本精品久久区| 亚洲看片网站| 亚洲一区二区不卡免费| 国内一区二区三区|