MFC消息分类及处理方式

1. 标准消息

除WM_COMMAND之外,所有以WM_开头的消息;从CWnd派生的类,都可以接收到这类消息,比如:

ON_WM_CREATE      对应WM_CREATE消息

ON_WM_PAINT           对应WM_PAINT消息

ON_WM_MOUSEMOVE    对应WM_MOUSEMOVE消息

  ON_WM_XXX   ……

对上边列举出的消息进行运用(功能:让一个字符创跟着鼠标的移动而移动),建一个win32简单应用程序,删除入口函数,将stdafx.h中的头文件
<windows.h> 更改为 <afxwin.h>,Project-->Settings菜单项中设置使用MFC库

// XiaoXi.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

class CMyFrameWnd : public CFrameWnd
{
	DECLARE_MESSAGE_MAP()
protected:
	afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );
	afx_msg void OnPaint( );
	afx_msg void OnMouseMove( UINT nFlags, CPoint point );
public:
	int xPos,yPos;
	CMyFrameWnd();

};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
ON_WM_CREATE(WM_CREATE,OnCreate)
ON_WM_PAINT(WM_PAINT,OnPaint)
ON_WM_MOUSEMOVE(WM_MOUSEMOVE,OnMouseMove)
END_MESSAGE_MAP()
CMyFrameWnd::CMyFrameWnd()
{
	xPos = 100;
	yPos = 100;
}

void CMyFrameWnd ::OnMouseMove( UINT nFlags, CPoint point )
{
	xPos = point.x;
	yPos = point.y;
	nFlags = MK_SHIFT;
	::InvalidateRect(m_hWnd,NULL,TRUE);
}

void CMyFrameWnd ::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd,&ps);
	TextOut(hdc,xPos,yPos,"Hello fc !",10);
	::EndPaint(m_hWnd,&ps);
}

int CMyFrameWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
	MessageBox("CMyFrameWnd::OnCreate");
	return CFrameWnd::OnCreate(lpCreateStruct);
}

class CMyWinApp: public CWinApp
{
public:
	virtual BOOL InitInstance();
};

CMyWinApp TheApp;
BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd*pFrame =  new CMyFrameWnd;
	pFrame->Create(NULL,"Xiaoxi");
	m_pMainWnd = pFrame;
    m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateData();
	return TRUE;

}

2.自定义消息:n的值有3万多个

#define WM_MYMESSAGE WM_USER+n

做一个按钮,点击按钮响应自己的定义的消息:

// XiaoXi.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

#define WM_MYMESSAGE WM_USER+1001  //自定义消息

class CMyFrameWnd : public CFrameWnd
{
	DECLARE_MESSAGE_MAP( )
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg LRESULT OnMyMessage( WPARAM wParam,LPARAM lParam );
	afx_msg void OnTest1( );

};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
ON_WM_CREATE( )
ON_COMMAND( 1001, OnTest1 )
END_MESSAGE_MAP()

int CMyFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	AfxMessageBox( "CMyFrameWnd::OnCreate" );
	::PostMessage( this->m_hWnd, WM_MYMESSAGE, 1, 2 );  //发自己定义的消息
	::CreateWindowEx( 0, "BUTTON", "Test1", WS_CHILD|   //窗口创建但未显示的时候创建按钮
		WS_VISIBLE, 100, 100, 100, 40,
		this->m_hWnd, (HMENU)1001,
		AfxGetInstanceHandle(), NULL );

	return CFrameWnd::OnCreate(lpCreateStruct);
}

void CMyFrameWnd::OnTest1( )
{
	AfxMessageBox( "Test1被点击" );
}
LRESULT CMyFrameWnd::OnMyMessage( WPARAM wParam, LPARAM lParam )
{
	AfxMessageBox( "自己的消息被处理" );
	return 0;
}

class CMyWinApp: public CWinApp
{
public:
	virtual BOOL InitInstance();
};

CMyWinApp TheApp;
BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd*pFrame =  new CMyFrameWnd;
	pFrame->Create(NULL,"Xiaoxi");
	m_pMainWnd = pFrame;
    m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateData();
	return TRUE;

}

