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

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

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

開(kāi)通VIP
COM——復合文檔與持續化--YXM的程序人生

                                  

一、復合文件的特點(diǎn)
 
  1. 復合文件的內部是使用指針構造的一棵樹(shù)進(jìn)行管理的。編寫(xiě)程序的時(shí)候要注意,由于使用的是單向指針,因此當做定位操作的時(shí)候,向后定位比向前定位要快;
  2. 復合文件中的“流對象”,是真正保存數據的空間。它的存儲單位為512字節。也就是說(shuō),即使你在流中只保存了一個(gè)字節的數據,它也要占據512字節的文件空間。
  3. 不同的進(jìn)程,或同一個(gè)進(jìn)程的不同線(xiàn)程可以同時(shí)訪(fǎng)問(wèn)一個(gè)復合文件的不同部分而互不干擾;
  4. 大家都有這樣的體會(huì ),當需要往一個(gè)文件中插入一個(gè)字節的話(huà),需要對整個(gè)文件進(jìn)行操作,非常煩瑣并且效率低下。而復合文件則提供了非常方便的“增量訪(fǎng)問(wèn)”能力;
  5. 當頻繁地刪除文件,復制文件后,磁盤(pán)空間會(huì )變的很零碎,需要使用磁盤(pán)整理工具進(jìn)行重新整合。和磁盤(pán)管理非常相似,復合文件也會(huì )產(chǎn)生這個(gè)問(wèn)題,在適當的時(shí)候也需要整理,但比較簡(jiǎn)單,只要調用一個(gè)函數就可以完成了。
 
