執行階段物件模型服務
類別 CObject
和 CRuntimeClass
封裝數個物件服務,包括存取運行時間類別資訊、串行化和動態物件建立。 從 CObject
衍生的所有類別都會繼承此功能。
對執行階段類別資訊的存取可讓您決定在執行階段的物件類別相關資訊。 當您需要進行函式引數的額外類別檢查時,以及當您必須根據物件類別撰寫特殊用途的程式碼時,能夠在執行階段決定物件的類別就很有用。 C++語言不支援運行時間類別資訊。
序列化是對於檔案來回寫入或讀取物件內容的程序。 即使應用程式結束之後,您還是可以使用序列化儲存物件的內容。 當應用程式重新啟動時,您可以從檔案讀取物件。 這類資料物件稱為「持續性」。
動態物件建立可讓您在執行階段建立指定類別的物件。 例如,因為架構需要動態建立文件、檢視和框架物件,所以必須支援動態建立。
下表列出支援的執行階段類別資訊、序列化和動態建立的 MFC 巨集。
如需這些運行時間物件服務和串行化的詳細資訊,請參閱類別:存取運行時間類別資訊一文。CObject
執行階段物件模型服務巨集
名稱 | 描述 |
---|---|
DECLARE_DYNAMIC |
啟用對於執行階段類別資訊的存取 (必須在類別宣告中使用)。 |
DECLARE_DYNCREATE |
啟用動態建立和存取執行階段類別資訊 (必須在類別宣告中使用)。 |
DECLARE_SERIAL |
啟用序列化和存取執行階段類別資訊 (必須在類別宣告中使用)。 |
IMPLEMENT_DYNAMIC |
啟用對執行階段類別資訊的存取 (必須在類別實作中使用)。 |
IMPLEMENT_DYNCREATE |
啟用動態建立和存取執行階段資訊 (必須在類別實作中使用)。 |
IMPLEMENT_SERIAL |
允許序列化和存取執行階段類別資訊 (必須在類別實作中使用)。 |
RUNTIME_CLASS |
傳回對應至已命名類別的 CRuntimeClass 結構。 |
OLE 經常需要在執行階段動態建立物件。 例如,OLE 伺服器應用程式必須能夠動態建立 OLE 項目以回應來自用戶端的要求。 同樣地,Automation 伺服器必須能夠建立項目以回應從 Automation 用戶端的要求。
MFC 程式庫提供 OLE 兩個特定巨集。
動態建立 OLE 物件
名稱 | 描述 |
---|---|
AFX_COMCTL32_IF_EXISTS |
判斷通用控制項程式庫是否實作指定的 API。 |
AFX_COMCTL32_IF_EXISTS2 |
判斷通用控制項程式庫是否實作指定的 API。 |
DECLARE_OLECREATE |
讓物件透過 OLE Automation 建立。 |
DECLARE_OLECTLTYPE |
GetUserTypeNameID 宣告控件類別的和 GetMiscStatus 成員函式。 |
DECLARE_PROPPAGEIDS |
宣告 OLE 控制項會提供屬性頁清單來顯示其屬性。 |
IMPLEMENT_OLECREATE |
讓物件經由 OLE 系統建立。 |
IMPLEMENT_OLECTLTYPE |
實作 GetUserTypeNameID 控件類別的和 GetMiscStatus 成員函式。 |
IMPLEMENT_OLECREATE_FLAGS |
這個巨集或 IMPLEMENT_OLECREATE 必須出現在實作檔中,任何使用 DECLARE_OLECREATE 的類別。 |
AFX_COMCTL32_IF_EXISTS
判斷通用控制項程式庫是否實作指定的 API。
語法
AFX_COMCTL32_IF_EXISTS( proc );
參數
proc
包含函式名稱以 Null 結束之字串的指標或指定函式的序數值。 如果這個參數是序數值,它必須是低序位文字;高序位文字必須為零。 這個參數必須是 Unicode 值。
備註
使用此巨集來判斷所指定的 proc
函式是否為 Common Controls 連結庫(而不是呼叫 GetProcAddress
。
需求
afxcomctl32.h
, afxcomctl32.inl
AFX_COMCTL32_IF_EXISTS2
判斷 Common Controls 連結庫是否實作指定的 API(這是 的 AFX_COMCTL32_IF_EXISTS
Unicode 版本)。
語法
AFX_COMCTL32_IF_EXISTS2( proc );
參數
proc
包含函式名稱以 Null 結束之字串的指標或指定函式的序數值。 如果這個參數是序數值,它必須是低序位文字;高序位文字必須為零。 這個參數必須是 Unicode 值。
備註
使用此巨集來判斷所指定的 proc
函式是否為 Common Controls 連結庫(而不是呼叫 GetProcAddress
。 此巨集是的 AFX_COMCTL32_IF_EXISTS
Unicode 版本。
需求
afxcomctl32.h
, afxcomctl32.inl
DECLARE_DYNAMIC
新增從衍生類別 CObject
時存取物件類別的運行時間資訊的能力。
DECLARE_DYNAMIC(class_name)
參數
class_name
類別的實際名稱。
備註
將 DECLARE_DYNAMIC
巨集新增至 類別的標頭 (.h
) 模組,然後將該模組包含在需要存取此類別物件的所有 .cpp
模組中。
如果您如所述使用 DECLARE_DYNAMIC
和 IMPLEMENT_DYNAMIC
宏,則可以使用 RUNTIME_CLASS
巨集 和函 CObject::IsKindOf
式來判斷運行時間對象的類別。
如果 DECLARE_DYNAMIC
包含在類別宣告中,則必須 IMPLEMENT_DYNAMIC
包含在類別實作中。
如需巨集的詳細資訊 DECLARE_DYNAMIC
,請參閱 CObject
類別主題。
範例
請參閱 IMPLEMENT_DYNAMIC
的範例。
需求
標頭: afx.h
DECLARE_DYNCREATE
可讓衍生類別的對象 CObject
在運行時間動態建立。
DECLARE_DYNCREATE(class_name)
參數
class_name
類別的實際名稱。
備註
架構會使用此功能動態建立新的物件。 例如,當您開啟新檔時所建立的新檢視。 文件、檢視和框架類別應該支持動態建立,因為架構需要動態建立它們。
在 DECLARE_DYNCREATE
類別的 .h
模組中新增巨集,然後在需要存取此類別物件的所有 .cpp
模組中包含該模組。
如果 DECLARE_DYNCREATE
包含在類別宣告中,則必須 IMPLEMENT_DYNCREATE
包含在類別實作中。
如需巨集的詳細資訊 DECLARE_DYNCREATE
,請參閱 CObject
類別主題。
注意
DECLARE_DYNCREATE
巨集包含的所有功能DECLARE_DYNAMIC
。
範例
請參閱 IMPLEMENT_DYNCREATE
的範例。
需求
標頭: afx.h
DECLARE_OLECTLTYPE
GetUserTypeNameID
宣告控件類別的和 GetMiscStatus
成員函式。
語法
DECLARE_OLECTLTYPE( class_name )
參數
class_name
控件類別的名稱。
備註
GetUserTypeNameID
和 GetMiscStatus
是純虛擬函式,在中 COleControl
宣告。 因為這些函式是純虛擬的,所以必須在控件類別中覆寫它們。 除了 DECLARE_OLECTLTYPE
之外,您必須將 IMPLEMENT_OLECTLTYPE
巨集新增至控件類別宣告。
需求
標頭: afxctl.h
DECLARE_PROPPAGEIDS
宣告 OLE 控制項會提供屬性頁清單來顯示其屬性。
語法
DECLARE_PROPPAGEIDS( class_name )
參數
class_name
擁有屬性頁之控件類別的名稱。
備註
在 DECLARE_PROPPAGEIDS
類別宣告結尾使用巨集。 然後,在定義 類別成員函式的檔案中 .cpp
,使用 BEGIN_PROPPAGEIDS
巨集,巨集每個控件屬性頁的專案,以及 END_PROPPAGEIDS
宣告屬性頁清單結尾的巨集。
如需屬性頁的詳細資訊,請參閱 ActiveX 控件:屬性頁一文。
需求
標頭: afxctl.h
DECLARE_SERIAL
產生可串行化之衍生類別所需的 CObject
C++標頭程序代碼。
DECLARE_SERIAL(class_name)
參數
class_name
類別的實際名稱。
備註
串行化是寫入或讀取檔案中對象內容的程式。
使用模組 DECLARE_SERIAL
中的 .h
巨集,然後將該模組包含在需要存取此類別物件的所有 .cpp
模組中。
如果 DECLARE_SERIAL
包含在類別宣告中,則必須 IMPLEMENT_SERIAL
包含在類別實作中。
DECLARE_SERIAL
巨集包含和DECLARE_DYNCREATE
的所有功能DECLARE_DYNAMIC
。
您可以使用 AFX_API
巨集,針對使用 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
宏的類別自動匯出CArchive
擷取運算符。 以下列程式代碼括住 .h
類別宣告(位於 檔案中):
#undef AFX_API
#define AFX_API AFX_EXT_CLASS
// <your class declarations here>
#undef AFX_API
#define AFX_API
如需巨集的詳細資訊 DECLARE_SERIAL
,請參閱 CObject
類別主題。
範例
class CAge : public CObject
{
public:
void Serialize(CArchive& ar);
DECLARE_SERIAL(CAge)
// remainder of class declaration omitted
需求
標頭: afx.h
IMPLEMENT_DYNAMIC
產生動態 CObject
衍生類別所需的C++程序代碼,並具有類別名稱和階層中位置的運行時間存取權。
IMPLEMENT_DYNAMIC(class_name, base_class_name)
參數
class_name
類別的實際名稱。
base_class_name
基類的名稱。
備註
在 IMPLEMENT_DYNAMIC
模組中使用 .cpp
巨集,然後只鏈接產生的物件程式代碼一次。
如需詳細資訊,請參閱 CObject
類別主題。
範例
class CPerson : public CObject
{
DECLARE_DYNAMIC(CPerson)
// other declarations
};
IMPLEMENT_DYNAMIC(CPerson, CObject)
需求
標頭: afx.h
IMPLEMENT_DYNCREATE
啟用與 巨集 搭配DECLARE_DYNCREATE
使用時,在運行時間動態建立衍生類別的物件CObject
。
IMPLEMENT_DYNCREATE(class_name, base_class_name)
參數
class_name
類別的實際名稱。
base_class_name
基類的實際名稱。
備註
架構會使用此功能動態建立新的物件,例如,在串行化期間從磁碟讀取物件時。 在類別 IMPLEMENT_DYNCREATE
實作檔案中新增巨集。 如需詳細資訊,請參閱 CObject
類別主題。
如果您使用 DECLARE_DYNCREATE
和 IMPLEMENT_DYNCREATE
宏,您可以使用 RUNTIME_CLASS
巨集 和 CObject::IsKindOf
成員函式來判斷運行時間對象的類別。
如果 DECLARE_DYNCREATE
包含在類別宣告中,則必須 IMPLEMENT_DYNCREATE
包含在類別實作中。
請注意,此巨集定義會叫用類別的預設建構函式。 如果 類別明確實作非簡單建構函式,也必須明確實作預設建構函式。 默認建構函式可以新增至 類別的 private
或 protected
成員區段,以防止從類別實作外部呼叫它。
範例
class CMyDynCreateObj : public CObject
{
int m_Num;
public:
DECLARE_DYNCREATE(CMyDynCreateObj)
CMyDynCreateObj(int Num) { m_Num = Num; }
private:
CMyDynCreateObj() { m_Num = 0; } // provide default constructor only for
// dynamic creation
};
IMPLEMENT_DYNCREATE(CMyDynCreateObj, CObject)
需求
標頭: afx.h
IMPLEMENT_OLECREATE_FLAGS
這個巨集或 IMPLEMENT_OLECREATE
必須出現在實作檔中,任何使用 DECLARE_OLECREATE
的類別。
語法
IMPLEMENT_OLECREATE_FLAGS( class_name, external_name, nFlags,
l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
參數
class_name
類別的實際名稱。
external_name
公開給其他應用程式的物件名稱(以引弧括住)。
nFlags
包含下列一或多個旗標:
afxRegInsertable
允許控制元件出現在 OLE 物件的 [插入物件] 對話框中。afxRegApartmentThreading
將登入的線程模型設定為ThreadingModel=Apartment
。afxRegFreeThreading
將登入的線程模型設定為ThreadingModel=Free
。
您可以結合這兩個旗標 afxRegApartmentThreading
和 afxRegFreeThreading
來設定 ThreadingModel=Both。 如需線程模型註冊的詳細資訊,請參閱 InprocServer32
Windows SDK。
l
、w1
、w2
、、b1
、b8
b6
b7
b2
b5
b4
b3
類別 CLSID 的元件。
備註
注意
如果您使用 IMPLEMENT_OLECREATE_FLAGS
,您可以使用 參數來指定物件支援的 nFlags
線程模型。 如果您要只支援單一線程模型,請使用 IMPLEMENT_OLECREATE
。
外部名稱是公開給其他應用程式的標識碼。 用戶端應用程式會使用外部名稱向自動化伺服器要求這個類別的物件。
OLE 類別識別碼是 物件的唯一 128 位標識碼。 它包含一個 、兩個 long
**WORD
**s 和八個 **BYTE
**s,如 語法描述中的 、w1
、 w2
和 b8
b1
所代表l
。 應用程式精靈和程式代碼精靈會視需要為您建立唯一的 OLE 類別識別碼。
需求
標頭: afxdisp.h
IMPLEMENT_OLECTLTYPE
實作 GetUserTypeNameID
控件類別的和 GetMiscStatus
成員函式。
語法
DECLARE_OLECTLTYPE( class_name, idsUserTypeName, dwOleMisc )
參數
class_name
控件類別的名稱。
idsUserTypeName
包含控制項外部名稱之字串的資源識別碼。
dwOleMisc
包含一或多個旗標的列舉。 如需此列舉的詳細資訊,請參閱 OLEMISC
Windows SDK 中的 。
備註
除了 IMPLEMENT_OLECTLTYPE
之外,您必須將 DECLARE_OLECTLTYPE
巨集新增至控件類別宣告。
成員 GetUserTypeNameID
函式會傳回識別控件類別的資源字串。 GetMiscStatus
會 OLEMISC
傳回控件的位。 此列舉會指定描述控制項其他特性的設定集合。 如需設定的完整描述 OLEMISC
,請參閱 OLEMISC
Windows SDK。
注意
ActiveX ControlWizard 所使用的預設設定包括:OLEMISC_ACTIVATEWHENVISIBLE
、、OLEMISC_SETCLIENTSITEFIRST
OLEMISC_INSIDEOUT
、OLEMISC_CANTLINKINSIDE
、 和 OLEMISC_RECOMPOSEONRESIZE
。
需求
標頭: afxctl.h
IMPLEMENT_SERIAL
產生動態 CObject
衍生類別所需的C++程序代碼,並具有類別名稱和階層中位置的運行時間存取權。
IMPLEMENT_SERIAL(class_name, base_class_name, wSchema)
參數
class_name
類別的實際名稱。
base_class_name
基類的名稱。
wSchema
將在封存中編碼的 UINT「版本號碼」,可讓還原串行化程式識別及處理舊版程式所建立的數據。 類別架構編號不得為 -1。
備註
在 IMPLEMENT_SERIAL
模組中使用 .cpp
巨集;然後只鏈接產生的物件程式代碼一次。
您可以使用 AFX_API
巨集,針對使用 DECLARE_SERIAL
和 IMPLEMENT_SERIAL
宏的類別自動匯出CArchive
擷取運算符。 以下列程式代碼括住 .h
類別宣告(位於 檔案中):
#undef AFX_API
#define AFX_API AFX_EXT_CLASS
// <your class declarations here>
#undef AFX_API
#define AFX_API
如需詳細資訊,請參閱 CObject
類別主題。
範例
IMPLEMENT_SERIAL(CAge, CObject, VERSIONABLE_SCHEMA | 2)
需求
標頭: afx.h
RUNTIME_CLASS
從C++類別的名稱取得運行時間類別結構。
RUNTIME_CLASS(class_name)
參數
class_name
類別的實際名稱(未以引弧括住)。
備註
RUNTIME_CLASS
會傳回 所指定class_name
類別之 結構的指標CRuntimeClass
。 只有 CObject
以 DECLARE_DYNAMIC
、 DECLARE_DYNCREATE
或 DECLARE_SERIAL
宣告的衍生類別會傳回 結構的指標 CRuntimeClass
。
如需詳細資訊,請參閱 CObject
類別主題。
範例
CRuntimeClass* prt = RUNTIME_CLASS(CAge);
ASSERT(strcmp(prt->m_lpszClassName, "CAge") == 0);
需求
標頭: afx.h
DECLARE_OLECREATE
可讓衍生類別的物件 CCmdTarget
透過 OLE 自動化建立。
DECLARE_OLECREATE(class_name)
參數
class_name
類別的實際名稱。
備註
此巨集可讓其他啟用 OLE 的應用程式建立此類型的物件。
在 DECLARE_OLECREATE
類別的 .h
模組中新增巨集,然後在需要存取此類別物件的所有 .cpp
模組中包含該模組。
如果 DECLARE_OLECREATE
包含在類別宣告中,則必須 IMPLEMENT_OLECREATE
包含在類別實作中。 使用 DECLARE_OLECREATE
類別宣告必須使用 DECLARE_DYNCREATE
或 DECLARE_SERIAL
。
需求
標頭: afxdisp.h
IMPLEMENT_OLECREATE
這個巨集或 IMPLEMENT_OLECREATE_FLAGS
必須出現在實作檔中,任何使用 DECLARE_OLECREATE
的類別。
IMPLEMENT_OLECREATE(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
參數
class_name
類別的實際名稱。
external_name
公開給其他應用程式的物件名稱(以引弧括住)。
l
、w1
、w2
、、b1
、b8
b6
b7
b2
b5
b4
b3
類別 CLSID 的元件。
備註
注意
如果您使用 IMPLEMENT_OLECREATE
,則預設僅支援單一線程模型。 如果您使用 IMPLEMENT_OLECREATE_FLAGS
,您可以使用 參數來指定物件支援的 nFlags
線程模型。
外部名稱是公開給其他應用程式的標識碼。 用戶端應用程式會使用外部名稱向自動化伺服器要求這個類別的物件。
OLE 類別識別碼是 物件的唯一 128 位標識碼。 它包含一個 、兩個 long
**WORD
**s 和八個 **BYTE
**s,如 語法描述中的 、w1
、 w2
和 b8
b1
所代表l
。 應用程式精靈和程式代碼精靈會視需要為您建立唯一的 OLE 類別識別碼。
需求
標頭: afxdisp.h