MFC消息映射机制如何运用ClassWizard
实验十一 MFC的简单消息映射与处理

实验十一 MFC的简单消息映射与处理(4学时)[实验目的]1、基本掌握Windows环境下MFC程序的开发流程和方法;2、基本掌握MFC中的消息映射与处理方法;[实验内容]创建一个单文档的MFC工程,使用ClassWizard在视图类中添加WM_KEYDOWN、WM_KEYUP、WM_CHAR键盘消息映射和消息响应函数,添加WM_LBUTTON、WM_ RBUTTON鼠标消息映射和消息响应函数及。
界面如图所示,实现如下功能:程序运行界面图(1)用户按下/释放Shift键时,程序在视图窗口中显示有关的提示信息。
(2)用户按下Shift+B键时,程序在视图窗口中显示有关的提示信息。
(3)用户在视图窗口中按下鼠标左键,并拖动鼠标时,在窗口中绘制一个随鼠标位置变化的椭圆。
当用户释放鼠标键时,停止椭圆的绘制。
[实验步骤](1)创建一个单文档的MFC工程;(2)使用ClassWizard在其视图类中添加键盘消息WM_KEYDOWN、WM_KEYUP和WM_CHAR(分别对应键的按下、松开和按键动作)和消息响应函数;(3)在视图类的头文件中添加成员变量,以记录按键状态:protected:BOOL bShiftdown, bShiftup, bShiftB;并在视图类的构造函数中,对上述成员变量进行初始化:*View::*View(){// TODO: add construction code herebShiftdown=bShiftup=bShiftB=FALSE; //赋初值}其中,红色内容对应VC自动生成部分。
*View为视图类名。
(4)在键盘消息响应函数中,判断按键的状态,并设置上述成员变量的值。
代码如下:void *View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: Add your message handler code here and/or call default//判断Shift键是否被按下if(nChar==VK_SHIFT){//AfxMessageBox("dd");bShiftdown=TRUE;bShiftup=FALSE;Invalidate(TRUE); //显示信息}CView::OnKeyDown(nChar, nRepCnt, nFlags);}void *View::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: Add your message handler code here and/or call default//判断Shift键是否被释放if(nChar==VK_SHIFT){//AfxMessageBox("dd");bShiftup=TRUE;//显示信息Invalidate(TRUE);bShiftdown=FALSE;}CView::OnKeyUp(nChar, nRepCnt, nFlags);}void *View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags){// TODO: Add your message handler code here and/or call defaultif((nChar==98)||(nChar==66)) //判断是否敲击了字符键B键或b键{if(bShiftdown){bShiftB=TRUE;bShiftdown=FALSE;//显示信息Invalidate(TRUE);}}CView::OnChar(nChar, nRepCnt, nFlags);}(5)对视图类的OnDraw函数进行重载,根据成员变量的值(实际对应着按键的状态),显示相关信息。
MFC 设置控件字体颜色、背景透明

1.打开对应对话框的类向导ClassWizard。
2.在消息映射MessageMaps中添加消息Message:WM_CTLCOLOR。
3.然后程序代码中会添加进函数:OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)4.在这个函数中添加if语句,其中的条件表达式改成想要设置的控件;比如改成: if (pWnd-> GetDlgCtrlID() == IDC_STATIC1 || pWnd-> GetDlgCtrlID() == IDC_STATIC2)注意,控件ID最好改过,如果多个控件使用同个默认ID,函数则不识别。
5.在if中添加以下语句:pDC->SetTextColor(RGB(255,255,255)); //设置字体为白色pDC->SetBkMode(TRANSPARENT); //设置背景为透明整个函数的代码如下:HBRUSH CHall::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor){HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);if (pWnd-> GetDlgCtrlID() == IDC_STATIC1 || pWnd-> GetDlgCtrlID() ==IDC_STATIC2 || pWnd-> GetDlgCtrlID() == IDC_STATIC3){pDC->SetBkMode(TRANSPARENT); //设置背景透明pDC->SetTextColor(RGB(255,255,255));return HBRUSH(GetStockObject(HOLLOW_BRUSH));}return hbr;}。
第四课 ClassWizard的应用

