執行階段物件模型服務
類別 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 值。
備註
使用此宏來判斷 Common Controls 程式庫是否為 所 proc
指定的函式(而不是呼叫 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 值。
備註
使用此宏來判斷 Common Controls 程式庫是否為 所 proc
指定的函式(而不是呼叫 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
、 b2
b5
b4
b6
b3
b7
、 b8
類別 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
、 b2
b5
b4
b6
b3
b7
、 b8
類別 CLSID 的元件。
備註
注意
如果您使用 IMPLEMENT_OLECREATE
,則預設僅支援單一線程模型。 如果您使用 IMPLEMENT_OLECREATE_FLAGS
,您可以使用 參數來指定物件支援的 nFlags
執行緒模型。
外部名稱是公開給其他應用程式的識別碼。 用戶端應用程式會使用外部名稱向自動化伺服器要求這個類別的物件。
OLE 類別識別碼是 物件的唯一 128 位識別碼。 它包含一個 、兩個 long
** WORD
**s 和八個 ** BYTE
**s,如 語法描述中的 、 w1
、 w2
和 b8
b1
所代表 l
。 應用程式精靈和程式碼精靈會視需要為您建立唯一的 OLE 類別識別碼。
需求
標頭 : afxdisp.h
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應