久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

COM組件設(shè)計與應(yīng)用(十八)——屬性包...

 楓葉飄紅 2007-07-13

COM組件設(shè)計與應(yīng)用(十八)——屬性包

作者:
楊老師

下載源代碼

一,、前言

  書接上回,,本回著落在介紹屬性包 IPersistPropertyBag 接口的實現(xiàn)方法和調(diào)用方式。屬性包,,是以“名稱 - 值”的方式提供組件持續(xù)性的支持,,而“名稱 - 值”恰恰又適合于用文本方式來表現(xiàn)。下面的片段是在 HTML 中插入 Microsoft MonthView Control ActiveX 控件后的樣式:

<object classid="clsid:232E456A-87C3-11D1-8BE3-0000F8754DA1" id="MonthView1">
<param name="_ExtentX" value="9393">
<param name="_ExtentY" value="4974">
<param name="_Version" value="393216">
<param name="ForeColor" value="0">
<param name="MaxSelCount" value="7">
<param name="MonthColumns" value="1">
<param name="CurrentDate" value="38632">
<param name="MaxDate" value="2958465">
<param name="MinDate" value="-53688">
</object>
以文本方式保存組件屬性,,比較直觀,、容易修改,上面 HTML 示例中的 <param name="屬性名" value="值"> 就很清晰,。下面開始介紹如何在組件中實現(xiàn) IPersistPropertyBag 接口,。

二,、組件的實現(xiàn)
(1)vc6.0 開發(fā)步驟
1、建立一個工作空間(WorkSpace),。
2,、在這個工作空間中,建立 ATL 工程,,示例程序工程為 Simple18,。
3、增加 ATL 對象類,,默認全部選項,。示例程序中的 ATL 對象短名稱是 Property。
4,、增加一些屬性,。在以前的章回中,我們只介紹了增加接口函數(shù)的方法,,由于今天是首次增加接口屬性,,所以稍微細致一些。步驟是,,在ClassView卡片中選擇接口(IProperty)后,,執(zhí)行鼠標右鍵菜單"Add Property..."



5、增加 BSTR 類型的接口屬性 str,,同樣的方式,,再增加一個 long 型的接口屬性 interger。在示例程序中,,這兩個屬性其實只為演示,,并沒有實際的意義。



6,、接口中的屬性,,多數(shù)情況下會對應(yīng)對象內(nèi)部的一個成員變量,因此我們現(xiàn)在要添加成員變量,。選擇對象類名,,執(zhí)行鼠標右鍵菜單"Add Member Variable...."




7、添加兩個成員變量,,一個是 CComBSTR m_str 對應(yīng)于接口屬性 str,;另一個是 long m_integer 對應(yīng)于接口屬性 integer。



(2)vc.net 開發(fā)步驟
1,、建立一個空白解決方案,。
2、在解決方案中,新增 ATL 項目,。示例程序中項目名稱叫 Simple18,, 注意不要選擇“屬性化編程”方式。
3,、添加 ATL 類,。選擇 “ATL 的簡單對象”。默認全部選項,。示例程序中 ATL 類短名稱為 Property,,類名稱為 CMyProperty。(注1)
4,、 增加一些屬性,。在以前的章回中,我們只介紹了增加接口函數(shù)的方法,,由于今天是首次增加接口屬性,,所以稍微細致一些。步驟是,,在類視圖卡片中選擇接口(IProperty)后,,執(zhí)行鼠標右鍵菜單"添加屬性..."



5、增加 BSTR 類型的接口屬性 str,,同樣的方式,,再增加一個 long 型的接口屬性 interger。在示例程序中,,這兩個屬性其實只為演示,,并沒有實際的意義。



6,、接口中的屬性,,多數(shù)情況下會對應(yīng)對象內(nèi)部的一個成員變量,因此我們現(xiàn)在要添加成員變量,。選擇對象類名,執(zhí)行鼠標右鍵菜單"添加變量...."



7,、添加兩個成員變量,,一個是 CComBSTR m_str 對應(yīng)于接口屬性 str;另一個是 long m_integer 對應(yīng)于接口屬性 integer,。


(3)實現(xiàn)代碼
  至此,,我們組件的框架已經(jīng)完成,下面該完成函數(shù)函數(shù)的實現(xiàn)了:
STDMETHODIMP Cxxx::get_str(BSTR* pVal)
{
*pVal = m_str.Copy();
return S_OK;
}
STDMETHODIMP Cxxx::put_str(BSTR newVal)
{
m_str = newVal;
return S_OK;
}
STDMETHODIMP Cxxx::get_integer(LONG* pVal)
{
*pVal = m_integer;
return S_OK;
}
STDMETHODIMP Cxxx::put_integer(LONG newVal)
{
m_integer = newVal;
return S_OK;
}
沒有什么復(fù)雜的,,就是實現(xiàn) str,、integer 兩個屬性值的設(shè)置和讀取功能。
(4)添加 IPersistPropertyBag 接口
  還記得我們在上回書中如何添加 IPersistStreamInit 的嗎?添加 IPersistPropertyBag 的方法也一樣,,但這次我們換一個方式,,即我們不從 IPersistPropertyBag 派生,而是從 IPersistPropertyBagImpl<> 派生,。在 ATL 中,,系統(tǒng)幫我們已經(jīng)完成了很多接口的默認實現(xiàn),我們只要從 IxxxImpl<> 派生,,然后再添加一些必要的映射和變量,,就可以了。這樣顯然要比自己去實現(xiàn)接口的所有函數(shù)要簡單許多了,。其實,,如果你明白了本回 IPersistPropertyBagImpl<> 派生的方法后,你完全可以修改前回書中的實現(xiàn)方法,,從 IPersistStreamInit 派生改進為從 IPersistStreamInitImpl<> 派生,。