• • •
• CPen类,RGB()返回COLORREF值,CBrush CPen类,RGB()返回COLORREF值
类 ,CRect类 CBitmap类 , CRect类 CBitmap类 • SelectObject() 可以将画笔,画刷,字体, 位图等选进设备描述表,并返回旧的, • FromHandle() GetStock程序消息映射 WindowProc(),在文件 MFC程序消息映射 WindowProc(),在文件
WinCore.cpp中,调用OnWndMsg()函数,会去子 WinCore.cpp中,调用OnWndMsg()函数,会去子 类DECLARE_MESSAGE_MAP()上看有没有声明消 DECLARE_MESSAGE_MAP()上看有没有声明消 息处理函数,如果没有则去调用父类的处理函 数,,参看MSDN 数,,参看MSDN ◆ CDC,提供和设备上下文交互的成员函数,画图 CDC,提供和设备上下文交互的成员函数,画图 等相关函数,保存了一个 HDC句柄,CDC *cDC HDC句柄,CDC =GetDC( ); CClientDC 仅访问客户区,CWindowDC 可访问整 仅访问客户区,CWindowDC 个窗口, GetParent() 返回窗口指针GetDesktopWindow() 返回窗口指针GetDesktopWindow() GetForegroundWindow
MFC简答题

简述MFC消息映射机制
MFC采用消息映射来处理消息。
绝大多数消息都可由MFC的CLassWizard 来映射。
将ClassWizard对话框切换到MessaageMaps页面,选择相应的Class Name与Object IDs选项,在Messages列表中选定消息名。
双击消息在XXX 类中自动添加了该消息的处理函数。
ClassWizard消息映射包括三个方面的内容。
一是在头文件XXX.h中声明消息处理函数;其次在XXX.cpp源文件前面的消息映射入口处,添加了相应的映射宏。
最后在XXX.cpp文件中写入一个空消息处理函数的模板以便用户填入具体代码。
简述模式对话框编程的主要步骤
(1)用MFC AppWizard[exe]生成单文档
(2)在资源视图中右击Dialog文件夹插入对话框
(3)设计对话框
右击工具栏空白处打开控件工具栏
(4)测试对话框单击编排/Test或Ctrl+T
(5)创建对话框类
在对话框模板空白处双击鼠标为对话框创建新类(或Ctrl+W)
(6)创建对话框数据成员
添加与对话框控件相关联的数据成员。
目的是接收用户输入的数据。
Ctrl+W->Member Variables
(7)在程序中使用对话框
若新建的对话框类为CDlog,在程序中使用如下代码:
CDlog dlg; //对话框类对象;
dlg.DoModal();// DoModal() :模式对话框函数用于对话框的显示与终止
(8) 在XXXView.cpp中添加头文件
如: #include “Dlog.h”。
消息处理与ClassWizard使用

如何添加一个成员变量? 如何添加一个消息处理函数? 如何添加一个新类? 试举出Windows操作系统中的几种消息类
型?
消息应用实例
该实例所要实现的功能是,当用鼠标想要 去单击对话框上的一个按钮时,这个按钮 就会跑掉,无论怎样都抓不到它。因此, 该实例的代码大部分功能应放在鼠标移动 WM_MOUSERMOVE消息中。
ClassWizard的使用
ClassWizard是Visual C++ 6.0中一个很重 要的组成部分,基本上所有的应用程序都 需要使用到该工具。在前面内容的讲解中, 一直都使用了该工具,但一直没有系统的 介绍其使用。本节将具体讲述 ClassWizard 各 个 选 项 卡 的 内 容 及 如 何 使 用它来添加类、成员等。
❖ 窗口消息是指对Windows应用程序的窗 口进行某些操作时发送的消息。Visual C++ 6.0中,包含了如下6种窗口消息。
❖ WM_CREATE:窗口被创建。 ❖ WM_DESTROY:窗口被销毁。 ❖ WM_CLOSE:窗口被关闭。 ❖ WM_MOVE:窗口发生移动。 ❖ WM_SIZE:窗口发生改变。 ❖ WM_PAINT:窗口发生重绘。
WM_LBUTTONDOWN:用户按下左键。 WM_LBUTTONUP:用户释放左键。 WM_LBUTTONDBCLICK:用户双击左键。 WM_RBUTTONDOWN:用户按下右键。 WM_RBUTTONUP:用户释放右键。 WM_RBUTTONDBCLICK:用户双击右键。
窗口消息
不管通过哪种方式,最终都会弹出 【ClassWizard】对话框。正如读者前面 所看到的,其包括5个选项卡,分别为:
MFC消息映射

