大家一起来,研究MFC

lgxysl 2005-05-21 09:46:49
其实,所以的windows开发的语言,最终都是调用windows API.要成为真正的编程高手,必须熟练掌握API。MFC就是对API的封装,全面深入了解MFC是如何调用API来产生各种各样的类的,对我们学习API很有帮助。为此,让我们大家一起来吧,共同深入研究MFC。

首先,我原来是学C的,对C++的一些语法有些不熟悉,例如宏的定义。
下面是MFC组织消息的宏代码,看得不是很明白,请大家帮研究解释一下:
/////////////////////////////////////////////////////////////////////////////
// Window message map handling

struct AFX_MSGMAP_ENTRY; // declared below after CWnd

struct AFX_MSGMAP
{
#ifdef _AFXDLL
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
#else
const AFX_MSGMAP* pBaseMap;
#endif
const AFX_MSGMAP_ENTRY* lpEntries;
};

#ifdef _AFXDLL
#define DECLARE_MESSAGE_MAP() \
private: \
static const AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
static AFX_DATA const AFX_MSGMAP messageMap; \
static const AFX_MSGMAP* PASCAL _GetBaseMessageMap(); \
virtual const AFX_MSGMAP* GetMessageMap() const; \

#else
#define DECLARE_MESSAGE_MAP() \
private: \
static const AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
static AFX_DATA const AFX_MSGMAP messageMap; \
virtual const AFX_MSGMAP* GetMessageMap() const; \

#endif

#ifdef _AFXDLL
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const AFX_MSGMAP* PASCAL theClass::_GetBaseMessageMap() \
{ return &baseClass::messageMap; } \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &theClass::_GetBaseMessageMap, &theClass::_messageEntries[0] }; \
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \

#else
#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
const AFX_MSGMAP* theClass::GetMessageMap() const \
{ return &theClass::messageMap; } \
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \
{ &baseClass::messageMap, &theClass::_messageEntries[0] }; \
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \

#endif

#define END_MESSAGE_MAP() \
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
}; \

// Message map signature values and macros in separate header
...全文
200 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lgxysl 2005-05-29
  • 打赏
  • 举报
回复
请大家指教、讨论!
luolovegui 2005-05-24
  • 打赏
  • 举报
回复
做个记号
lgxysl 2005-05-24
  • 打赏
  • 举报
回复
请指教!
请大家支持!
lgxysl 2005-05-22
  • 打赏
  • 举报
回复
请指教!
lgxysl 2005-05-21
  • 打赏
  • 举报
回复
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = ...
===================================================================
这是一个类静态数组,在.h文件中是否声明一下。所以一定要定义它的大小的。
其实楼主这个就是MFC的消息映射结构
————————————————————————————————
我知道它是消息映射结构,但好象并没有定义它的大小呀。因为在用

BEGIN_MESSAGE_MAP(CLgxgridForMoreDocView, CView)
ON_WM_KEYDOWN()
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SIZE()
//并不知道用户要在这里添加多少条消息!
END_MESSAGE_MAP()

声明消息映射时并不知道会添加多少条消息!


如果我们把这段宏展开,就成了下面的:
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] =
{
ON_WM_KEYDOWN()
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_SIZE()
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};

我弄不明白它们是如何映射成:
switch(MESSAGE)
{
case xxx:
//处理函数xxx
case yyy:
//处理函数yyy
}
这样的结构的。我们知道,消息最终是这样处理的,尽管MFC把它封装了。


lianglp 2005-05-21
  • 打赏
  • 举报
回复
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = ...
===================================================================
这是一个类静态数组,在.h文件中是否声明一下。所以一定要定义它的大小的。
其实楼主这个就是MFC的消息映射结构。
lgxysl 2005-05-21
  • 打赏
  • 举报
回复
afx.h里的是头文件
菲斯可儿 2005-05-21
  • 打赏
  • 举报
回复
afx.h
简单点的办法,在工程里随便什么地方写个CObject 然后goto defination
lgxysl 2005-05-21
  • 打赏
  • 举报
回复
CObject类的CPP代码在哪里,没法找到,有谁能告诉我?
蒋晟 2005-05-21
  • 打赏
  • 举报
回复
http://blog.csdn.net/jiangsheng/archive/2004/01/05/3797.aspx
lgxysl 2005-05-21
  • 打赏
  • 举报
回复
下面是基类CObject的头文件代码:
/////////////////////////////////////////////////////////////////////////////
// class CObject is the root of all compliant objects

#ifdef _AFXDLL
class CObject
#else
class AFX_NOVTABLE CObject
#endif
{
public:

// Object model (types, destruction, allocation)
virtual CRuntimeClass* GetRuntimeClass() const;
virtual ~CObject(); // virtual destructors are necessary

// Diagnostic allocations
void* PASCAL operator new(size_t nSize);
void* PASCAL operator new(size_t, void* p);
void PASCAL operator delete(void* p);
#if _MSC_VER >= 1200
void PASCAL operator delete(void* p, void* pPlace);
#endif

#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
// for file name/line number tracking using DEBUG_NEW
void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
#if _MSC_VER >= 1200
void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine);
#endif
#endif

// Disable the copy constructor and assignment by default so you will get
// compiler errors instead of unexpected behaviour if you pass objects
// by value or assign objects.
protected:
CObject();
private:
CObject(const CObject& objectSrc); // no implementation
void operator=(const CObject& objectSrc); // no implementation

// Attributes
public:
BOOL IsSerializable() const;
BOOL IsKindOf(const CRuntimeClass* pClass) const;

// Overridables
virtual void Serialize(CArchive& ar);

#if defined(_DEBUG) || defined(_AFXDLL)
// Diagnostic Support
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

// Implementation
public:
static const AFX_DATA CRuntimeClass classCObject;
#ifdef _AFXDLL
static CRuntimeClass* PASCAL _GetBaseClass();
#endif
};

大家分析一下!
lgxysl 2005-05-21
  • 打赏
  • 举报
回复
尤其是这一句,是什么意思呢?在C中,[]表示一个数组,这是否也与数组有关?
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass::_messageEntries[] = \
{ \

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