3.命令消息(WM_COMMAND)

来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息

两种形式:

ON_COMMAND( ID, 处理函数)

ON_COMMAND_RANGE( 起始ID, 终止ID, 处理函数 )

例子:创建三个按钮,我们先按照普通消息处理COMMAND消息

补充: WM_COMMAND的消息会在文档,视图,框架,应用程序 四种链表进行遍历形成消息网

// XiaoXi.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

class CMyFrameWnd : public CFrameWnd
{
	DECLARE_MESSAGE_MAP( )
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnTest( UINT nID );

};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
ON_WM_CREATE( )
ON_COMMAND_RANGE( 1001, 1003, OnTest ) //多个按钮共用一个宏
END_MESSAGE_MAP()

int CMyFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	AfxMessageBox( "CMyFrameWnd::OnCreate" );
	::CreateWindowEx( 0, "BUTTON", "Test1", WS_CHILD|   //窗口创建但未显示的时候创建按钮
		WS_VISIBLE, 100, 100, 100, 40,
		this->m_hWnd, (HMENU)1001,
		AfxGetInstanceHandle(), NULL );
	::CreateWindowEx ( 0, "BUTTON", "Test2", WS_CHILD|
		WS_VISIBLE, 100, 200, 100, 40,
		this->m_hWnd, (HMENU)1002,
		AfxGetInstanceHandle(), NULL );
	::CreateWindowEx( 0, "BUTTON", "Test3", WS_CHILD|
		WS_VISIBLE, 100, 300, 100, 40,
		this->m_hWnd, (HMENU)1003,
		AfxGetInstanceHandle(), NULL );

	return CFrameWnd::OnCreate(lpCreateStruct);
}

VOID CMyFrameWnd::OnTest( UINT nID )
{
	if( nID==1001)
		AfxMessageBox( "Test1被点击" );
	else if( nID == 1002 )
		AfxMessageBox( "Test2被点击" );
	else
		AfxMessageBox( "Test3被点击" );
}

class CMyWinApp: public CWinApp
{
public:
	virtual BOOL InitInstance();
};

CMyWinApp TheApp;
BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd*pFrame =  new CMyFrameWnd;
	pFrame->Create(NULL,"Xiaoxi");
	m_pMainWnd = pFrame;
    m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateData();
	return TRUE;

}

4 通知消息

由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。

ON_EN_CHANFE

ON_通知码

例子:加一个编辑框。

// XiaoXi.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

class CMyFrameWnd : public CFrameWnd
{
	DECLARE_MESSAGE_MAP( )
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnEnChange( );

};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
ON_WM_CREATE( )
ON_EN_CHANGE( 1004, OnEnChange )
END_MESSAGE_MAP()

int CMyFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	::CreateWindowEx( 0, "EDIT", "", WS_CHILD|WS_VISIBLE|
		WS_BORDER, 300, 100, 100, 100,
		this->m_hWnd, (HMENU)1004,
		AfxGetInstanceHandle(), NULL );

	return CFrameWnd::OnCreate(lpCreateStruct);
}

void CMyFrameWnd::OnEnChange( )
{
	AfxMessageBox( "内容被修改" );
}

class CMyWinApp: public CWinApp
{
public:
	virtual BOOL InitInstance();
};

CMyWinApp TheApp;
BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd*pFrame =  new CMyFrameWnd;
	pFrame->Create(NULL,"Xiaoxi");
	m_pMainWnd = pFrame;
    m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateData();
	return TRUE;

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-08 21:30:21

MFC消息分类及处理方式的相关文章

MFC 消息的分类

来源:孙鑫 c++ 第6集 MFC 消息的分类,布布扣,bubuko.com

深入浅出MFC——消息映射与命令传递(六)

1. 消息分类: 2. 万流归宗——Command Target(CCmdTarget): 3. "消息映射"是MFC内建的一个信息分派机制.通过三个宏(DECLARE_MESSAGE_MAP/BEGIN.../ON.../END...)完成消息网的建构. 4. 注意:CWinThread派生自CCmdTarget,但没有DECLARE_/BEGIN_/END_宏组. 5. 消息映射与虚函数: 6.