MFC消息映射摘要:控件通知消息有很多种,但是有一种是很常用,但是又不是很容易掌握的,那就是WM_NOTIFY,我试着对此做一下比较全面的论述,有不对的地方,还希望各路大虾批评指正。
控件通知消息在《深度解析VC中的消息(上)》中,我们提到了消息的分类有3种:窗口消息、命令消息和控件通知消息,我们这里要谈的是最后一种:控件通知消息。
控件通知消息,是指这样一种消息,一个窗口内的子控件发生了一些事情,需要通知父窗口。
通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框,以及Windows公共控件如树状视图、列表视图等。
例如,单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。
她类似于命令消息,当用户与控件窗口交互时,那么控件通知消息就会从控件窗口发送到它的主窗口。
但是这种消息的存在并不是为了处理用户命令,而是为了让主窗口能够改变控件,例如加载、显示数据。
例如按下一个按钮,他向父窗口发送的消息也可以看作是一个控件通知消息;单击鼠标所产生的消息可以由主窗口直接处理,然后交给控件窗口处理。
控件通知消息主要由窗口类即直接或间接由CWND类派生类处理。
控件通知格式控件通知经历了一个演变过程,因而SendMessage( )的变量Message、wParam和lParam有三种格式。
第一控件通知格式第一控件通知格式只是窗口消息的子集。
它的特征格式如下:WM_XXXX。
它主要来自下面的3种消息类型:(1)表示一个控件窗口要么已经被创建或销毁,要么已经被鼠标单击的消息:WM_PARENTNOTIFY;(2)发送到父窗口,用来绘制自身窗口的消息,例如:WM_CTLCOLOR、WM_DRAWITEM、WM_MEASUREITEM、WM_DELETEITEM、WM_CHARTOITEM、WM_VKTOITEM、WM_COMMAND 和WM_COMPAREITEM(3)有滚动调控件发送,通知父窗口滚动窗口的消息:WM_VSCROLL和WM_HSCROLL第二控件通知格式第二控件通知格式与命令消息共享,它的特征格式如下:WM_COMMAND。
MFC的消息机制的实现原理和消息处理的过程

下面几节将分析MFC的消息机制的实现原理和消息处理的过程。
为此,首先要分析ClassWizard实现消息映射的内幕,然后讨论MFC 的窗口过程,分析MFC窗口过程是如何实现消息处理的。
1.消息映射的定义和实现1.MFC处理的三类消息根据处理函数和处理过程的不同,MFC主要处理三类消息:∙Windows消息,前缀以“WM_”打头,WM_COMMAND例外。
Windows消息直接送给MFC窗口过程处理,窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC窗口类的成员函数。
∙控制通知消息,是控制子窗口送给父窗口的WM_COMMAND通知消息。
窗口过程调用对应的消息处理函数。
一般,由窗口对象来处理这类消息,也就是说,这类消息处理函数一般是MFC 窗口类的成员函数。
需要指出的是,Win32使用新的WM_NOFITY来处理复杂的通知消息。
WM_COMMAND类型的通知消息仅仅能传递一个控制窗口句柄(lparam)、控制窗ID和通知代码(wparam)。
WM_NOTIFY能传递任意复杂的信息。
∙命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。
通过消息映射机制,MFC框架把命令按一定的路径分发给多种类型的对象(具备消息处理能力)处理,如文档、窗口、应用程序、文档模板等对象。
能处理消息映射的类必须从CCmdTarget类派生。
在讨论了消息的分类之后,应该是讨论各类消息如何处理的时候了。
但是,要知道怎么处理消息,首先要知道如何映射消息。
1.MFC消息映射的实现方法MFC使用ClassWizard帮助实现消息映射,它在源码中添加一些消息映射的内容,并声明和实现消息处理函数。
现在来分析这些被添加的内容。
在类的定义(头文件)里,它增加了消息处理函数声明,并添加一行声明消息映射的宏DECLARE_MESSAGE_MAP。
mfc原理和消息映射

