应用程序由各种对象组成.大多数情况下,计算机上运行的应用程序不止一个,并且不断要求操作系统执行某些分配.因为可能会出现无法预测的许多请求,操作系统会将其留给对象来指定他们想要的内容,何时需要,以及他们期望的行为或结果.
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项目来看一个简单的例子.
第1步 : 要创建MFC项目,请右键单击项目并选择"属性".
步骤2 : 在左侧部分中,单击"配置属性"和"rarr";一般.
第3步 : 在"项目默认值"部分中选择"在共享DLL中使用MFC"选项,然后单击"确定".
步骤4 : 我们需要添加一个新的源文件.
第5步 : 右键单击Project并选择Add → 新项目.
第6步 : 在"模板"部分中,单击"C ++文件(.cpp)".
第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消息.
消息 | 地图条目 | 描述 |
---|---|---|
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_DRAWITEM | ON_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步 : 编译并执行上面的代码时,您将看到以下输出.
第6步 : 当您单击"确定"时,它将显示主窗口.
图形应用程序的一个主要功能是提供允许用户与机器交互的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键时,它将显示以下消息.
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.
Step 5 : When you click OK, you will see the following message.
Step 6 : Right-click on this window. Now, when you release the right button of the mouse, it will display the following message.