03月10, 2007

MFC学习笔记#1

作为Windows的Framework需要解决的一个问题就是 消息映射 Message Mapping

Delphi中由于有编译器的支持,可以直接在用户编写的类中处理需要处理的消息:

procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;

在MFC中就比较复杂了. afx使用宏来实现Windows消息到处理函数的映射而没有使用会带 而外的开销:由于C++中实现虚函数需要一个分发表vtable,而无论子类是否重写父类的虚函数, 都需要4个字节的开销.在CWnd类中至少要处理100个以上的消息.这样设计会带来很大的问题.

afx用一组宏将用于消息映射的数据保存在类中.大概情况是:记录该类可以处理的Windows消息, 当消息来到时,对比自己可以处理的消息列表,如果可以处理,就交给列表中记录的函数来处理. 而这个函数就是我们自己些的.比如 OnLButtonDown等

afx.h 中声明了mfc中最基础的类

struct CRuntimeClass;                  // object type information

class CObject;                                // the root of all objects classes

class CException;                         // the root of all exceptions
          class CArchiveException;              // archive exception
          class CFileException;                 // file exception
          class CSimpleException;
           class CMemoryException;               // out-of-memory exception
           class CNotSupportedException; // feature not supported exception

class CFile;                              // raw binary file
          class CStdioFile;                     // buffered stdio text/binary file
          class CMemFile;                       // memory based file

// Non CObject classes
class CString;                                // growable string type
class CTimeSpan;                              // time/date difference
class CTime;                                  // absolute time/date
struct CFileStatus;                           // file status information
struct CMemoryState;                          // diagnostic memory support

class CArchive;                               // object persistence tool
class CDumpContext;                           // object diagnostic dumping

先看一下CRuntimeClass

struct CRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;//保存类名
int m_nObjectSize;//类对象大小
UINT m_wSchema; // schema number of the loaded class//是否可序列化
CObject* (PASCAL* m_pfnCreateObject)(); // 指向类的构造函数的指针

           //指向父类CRuntimeClass的指针
#ifdef _AFXDLL
CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CRuntimeClass* m_pBaseClass;
#endif

// Operations
CObject* CreateObject(); //动态创建
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; //类型鉴别

// Implementation
void Store(CArchive& ar) const; //序列化
static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum) ;//"反序列化"

// CRuntimeClass objects linked together in simple list
CRuntimeClass* m_pNextClass;               // linked list of registered classes //注册类列表
};

CRuntimeClass 是MFC中很重要的一个类,动态创建实例是最常用的功能之一

// Helper macros for declaring CRuntimeClass compatible classes

#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name) 
protected: 
static CRuntimeClass* PASCAL _GetBaseClass(); 
public: 
static const AFX_DATA CRuntimeClass class##class_name; 
virtual CRuntimeClass* GetRuntimeClass() const; 

#define _DECLARE_DYNAMIC(class_name) 
protected: 
static CRuntimeClass* PASCAL _GetBaseClass(); 
public: 
static AFX_DATA CRuntimeClass class##class_name; 
virtual CRuntimeClass* GetRuntimeClass() const; 

#else
#define DECLARE_DYNAMIC(class_name) 
public: 
static const AFX_DATA CRuntimeClass class##class_name; 
virtual CRuntimeClass* GetRuntimeClass() const; 

#define _DECLARE_DYNAMIC(class_name) 
public: 
static AFX_DATA CRuntimeClass class##class_name; 
virtual CRuntimeClass* GetRuntimeClass() const; 

#endif

// not serializable, but dynamically constructable
#define DECLARE_DYNCREATE(class_name) 
DECLARE_DYNAMIC(class_name) 
static CObject* PASCAL CreateObject();

#define _DECLARE_DYNCREATE(class_name) 
_DECLARE_DYNAMIC(class_name) 
static CObject* PASCAL CreateObject();

#define DECLARE_SERIAL(class_name) 
_DECLARE_DYNCREATE(class_name) 
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &pOb);

CObject 基本服务:

BOOL IsSerializable() const;
BOOL IsKindOf(const CRuntimeClass* pClass) const; //类型鉴别

// Overridables
virtual void Serialize(CArchive& ar); //序列化

// Diagnostic Support //诊断支持
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;

//动态创建,利用CRuntimeClass里的m_pfnCreateObject
CObject* CRuntimeClass::CreateObject()

CWnd 在afxwin.h中定义,在wincore.cpp中实现 CWnd封装的功能

// Window tree access
// Message Functions
// Message processing for modeless dialog-like windows
// Window Text Functions
// CMenu Functions - non-Child windows only
// Window Size and Position Functions
// Coordinate Mapping Functions
// Update/Painting Functions
// Timer Functions
// ToolTip Functions
// Window State Functions
// Dialog-Box Item Functions
// Scrolling Functions
// Window Access Functions
// Alert Functions
// Clipboard Functions
// Caret Functions
// Shell Interaction Functions
// Icon Functions
// Context Help Functions
// Dialog Data support
// Help Command Handlers
// Layout and other functions
// OLE control wrapper functions

/* 消息处理函数 */
// Window-Management message handler member functions
// Nonclient-Area message handler member functions
// System message handler member functions
// Input message handler member functions
// Initialization message handler member functions
// Clipboard message handler member functions
// Control message handler member functions
// MDI message handler member functions
// Menu loop notification messages

Windows 控件的实现文件在 winctrl1.cpp~winctrl7.cpp

本文链接:http://aztack.wang/post/mfc-note-1.html

-- EOF--

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。