MFC思想win32程序中创建一个窗口的过程:设计窗口阶段(由WNDCLASS结构描述部分)、窗口的注册及创建显示过程、消息循环部分。
win32用标准的C语言代码实现,是面向过程的。
在MFC中采用了面向对象的思想,即用面向对象的C++思想对以上代码进行了封装,也就是说将一些对窗口进行操作的API的函数封装到了一个类中,以下我将用简短的代码来演示一下这个过程:class CWnd{public:HWND m_hWnd;BOOL Create();BOOL ShowWindow();};BOOL CWnd::Create(){WNDCLASS wndClass;wndClass.style=CS_HREDRAW;wndClass.lpfnWndProc=(WNDPROC)DefWndProc;wndClass.cbClsExtra=0;wndClass.cbWndExtra=0;wndClass.hInstance=hInstance;wndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));wndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));LOGBRUSH lgbr;lgbr.lbStyle=BS_SOLID;lgbr.lbColor=RGB(192,192,0);lgbr.lbHatch=0;wndClass.hbrBackground=CreateBrushIndirect(&lgbr);wndClass.lpszMenuName=NULL;wndClass.lpszClassName="mycls";RegisterClass(&wndClass);HWND hWnd;m_hWnd=CreateWindow("mycls","窗口标题",WS_OVERLAPPEDWINDOW,0,NULL,NULL,hInstance,NULL);if(m_hWnd!=NULL)return true;elsereturn false;}BOOL CWnd::ShowWindow(){return ShowWindow(hWnd,nCmdShow);}为了保证代码和以前的执行方式一样,Winmain()函数可以写成如下形式:int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){CMyWnd m_wnd;m_wnd.Create();m_wnd.ShowWindow();MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return true;}此时,如果再写一个新的类来对剩下的代码进行封装,代码如下:class CWinApp{public:CWnd * m_pMainWnd;BOOL InitInstance();BOOL Run();CWinApp ();};CWinApp:: CWinApp (){if(InitInstance())Run();}BOOL CWinApp::InitInstance(){CWnd m_wnd;m_pMainWnd=&m_wnd;m_pMainWnd->Create();m_pMainWnd->ShowWindow();return true;}BOOL CWinApp::Run(){MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return true;}CWinApp theApp;int PASCAL WinMain() {}Windows消息的产生:1用户按键或者鼠标操作可以产生消息,如WM_KEYDOWN,WM_LBUTTONDOWN等;2系统可以自己产生消息,如,创建窗口的时候会产生WM_CREATE,WM_TIMER等;3应用程序间可以定义自己的消息,在应用程序间进行消息通讯;Windows消息的分类:1窗口消息(Windows Message):通常跟窗口的移动、创建,关闭等操作有关。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
M F C消息映射机制如何
运用C l a s s W i z a r d The Standardization Office was revised on the afternoon of December 13, 2020
画图的基本应用:
Point的应用,在mfc中的很多的位置都要用到。
只是当前点的信息,xy坐标,MoveToEx 移动位置函数The MoveToEx function updates the current position to the specified point and optionally returns the previous position.
LineTo 画直线的函数
CDC类,作图相关的操作
GetDC,cwnd::getdc 以及cdc的释放(区别hdc),两者的范围不同,调用方式不同
CClientDC 不需要显示地调用getdc和releasedc,只需要声明类的定义和类的调用。
Cliendc对象里利用view指针构造,但是调用的时候用的是对象的点调用方式。
Cwnd::getparent 获得父窗口的指针,view的父窗口是frame。
注意区别view 和framework的客户区域。
Cwindowdc类和clientdc一样自动调用getdc和releasedc。
了解他的访问客户区的范围。
Getdesktopwindow 获得桌面窗口。
创建画笔:
CPen 类,设置画笔的属性,包括一些类型宽度,颜色。
CDC::SelectObject 用的过程中要保存原来的画笔指针。
创建一个阴影线的笔只能是1或更小。
(其他的注意情况看msdn)。
创建画刷:
CBrush 类的方法
FillRect填充矩形的区域。
CRect类,几种不同的方法。
用位图填充画刷。
CBitmap 的构造函数,没有参数。
调用之前必需初始化。
透明画刷的创建:
(); 画出矩形。
空画刷:GetStockObject
CBrush::FromeHandle
空画刷的实现方法:
CBrush *brush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
CBrush *oldbrush=(brush);
(CRect(org,point));
(oldbrush);
理解
消息响应的知识:
MouseMove。