MFC消息机制
来源:互联网 发布:软件著作权代办 编辑:程序博客网 时间:2024/06/05 14:48
Windows程序和MFC程序是靠消息驱动的,他们对于消息的处理本质上是相同的。只是Windows程序对于消息处理的过程十分清晰明了,MFC程序则掩盖了消息处理的过程,以消息映射的方式呈现在开发者面前,使得开发消息的处理十分简单。用多了mfc就想对它的消息映射机制有一个本质的了解,下面将对消息映射做详细的分析。当然,在分析MFC消息映射之前首先对Windows程序的消息处理过程进行一个简单的描述。
1、Windows应用程序消息处理
1、Windows应用程序消息处理
Windows程序都维护有自己的消息队列,保存了队列消息(当然也有非队列消息,它们直接发给窗口),并用过消息循环对消息进行处理。消息循环首先通过GetMessage取得消息并从队列中移走,对于加速键会调用TranslateAccelerator函数,对其进行翻译和处理,如果处理成功就不在调用TranslateMessage。如果不是加速键,就进行消息的转换和派发,让目的窗口的窗口过程来处理消息。示例代码:
while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }真正处理消息的是所谓的窗口过程(LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)),这个函数的参数记录了过程对应的窗口、消息的ID以及参数,在其内部开发者可以实现自己需要的消息处理功能。那消息分发是如何发送给窗口过程的呢?我们知道窗口创建过程中有一个注册窗口类的步骤,如下:
ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; // 啊!!!原来在这里 wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSP)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WINDOWSP); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); }
2、MFC消息映射
MFC窗口使用同一窗口过程,通过消息映射隐藏了消息处理的过程,更加详细点是隐藏了,那消息映射如何实现的呢?
首先,我们先对MFC的消息映射做一个简单介绍。MFC为了实现消息映射在响应消息的类内部自动做了如下两方面的处理:
a、消息映射声明和实现
在类的定义(头文件)里,添加声明消息映射的宏DECLARE_MESSAGE_MAP,在类的实现(源文件)里,通过
BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()实现消息映射。
b、消息响应函数的声明和实现
当通过ClassWizard添加消息响应函数时就会自动添加函数的声明和实现,代码如下:
声明:
//{{AFX_MSG afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP()映射:
BEGIN_MESSAGE_MAP(CTestDialog, CDialog) //{{AFX_MSG_MAP(CTestDialog) ON_WM_TIMER() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP()实现:
void CTestDialog::OnPaint() { } void CTestDialog::OnTimer(UINT nIDEvent) { CDialog::OnTimer(nIDEvent); }
3、例子
.h
class DlgClass : public BaseDlg{ DECLARE_DYNAMIC(DlgClass) enum {IDD_IDD_DIALOG_sss};protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持virtual void OnOK();virtual void OnCancel();virtual BOOL OnInitDialog();afx_msg void OnCheckContourBold();afx_msg void OnCheckContourShowname();DECLARE_MESSAGE_MAP()};.cpp
#include "DlgBoldContour.h"IMPLEMENT_DYNAMIC(CDlgBoldContour, jgBaseDialog)void CDlgBoldContour::DoDataExchange(CDataExchange* pDX){jgBaseDialog::DoDataExchange(pDX);DDX_Control(pDX, IDC_CHECK_CONTOUR_SHOWNAME, m_ShowContourName);}BEGIN_MESSAGE_MAP(CDlgBoldContour, jgBaseDialog)ON_BN_CLICKED(IDC_CHECK_CONTOUR_BOLD, OnCheckContourBold)ON_BN_CLICKED(IDC_CHECK_CONTOUR_SHOWNAME, OnCheckContourShowname)END_MESSAGE_MAP()void CDlgBoldContour::OnOK() {...}
阅读全文
0 0
- MFC消息机制---消息映射
- MFC消息机制
- MFC消息映射机制
- MFC消息响应机制
- MFC消息响应机制
- MFC消息响应机制
- MFC消息映射机制
- MFC中消息机制
- MFC消息响应机制
- MFC的消息机制
- MFC消息映射机制
- MFC的消息机制
- C++ MFC 消息机制
- MFC 的消息机制
- MFC消息映射机制
- MFC消息机制
- MFC消息映射机制
- MFC的消息机制
- 实现手机号码中间4位用星号(*)替换显示
- NYOJ 664 数字整除
- css中box-shadow的应用技巧
- 练习三 求1+2!+3!+...+20!的和
- MongoDb--初识
- MFC消息机制
- Hibernate多对一、多对多关系--cascade、inverse
- 在CSDN上如何快速转载博客
- iOS 证书申请和使用详解
- GBDT和XGBOOST的区别
- Leetcode解题笔记 1.Two Sum [Easy]
- 实现-超级课程表——校园登录(2)
- Maven阿里云仓库地址配置
- java--依赖、关联、聚合和组合之间区别的理解