在MFC对话框中自定义消息及其响应函数
- 格式:pdf
- 大小:106.21 KB
- 文档页数:4
MFC实现动态菜单及响应函数MFC中利用CMenu类动态添加弹出菜单和响应函数步骤:1 声明一个菜单:CMenu menu;2 生成菜单对象:menu.CreatePopupMenu();3 给菜单添加上内容:menu.AppendMenu(MF_STRING,WM_CLEARHOSTS,"清除HOSTS");AppendMenu函数具体的意义可以查看MSDN,其中WM_CLEARHOSTS为自定义的一个消息,最后一个参数为菜单的text,点击这个菜单就可以调用WM_CLEARHOSTS消息的处理函数。
4 添加子弹出菜单:CMenu submenu;submenu.CreatePopupMenu();menu.AppendMenu(MF_POPUP,(UINT_PTR)(submenu.m_hM enu),"sub");5 设置当失去焦点时菜单自动消失SetForegroundWindow();6 设置菜单的位置:menu.TrackPopupMenu();以上各步连接起来就是一个完整的动态生成菜单的步骤,当动态生成的菜单很多且菜单又不固定的时候,预先为每个菜单都定义一个消息和消息处理函数是很麻烦且不现实的,现在介绍一种方法来动态响应动态生成的菜单。
其原理就是利用OnCommand函数。
首先,要为每一个动态生成的菜单指定一个ID,方式如下menu.AppendMenu(MF_STRING,ID,"yourMenuName");其中参数ID为一个唯一的整数,可以由你自己指定,当鼠标单击此菜单的时候,系统发送一个消息,此消息优先被OnCommand函数接收,OnCommand函数的原形为:BOOL OnCommand(WPARAM wParam, LPARAM lParam);假如你指定菜单的ID为10001,响应函数的具体写法为:BOOL OnCommand(WPARAM wParam, LPARAM lParam){int menuID = LOWORD(wParam);if(menuID > 10000){//添加你自己的处理代码}}如果是使用对话框的mfc,自己重载OnCommand函数即可做一个MFC程序的时候碰到一个需求。
MFC实现动态菜单及响应函数一、实现步骤1.调用AppendMenu函数在菜单栏添加菜单2.调用AppendMenu函数在菜单栏菜单项添加子菜单3.调用AppendMenu函数在菜单栏菜单项添加动态子菜单4.将菜单所属的窗口句柄传入OnInitMenu函数5.在OnInitMenu函数中清除原有的菜单6.在菜单窗口中添加新的菜单二、代码1.主程序代码```// MFC_DynamicMenu.cpp : 定义应用程序的入口点。
//#include "stdafx.h"#include "MFC_DynamicMenu.h"#define MAX_LOADSTRING 100//全局变量:HINSTANCE hInst; // 当前实例WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名//此代码模块中包含的函数的前向声明:ATOM MyRegisterClass(HINSTANCE hInstance);BOOL InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow)UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);//TODO:在此处放置代码。
//初始化全局字符串LoadStringW(hInstance, IDS_APP_TITLE, szTitle,MAX_LOADSTRING);LoadStringW(hInstance, IDC_MFCCDYNAMICMENU, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);//执行应用程序初始化:if (!InitInstance (hInstance, nCmdShow))return FALSE;}HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MFCCDYNAMICMENU));MSG msg;//主消息循环:while (GetMessage(&msg, nullptr, 0, 0))if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) TranslateMessage(&msg);DispatchMessage(&msg);}}return (int) msg.wParam;//// 函数: MyRegisterClass////目标:注册窗口类。
MFC自定义消息步骤MFC(Microsoft Foundation Classes)是Microsoft公司为Windows平台开发的C++类库,它封装了许多Windows API函数,简化了Windows应用程序的开发过程。
在MFC中,可以使用自定义消息来进行应用程序内部的消息传递。
自定义消息的步骤如下:1. 定义消息常量:首先,在需要使用自定义消息的地方(通常是对话框或视图类中),定义一个用于表示自定义消息的整型常量。
可以使用WM_USER作为基准值,如const UINT WM_MY_MESSAGE = WM_USER + 12. 注册消息:在应用程序启动时,通常在InitInstance函数中,使用CWinApp类的RegisterWindowMessage函数来注册自定义消息,该函数用于获取一个唯一的消息值,如:UINT myMessage = RegisterWindowMessage(LPCTSTR pString).3. 处理消息:在需要处理自定义消息的类中,重写消息处理函数(通常是OnWndMsg函数),根据自定义消息的值,对相应的消息进行处理。
如:BEGIN_MESSAGE_MAP(CMyDialog, CDialog)ON_WM_COPYDATA//...ON_REGISTERED_MESSAGE(myMessage, OnMyMessageHandler)END_MESSAGE_MAPLRESULT CMyDialog::OnMyMessageHandler(WPARAM wParam, LPARAM lParam)//处理自定义消息//...return 0;4. 发送消息:要发送自定义消息,可以使用CWnd类的PostMessage或SendMessage函数。
其中,PostMessage函数用于异步发送消息,而SendMessage函数用于同步发送消息。
(1) 异步发送消息(PostMessage):CWnd* pDestWnd = GetDlgItem(IDC_MY_CONTROL);pDestWnd->PostMessage(myMessage, wParam, lParam);(2) 同步发送消息(SendMessage):CWnd* pDestWnd = GetParent(;pDestWnd->SendMessage(myMessage, wParam, lParam);5.消息映射宏:在使用消息映射宏处理自定义消息时,需要使用ON_REGISTERED_MESSAGE宏,该宏会自动在消息映射表中添加对应的消息处理函数。
MFC中将窗口最小化至系统托盘1.在对话框类中声明NOTIFYICONDATA变量class CCamProjDlg : public CDialog{...NOTIFYICONDATA nid;BOOL isNotify;...}//初始化isNotify = false;2.在resource.h文件中自定义消息#define WM_SHOWTASK 10013.在对话框类中声明消息相应函数class CCamProjDlg : public CDialog{...afx_msg LRESULT onShowTask(WPARAM wParam,LPARAM lParam);...}4、在消息映射中添加BEGIN_MESSAGE_MAP(CCamProjDlg, CDialog)...ON_MESSAGE(WM_SHOWTASK,onShowTask)...END_MESSAGE_MAP()5.定义消息响应函数LRESULT CCamProjDlg::onShowTask( WPARAM wParam, LPARAM lParam ){ // wParam接收的是图标的ID,而lParam接收的是鼠标的行为if( wParam != IDR_MAINFRAME )return 1;switch(lParam){case WM_RBUTTONUP: // 右键起来时弹出快捷菜单,这里只有一个"关闭"{LPPOINT lpoint = new tagPOINT;::GetCursorPos(lpoint); // 得到鼠标位置CMenu menu;menu.CreatePopupMenu(); // 声明一个弹出式菜单menu.AppendMenu(MF_STRING,WM_DESTROY,_T("关闭")); // 增加菜单项"关闭",点击则发送消息WM_DESTROY给主窗口(已隐藏),将程序结束。
MFC编程⼊门之九(对话框:为控件添加消息处理函数) 这⼀节讲的主要内容是如何为控件添加消息处理函数。
MFC为对话框和控件定义了诸多消息,我们对他们操作时会触发消息,这些消息最终由消息处理函数处理,⽐如我们点击按钮时就会产⽣BN_CLICKED消息,修改编辑框内容时会产⽣EN_CHANGE消息等。
⼀般为了让某种操作达到效果,我们只需要实现某个消息的消息处理函数。
⼀、添加消息处理函数 仍然以前⾯的计算器程序为例,说明怎样为“计算”按钮添加消息处理函数,添加⽅法列出4中: 1、使⽤Class Wizard添加消息处理函数 ⽤过VC++6.0的朋友应该对Class Wizard很熟悉了,添加类、消息处理函数等经常会⽤到它,可以说是⼀个很核⼼的功能。
但从VS2002开始就见不到ClassWizard了,⼤部分功能都集成到对话框和控件等的属性了,使⽤很⽅便。
到VS2010,久违的Class Wizard⼜回来了。
⼤家应该记得,“计算”按钮的ID为IDC_CALCULATE_BUTTON。
上图中Commands标签下,Object IDs列表中有此ID,因为我们是想实现点击按钮后的消息处理函数,所以在Message列表中选择BN_CLIECKED消息,然后点右上⽅的Add Handler就可以添加BN_CALCULATE_CLICKED消息处理函数OnClickedAddButton了。
当然你也可以改名,但⼀般⽤的默认的就可以。
2、通过”Add Event Handler...“添加消息处理函数 在”计算“按钮上点右键,然后在右键菜单中选择菜单项”Add Event Handler...“,弹出”Event Handler Wizard“对话框,如下图: 可见"Message type"中默认选中的就是BN_CLICKED消息,函数名和所在类都已经⾃动给出,直接点”Add and Edit“就可以了。
MFC动态按钮的创建及其消息响应(⾃定义消息)动态按钮(多个)的创建:1、在类中声明并定义按钮控件的ID#define IDC_D_BTN 100002、在类的OnInitDialog()函数中动态创建按钮(建⽴按钮对象时最好建⽴对象的指针)3、⼿动释放对象指针下⾯是动态⽣成多个按钮的例⼦:CButton* btn = new CButton[5];DWORD dwStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;for(int i = 0; i < 5; i++){btn[i].Create(_T("动态按钮"), dwStyle,CRect(20+80*i,20,80+80*i,60),this,IDC_D_BTN+i);}注:Create()的第⼀个参数为按钮的标题,可直接给出(如上所⽰),也可在String Table中先定义字符串,再利⽤控件的LoadString()函数将字符串读取进来程序运⾏效果如下所⽰:动态按钮(多个)的消息响应: ⼀个MFC的消息响应函数在程序中有三处相关信息:函数原型、函数实现以及⽤来关联消息和消息响应函数的宏。
头⽂件中在两个AFX_MSG注释宏之间是消息响应函数原型的声明。
源⽂件中有两处:⼀处是在AFX_MSG_MAP注释宏之间的消息映射宏,⽤来关联消息和消息响应函数的宏;另⼀处是源⽂件中的消息响应函数的实现代码。
下⾯为动态⽣成的多个按钮的消息响应的建⽴步骤:1、在对话框类的定义⽂件(.h⽂件)中声明消息响应函数OnButtonClickafx_msg void OnButtonClick(UINT uID);注:OnButtonClick函数的参数nID代表响应函数对应按钮控件的ID号,单个按钮可不设参数2、在对话框类的函数实现⽂件(.cpp⽂件)中定义消息映射ON_COMMAND_RANGE (多个按钮) 在函数实现⽂件中的消息映射部分(BEGIN_MESSAGE_MAP与END_MESSAGE_MAP之间)定义按钮控件与其消息响应函数之间的映射关系。
用户自定义消息SendMessage的使用这里主要讲一下mfc中SendMessage的使用方法。
传递消息主要分4步:1.在类的定义中声明消息函数:afx_msg void AAA();2.在相应的cpp文件中的MESSAGE_MAP区域内添加ON_MESSAGE(MESSAGE_ID,AAA),其中参数1为要传递消息的ID,参数2为刚刚声明的函数名称,不用带括号。
3.实现消息函数:在cpp文件中添加LRESULT 类名::AAA(WPARAM wparam,LPARAM lparam){执行内容……return 0;}4.发送消息:在需要发送消息的地方添加下列语句:HWND hWnd = ::FindWindowEx( m_hWnd, NULL, NULL, WINDOW_TEXT ) ;FromHandle(hWnd)->SendMessage(MESSAGE_ID,a,b);其中,m_hWnd为接收消息的父窗口的句柄,WINDOW_TEXT为接收消息窗口的标题,得到的hWnd为接收消息窗口的句柄。
调用该窗口的SendMessage 函数,MESSAGE_ID为刚刚设定的消息ID,a和b是要传递的参数。
注:在这4个步骤中,前三个我在做的时候基本没什么障碍。
问题主要出现在第4步。
开始找到网上的例子给的都是FindWindow函数,怎么用都不好使。
后来看到有人说FindWindow是找操作系统下打开的窗口的句柄,找窗口中子窗口要用FindWindowEx函数。
我也尝试过用对话框的ID找到相应的句柄,像GetDlgItem(ID)函数一样,未果。
我使用的对话框都是没有标题栏的,所以也就没有窗口的标题,当然这并不会影响我设置标题。
只要在生成该窗口的区域内添加SetWindowText(“窗口标题”)就可以了。
也就是说窗口标题可以设置,但是不会显示。
最后一点在SendMessage()函数中,MFC默认传递的参数是WPARAM和LPARAM型(一个是UINT型,一个LONG型),如果要传递浮点类型,或者其它不是整数的类型,就可以用指针的形式传递(如果发送方只是申请一个变量并以地址的形式传递,然后接收方以指针的形式接收,如果在执行完SendMessage 之后原函数体立即结束了,我不知道在接收函数体接收和使用该变量的之间的一瞬间,该内存区域会不会被占用,我觉得还是有这种可能的。
mfc自定义消息用法在MFC(Microsoft Foundation Class)中,自定义消息可以通过两种方式定义和使用:通过注册消息和通过自定义消息常量。
一、通过注册消息的方式:1. 调用`RegisterWindowMessage`函数定义一个系统唯一的消息,例如:`static UINT WM_MY_MESSAGE = RegisterWindowMessage("User");`2. 使用`ON_REGISTERED_MESSAGE`宏指令代替`ON_MESSAGE`宏指令,其余步骤同上。
二、通过自定义消息常量方式:1. 在公共头文件中添加自定义消息常量,例如:`const UINTWM_TESTMESSAGE = WM_USER + 0x100;`2. 在类的头文件中,添加对应的消息处理函数声明,例如:`afx_msg LRESULT OnTestMessage(WPARAM wParam, LPARAM lParam);`3. 在类的实现文件中,添加消息映射,以告知程序当接收到自定义消息时,应该交由哪个函数处理。
例如:```c++BEGIN_MESSAGE_MAP(CReceiveDlg, CDialogEx)ON_MESSAGE(WM_TESTMESSAGE, OnTestMessage)END_MESSAGE_MAP()```4. 编写消息对应的函数具体实现。
例如:```c++LRESULT CReceiveDlg::OnTestMessage(WPARAM wParam, LPARAM lParam){// 消息处理的具体实现代码...return 0;}```5. 使用`PostMessage`或`SendMessage`发送自定义消息。
例如:`::PostMessage(m_pRecvDlg->GetSafeHwnd(), WM_TESTMESSAGE, (WPARAM)pInfo, 0);`。
MFC动态控件添加消息响应MFC动态创建控件的消息处理前些天有⼈在论坛⾥问在动态创建TreeCtrl后怎么响应消息于是便写了⼀点⾃⼰的⼼得现整理如下。
本例在MFC动态创建控件的消息处理前些天有⼈在论坛⾥问在动态创建TreeCtrl后怎么响应消息于是便写了⼀点⾃⼰的⼼得现整理如下。
本例在view中动态创建⼀个ListCtrl并响应其NM_CLICK消息先写出动态创建的代码: 新建⼀SDI⼯程给view加上⼀个成员变量:CListCtrl m_list 在view的OnCreate中创建它:ifm_list.CreateWS_BORDER WS_CHILD WS_VISIBLELVS_ICON LVS_AUTOARRANGELVS_EDITLABELSCRect1010310210thisID_LISTCTRLTRACE0Failed to create ListCtrl windownreturn -1//添加⼀些项CString strforint i0i10istr.Formatitemdim_list.InsertItemistr 其中的ID_LISTCTRL是这个控件的ID当然你可以直接⽤数值来表⽰但为了程序清淅还是定义⼀个常量的好在主菜单View-Resource Symbols弹出的对话框中New按钮在Name下⾯输⼊ID_LISTCTRL. 创建完毕编译链接后就可以运⾏了但你怎么它都没反应当然因为我们还没写消息处理的代码。
通常做法是⼿动写消息处理函数及消息映射⾄少得三步1在头⽂件中定义消息处理函数的原型2在cpp中实现这个函数3在BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间写上消息映射。
如果是单单处理⼀个消息的话那还可以忍受消息⼀多的话不但⿇烦还容易出错。
所以我采取下⾯的⽅法: 1.打开about对话框资源放⼊⼀个ListCtrl控件到对话框中并将其ID设为ID_LISTCTRL. 2.CtrlW把Class Name由原来的CAboutDlg改为CxxxView在左边的Object IDS中选择ID_LISTCTRL这时右边会出现相应的通知消息这时就可以跟平常⼀样双击添加消息映射了. 嘿嘿是不是跟在对话框⾥响应控件的消息⼀样很⽅便呀. 有⼀点需要注意只有当打开你加⼊控件的那个对话框资源编辑器的时候按CtrlW时Class Wizard中才会出现那个ID_LISTCTRL还有发⾏时注意把对话框上的listctrl控件删掉.。
MFC中的消息发送与响应1. 主窗口向子窗口发送消息:/phenixyf/article/details/9300425从主窗口向子窗口发送消息,可以在子窗口中添加自定义的消息,然后在主窗口中需要地方呼叫该消息。
呼叫方法:1.将子窗口添加为主窗口的成员变量;2.主窗口呼叫该消息,成员变量名.SendMessage(UM_PROGRESS);子窗口添加自定义消息步骤如下:1、定义消息。
在Windows中,所有的消息都用一个特定的整数值来表示,为了避免自定义消息与已存在的其他消息发生冲突,应该利用Windows提供的一个常量:WM_USER,小于这个常量的是系统保留的。
即用户自定义的消息至少为WM_USER+1,注意最后表示的消息的数值不要超过0x7FFF。
在开发Windows95应用程序时,Microsoft推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。
#define UM_PROGRESS WM_USER + 100将上句添加到子窗口类的头文件(.h)中。
2、在子窗口类头文件的AFX_MSG块中声明消息处理函数:class CMainFrame:public CFrameWnd{protected://{{AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnTimer(UINT nIDEvent);afx_msg LRESULT OnProgress(WPARAM wParam, LPARAM lParam);//}}AFX_MSGDECLARE_MESSAGE_MAP()3、在子窗口类的实现文件(.cpp)中,使用ON_MESSAGE宏指令将消息映射到消息处理表中。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)//{{AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()ON_WM_TIMER()ON_MESSAGE(UM_PROGRESS, OnProgress)//注意这条语句的后面没有分号//}}AFX_MSG_MAPEND_MESSAGE_MAP()4、实现消息处理函数。
MFC自定义消息和子对话框父对话框发送消息消息机制是windows的典型运行机制,在MFC中有很多的消息如WM_BTN**等。
但是在有些情况下我们需要自定义一些消息去做一些我们需要的功能,MFC的向导不能帮助我们做到这一点,我们可以通过添加相应的代码去完成这个功能。
添加自定义消息操作如下:1. 建立MFC工程,如基于对话框的应用程序,Test。
2. 在资源中添加要处理的消息的值,即在CTestDlg.h 中添加如下代码。
(因为很多MFC的消息是在WM_USER内的,所以这里用比WM_USER大的消息)#define WM_MyMessage (WM_USER+100)3. 声明消息处理函数,在CTestDlg.h中添加代码1.class CTestDlg : public CDialog2.{3.protected:4.……5.// 生成的消息映射函数6.……7.afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); // add lyw8.DECLARE_MESSAGE_MAP()9.……4. 添加消息映射处理,在CTestDlg.cpp中人找到如下部分添加代码1.BEGIN_MESSAGE_MAP(CTestDlg, CDialog)2.……3.ON_MESSAGE(WM_MyMessage, OnMyMessage)4.END_MESSAGE_MAP()5. 实现自己的自定义消息处理1.LRESULT CT estDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)2.{3.//MessageBox("recv msg success");4.//添加自己的消息处理5.……6.return 0;7.}6. 如果要发送一个自定义的消息,使用代码SendMessage( WM_MyMessage, 0, 0);或者PostMessage(WM_MyMessage, 0, 0);如果是在子对话框里,想向父对话框发送消息GetParent()->SendMessage(WM_XXX,a,b);//或使用如下代码发送消息:HWND hwnd = ::GetParent(m_hWnd);::SendMessage(hwnd,WM_XXX,a,b);//SendMessage(WM_add_event_ok,a,b);//在测试中,不使用GetParent()->的时候,消息无法传递到父窗口的消息处理函数中,只有增加了GetParent()->后,消息才能成功的发送。
mfc子对话框自定义消息及响应函数在MFC程序中,子对话框是一种非常常用的UI组件,它可以作为主对话框的一个子窗口,用于显示和处理某个特定功能的界面和逻辑。
而在子对话框中,我们经常需要自定义消息和响应函数,以便实现自己的业务需求。
接下来,本文将为大家介绍如何在MFC子对话框中自定义消息和响应函数。
一、什么是自定义消息和响应函数?在MFC程序中,消息是指窗口和控件之间的通讯机制。
当用户执行某些操作时,窗口或控件会向消息队列中发送一条消息,然后消息循环会将这些消息逐个分发给窗口和控件,从而触发相应的事件和动作。
而自定义消息和响应函数,则是指我们可以自己定义一些特定的消息类型和相应的处理函数,从而实现对某些特定事件的处理。
比如,我们可以定义一个自己的WM_MY_MESSAGE消息,然后在子对话框中添加一个响应函数OnMyMessage,当收到这个消息时,就会自动调用该响应函数来处理相应的业务逻辑。
二、如何定义自定义消息和响应函数?在MFC程序中,定义自定义消息和响应函数的步骤如下:1.在resource.h文件中添加自定义消息的宏定义,如下所示:#define WM_MY_MESSAGE (WM_USER+100)其中,WM_USER是一个预定义的消息码,代表用户自定义消息的起始码,因此我们可以在此基础上加上一个任意数字来定义自己的消息码。
2.在子对话框的头文件中声明自定义消息的处理函数,如下所示:afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);其中,afx_msg是一个宏定义,代表该函数是一个MFC消息处理函数,LRESULT是一个预定义的返回值类型,代表消息的处理结果。
3.在子对话框的源文件中实现自定义消息的处理函数,如下所示:LRESULT CMySubDlg::OnMyMessage(WPARAM wParam, LPARAM lParam){// 在这里实现自己的业务逻辑return 0;}其中,CMySubDlg是子对话框的类名,OnMyMessage是自定义消息的处理函数名,wParam和lParam分别代表消息的参数,可以根据具体情况进行解析和使用。
用户自定义消息SendMessage的使用这里主要讲一下mfc中SendMessage的使用方法。
传递消息主要分4步:1.在类的定义中声明消息函数:afx_msg void AAA();2.在相应的cpp文件中的MESSAGE_MAP区域内添加ON_MESSAGE(MESSAGE_ID,AAA),其中参数1为要传递消息的ID,参数2为刚刚声明的函数名称,不用带括号。
3.实现消息函数:在cpp文件中添加LRESULT 类名::AAA(WPARAM wparam,LPARAM lparam){执行内容……return 0;}4.发送消息:在需要发送消息的地方添加下列语句:HWND hWnd = ::FindWindowEx( m_hWnd, NULL, NULL, WINDOW_TEXT ) ;FromHandle(hWnd)->SendMessage(MESSAGE_ID,a,b);其中,m_hWnd为接收消息的父窗口的句柄,WINDOW_TEXT为接收消息窗口的标题,得到的hWnd为接收消息窗口的句柄。
调用该窗口的SendMessage 函数,MESSAGE_ID为刚刚设定的消息ID,a和b是要传递的参数。
注:在这4个步骤中,前三个我在做的时候基本没什么障碍。
问题主要出现在第4步。
开始找到网上的例子给的都是FindWindow函数,怎么用都不好使。
后来看到有人说FindWindow是找操作系统下打开的窗口的句柄,找窗口中子窗口要用FindWindowEx函数。
我也尝试过用对话框的ID找到相应的句柄,像GetDlgItem(ID)函数一样,未果。
我使用的对话框都是没有标题栏的,所以也就没有窗口的标题,当然这并不会影响我设置标题。
只要在生成该窗口的区域内添加SetWindowText(“窗口标题”)就可以了。
也就是说窗口标题可以设置,但是不会显示。
最后一点在SendMessage()函数中,MFC默认传递的参数是WPARAM和LPARAM型(一个是UINT型,一个LONG型),如果要传递浮点类型,或者其它不是整数的类型,就可以用指针的形式传递(如果发送方只是申请一个变量并以地址的形式传递,然后接收方以指针的形式接收,如果在执行完SendMessage 之后原函数体立即结束了,我不知道在接收函数体接收和使用该变量的之间的一瞬间,该内存区域会不会被占用,我觉得还是有这种可能的。
MFC开发中添加⾃定义消息和消息响应函数(1)在.h或.cpp⽂件定义⼀个消息 #define CLICK_MESSAGE_BOX WM_USER+1001 //add by 20180612 给主窗⼝ctrl.cpp发送消息 //⾃定义消息 #define WM_PENSIGNMSG WM_USER+1001(2)在.h中类定义⾥添加消息映射DECLARE_MESSAGE_MAP() //类的定义 class CamPenSignerCtrl : public COleControl { // 消息映射 DECLARE_MESSAGE_MAP() }(3)在.h中类定义⾥添加宏⾥⾯添加消息处理函数声明 //类的定义 class CamPenSignerCtrl : public COleControl { //add by 20180612 给主窗⼝ctrl.cpp发送消息 //定义消息处理函数 afx_msg LRESULT OnPensignMsgHandler(WPARAM wParam, LPARAM lParam); }(4)cpp⽂件⾥链接消息和消息映射函数 BEGIN_MESSAGE_MAP(CamPenSignerCtrl, COleControl) //add by 20180612 给主窗⼝ctrl.cpp发送消息 //实现消息映射 ON_MESSAGE(WM_PENSIGNMSG,OnPensignMsgHandler) END_MESSAGE_MAP()(5)cpp中实现消息响应函数 afx_msg LRESULT CamPenSignerCtrl::OnPensignMsgHandler(WPARAM w,LPARAM l) { int nCode=l; EvtHandler(nCode); return 0; }(6)然后在本类中调⽤::PostMessage(PENSIGNMSG _MSG,0,0),当在这触发候,.cpp中的消息响应函数就触发了。
Qq:1047825419一、消息消息本质上是函数,所以要写自己定义的消息就要定义好函数。
当消息被触发的时候执行的就是这个函数了。
二、使用class wizard添加消息的分析当我们通过class wizard或者在工作空间中使用鼠标右键添加virtual message 时,工程会在以下几处发生变化:①②③解释:当为CmainFrame类添加自定义的消息时,CmainFrame的头文件会发生①②两处变化,定义文件会发生③变化。
自定义消息本质上就是为类添加一个成员函数,然后将这个函数注册为消息,使得其可以被触发而不是要手动调用。
这个“将函数注册为消息”就是将函数添加到消息宏中。
有一点,触发自己定义的消息要使用SendMessage函数。
这样就总结出在什么情况下使用自定义消息了:我们需要响应用户的操作,但是系统又没有响应的消息行为可以满足我们的需要,所以我们定义自己的消息行为以满足我们的需求。
当满足触发条件的话,我们就向系统发送这个消息,系统就会使用GetMessage函数分离出我们的消息并且执行这个消息了。
三、定义自己的消息由二可以知道我们对①②③三个地方一起修改就可以定义好我们自己的消息了。
首先,在类体(头文件)中添加消息原型:在类体的//{{AFX_MSG段中添加消息原型://{{AFX_MSG(CMainFrame)afx_msg void OnMyMessage();//}}AFX_MSG其次,在类定义(定义文件)中添加好消息映射:在BEGIN_MESSAGE_MAP段中添加:BEGIN_MESSAGE_MAP(CMainFrame ,CMainWnd)ON_MESSAGE(MessageID ,OnMyMessage)END_MESSAGE_MAP()最后,写好函数体:void CmainFrame::OnMyMessage(){MessageBox(“this is my message”);}四、关于调用当我们需要使用这个消息的时候,就使用SendMessage函数。
MFC中如何动态创建控件并响应其消息原理:利用窗体上的消息都会经OnCmdMsg进行路由处理的原理,在这里截获自己动态生成的那些控件,然后通过自定义消息发送出去(带上控件id),经自己的消息处理函数处理即可。
1、定义起始控件ID号,和自定义消息UINT Start_CtlID = 1980;#define DynamicBtnMessage WM_USER+200后面动态创建的控件id号会基于Start_CtlID自增;2、在OnInitDialog中动态创建控件窗体类中定义:CArray btnArray 以保存动态创建的按钮int btnw=120;int btnh = 50;//创建*3个button,顺序排列for (int i=0;i<5;i++){for (int j=0;j<5;j++){CString str;str.Format(_T("Cam%d"),Start_CtlID-1980);r.left =100 + (j*btnw);r.top =250 + (i*btnh);r.bottom = r.top + btnh;r.right =r.left + btnw;CButton *btn = CreateButton(Start_CtlID,str,r, BS_FLAT);btn->ShowWindow(SW_SHOW);btnArray.Add(btn);}}3 在OnCmdMsg中处理控件点击消息BOOL CFormDlg::OnCmdMsg(UINT nID, int nCode, void*pExtra,AFX_CMDHANDLERINFO* pHandlerInfo){// 判断传进来的控件id位于动态创建button的id之间,并且命令nCode是控件命令(比如点击事件消息),注:其它系统事件也会走到这个函数里进行分发的。
MFC基于对话框——右键弹出菜单,并响应函数1、新建一个菜单资源,比如把菜单的ID号为IDR_MENU1。
2、在ClassWizard中void CArcSoft_EffectDlg::OnRButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCMenu menu; //定义下面要用到的cmenu对象menu.LoadMenu(IDR_MENU1); //装载自定义的右键菜单CMenu *pContextMenu=menu.GetSubMenu(0); //获取第一个弹出菜单,所以第一个菜单必须有子菜单CPoint point1;//定义一个用于确定光标位置的位置GetCursorPos(&point1);//获取当前光标的位置,以便使得菜单可以跟随光标pContextMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RI GHTBUTTON,point1.x,point1.y,AfxGetMainWnd()); //在指定位置显示弹出菜单CDialog::OnRButtonDown(nFlags, point1);}这时,当右键点击对话框,就可以将菜单调出来了,但如何响应,菜单项呢?请继续看:3、在资源视图中右键单击菜单项,建立类向导(ClassWizard),此时会弹出一个对话框,点击第二个,加入到已存在的类,按确定。
4、在资源视图中为菜单中的每一项建立类向导,并添加Command响应函数,然后在这个函数中加入语句就可以啦。
ON_COMMAND(ID_COPY, OnCopy)//加Command响应函数,自动出现的灰色语句void CArcSoft_EffectDlg::OnCopy(){// TODO: Add your command handler code hereMessageBox("复制成功!");}。
6.1 传统控件在上一课的表5.1已经列出了Windows的传统控件及其对应的控件类。
在这些控件中,读者应该重点掌握命令按钮、选择框、单选按钮、编辑框、列表框和组合框。
.1.1 传统控件的控件通知消息控件通过向父窗口发送控件通知消息来表明发生了某种事件.例如,当用户在按钮上单击鼠标时,按钮控件会向父窗口发送BN_CLICKED消息.传统控件的通知消息实际上是通过WM_COMMAND消息发给父窗口的(滚动条除外),在该消息的wParam中含有通知消息码(如BN_CLICKED)和控件的ID,在lParam中则包含了控件的句柄.利用ClassWizard可以很容易地为控件通知消息加入消息映射和消息处理函数,这在上一章中已经演示过了.传统控件的消息映射宏是ON_XXXX,其中XXXX表示通知消息码,如BN_CLICKED.ON_XXXX消息映射如下所示,该宏有两个参数,一个是控件的ID,一个是消息处理函数名.ON_XXXX(nID, memberFxn)消息处理函数的声明应该有如下形式:afx_msg void memberFxn( );例如,某按钮的BN_CLICKED消息的消息映射及其处理函数的声明如下所示ON_BN_CLICKED(IDC_ADD,OnAdd)afx_msg void OnAdd( );有时,为了处理方便,需要把多个ID连续的控件发出的相同消息映射到同一个处理函数上.这就要用到ON_CONTROL_RANGE宏.ON_CONTROL_RANGE消息映射宏的第一个参数是控件消息码,第二和第三个参数分别指明了一组连续的控件ID中的头一个和最后一个ID,最后一个参数是消息处理函数名。
例如,要处理一组单选按钮发出的BN_CLICKED消息,相应的消息映射如下所示:ON_CONTROL_RANGE(BN_CLICKED, IDC_FIRST, IDC_LAST, OnRadioClicked)函数OnRadioClicked的声明如下,该函数比上面的OnAdd多了一个参数nID以说明发送通知消息的控件ID.afx_msg void OnRadioClicked(UINT nID);ClassWizard不支持ON_CONTROL_RANGE宏,所以需要手工建立消息映射和消息处理函数.检查框应指定风格WS_CHILD|WS_VISIBLE|WS_TABSTOP| BS_AUTOCHECKBOX。
在MFC对话框中自定义消息及其映射函数
注:红色字体部分为自己添加的代码
1.在对话框源代码(**Dlg.cpp)中自定义一个消息代码
#include "stdafx.h"
#include "test_message.h"
#include "test_messageDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_MyMessage WM_USER+101(此处为自己添加的代码, WM_MyMessage:自定义的消息名称
WM_USER+101:自定义消息系统分配的号,格式为WM_USER+X,X 可为1到0X7FFF)
2.在对话框头文件(**Dlg.h)声明消息映射函数
class CT est_messageDlg : public CDialog
{
// Construction
public:
CT est_messageDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DAT A(CT est_messageDlg)
enum { IDD = IDD_TEST_MESSAGE_DIALOG };
CString m_MapMessage;
//}}AFX_DAT A
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CT est_messageDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CT est_messageDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnBUTTONSendMessage();
afx_msg void MyFucntion();//自定义函数声明
afx_msg void OnButton1();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
3.在对话框源代码(**Dlg.cpp)中建立消息映射
BEGIN_MESSAGE_MAP(CT est_messageDlg, CDialog)
//{{AFX_MSG_MAP(CT est_messageDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_SendMessage,
OnBUTTONSendMessage)
ON_MESSAGE(WM_MyMessage,MyFucntion)//消息映射函数声明,WM_MyMessage:消息映射函数对应消息,MyFucntion:消息映射函数的函数名
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
4.在对话框源代码(**Dlg.cpp)中定义消息映射函数,即实现消息的响应
//自定义消息映射函数定义
void CT est_messageDlg::MyFucntion()
{
m_MapMessage="Yes.You did it!!";
UpdateData(FALSE);
}
5. .在对话框源代码(**Dlg.cpp)中某个函数处发送自定义消息
void CT est_messageDlg::OnBUTTONSendMessage()
{
// TODO: Add your control notification handler code here
SendMessage(WM_MyMessage);
/// WM_MyMessage:消息名
}。