示例一:建立一個(gè)復合文件,并在其下建立一個(gè)子存儲,在該子存儲中再建立一個(gè)流,寫(xiě)入數據。
	void SampleCreateDoc()            {            ::CoInitialize(NULL);	// COM 初始化            // 如果是MFC程序,可以使用AfxOleInit()替代            HRESULT hr;		// 函數執行返回值            IStorage *pStg = NULL;	// 根存儲接口指針            IStorage *pSub = NULL;	// 子存儲接口指針            IStream *pStm = NULL;	// 流接口指針            hr = ::StgCreateDocfile(	// 建立復合文件            L"c:\\a.stg",	// 文件名稱(chēng)            STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,	// 打開(kāi)方式            0,		// 保留參數            &pStg);		// 取得根存儲接口指針            ASSERT( SUCCEEDED(hr) );	// 為了突出重點(diǎn),簡(jiǎn)化程序結構,所以使用了斷言。            // 在實(shí)際的程序中則要使用條件判斷和異常處理            hr = pStg->CreateStorage(	// 建立子存儲            L"SubStg",	// 子存儲名稱(chēng)            STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,            0,0,            &pSub);		// 取得子存儲接口指針            ASSERT( SUCCEEDED(hr) );            hr = pSub->CreateStream(	// 建立流            L"Stm",		// 流名稱(chēng)            STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,            0,0,            &pStm);		// 取得流接口指針            ASSERT( SUCCEEDED(hr) );            hr = pStm->Write(		// 向流中寫(xiě)入數據            "Hello",		// 數據地址            5,		// 字節長(cháng)度(注意,沒(méi)有寫(xiě)入字符串結尾的\0)            NULL);		// 不需要得到實(shí)際寫(xiě)入的字節長(cháng)度            ASSERT( SUCCEEDED(hr) );            if( pStm )	pStm->Release();// 釋放流指針            if( pSub )	pSub->Release();// 釋放子存儲指針            if( pStg )	pStg->Release();// 釋放根存儲指針            ::CoUninitialize()		// COM 釋放            // 如果使用 AfxOleInit(),則不調用該函數            }	
 
示例二:打開(kāi)一個(gè)復合文件,枚舉其根存儲下的所有對象。
	#include 	// ANSI、MBCS、UNICODE 轉換            void SampleEnum()            {	// 假設你已經(jīng)做過(guò) COM 初始化了            LPCTSTR lpFileName = _T( "c:\\a.stg" );            HRESULT hr;            IStorage *pStg = NULL;            USES_CONVERSION;            LPCOLESTR lpwFileName = T2COLE( lpFileName );	// 轉換T類(lèi)型為寬字符            hr = ::StgIsStorageFile( lpwFileName );	// 是復合文件嗎?            if( FAILED(hr) )	return;            hr = ::StgOpenStorage(			// 打開(kāi)復合文件            lpwFileName,			// 文件名稱(chēng)            NULL,            STGM_READ | STGM_SHARE_DENY_WRITE,            0,            0,            &pStg);				// 得到根存儲接口指針            IEnumSTATSTG *pEnum=NULL;	// 枚舉器            hr = pStg->EnumElements( 0, NULL, 0, &pEnum );            ASSERT( SUCCEEDED(hr) );            STATSTG statstg;            while( NOERROR == pEnum->Next( 1, &statstg, NULL) )            {            // statstg.type 保存著(zhù)對象類(lèi)型 STGTY_STREAM 或 STGTY_STORAGE            // statstg.pwcsName 保存著(zhù)對象名稱(chēng)            // ...... 還有時(shí)間,長(cháng)度等很多信息。請查看 MSDN            ::CoTaskMemFree( statstg.pwcsName );	// 釋放名稱(chēng)所使用的內存            }            if( pEnum )	pEnum->Release();            if( pStg )	pStg->Release();            }            
 
二、持續性原理
    持續性,也叫永久性。組件方提供 IPersistXXX 接口,調用者(容器)提供存儲介質(zhì),比如文件啦、內存啦、注冊表啦、流啦、文本啦......啦啦拉。需要保存的時(shí)候,調用者通過(guò) IPersistXXX::Save() 接口函數讓組件去自己存儲屬性信息,而調用者根本不用關(guān)心存儲格式和存儲內容;需要還原狀態(tài)的時(shí)候,調用者打開(kāi)存儲介質(zhì),然后同樣調用 IPersistXXX::Load() 接口函數讓組件自己去讀取屬性信息并完成初始化的設置。
 
持續性接口組件的實(shí)現
1、建立一個(gè) ATL 工程項目。
2、增加 ATL 組件類(lèi),vc.net 使用者注意不要選擇“屬性化編程”方式,其它的設置全部使用默認方法。當然你愿意適當地改變選擇也無(wú)所謂。
3、設計完成你的組件功能。
   示例程序中,實(shí)現了一個(gè)接口函數 GetNext() 負責計算下一個(gè)素數。
4、添加IPersistStreamInit 接口。
 
	class ATL_NO_VTABLE Cxxx :            public CComObjectRootEx<...>,            public CComCoClass<...>,            ......            public IPersistStreamInit	// 手工添加持續性接口            {            ......            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 接口函數。
手工在 h 頭文件中增加函數聲明:
 
	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í)現:
 
	// IPersist            STDMETHODIMP Cxxx::GetClassID(/*[out]*/CLSID * pClassID)            {            *pClassID = GetObjectCLSID();            return S_OK;            }            // IPersistStream            STDMETHODIMP Cxxx::IsDirty(void)            {            if( 數據已經(jīng)改變,需要保存 )	return S_OK;            else			return S_FALSE;            }            STDMETHODIMP Cxxx::Load(/*[in]*/IStream *pStm)            {            return pStm->Read( 讀到哪里, 讀多長(cháng)字節, NULL);            }            STDMETHODIMP Cxxx::Save(/*[in]*/IStream *pStm,/*[in]*/BOOL fClearDirty)            {            if( fClearDirty )	清除內部表示數據變化的變量;            return pStm->Write( 需要保存的數據指針, 寫(xiě)多長(cháng)字節, NULL );            }            STDMETHODIMP Cxxx::GetSizeMax(/*[out]*/ULARGE_INTEGER *pcbSize)            {            pcbSize->LowPart = 需要保存數據長(cháng)度的低位;            pcbSize->HighPart = 需要保存數據長(cháng)度的高位;// 一般都是0,難道你的數據長(cháng)度都超過(guò)了 4G?            return S_OK;            }            // IPersistStreamInit            STDMETHODIMP Cxxx::InitNew(void)            {            內部屬性數據默認初始化;            設置或清除內部表示數據變化的變量;            return S_OK;            }
 
示例代碼:http://xmyang.bokee.com/inc/PersistSample.rar

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
VC知識庫文章 - COM 組件設計與應用(一)——起源及復合文件
如何抓住狡猾的狐貍?(復合文檔)
IPicture總結 - crearo的專(zhuān)欄
利用VC控制OFFICE文件(.doc、.xls、.ppt)的摘要屬性(標題、作者、公司 和 備注)
Windows RPC編程入門(mén)
MFC 加載 和顯示圖片的幾個(gè)函數與例子 ,可以顯示任何圖片
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

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