按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
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