class ATL_NO_VTABLE Cxxx :
public CComObjectRootEx<...>,
public CComCoClass<...>,
public IDispatchImpl<...>,
public IPersistPropertyBagImpl<Cxxx>	// 手工添加派生類
{
... ... ...
BEGIN_COM_MAP(Cxxx)
... ... ...
COM_INTERFACE_ENTRY(IPersistPropertyBag)	// 手工添加接口表
END_COM_MAP()
... ... ...
	// 手工添加屬性映射表,這是 IPersistXXXImpl 所必須的,。
// 將來你在寫 ActiveX 的時候,,ATL 向?qū)臀覀兲砑訉傩杂成浔?
BEGIN_PROP_MAP(Cxxx)
// 參數(shù):"屬性名稱", 接口屬性序號(見IDL文件), 屬性頁對話窗
PROP_ENTRY("str", 1, CLSID_NULL)
PROP_ENTRY("integer", 2, CLSID_NULL)
END_PROP_MAP()
... ... ...
public:
... ... ...
// 這個成員變量,是 IPersistXXXImpl 所必須的
bool m_bRequiresSave;	// 表示屬性數(shù)據(jù)是否已經(jīng)改變而需要保存
};
  我們只要手工添加以上內(nèi)容,,而不用自己寫任何 IPersistPropertyBag 接口的函數(shù),,多簡單呀!天空出彩霞呀,,地上開紅花呀......會唱這只歌的同學(xué)請舉手,,每個人獎勵 vckbase 的專家分 500 !

三,、調(diào)用者的實現(xiàn)
  我們在閱讀 MSDN 關(guān)于 IPersistPropertyBag 接口函數(shù)的時候,,你會發(fā)現(xiàn)還需要一個接口 IPropertyBag 與之配合才能實現(xiàn)屬性包功能。而 IPropertyBag 則需要我們在調(diào)用者(容器)中來實現(xiàn)該接口,。它們之間的關(guān)系如下:



   前面幾回書中,,我們已經(jīng)學(xué)會了從 IUnknown 派生類,也學(xué)會了從 IDispatch 派生類,,也學(xué)會了從 ICallBack 派生類......同樣,,這回我們要從 IPropertyBag 派生了。在示例程序中,,我們添加了一個類 CPropertyBag::public IPropertyBag,,同時重載了所有的虛函數(shù)。

 

STDMETHODIMP CPropertyBag::QueryInterface(const struct _GUID &iid,void ** ppv)
{
*ppv = this;
return S_OK;
}
ULONG __stdcall CPropertyBag::AddRef(void)
{	return 1;		}	// 做個假的就可以,,因為反正這個對象在程序結(jié)束前是不會退出的
ULONG __stdcall CPropertyBag::Release(void)
{	return 0;		}	// 做個假的就可以,,因為反正這個對象在程序結(jié)束前是不會退出的
STDMETHODIMP CPropertyBag::Read(LPCOLESTR pszPropName,VARIANT *pVar,IErrorLog *pErrorLog)
{
// 根據(jù) pszPropName 指定的屬性名稱,,你要提供該屬性的值。
// 而值的數(shù)據(jù)類型已經(jīng)在 pVal->vt 中指定了,。
if( 如果能提供指定的數(shù)據(jù) )	return S_OK;
else	return E_FAIL;
}
STDMETHODIMP CPropertyBag::Write(LPCOLESTR pszPropName,VARIANT *pVar)
{
// 根據(jù) psaPropName 指定的屬性名稱和 pVar 提供的值
// 你保存到文本中去吧,。
return S_OK;
}
  以上是調(diào)用者(容器)程序的關(guān)鍵部分,其它的管理和協(xié)調(diào)部分,,讀者去閱讀示例程序代碼,。編譯注冊組件,并運行調(diào)用者示例程序,,顯示如下:



  在編輯窗口中你可以隨便指定 str 和 interger 的值,,然后“啟動組件”,那么你設(shè)定的屬性值就會在啟動組件的同時,,通過 IPersistPropertyBag 接口設(shè)置到組件中(還原了持續(xù)性的環(huán)境),。而后,你就可以在下面的 Property 分組操作中,,“設(shè)置/讀取”組件的屬性了,。當(dāng)“關(guān)閉組件”的時候,程序通過調(diào)用 IPersistPropertyBag 接口函數(shù),,又重新取得組件的屬性名稱和值保存到編輯窗的文本中了,。

四、小結(jié)
  理解了本回屬性包接口的功能,,你就能體會出 IE 是如何裝載 ActiveX (注2)控件并設(shè)置控件的狀態(tài)了,。

注1:在 vc.net 中,由于系統(tǒng)已經(jīng)有 CProperty 類,,所以這里我們改換名稱為 CMyProperty,。
注2:通過十八回的學(xué)習(xí),我們已經(jīng)了解組件的一些常用接口,,為我們學(xué)習(xí) ActiveX 的組件編程打下了基礎(chǔ),。下回書,我們就開始學(xué)習(xí) ActiveX,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多