您的位置:首页 > 编程语言 > C语言/C++

[面试] C/C++ —— MFC(四)

2016-03-27 18:49 495 查看
(1)窗口创建消息:WM_CREATE,如果想让一个类捕获该消息,就需在类的内部提供 OnCreate() 消息处理函数。

(2)windows 是一种基于消息的编程;

消息循环的过程

(1)一旦有消息产生,

(2)操作系统会将消息放入消息队列,

(3)应用程序通过 GetMessage() 从消息队列中取出消息

(4)通过 DispatchMessage 交由给操作系统

(5)操作系统调用窗口过程(WndProc)进行处理

以上是传统的 Windows 程序的做法,MFC 框架提供了“全新”的消息映射,所谓消息映射,建立的是窗口的句柄C++类对象的指针的对应关系。

父类与父窗口

父类子类是从继承关系的角度来定义的;

父窗口子窗口则是通过逻辑关系指定的;

比如一个典型的单文档应用程序:

class C**View :public CView;


用户视图类的父类是 CView 类,但其父窗口却是 CMainFrame;

用户视图类可通过 GetParent() 获得 CMainFrame 对象的指针。

CWnd 类

class CWnd : public CCmdTarget
{
DECLARE_DYNCREATE(CWnd)
protected:
static const MSG* PASCAL GetCurrentMessage();

// Attributes
public:
HWND m_hWnd;            // must be first data member
int MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption = NULL, UINT nType = MB_OK);


HWND m_hWnd; 必须作为 CWnd 的一个数据成员,其内部也有一个 MessageBox 成员函数,可以想见的是,CWnd 类中的 MessageBox 成员函数仍然会调用全局的 MessageBox,又因为 CWnd 类已经封装了 HWND 的数据成员,因此作为CWnd 类成员的MessageBox函数不必显式地传递 HWND(窗口句柄)。

int CWnd::MessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption, UINT nType)
{
if (lpszCaption == NULL)
lpszCaption = AfxGetAppName();
int nResult = ::MessageBox(GetSafeHwnd(), lpszText, lpszCaption, nType);
return nResult;
}


而这里的 GetSafeHwnd 因为没有全局的作用域限定符(::),也应该为CWnd 类的成员函数,如下:

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
{ return this == NULL ? NULL : m_hWnd; }


通过 ClassWizard 添加的消息响应函数,为整个工程带来的变动

如为 CDrawView 类增加 WM_LBUTTONDOWN 消息的消息响应函数,

(1)会在 CDrawView 类的头文件(DrawView.h)增加函数声明

class CDrawView : public CView
{
protected: // create from serialization only
CDrawView();
DECLARE_DYNCREATE(CDrawView)
...
protected:
//{{AFX_MSG(CDrawView)
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};


(2)在 CDrawView 类的cpp文件(DrawView.cpp)消息映射中增加 ON_WM_LBUTTON 将消息和消息响应函数相关联,一旦有该消息产生,便会调用该与其关联的消息响应函数;

BEGIN_MESSAGE_MAP(CDrawView, CView)
//{{AFX_MSG_MAP(CDrawView)
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
// Standard printing commands
...
END_MESSAGE_MAP()


(3)在 CDrawView 类的cpp文件(DrawView.cpp)增加该函数的实现(implementation)

void CDrawView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CView::OnLButtonDown(nFlags, point);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: