MFC - 消息活动

应用程序由各种对象组成.大多数情况下,计算机上运行的应用程序不止一个,并且不断要求操作系统执行某些分配.因为可能会出现无法预测的许多请求,操作系统会将其留给对象来指定他们想要的内容,何时需要,以及他们期望的行为或结果.

概述

  • Microsoft Windows操作系统无法预测一个对象需要处理的请求类型以及分配另一个对象需要.

  • 要管理所有这些分配和请求,对象会发送消息.

  • 每个对象都有责任决定发送什么消息以及何时发送.

  • 为了发送消息,控件必须创建一个事件.

  • 为了区分两者,消息的名称通常以WM_开头,代表Window Message.

  • 事件的名称通常以On开头,表示操作.

  • 事件是发送混乱的动作年龄.

消息地图

由于Windows是面向消息的操作系统, Windows环境的大部分编程涉及消息处理.每次发生按键或鼠标点击等事件时,都会向应用程序发送一条消息,然后必须处理该事件.

  • 为了让编译器管理消息,它们应该包含在类定义中.

  • DECLARE_MESSAGE_MAP 宏应该是在类定义的末尾提供,如下面的代码所示.

class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      DECLARE_MESSAGE_MAP()
};

  • 实际消息应列在DECLARE_MESSAGE_MAP行的正上方.

  • 要实现这些消息,您需要创建一个程序正在使用的消息表.

  • 此表使用两个分隔宏;

  • 它以 BEGIN_MESSAGE_MAP 开头,以 END_MESSAGE_MAP 宏结束.

  • BEGIN_MESSAGE_MAP宏有两个参数,类的名称和派生类的MFC类,如下面的代码所示.

#include <afxwin.h>
class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {

   // Create the window's frame
   Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
                                      CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
   public:
      BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance(){
   m_pMainWnd = new CMainFrame;
   m_pMainWnd->ShowWindow(SW_SHOW);
   m_pMainWnd->UpdateWindow();
   return TRUE;
}
 CMessagesApp theApp;

让我们通过创建一个新的Win32项目来看一个简单的例子.

Win32项目

第1步 : 要创建MFC项目,请右键单击项目并选择"属性".

步骤2 : 在左侧部分中,单击"配置属性"和"rarr";一般.

第3步 : 在"项目默认值"部分中选择"在共享DLL中使用MFC"选项,然后单击"确定".

步骤4 : 我们需要添加一个新的源文件.

第5步 : 右键单击Project并选择Add → 新项目.

第6步 : 在"模板"部分中,单击"C ++文件(.cpp)".

Win Project

第7步 : 点击添加以继续.

步骤8 : 现在,在* .cpp文件中添加以下代码.

#include <afxwin.h>
class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      DECLARE_MESSAGE_MAP()
};

CMainFrame::CMainFrame() {
   // Create the window's frame
   Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
      CRect(120, 100, 700, 480), NULL);
}

class CMessagesApp : public CWinApp {
   public:
      BOOL InitInstance();
}
CMessagesApp theApp;

Windows消息

有不同类型的Windows消息,如创建窗口,显示窗口等.一些常用的Windows消息.


<td style ="vertical-align:中""WM_DRAWITEM <td style ="vertical-align:中""ON_WM_MOUSELEAVE()
消息地图条目描述
WM_ACTIVATE ON_WM_ACTIVATE()框架在激活或停用CWnd对象时调用此成员函数.
WM_ACTIVATEA PP  ON_WM_ACTIVATEAPP()框架将此成员函数调用到正在激活的任务的所有顶级窗口以及正在停用的任务的所有顶级窗口.
WM_APPCOMM AND ON_WM_APPCOMMAND()框架在用户生成应用程序命令事件时调用此成员函数.
WM_CANCELMODE WM_CANCELMODE()框架调用此成员函数通知CWnd取消任何内部模式.
WM_CHILDACTIVATE ON_WM_CHILDACTIVATE()如果CWnd对象是多文档界面( MDI)子窗口,当用户单击窗口的标题栏或窗口是ac时,框架调用OnChildActivate生气,移动或大小.
WM_CLIPBOAR DUPDATE ON_WM_CLIPBOARDUPDATE()当剪贴板的内容发生变化时,框架会调用此成员函数.
WM_CLOSE ON_WM_CLOSE()框架将此成员函数调用为CWnd或应用程序要终止的信号.
WM_CONTEXTMENU ON_WM_CONTEXTMENU()当用户在窗口中单击鼠标右键(右键单击)时,框架调用.
WM_COPYDATA ON_WM_COPYDATA()这个成员函数是调用框架将数据从一个应用程序复制到另一个应用程序.
WM_CREATE ON_WM_CREATE()框架在应用程序请求时调用此成员函数通过调用Create或CreateEx成员函数来创建Windows窗口.
WM_CTLCOLOR ON_WM_CTLCOLOR()框架调用此成员函数时即将绘制儿童控制.
WM_DELETEITEM ON_WM_DELETEITEM()框架调用此成员函数通知所有者绘制的所有者列表框或组合框销毁列表框或组合框或已删除项目.
WM_DESTROY ON_WM_DESTROY()框架调用此成员函数通知CWnd对象它正在被销毁.
WM_DRAWITEMON_WM_DRAWITEM()框架调用此成员当控件或菜单的可视方面发生变化时,所有者绘制按钮控件,组合框控件,列表框控件或菜单的所有者的功能.
WM_DROPFILES ON_WM_DROPFILES ()当用户在已将自己注册为已删除文件的收件人的窗口上释放鼠标左键时,框架会调用此成员函数.
WM_ENABLE ON_WM_ENABLE()当应用程序更改CWnd对象的启用状态时,框架将调用此成员函数.语法.
WM_HELPINFO ON_WM_HELPINFO()在应用程序中处理F1帮助(使用当前上下文).
WM_HOTKEY ON_WM_HOTKEY()当用户按下系统范围的热键时,框架会调用此成员函数.
WM_HSCROLL ON_WM_HSCROLL ()框架在用户单击窗口的水平滚动条时调用此成员函数.
WM_KEYDOWN ON_WM_KEYDOWN()当按下非系统键时,框架会调用此成员函数.
WM_KEYUP ON_WM_KEYUP()框架在释放非系统密钥时调用此成员函数.
WM_KILLFOCUS ON_WM_KILLFOCUS()框架在此之前调用此成员函数失去输入焦点.
WM_LBUTTONDBLCLK ON_WM_LBUTTONDBLCLK()当用户双击鼠标左键时,框架会调用此成员函数./td>
WM_LBUTTONDOWN ON_WM_LBUTTONDOWN()当用户按下鼠标左键时,框架会调用此成员函数.
WM_LBUTTONUP ON_WM_LBUTTONUP()框架调用当用户释放鼠标左键时此成员函数.
WM_MBUTTONDBLCLK ON_WM_MBUTTONDBLCLK()当用户加倍时,框架调用此成员函数点击鼠标中键.
WM_MBUTTONDOWN ON_WM_MBUTTONDOWN()当用户按下鼠标中键时,框架会调用此成员函数.
WM_MBUTTONUP ON_WM_MBUTTONUP()当用户释放鼠标中键时,框架会调用此成员函数.
WM_MENUSELECT ON_WM_MENUSELECT()如果CWnd对象与菜单相关联,则当用户选择菜单项时,框架将调用OnMenuSelect.
WM_MOUSEACTIVATE ON_WM_MOUSEACTIVATE()当光标处于非活动窗口并且用户按下鼠标按钮时,框架调用此成员函数.
WM_MOUSEHOVER ON_WM_MOUSEHOVER()当光标悬停在窗口的客户区域上一段时间之前调用TrackMouseEvent时,框架会调用此成员函数.
WM_MOUSEHWHEEL ON_WM _MOUSEHWHEEL()框架在桌面窗口管理器(DWM)组成当前窗口时调用此成员,并且该窗口最大化.
WM_MOUSELEAVE ON_WM_MOUSELEAVE()当光标离开先前调用TrackMouseEvent时指定的窗口的客户区域时,框架调用此成员函数.
WM_MOUSEMOVE ON_WM_MOUSEMOVE()当鼠标光标移动时,框架会调用此成员函数.
WM_MOVE ON_WM_MOVE()框架在移动CWnd对象后调用此成员函数.
WM_P AINT ON_WM_PAINT()框架在Windows或应用程序中调用此成员函数请求重新绘制应用程序窗口的一部分.
WM_SETFOCUS() ON_WM_SETFOCUS()框架在获得之后调用此成员函数输入焦点.
WM_SIZE() ON_WM_SIZE()框架在窗口大小发生变化后调用此成员函数.
WM_TIMER ON_WM_TIMER()框架在用于安装计时器的SetTimer成员函数中指定的每个间隔后调用此成员函数.
WM_VSCROLL ON_WM_VSCROLL()框架在用户单击窗口的垂直滚动条时调用此成员函数.
WM_WINDOWPOSCHANGED ON_WM_WINDOWPOSCHANGED()框架调用由于调用SetWindowPos成员函数或其他窗口管理函数而导致大小,位置或Z顺序发生更改时,此成员函数.

让我们看一个窗口创建的简单示例.

WM_CREATE : 当创建一个名为窗口的对象时,创建对象的框架会发送一条标识为 ON_WM_CREATE 的消息.

步骤1 : 要创建ON_WM_CREATE,请添加afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);在DECLARE_MESSAGE_MAP()之前,如下所示.

class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      DECLARE_MESSAGE_MAP()
};

第2步 : 在BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)之后和END_MESSAGE_MAP()

之前添加ON_WM_CREATE()

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
END_MESSAGE_MAP()

第3步 : 这是OnCreate()的实现

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
   // Call the base class to create the window
   if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {

      // If the window was successfully created, let the user know
      MessageBox(L"The window has been created!!!");
      // Since the window was successfully created, return 0
      return 0;
   }
   // Otherwise, return -1
   return -1; 
}

第4步 : 现在你的* .cpp文件看起来如下面的代码所示.

#include <afxwin.h>
class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {

   // Create the window's frame
   Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
      CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
   public:
      BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
END_MESSAGE_MAP()
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
   // Call the base class to create the window
   if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {
      // If the window was successfully created, let the user know
      MessageBox(L"The window has been created!!!");
      // Since the window was successfully created, return 0
      return 0;
   }
   // Otherwise, return -1
   return -1;
}
BOOL CMessagesApp::InitInstance() { 
   m_pMainWnd = new CMainFrame;
   m_pMainWnd -> ShowWindow(SW_SHOW);
   m_pMainWnd -> UpdateWindow();
   return TRUE;
} 
 CMessagesApp theApp;

第5步 : 编译并执行上面的代码时,您将看到以下输出.

Message

第6步 : 当您单击"确定"时,它将显示主窗口.

Message

命令消息

图形应用程序的一个主要功能是提供允许用户与机器交互的Windows控件和资源.我们将学习的控件示例包括按钮,列表框,组合框等.

我们在上一课中介绍的一种资源是菜单.这些控件和资源可以在用户单击它们时发起自己的消息.从Windows控件或资源发出的消息称为命令消息.

让我们看一个命令消息的简单示例.

为了使您的应用程序能够创建新文档,CWinApp类提供了OnFileNew()方法.

afx_msg void OnFileNew();

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_COMMAND(ID_FILE_NEW, CMainFrame::OnFileNew)
END_MESSAGE_MAP()

这是方法定义 :

void CMainFrame::OnFileNew() {
   // Create New file
}

键盘消息

键盘是连接到计算机的硬件对象.默认情况下,它用于在控件上输入可识别的符号,字母和其他字符.键盘上的每个键都会显示一个符号,一个字母或这些键的组合,以指示键可以用于什么.用户通常按下一个键,该键向程序发送信号.

每个键都有一个操作系统可以识别的代码.此代码称为虚拟密钥代码.

Sr.No.常数/value&说明
1

VK_LBUTTON

鼠标左键

2

VK_RBUTTON

鼠标右键

3

VK_CANCEL

控制中断处理

4

VK_MBUTTON

鼠标中键(三键鼠标)

5

VK_BACK

BACKSPACE键

6

VK_RETURN

ENTER键

7

VK_TAB

TAB键

8

VK_CLEAR

CLEAR键

9

VK_SHIFT

SHIFT键

10

VK_CONTROL

CTRL键

11

VK_MENU

ALT键

12

VK_PAUSE

PAUSE键

13

VK_CAPITAL

CAPS LOCK键

14

VK_ESCAPE

ESC键

15

VK_SPACE

空格键

16

VK_PRIOR

PAGE UP键

17

VK_NEXT

PAGE DOWN键

18

VK_END

END键

19

VK_HOME

HOME键

20

VK_LEFT

LEFT箭头键

21

VK_UP

向上箭头键

22

VK_RIGHT

右箭头键

23

VK_DOWN

向下箭头键

24

VK_SELECT

SELECT键

25

VK_PRINT

PRINT键

26

VK_EXECUTE

执行密钥

27

VK_SNAPSHOT

P RINT SCREEN键

28

VK_INSERT

INS键

29

VK_DELETE

DEL键

30

VK_NUMPAD0

数字键盘0键

31

VK_NUMPAD1

数字键盘1键

32

VK_NUMPAD2

数字键盘2键

33

VK_NUMPAD3

数字小键盘3键

34

VK_NUMPAD4

数字键盘4键

35

VK_NUMPAD5

数字键盘5键

36

VK_NUMPAD6

数字小键盘6键

37

VK_NUMPAD7

数字键盘7键

38

VK_NUMPAD8

数字小键盘8键

39

VK_NUMPAD9

数字键盘9键

40

VK_MULTIPLY

Multiply key

41

VK_ADD

添加键

42

VK_SEPARATOR

分隔符键

43

VK_SUBTRACT

减去关键

44

VK_DECIMAL

十进制键

45

VK_DIVIDE

除键

46

VK_F1

F1键

47

VK_F2

F2键

48

VK_F3

F3键

49

VK_F4

F4键

50

VK_F5

F5键

52

VK_F6

F6键

53

VK_F7

F7键

54

VK_F8

F8键

55

V K_F9

F9键

56

VK_F10

F10键

57

VK_F11

F11键

58

VK_F12

F12键

59

VK_NUMLOCK

NUM LOCK键

60

VK_SCROLL

滚动锁定键

61

VK_LSHIFT

左侧SHIFT键

62

VK_RSHIFT

右移SHIP键

63

VK_LCONTROL

左控制键

64

VK_RCONTROL

右控制键

按一个键会导致 WM_KEYDOWN 或 WM_SYSKEYDOWN 消息将被放置在线程消息中.这可以定义如下 :

afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

让我们看一个简单的例子.

第1步 : 这是消息.

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
   ON_WM_KEYDOWN()
END_MESSAGE_MAP()

第2步 : 这是OnKeyDown()的实现.

void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
   switch (nChar) {

      case VK_RETURN:
         MessageBox(L"You pressed Enter");
         break;
      case VK_F1:
         MessageBox(L"Help is not available at the moment");
         break;
      case VK_DELETE:
         MessageBox(L"Can't Delete This");
         break;
      default:
         MessageBox(L"Whatever");
   }
}

第3步 : 编译并执行上面的代码时,您将看到以下输出.

消息窗口

第4步 : 当您按Enter键时,它将显示以下消息.

消息输出

Mouse Messages

The mouse is another object that is attached to the computer allowing the user to interact with the machine.

  • If the left mouse button was pressed, an ON_WM_LBUTTONDOWN message is sent. The syntax of this message is  :

    • afx_msg void OnLButtonDown(UINT nFlags, CPoint point)

  • If the right mouse button was pressed, an ON_WM_RBUTTONDOWN message is sent. Its syntax is  :

    • afx_msg void OnRButtonDown(UINT nFlags, CPoint point)

  • Similarly If the left mouse is being released, the ON_WM_LBUTTONUP message is sent. Its syntax is  :

    • afx_msg void OnLButtonUp(UINT nFlags, CPoint point)

  • If the right mouse is being released, the ON_WM_TBUTTONUP message is sent. Its syntax is  :

    • afx_msg void OnRButtonUp(UINT nFlags, CPoint point)

Let us look into a simple example.

Step 1  :  Add the following two functions in CMainFrame class definition as shown in the following code.

class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
      afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
      afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
      DECLARE_MESSAGE_MAP() 
 };

第2步 :  Add the following two Message Maps.

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_KEYDOWN()
   ON_WM_LBUTTONDOWN()
   ON_WM_RBUTTONUP()
END_MESSAGE_MAP()

Step 3  :  Here is the functions definition.

void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) { 
   CString MsgCoord;
   MsgCoord.Format(L"Left Button at P(%d, %d)", point.x, point.y);
   MessageBox(MsgCoord);
}
void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) { 
   MessageBox(L"Right Mouse Button Up");
}

Step 4  :  When you run this application, you will see the following output.

Mouse Messages

Step 5  :  When you click OK, you will see the following message.

Mouse Messages

Step 6  :  Right-click on this window. Now, when you release the right button of the mouse, it will display the following message.

Mouse Messages