MFC对话框向主窗体传递消息机制
MFC 模态对话框的实现原理

1. 模态对话框在涉及GUI程序开发的过程中,常常有模态对话框以及非模态对话框的概念模态对话框:在子界面活动期间,父窗口是无法进行消息响应。
独占用户输入非模态对话框:各窗口之间不影响主要区别:非模态对话框与APP共用消息循环,不会独占用户。
模态对话框独占用户输入,其他界面无法响应在用户层的主要逻辑如下:1 TestDlgdlg;23 if (dlg.DoModal() == IDOK)4 {5 //处理完毕后的操作6 }7 .......//后续处理在具体实现中,有如下几个步骤:1. 让父窗口失效EnableWindow(parentWindow, FALSE)2. 建立模态对话框自己的消息循环(RunModalLoop)3. 直至接收关闭消息,消息循环终止,并销毁窗口。
01 INT_PTR CDialog::DoModal()02 {03 //对话框资源加载04 ......0506 //在创建模态窗口之前先让父窗口失效,不响应键盘、鼠标产生的消息07 HWND hWndParent = PreModal();08 AfxUnhookWindowCreate();09 BOOL bEnableParent = FALSE;1011 if (hWndParent&&hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))12 {13 ::EnableWindow(hWndParent, FALSE);14 bEnableParent = TRUE;15 .......16 }1718 //创建模态窗口,并进行消息循环,若窗口不关闭,则循环不退出 19 AfxHookWindowCreate(this);20 VERIFY(RunModalLoop(dwFlags) == m_nModalResult);2122 //窗口关闭,销毁窗口23 DestroyWindow();24 PostModal();2526 //释放资源,并让父窗口有效27 pMainWnd->EnableWindow(TRUE);2829 //返回30 return m_nModalResult;31 }2. 模态窗口中的消息循环01 int CWnd::RunModalLoop(DWORD dwFlags)02 {03 //要检查窗口状态是否是模态窗口04 //若状态一直为模态,则一直进行消息循环05 for (;;)06 {07 ASSERT(ContinueModal());0809 // phase1: check to see if we can do idle work10 while (bIdle&&11 !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE)) 12 {13 ASSERT(ContinueModal());1415 // show the dialog when the message queue goes idle 16 if (bShowIdle)17 {18 ShowWindow(SW_SHOWNORMAL);19 UpdateWindow();20 bShowIdle = FALSE;21 }2223 // call OnIdle while in bIdle state24 if (!(dwFlags& MLF_NOIDLEMSG) &&hWndParent != NULL &&lIdleCount == 0)25 {26 // send WM_ENTERIDLE to the parent27 ::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);28 }29 if ((dwFlags& MLF_NOKICKIDLE) ||30 !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))31 {32 // stop idle processing next time33 bIdle = FALSE;34 }35 }3637 //在有消息的情况下取消息处理38 do39 {40 ASSERT(ContinueModal());4142 // pump message, but quit on WM_QUIT43 if (!AfxPumpMessage())44 {45 AfxPostQuitMessage(0);46 return -1;47 }4849 // show the window when certain special messages rec'd 50 if (bShowIdle&&51 (pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))52 {53 ShowWindow(SW_SHOWNORMAL);54 UpdateWindow();55 bShowIdle = FALSE;56 }5758 if (!ContinueModal())59 goto ExitModal;6061 // reset "no idle" state after pumping "normal" message 62 if (AfxIsIdleMessage(pMsg))63 {64 bIdle = TRUE;65 lIdleCount = 0;66 }6768 } while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));69 }7071 ExitModal:72 m_nFlags&= ~(WF_MODALLOOP|WF_CONTINUEMODAL);73 return m_nModalResult;74 } GetMessage 与PeekMessage 的区别:GetMessage:用于从消息队列读取消息。
多媒体定时器方法中MFC跨线程传递窗口类消息的实现

多媒体定时器方法中MFC跨线程传递窗口类消息的实现傅瑶;韩诚山【期刊名称】《微型电脑应用》【年(卷),期】2014(30)6【摘要】为实现高频数据采集,采用多媒体定时器的方法实现上位机精确定时,同时研究实现了MFC中跨线程窗口类消息传递问题的解决方案。
实验表明,定时精度高,达到10毫秒精确定时,不会出现数据丢失,运行良好。
%To achieve high-frequency data collection, it uses multimedia timer method to achieve precise timing on PC, while re-search to achieve a cross-thread the MFC window class messaging solution to the problem. Experimental results show that timing accuracy is high, precision timing up to 10 milliseconds, without data loss, running well.【总页数】3页(P5-6,9)【作者】傅瑶;韩诚山【作者单位】中科院长春光机所;中科院长春光机所【正文语种】中文【中图分类】TP391.8【相关文献】1.在机顶盒环境中实现基于窗口消息传递的通用GUI [J], 张萍2.在MFC DLLs中导出资源及其相关类的实现方法 [J], 何珍文3.拦截Windows传递VB窗口的消息 [J], 刘建都;周炜;周创明4.MFC中的消息映射和命令传递 [J], 甄力;郭宝增5.消息传递网络中的消息传递机制和路由算法 [J], 朱永华;姚洪;徐炜民因版权原因,仅展示原文概要,查看原文内容请购买。
mfc 回到主线程执行方法

在MFC(Microsoft Foundation Classes)中,通常使用Win32的API来执行跨线程的操作。
但如果你需要从一个非UI线程(比如一个工作线程或后台线程)返回到主UI线程并执行某个方法,你可以使用多种技术来实现。
下面是一个基本的方法,使用PostMessage或SendMessage来通知主线程执行某个操作。
定义自定义消息:首先,你需要定义一个自定义的消息,这样当后台线程需要主线程执行某个操作时,就可以发送这个消息。
cpp#define WM_MY_CUSTOM_MESSAGE (WM_USER + 1)处理消息:在你的主窗口类(通常是一个从CWnd或CDialogEx派生的类)中,你需要重写WindowProc方法来处理这个自定义消息。
cppBEGIN_MESSAGE_MAP(CYourMainWindow, CFrameWnd)ON_MESSAGE(WM_MY_CUSTOM_MESSAGE, &CYourMainWindow::OnMyCustomMessage)END_MESSAGE_MAP()LRESULT CYourMainWindow::OnMyCustomMessage(WPARAM wParam, LPARAM lParam){// 在这里执行你需要的方法或操作return0;}从后台线程发送消息:当你的后台线程需要主线程执行某个操作时,它可以发送自定义的消息。
cpp::PostMessage((HWND)yourMainWindowHandle, WM_MY_CUSTOM_MESSAGE, 0, 0);这里,yourMainWindowHandle是主窗口的句柄。
你可以通过多种方式获取这个句柄,比如将其作为参数传递给后台线程,或者在创建后台线程之前保存它。
4.注意事项:使用PostMessage是异步的,意味着它会立即返回,而消息会被放入主线程的消息队列中等待处理。
mfc使用手册

mfc使用手册MFC(Microsoft Foundation Class Library)是微软提供的一个类库,用于简化Windows应用程序的开发过程。
以下是MFC使用手册的简要介绍:1. 简介:MFC是一个基于C++的类库,它提供了许多用于构建Windows应用程序的类和函数。
通过使用MFC,开发人员可以快速地构建具有一致外观和感觉的应用程序,并利用Windows平台提供的各种功能。
2. 安装和配置:在开始使用MFC之前,您需要安装Microsoft Visual Studio并确保安装了MFC开发工作负载。
安装完成后,您需要创建一个新的MFC项目或打开一个现有的MFC项目。
3. 创建MFC应用程序:要创建一个新的MFC应用程序,您需要使用Microsoft Visual Studio的向导。
选择“File”菜单中的“New”选项,然后选择“Project”。
在弹出的对话框中,选择“MFC Application”并按照向导的提示完成应用程序的创建过程。
4. MFC类库:MFC提供了许多用于构建应用程序的类和函数。
以下是一些常用的MFC类:CWinApp:应用程序对象类,用于管理应用程序级别的操作,例如初始化应用程序和退出应用程序。
CWnd:窗口类,用于管理窗口的各种操作,例如创建窗口、处理消息和绘制窗口。
CDocument:文档类,用于管理应用程序中的文档数据。
CView:视图类,用于管理应用程序中的视图,例如显示文档数据和与用户交互。
5. MFC消息处理:MFC使用消息传递机制来处理用户与应用程序的交互。
每个窗口和控件都处理一组预定义的消息,例如鼠标点击、键盘输入和窗口大小改变等。
通过覆盖类中的虚函数,您可以定义应用程序如何响应这些消息。
6. MFC对话框和控件:MFC提供了许多内置的对话框和控件,例如按钮、文本框和列表框等。
您可以使用对话框编辑器来创建对话框,并将控件拖放到对话框中。
用MFC实现消息的发送和接收(含服务器)

新建WClient工程基于对话框OK,直接Finish界面制作我们需要三个按钮移除它们接下来添加六个静态文本三个编辑框两个列表控件,最后我们有:接下来设置控件文本,控件ID,设置成员变量,排布界面调整:-设置文本居右横排变竖排:Center vertically 反选中。
拉长两个静态文本控件调整两个ListBox同样大小Make Same Size空间ID设置:成员变量设置:你可以使用Ctrl+W快捷键跳出该窗口点OK点OK点OK点OK点OK点OK点OK点OK点OK点OK点OK现在客户端界面已经准备好了,接下来就是服务器了过程略:现在所有界面准备完毕,接下来为两个程序添加对应的继承CSocket类的类在WClient中:Ctrl+W –》Add Class-》NewClass我们添加了什么呢?在WClient中:Ctrl+W –》Add Class-》NewClass然后呢接下来为两个类添加虚函数CWClientSocket 调出右键菜单Add Handler ,我们将所有的都添加进去。
虽然不是所有的都用的上,但有总比没有好CWServerSocket接下来我们可以看看CPP H文件中的变化头文件(.h)源文件(.cpp)接下来添加代码:首先,服务器端需要响应客户端连接接受客户端发送的数据,向客户端发送数据,管理Socket套接字。
则服务器端需要对OnAccept、OnRecieve、OnClose事件进行响应处理。
在CServerDlg.h中定义窗体响应Socket类对应事件的响应函数定义Socket对象,以及CSocketFile ,CArchive对象(有关说明查阅课本169页)在CServerDlg.h中包含我们定义的CWServerSocket对象的变量用于监听端口,以及与客户端(一个)进行通信添加CWServerSocket.h头文件定义对象在CServerSocket.h中定义用于存储窗体变量的指针,和初始化函数。
MFC六大核心机制

MFC六大核心机制1.消息映射机制:MFC使用明确的消息映射机制来处理用户界面和系统事件。
应用程序通过重写消息映射函数来处理不同的消息事件,如鼠标点击、按键操作等。
消息映射机制使得开发者可以方便地响应和处理不同的用户交互动作。
2. 文档视图(Doc/View)体系:MFC采用了文档视图体系,将应用程序数据(文档)和用户界面(视图)分离。
文档表示应用程序的数据,视图代表用户界面,通过文档视图模式可以实现多视图的显示和操作。
开发者可以自定义文档类和视图类,通过它们来管理和展示数据。
3.对象序列化机制:对象序列化是指将对象的状态转换为可以存储或传输的格式,以便于在不同的环境中恢复对象的状态。
MFC提供了强大的对象序列化支持,可以方便地对应用程序的数据进行存储和加载。
开发者只需将需要序列化的成员变量标记为可序列化,并实现相关的序列化函数即可实现数据的持久化。
4.多线程支持:MFC提供了多线程支持,使得应用程序可以在多个线程中同时执行任务。
开发者可以使用MFC提供的线程类来创建和管理线程,并通过消息机制进行线程间的通信。
多线程支持有助于提高应用程序的性能和响应能力。
MFC的运行时类是一组用于封装常用功能的类,包括字符串操作、容器类、文件I/O等。
这些类提供了方便、高效的操作接口,减少了开发者对底层操作的依赖。
开发者可以直接使用MFC提供的运行时类来简化开发过程。
6.扩展性:MFC提供了丰富的扩展性机制,包括自定义控件、自定义对话框、自定义视图等。
开发者可以通过派生已有的MFC类来创建自定义的控件或界面,以满足特定的应用程序需求。
扩展性机制使得开发者可以充分发挥自己的创造力和想象力,实现更加个性化的应用程序。
总结:MFC六大核心机制为开发者提供了丰富的类和功能,使得开发Windows图形界面应用程序更加简单和高效。
通过消息映射机制、文档视图体系、对象序列化机制、多线程支持、运行时类和扩展性机制,开发者可以轻松地实现各种应用程序的需求,并提供更好的用户体验。
MFC对话框与对话框之间的参数传递实例

MFC对话框与对话框之间的参数传递实例在MFC中,对话框是一种常用的窗口类型,用于显示和接收用户输入。
对话框之间的参数传递是实现不同对话框之间数据交互的一种重要方法。
本文将通过一个实例来演示如何在MFC对话框之间进行参数传递。
首先,我们需要在对话框A的头文件中添加一个成员变量来保存需要传递的文本。
在对话框A的类声明中添加如下代码:```cppCString m_strText;``````cppUpdateData( FALSE ); // 将对话框中的控件值与成员变量关联``````cppCDialogB dlgB; // 创建对话框B的实例dlgB.m_strText = m_strText; // 将对话框A的成员变量值传递给对话框B的成员变量dlgB.DoModal(; // 显示对话框B```注意,我们在创建对话框B的实例之后,直接将对话框A的成员变量值赋给对话框B的成员变量。
这样,当对话框B显示时,对话框B的成员变量就会包含对话框A传递过来的值。
现在,我们来处理对话框B。
同样地,在对话框B的头文件中添加一个成员变量来保存从对话框A传递过来的文本。
在对话框B的类声明中添加如下代码:```cppCString m_strText;```然后,在对话框B的OnInitDialog(函数中,将文本框与成员变量关联起来,并设置文本框的值为成员变量的值。
在OnInitDialog(函数中添加如下代码:```cppUpdateData( FALSE ); // 将对话框中的控件值与成员变量关联```最后,在对话框B的.cpp文件中,我们可以使用m_strText的值进行一些处理。
比如,在OnOK(函数中,我们可以将m_strText的值输出到调试窗口。
在OnOK(函数中添加如下代码:```cppUpdateData( TRUE ); // 将文本框中的文本值与成员变量关联//将文本值输出到调试窗口TRACE( _T( "传递的文本值为:%s\n" ), m_strText );```现在,当我们在对话框A中输入一些文本,然后点击按钮,对话框B 将被创建并显示出来。
MFC教程(4)

MFC教程(4)但是在当前例子中,当前对象的类CTview没有覆盖该函数,所以CWnd的WindowProc被调用。
这个函数把下一步的工作交给OnWndMsg函数来处理。
如果OnWndMsg没有处理,则交给DefWindowProc来处理。
OnWndMsg和DefWindowProc都是CWnd类的虚拟函数。
OnWndMsg的原型如下:BOOL CWnd::OnWndMsg( UINT message,WPARAM wParam, LPARAM lParam,RESULT*pResult ); 该函数是虚拟函数。
和WindowProc一样,由于当前对象的类CTview没有覆盖该函数,所以CWnd的OnWndMsg被调用。
在CWnd中,MFC使用OnWndMsg来分别处理各类消息:如果是WM_COMMAND消息,交给OnCommand处理;然后返回。
如果是WM_NOTIFY消息,交给OnNotify处理;然后返回。
如果是WM_ACTIVATE消息,先交给_AfxHandleActivate 处理(后面5.3.3.7节会解释它的处理),再继续下面的处理。
如果是WM_SETCURSOR消息,先交给_AfxHandleSetCursor处理;然后返回。
如果是其他的Windows消息(包括WM_ACTIVATE),则首先在消息缓冲池进行消息匹配,若匹配成功,则调用相应的消息处理函数;若不成功,则在消息目标的消息映射数组中进行查找匹配,看它是否处理当前消息。
这里,消息目标即CTview对象。
如果消息目标处理了该消息,则会匹配到消息处理函数,调用它进行处理;否则,该消息没有被应用程序处理,OnWndMsg返回FALSE。
关于Windows消息和消息处理函数的匹配,见下一节。
缺省处理函数DefWindowProc将在讨论对话框等的实现时具体分析。
Windows消息的查找和匹配CWnd或者派生类的对象调用OnWndMsg搜索本对象或者基类的消息映射数组,寻找当前消息的消息处理函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
对话框向主窗体传递消息,在视图中显示
现举例说明对话框向主窗体传递消息,以及主窗体响应消息的过程。
我们拿单文档来说明,我们要实现下列功能:通过对话框,在文本框中输入字符串,在视图中显示刚才输入的字符串。
1、在应用程序向导中选择单个文档,然后完成。
我这里的项目名称为mybook
2、在资源视图中,插入一对话框,对话框名称为dlg_wzm。
3、在刚才生成的对话框中插入一文本框,设置好相应的类和变量。
为确认按钮生成响应函数。
同时在mybook.cpp的BOOL CMyBookApp::InitInstance()函数中让该对话框启动,也就是加入CDlg_wzm dlg; dlg.DoModal();两行程序,当然在前面的要加入#include "dlg_wzm.h"。
(详细过程略)
4、下面重点在于点击该对话框的确认按钮向主窗体发送消息。
要现定义一个消息名称。
在stdafx.h文件中加入一行:
#define WM_MYMESSAGE WM_USER+100
5、在CMainFrame的pulic申明中加入一变量CString wzmstr。
目的是为了保存对话框中的字符串的值。
在对话框的Onok()函数中:
void CDlg_wzm::OnOK()
{
// TODO: Add extra validation here
this->UpdateData(true);
CMainFrame* pWnd=(CMainFrame*)AfxGetMainWnd(); //得到父窗体的指针
pWnd->wzmstr=this->m_input_edit;
ASSERT(pWnd!=NULL);
::SendMessage(pWnd->GetSafeHwnd(), WM_MYMESSAGE,0,0); //发送消息
//注意WM_MYMESSAGE就是我们前面定义的消息。
//CDialog::OnOK();
}
6、下面我们看看主窗体怎么接受消息。
我们要在主窗体中设置消息映射。
在mainfrm.h的protected声明中:
afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam);
在mainfrm.cpp文件中,
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code !
ON_WM_CREATE()
ON_MESSAGE(WM_MYMESSAGE,OnMyMessage) //这里是我们加入的。
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
然后在mainfrm.cpp的文件最下面加入一个函数:
void CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
CView *pView=this->GetActiveView(); //得到视图指针
if(pView)
{
CClientDC dc(pView);
dc.TextOut(0,0,wzmstr);//向视图中写入对话框中的edit中的字符串。
}
}
7、完成调试。
什么?不能通过。
那你肯定是忘记在dlg_wzm.cpp的开头加入#include "mainfrm.h"了。
呵呵,最终效果如下。