MFC消息映射的原理:笔记

多态的实现机制有两种,一是通过查找绝对位置表,二是查找名称表:两者各有优缺点,那么为什么mfc的消息映射采用了第二种方法,而不是c++使用的第一种呢?因为在mfc的gui类库是一个庞大的继承体系,而里面的每个类有很多成员函数(只说消息反映相关的成员函数啊),而且在派生类中,需要改写的也比较少(我用来做练习的程序就是那么一两个,呵呵).那么用c++的虚函数的实现机制会导致什么问题呢?就是大量虚表的建立使得空间浪费掉很多. 嗯-怎么办呢?于是各大c++名库(比如QT,MFC,VCL-)在消息映射的实

MFC 消息映射表和虚函数实现消息映射到底谁的效率高

深入浅出MFC对于虚函数实现方式的缺点,它指出:虚函数耗费大量内存,系统最终将被这些额外负担拖垮.    但是现在对于容量巨大的白菜价格的内存来说,这种额外负担是否已经过时了呢~?    书中提到,虚函数表中的每一个项目都是一个函数指针,价值4字节,如果基类的虚函数表有100项 (MFC里面的消息数量是否在这个数量级?),经过十层继承,开支散叶,总共需要耗费多少内存?    我粗略地算了下,不知道这种计算方法是否正确,4Byte*100项=400Byte.如果CCmdTarget中定义100个消

如何给对话框中的控件发送消息呢?Windows消息分类

以博文CTabCtrl中介绍的那样,给Tab添加子对话框来显示Tab内容.那么如果这个子对话框中含有个CTreeCtrl控件,有个Button控件,我想要模拟给这两个控件发送消息,该怎么办呢?直接把给控件的消息给控件容器(控件的父窗口)是没有用的.为什么呢?首先要明白windows的消息分类: Windows消息的分类 1. 标准消息(队列消息)除WM_COMMAND之外,所有以WM_开头的消息都是标准消息,如WM_MOUSEMOVE.WM_LBUTTONUP.WM_KEYDOWN.WM_C

MFC编程入门之五(MFC消息映射机制概述)

在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作.比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应. 一.什么是消息?  窗口消息一般由三个部分组成:1.一个无符号整数,是消息值:2.消息附带的WPARAM类型的参数:3.消息附带的LPARAM类型的参数.其实,我们一般所说的消息是侠义上的消息值,也就是一个无符号整数,经常被定义为宏. 二.什么是消息映射机制?  MFC使用一种消息映射机制来处理消息,在应

VS2010/MFC编程入门之五(MFC消息映射机制概述)

VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html     上一讲鸡啄米为大家简单分析了MFC应用程序框架,这一讲是关于MFC消息映射机制的内容.        前面已经说过,Windows应用程序是消息驱动的.在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作.比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的

MFC消息映射与命令传递

题外话:刚开始学视窗程序设计的时候,我就打印了一本Windows消息详解,里面列举了各种已定义消息的意义和作用,共10多页,在编程的时候翻翻,有时觉得很受用.我发觉很多编程的朋友,虽然每天都面对消息,却很少关注它.C++程序员有一个通病,很想写“自己”的程序,即每一行代码都想自己写出来.如果用了一些库,总希望能完全理解库里的类或函数是怎么一回事,否则就“不踏实”.对于消息,许多朋友只关心常用的几个,对其余的漠不关心.其实,Windows中有很多不常用的消息却很有用,程序员可能通过响应这些消息实现

MFC消息映射机制

1 消息循环所在的函数 CWinApp::Run 2  消息类别 <1>Windows Messages WM_XX前缀开头,但是除了WM_COMMAND消息外. <2>Control Notifications 包含来自控件或者子窗口发给父窗口的 WM_COMMAND的通知消息. <3>Command Messages 菜单,工具栏按钮,快捷键 3 消息的发送和接受 CWinApp::Run函数接受消息并且将他们分派到合适的窗口,大多数命令消息时被发送到主框架窗口.接