友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
深入浅出MFC第2版(PDF格式)-第35部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
{
DECLARE_DYNCREATE(CMyView)
。。。
};
在。cpp 档中又有这些动作:
IMPLEMENT_DYNAMIC(CCmdTarget; CObject)
IMPLEMENT_DYNAMIC(CWinThread; CCmdTarget)
IMPLEMENT_DYNAMIC(CWinApp; CWinThread)
IMPLEMENT_DYNCREATE(CWnd; CCmdTarget)
IMPLEMENT_DYNCREATE(CFrameWnd; CWnd)
IMPLEMENT_DYNAMIC(CDocument; CCmdTarget)
IMPLEMENT_DYNAMIC(CView; CWnd)
IMPLEMENT_DYNCREATE(CMyFrameWnd; CFrameWnd)
IMPLEMENT_DYNCREATE(CMyDoc; CDocument)
IMPLEMENT_DYNCREATE(CMyView; CView)
于是组织出图3…2 这样一个大网。
147
…………………………………………………………Page 210……………………………………………………………
第篇 勿在浮砂築高台
CObject::classCObject CCmdTarget::classCCmdTarget CWinThread::classCWinThread
“CObject” “CCmdTarget” “CWinThread”
4 4 4
m_pfnCreateObject NULL m_pfnCreateObject NULL m_pfnCreateObject NULL
m_pNextClass m_pNextClass m_pNextClass
NULL
CFrameWnd::classCFrameWnd CWnd::classCWnd CWinApp::classCWinApp
“CFrameWnd” “CWnd” “CWinApp”
12 4 4
m_pfnCreateObject m_pfnCreateObject m_pfnCreateObject NULL
m_pNextClass m_pNextClass m_pNextClass
CDocument::classCDocument CView::classCView
“CDocument” “CView” (static 变量)
4 4 CRuntimeClass::pFirstClass
m_pfnCreateObject NULL m_pfnCreateObject NULL
m_pNextClass m_pNextClass
图3…2 以CRuntimeClass 对象构成的 「类别型录网」。本图只列出与动态
生成 (Dynamic Creation)有关系的成员。凡是m_pfnCreateObject
不为NULL 者, 即可动态生成。
现在,我们开始仿真动态生成。首先在main 函数中加上这一段码:
void main()
{
。。。
//Test Dynamic Creation
CRuntimeClass* pClassRef;
CObject* pOb;
while(1)
{
148
…………………………………………………………Page 211……………………………………………………………
第3章 MFC 六大關鍵技術之模擬
if ((pClassRef = CRuntimeClass::Load()) == NULL)
break;
pOb = pClassRef…》CreateObject();
if (pOb != NULL)
pOb…》SayHello();
}
}
并设计
CRuntimeClass CreateObj ect CRuntimeClass Load
:: 和 :: 如:
// in implementation file
CObject* CRuntimeClass::CreateObject()
{
if (m_pfnCreateObject == NULL)
{
TRACE1(〃Error: Trying to create object which is not 〃
〃DECLARE_DYNCREATE nor DECLARE_SERIAL: %hs。n〃;
m_lpszClassName);
return NULL;
}
CObject* pObject = NULL;
pObject = (*m_pfnCreateObject)();
return pObject;
}
CRuntimeClass* PASCAL CRuntimeClass::Load()
{
char szClassName'64';
CRuntimeClass* pClass;
// JJHOU : instead of Load from file; we Load from cin。
cout 》 szClassName;
for (pClass = pFirstClass; pClass != NULL; pClass = pClass…》m_pNextClass)
{
if (strcmp(szClassName; pClass…》m_lpszClassName) == 0)
return pClass;
}
TRACE1(〃Error: Class not found: %s n〃; szClassName);
return NULL; // not found
}
149
…………………………………………………………Page 212……………………………………………………………
第篇 勿在浮砂築高台
然后,为了验证这样的动态生成机制的确有效(也就是对象的确被产生了),我让许多
个类别的构造式都输出一段文字,而且在取得对象指针后,真的去调用该对象的一个成
员函数SayHello 。我把SayHello 设计为虚拟函数,所以根据不同的对象类型,会调用
到不同的SayHello 函数,出现不同的输出字符串。
请注意,main 函数中的while 循环必须等到CRuntimeClass::Load 传回NULL 才会停
止,而CRuntimeClass::Load 是在它从整个「类别型录网」中找不到它要找的那个类别
名称时,才传回NULL 。这些都是我为了仿真与示范,所采取的权宜设计。
Frame6 的命令列编译联结动作是(环境变量必须先设定好,请参考第4章的「安装与设
定」一节):
cl my。cpp mfc。cpp
下面是Frame6 的执行结果。粗体表示我(程序执行者)在屏幕上输入的类别名称:
enter a class name。。。 CObject
Error: Trying to create object which is not DECLARE_DYNCREATE
or DECLARE_SERIAL: CObject。
enter a class name。。。 CView
Error: Trying to create object which is not DECLARE_DYNCREATE
or DECLARE_SERIAL: CView。
enter a class name。。。 CMyView
CWnd Constructor
CMyView Constructor
Hello CMyView
enter a class name。。。 CMyFrameWnd
CWnd Constructor
CFrameWnd Constructor
CMyFrameWnd Constructor
Hello CMyFrameWnd
enter a class name。。。 CMyDoc
CMyDoc Constructor
Hello CMyDoc
150
…………………………………………………………Page 213……………………………………………………………
第3章 MFC 六大關鍵技術之模擬
enter a class name。。。 CWinApp
Error: Trying to create object which is not DECLARE_DYNCREATE
or DECLARE_SERIAL: CWinApp。
enter a class name。。。 CJjhou (故意输入一个不在「类别型录网」中的类别名称)
Error: Class not found: CJjhou (程序结束)
Frame6 范例程序
MFC。H
#0001 #define BOOL int
#0002 #define TRUE 1
#0003 #define FALSE 0
#0004 #define LPCSTR LPSTR
#0005 typedef char* LPSTR;
#0006 #define UINT int
#0007 #define PASCAL _stdcall
#0008 #define TRACE1 printf
#0009
#0010 #include
#0011 #include
#0012 #include
#0013
#0014 class CObject;
#0015
#0016 struct CRuntimeClass
#0017 {
#0018 // Attributes
#0019 LPCSTR m_lpszClassName;
#0020 int m_nObjectSize;
#0021 UINT m_wSchema; // schema number of the loaded class
#0022 CObject* (PASCAL* m_pfnCreateObject)(); // NULL =》 abstract class
#0023 CRuntimeClass* m_pBaseClass;
#0024
#0025 CObject* CreateObject();
#0026 static CRuntimeClass* PASCAL Load();
#0027
#0028 // CRuntimeClass objects linked together in simple list
#0029 static CRuntimeClass* pFirstClass; // start of class list
#0030 CRuntimeClass* m_pNextClass; // linked list of registered classes
#0031 };
#0032
#0033 struct AFX_CLASSINIT
151
…………………………………………………………Page 214……………………………………………………………
第篇 勿在浮砂築高台
#0034 { AFX_CLASSINIT(CRuntimeClass* pNewClass); };
#0035
#0036 #define RUNTIME_CLASS(class_name)
#0037 (&class_name::class##class_name)
#0038
#0039 #define DECLARE_DYNAMIC(class_name)
#0040 public:
#0041 static CRuntimeClass class##class_name;
#0042 virtual CRuntimeClass* GetRuntimeClass() const;
#0043
#0044 #define DECLARE_DYNCREATE(class_name)
#0045 DECLARE_DYNAMIC(class_name)
#0046 static CObject* PASCAL CreateObject();
#0047
#0048 #define _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; wSchema; pfnNew)
#0049 static char _lpsz##class_name'' = #class_name;
#0050 CRuntimeClass class_name::class##class_name = {
#0051 _lpsz##class_name; sizeof(class_name); wSchema; pfnNew;
#0052 RUNTIME_CLASS(base_class_name); NULL };
#0053 static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);
#0054 CRuntimeClass* class_name::GetRuntimeClass() const
#0055 { return &class_name::class##class_name; }
#0056
#0057 #define IMPLEMENT_DYNAMIC(class_name; base_class_name)
#0058 _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; 0xFFFF; NULL)
#0059
#0060 #define IMPLEMENT_DYNCREATE(class_name; base_class_name)
#0061 CObject* PASCAL class_name::CreateObject()
#0062 { return new class_name; }
#0063 _IMPLEMENT_RUNTIMECLASS(class_name; base_class_name; 0xFFFF;
#0064 class_name::CreateObject)
#0065
#0066 class CObject
#0067 {
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!