MFC的运行顺序

合集下载

MFC程序的运行过程

MFC程序的运行过程
extern "C" int WINAPI_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
// call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); }
(WinMain 函数实现:E:Program FilesMicrosoft Visual StudioVC98MFCSRC 下的 APPMODUL.CPP 文件中) 4.在 WinMain 函数中,实际上是通过调用 AfxWinMain 函数来完成其功能的
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestDoc),
RUNTIME_CLASS(CMainFrame),
// main SDI frame window
RUNTIME_CLASS(CTestView));
// such as the name of your company or organization. SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)

mfc基本程序

mfc基本程序

mfc基本程序
MFC(Microsoft Foundation Class)是微软基础类库,是微软公司实现的一个c++类库,主要封装了大部分Windows API函数。

下面是MFC基本程序的步骤:
1. 添加相应的头文件和库文件:在使用API时,需要添加相应的头文件和库文件,例如PlaySound需要头文件mmsystem.h和库文件WINMM.LIB的支持。

2. 设计窗口类:定义一个从CWnd 类继承而来的派生类,负责处理用户交互和绘图等操作。

3. 注册窗口类:使用AfxRegisterClass 函数将窗口类注册到 Windows 系统中。

4. 创建窗口对象:使用CreateWindow 函数创建一个窗口对象,并将其显示在屏幕上。

5. 循环取消息:通过消息循环从Windows 系统接收消息,并将其发送给窗口对象进行处理。

6. 处理消息:在窗口对象的处理函数中,根据接收到的消息类型进行相应的处理。

请注意,上述步骤仅为MFC基本程序的一般性指导,具体的程序编写可能因项目需求和个人喜好而有所不同。

如果你需要更详细的信息或有特定的问题,请提供更多细节以便获得更准确的回复。

MFC单文档模式中,四个类对消息处理的优先级

MFC单文档模式中,四个类对消息处理的优先级

MFC单⽂档模式中,四个类对消息处理的优先级MFC的单⽂档架构,有四个类(这⾥忽略About对话框类):1. MainFrame2. App3. Doc4. View这四个类和MVC设计模式的关系如下:1. MainFrame代表着MVC的C (Control)。

2. App可以理解为对hInstance的封装。

3. Doc对应着MVC的M (Model)。

4. View对应着MVC的V (View)。

这四个类全部继承⾃CCmdTarget类,所以它们都具有处理消息的能⼒。

问题是:同⼀个WM_COMMAND消息,谁先处理,谁后处理(4个类对消息处理的优先级问题)?现在做试验分析,⾸先要明确WM_COMMAND消息的产⽣⽅式。

以下三种情况都能产⽣WM_COMMAND消息:1. 菜单选项的点击2. 控件状态的改变(例如按钮按下)3. 键盘快捷键的按下⾸先增加⼀个菜单选项:然后在每个类中,都进⾏如下操作:进⼊类向导,在Command标签中增加关于此菜单项的处理函数:在每个函数内部写⼀个AfxMessageBox()函数,作为标记:这样,现在每个类都有了标记⽤的弹框提⽰。

运⾏程序,点击此菜单项,就知道这四个类对WM_COMMAND消息处理的优先权了:结果是View类对VM_COMMAND消息作出了响应。

经测试,⼀旦⼀个类处理了消息,其他类就不会处理了(也就是说只会弹出⼀个对话框(刚才设置了4个AfxMessageBox)),这四个类的优先级顺序为:1. View2. Doc3. MainFrame4. App现在探究这个顺序的原因。

研究的⽅法是在CSingleView::OnHelpTestcmd()函数⾥下断点,断下来之后分析栈回溯:分析之后找到原因:CFrameWnd::OnCmdMsg()函数内部,通过顺序结构规定了这四个类对WM_COMMAND消息的处理优先级:从代码以及注释中,可以清楚地看到这个优先级:View第⼀,下⼀个是MainFrame,最后是App。

MFC 运行过程

MFC 运行过程

执行一个windows应用程序包括初始化,运行和终止三大任务,MFC中的应用类封装了windows应用程序要做的这三大任务,这三大任务对应的三个主要函数就是InitInstance(),Run()和ExitInstance()。

应用类的基类是CWinApp类,MFC AppWizard自动生成的应用程序框架中的应用类就是由CWinApp类派生的。

注:应用程序必须有而且只能有一个CWinApp派生类,而且这个类只能有一个对象,这个对象是一个全程对象,即theAppCWinApp类有下面几个关键的虚函数,可供用户重载:InitInstance(),Run(),ExitInstance(),OnIdle()其中InitInstance()函数是必须重载的,而通常情况下也只需要重载InitInstance(),其他函数用户根据需要决定是否重载。

由于InitInstance()必须重载,所以在MFC AppWizard自动生成的应用程序框架中就自动重载了应用程序运行过程:InitInstance() 注:因为AppWizard已经重载了InitInstance(),所以这里调用的InitInstance()就是程序中重载的InitInstance() Run()注:WinMain()函数隐藏在应用框架内部,是看不到的。

InitInstance()函数:顾名思义,InitInstance()函数就是初始化实例。

Windows对同一个应用程序可以运行多个实例。

比如,如果已经在运行任务管理器,用户还可以再一次或多次启动任务管理器。

这样,系统就有多个任务管理器同时在运行,这些运行着的任务管理器就是任务管理器应用程序的多个运行实例。

当每次启动某个应用程序的一个实例时,WinMain()函数都要调用InitInstance()函数。

Run()函数:应用程序的大部分时间都是在应用类的Run()成员函数中打转转。

WinMain()函数在调用InitInstance()函数进行初始化完毕之后,就调用Run()函数来处理消息循环。

mfc使用手册

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 控件顺序 -回复

mfc 控件顺序 -回复

mfc 控件顺序-回复什么是MFC 控件顺序?MFC(Microsoft Foundation Classes)是一个用于开发Windows 应用程序的C++ 类库。

MFC 控件顺序是指在MFC 应用程序中,控件的显示和响应焦点的顺序。

当在界面中有多个控件时,通过控件顺序可以确定用户在操作界面时,按Tab 键或者使用鼠标切换焦点的顺序。

为什么需要MFC 控件顺序?控件顺序在用户界面设计中起到了非常重要的作用。

通过合理设置控件顺序可以提高用户体验和效率,使得用户更加方便地在应用程序中进行操作。

同时,控件顺序也决定了用户在操作界面时焦点的切换,从而影响到用户的输入和交互流程。

如何设置MFC 控件顺序?设置MFC 控件顺序可以通过两种方式实现,一种是使用资源编辑器,另一种是通过代码设置。

使用资源编辑器设置MFC 控件顺序:1. 打开MFC 应用程序的资源文件(通常为 .rc 后缀)。

2. 在资源编辑器中找到对应的对话框资源,双击打开。

3. 确保在对话框资源的编辑模式下,点击工具栏中的"Tab Order" 按钮。

4. 在对话框中,按下Tab 键或使用鼠标点击每个控件,规定每个控件的顺序。

5. 完成设置后,点击工具栏中的"Tab Order" 按钮再次退出控件顺序编辑模式。

6. 保存资源文件并进行编译。

通过代码设置MFC 控件顺序:1. 打开MFC 应用程序的对话框类的源文件(通常以 .cpp 为后缀)。

2. 在对话框的构造函数中,使用`SetWindowPos()` 函数设置每个控件的Tab 键顺序。

例如,`SetWindowPos(IDC_BUTTON1, 0);` 表示将IDC_BUTTON1 设置为第一个控件。

3. 根据需要设置其他控件的顺序。

4. 保存并编译代码。

如何调整MFC 控件顺序?在MFC 应用程序中,可以根据需求调整控件的顺序。

使用资源编辑器调整MFC 控件顺序:1. 打开MFC 应用程序的资源文件,找到对应对话框资源。

mfc实现流程

mfc实现流程

mfc实现流程
MFC(Microsoft Foundation Class Library)是微软提供的一个类库,用于在Windows环境下开发基于C++的图形用户界面(GUI)应用程序。

使用MFC可以简化Windows应用程序的开发过程。

以下是使用MFC实现应用程序的基本流程:
1. 创建项目:在Visual Studio中创建一个新的MFC项目。

选择“File”菜单中的“New”->“Project”,然后选择“MFC Application”。

2. 设置项目属性:在项目创建后,需要设置一些属性,如应用程序类型(单文档或多文档)、使用的MFC版本等。

3. 设计界面:使用Visual Studio的设计器,在图形界面中添加需要的控件,如按钮、文本框等。

也可以手动编写代码来创建控件。

4. 编写代码:根据需要编写代码,包括处理用户输入、更新界面、访问数据库等。

MFC提供了许多类和函数,用于简化常见的编程任务。

5. 编译和运行:编译代码并运行应用程序,检查是否存在错误。

6. 调试:如果应用程序中存在错误,使用调试器来查找和修复问题。

7. 测试:进行彻底的测试,确保应用程序在不同情况下都能正常工作。

8. 部署:完成测试后,可以将应用程序部署到目标机器上。

以上是使用MFC实现应用程序的基本流程。

具体实现细节会根据具体需求和项目规模有所不同。

mfc使用教程

mfc使用教程

mfc使用教程MFC使用教程不要标题MFC是Microsoft Foundation Class的缩写,是一套C++的库,用于开发Windows平台的应用程序。

以下是一个简单的MFC使用教程,帮助你了解如何创建一个基本的MFC应用程序。

首先,打开Visual Studio并选择创建新项目。

在项目模板中,选择"MFC应用程序"。

在下一步中,选择"对话框"作为应用程序类型。

接下来,选择项目的名称和位置,然后点击"完成"按钮。

Visual Studio将自动生成一个MFC应用程序的基本框架。

应用程序的主要代码位于"MainFrm.cpp"和"MainFrm.h"文件中。

打开"MainFrm.cpp"文件,你将看到一个名为"Create"的函数。

在这个函数中,可以创建应用程序的主窗口。

在"Create"函数的内部,使用"MFC应用程序向导"提供的函数来创建一个对话框。

例如,可以使用"CDialogEx"类来创建一个简单的对话框。

在"Create"函数的最后,需要调用"ShowWindow"函数显示主窗口,并调用"UpdateWindow"函数来更新窗口。

在"MainFrm.h"文件中,你可以定义应用程序的主窗口类。

例如,可以继承自"CFrameWnd"类,并添加自定义的成员变量和函数。

在"MainFrm.cpp"文件的"Create"函数中,还可以添加一些自定义的代码,例如设置窗口的标题和大小,添加菜单和工具栏等。

最后,编译并运行应用程序。

你应该能够看到一个简单的MFC应用程序的窗口。

mfc运行流程

mfc运行流程

mfc运行流程
MFC程序的运行流程如下:
1.程序启动
程序启动时,首先会调用WinMain函数。

WinMain函数是MFC程序的入口函数,负责程序的初始化和运行。

2.程序初始化
在WinMain函数中,会调用CWinApp::InitInstance()函数进行程序的初始化。

CWinApp::InitInstance()函数负责注册窗口类、创建应用程序对象、创建窗口等工作。

3.窗口创建
在程序初始化完成后,会创建应用程序的窗口。

应用程序窗口是应用程序的入口,用户可以通过应用程序窗口与应用程序进行交互。

4.消息循环
在窗口创建完成后,会进入消息循环。

消息循环是MFC程序的核心,负责处理来自操作系统的消息。

5.程序退出
用户关闭应用程序时,会调用CWinApp::ExitInstance()函数退出程序。

CWinApp::ExitInstance()函数负责释放程序使用的资源。

mfc框架的基本运行原理

mfc框架的基本运行原理

mfc框架的基本运行原理
MFC(Microsoft Foundation Class)是一个基于Windows操作
系统的GUI(图形用户界面)开发工具集,它构建在Win32 API上,提供了许多用于Windows应用程序开发的类和函数。

MFC框架的基本运行原理可以概括为以下几个步骤:
1. 应用程序启动时,会创建一个主窗口对象,并将其显示在屏幕上。

2. 主窗口对象包含一个消息循环,用于响应用户的输入和操作,并调用相应的处理函数来处理这些消息。

3. 当用户对某个控件(如按钮、菜单、文本框等)进行操作时,该控件会生成一个事件(事件通常由Windows系统内部生成),该事件将被传递到主窗口对象,由主窗口对象的消息循环接收并传递给相应的处理函数处理。

4. 处理函数根据事件的类型和参数来改变应用程序的状态或修改相关控件的属性,然后更新主窗口或其他相关窗口的显示内容。

5. 当用户关闭应用程序时,主窗口对象会收到一条关闭消息,然后销毁所有相关窗口和资源,最终结束应用程序的运行。

总的来说,MFC框架的基本运行原理就是通过消息循环和事
件处理机制来处理用户的输入和操作,从而实现应用程序的界面交互和业务逻辑。

mfc 控件顺序 -回复

mfc 控件顺序 -回复

mfc 控件顺序-回复关于MFC(Microsoft Foundation Class)控件顺序的话题,我将一步一步回答并解释相关的概念和使用方法。

MFC是微软公司提供的一种用于开发Windows应用程序的框架。

它使用C++语言编写,提供了一系列强大的类和方法,用于创建用户界面和处理用户交互。

在MFC中,控件是用户界面的基本构建块,用于显示和接收用户输入。

控件顺序指的是控件在界面上的布局顺序,即用户按下Tab键时,焦点将依次转移到下一个控件。

要实现控件顺序,我们需要以下步骤:1. 创建一个对话框或窗口类:MFC应用程序通常由对话框或窗口组成。

对话框是一个独立的窗口,它包含了一组控件,用于与用户进行交互。

窗口是一个包含在框架窗口中的独立区域,可以包含子控件。

2. 在对话框或窗口中添加控件:使用MFC提供的资源编辑器,我们可以很方便地在对话框或窗口中添加控件。

选择合适的控件类型,如按钮、文本框、复选框等,并将其拖放到对话框或窗口上。

3. 设置控件的tab顺序:默认情况下,MFC将控件的tab顺序设置为它们在对话框资源中的添加顺序。

但如果我们想自定义tab顺序,可以按照以下步骤操作:a. 打开对话框或窗口资源,选择要设置tab顺序的控件。

b. 在属性框中找到“TabStop”属性,并将其设置为TRUE。

这将允许该控件参与tab顺序切换。

c. 在属性框中找到“ID”属性,将其设置为唯一的非零值。

这将确定控件的tab顺序。

4. 处理tab键消息:在MFC应用程序中,如果我们想要自定义tab键的行为,可以处理WM_NEXTDLGCTL消息。

这个消息在用户按下tab键时会被发送到当前具有键盘焦点的窗口。

通过处理这个消息,我们可以指定下一个具有焦点的控件。

a. 在对话框、窗口或控件的消息映射中添加一个处理WM_NEXTDLGCTL消息的函数。

b. 在这个函数中,使用CWnd类的NextDlgCtrl函数获取下一个具有焦点的控件的句柄,并使用SetFocus函数将焦点设置在该控件上。

mfc 控件顺序 -回复

mfc 控件顺序 -回复

mfc 控件顺序-回复MFCTest组件的顺序,指的是在进行MFC应用程序开发时,组件的创建和初始化顺序。

正确的组件顺序对于应用程序的正常运行至关重要。

下面我将一步一步回答关于MFC控件顺序的问题。

1. 了解MFC控件首先,了解MFC控件是至关重要的。

MFC(Microsoft Foundation Classes),是微软开发的一种用于开发Windows应用程序的库。

MFC框架提供了很多控件,例如按钮、文本框、列表框等,开发人员可以使用这些控件创建用户界面。

2. 了解控件创建的过程在进行MFC应用程序开发时,控件的创建是一个重要的步骤。

控件的创建包括两个主要的过程,即资源文件的设计和控件的初始化。

通过资源文件可以进行控件的布局设计,而控件的初始化包括控件的创建和控件属性的设置。

3. 控件的创建顺序控件的创建顺序对于应用程序的运行至关重要。

通常,控件的创建顺序应该从上到下,从左到右进行。

这是因为在应用程序的布局设计中,通常会按照这个顺序来进行控件的排列。

4. 控件管理在MFC应用程序中,控件的管理是一个关键的任务。

通常,开发人员可以使用一种叫做控件变量的方式对控件进行管理。

控件变量是一个指向控件的指针,在程序中可以使用控件变量来对控件进行操作。

5. 控件的初始化顺序在进行控件的初始化时,应该按照控件的创建顺序进行。

这意味着先初始化上方的控件,再初始化下方的控件,先初始化左边的控件,再初始化右边的控件。

这样可以确保控件的正确创建和初始化。

6. 对控件属性的设置在控件的初始化过程中,可以对控件的属性进行设置。

通常,可以设置控件的大小、位置、字体、颜色等属性。

根据实际需求,开发人员可以根据控件的类型进行不同的设置。

7. 控件事件处理在应用程序中,控件的事件处理是一个重要的部分。

MFC框架提供了很多事件处理机制,例如按钮的点击事件、文本框的变化事件等。

开发人员可以通过重写相应的函数来进行事件的处理。

8. 控件之间的交互在应用程序中,控件之间的交互是一个常见的需求。

mfc 控件顺序

mfc 控件顺序

mfc 控件顺序
在MFC(Microsoft Foundation Class)中,控件的顺序可以通过动态创建时设置样式,或使用Tab键顺序等方式进行改变。

控件顺序指的是用户通过不同的输入设备(如鼠标、键盘等)进行控件操作时,控件接收输入焦点的顺序。

合理的控件顺序可以提高用户界面的易用性,使用户在操作的过程中更加顺畅。

控件顺序的影响因素包括界面布局和控件类别。

控件在界面中的位置和排列方式会直接影响控件的访问顺序。

通常,从左上角到右下角的阅读顺序被认为是一种合理的控件访问顺序。

不同类型的控件可能有不同的默认访问顺序。

例如,在一个对话框中,按钮类控件通常有更高的优先级,因为用户经常需要直接操作按钮。

如果您希望调整MFC中的控件顺序,可以参考以下步骤:
1.在动态创建控件的时候STYLE设置成为WS_CHILD|WS_VISIBLE |WS_TABSTOP,其中WS_TABSTOP是影响TAB顺序的。

先创建的控件T AB顺序在前。

如果要颠倒TAB顺序的话,就把在创建控件时把WS_T ABSTOP去掉,并增加对“TAB键被按下”事件的捕捉,人工使用SET FOCUS来控制TAB顺序。

2.编辑界面按下ctrl+D键,就会出现所有控件的Tab键顺序,按照自己想要的顺序依次点击控件的数字标识,就可以重新安排控件的TAB键顺序。

MFC执行顺序

MFC执行顺序

1、创建Application object对象theApp程序一开始生产一个(且只有一个)Application object对象theApp,也即一个CWinApp 对象,这个全局对象一产生,便执行其构造函数,因为并没有定义CMyWinApp构造函数,所以即执行CWinApp类的构造函数。

该函数定义于APPCORE.CPP第75行,你可以自己搜出来啃一啃,因此,CWinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置与初值。

2、WinMain登场用SDK编程序时,程序的入口点是WinMain函数,而在MFC程序里我们并没有看到WinMain函数,哦!~ 原来她是被隐藏在MFC代码里面了。

当theApp配置完成后,WinMain 登场,慢!细看程序,并没连到WinMain函数的代码啊!这个我也不知道,MFC早已准备好并由链接器直接加到应用程序代码中了,原来她在APPMODUL.CPP里面,好,我们就认为当theApp配置完成后,程序就转到APPMODUL.CPP来了。

那执行什么呢?看看下面从APPMODUL.CPP摘出来的代码:extern "C" int WINAPI_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){// call shared/exported WinMainreturn AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);}_tWinMain函数的“_t”是为了支持Unicode而准备的一个宏。

_tWinMain函数返回值是AfxWinMain函数的返回值,AfxWinMain函数定义于WINMAIN.CPP第21行,稍加整理,去芜存菁,就可以看到这个“程序进入点”主要做些什么事:int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){int nReturnCode = -1;CWinApp* pApp = AfxGetApp();AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);pApp->InitApplication();pApp->InitInstance()nReturnCode = pApp->Run();AfxWinTerm();return nReturnCode;}AfxGetApp()函数是取得CMyWinApp对象指针,故上面函数第6至8行相当于调用:CMyWinApp::InitApplication();CMyWinApp::InitInstance()CMyWinApp::Run();因而导致调用:CWinApp::InitApplication(); //因为CMyWinApp 并没有改写InitApplication CMyWinApp::InitInstance() //因为CMyWinApp 改写了InitInstanceCWinApp::Run(); //因为CMyWinApp 并没有改写Run用过SDK写程序的朋友,现在可能会发出会心的微笑。

mfc onpaint oninitdialog 顺序

mfc onpaint oninitdialog 顺序

mfc onpaint oninitdialog 顺序英文版MFC (Microsoft Foundation Class) is a wrapper around the Windows API that provides an object-oriented approach to Windows programming. In MFC, the OnInitDialog and OnPaint functions play crucial roles in the life cycle of a dialog box.OnInitDialog:The OnInitDialog function is called when a dialog box is first created. It is a good place to perform initialization tasks such as setting up controls, adding data to lists, or configuring the dialog's appearance. This function is typically called only once during the dialog's lifecycle.OnPaint:The OnPaint function is called whenever a portion of the dialog box needs to be redrawn. This can happen for various reasons, such as when the dialog is first displayed, when a control within the dialog is updated, or when the dialog isexposed after being covered by another window. The OnPaint function is responsible for drawing the dialog's contents onto the screen.The Order of OnInitDialog and OnPaint:In the life cycle of an MFC dialog box, OnInitDialog is typically called first, followed by OnPaint. This means that any initialization tasks performed in OnInitDialog (such as setting up controls or configuring the dialog's appearance) will be reflected in the first OnPaint call.It's important to note that while OnInitDialog is called only once during the dialog's lifecycle, OnPaint can be called multiple times. Therefore, any drawing code placed in OnPaint should be designed to handle multiple invocations, as well as the possibility that the dialog's state may have changed since the last invocation.中文翻译:MFC中的OnInitDialog和OnPaint的顺序MFC(Microsoft Foundation Class)是Windows API的一个包装器,它为Windows编程提供了一个面向对象的方法。

MFC程序流程

MFC程序流程

MFC程序流程程序的诞生application object产生,内存于是获得配置,初值设立afxWinMain执行afxwinInit,调用afxInitThread把消息队列加大afxWinMain执行 InitApplication 是CWinApp的虚函数,通常不该写afxWinMain执行 InitInstance 是CWinApp的虚函数,必须改写CMyFrameWnd构造式调用Create ,产生窗口,回到InitInstance中继续执行ShowWindow 显示窗口执行UpdateWindow 发送WM_PAINT回到AfxWinMain 执行Run,进入循环。

程序开始运作程序获得WM_PAINT消息。

(藉由CWinApp::Run中的::GetMessage循环)WM_PAINT经由DispatchMessage送到窗口函数CWnd::DefWindowProc中。

CWnd::DefWindowProc将消息绕行过消息映射表格(Message Map)绕行过程中发现有吻合项目,于是调用项目中对应的函数,此函数是应用程序利用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间的宏设立起来的。

标准消息的处理历程亦有标准命名,例如WM_PAINT必然由OnPaint处理程序的死亡:使用者按关闭。

发送WM_CLOSECMyFrameWnd并没有设置WM_CLOSE处理例程,于是交给于设置之处理例程。

预设函数对于WM_CLOSE的处理方式是调用::DestroyWindow并因而发出WM_DESTROY预设之WM_DESTORY处理方式是调用::PostQuitMessge发出WM_QUITCWinApp::Run收到WM_QUIT后会结束内部消息循环,然后调用ExitInstance,CWinApp的虚函数如果CMyWinApp改写了ExitInstance,那么CWinApp::Run就调用CMyWinApp::ExitInstance.回到AfxWinMain 执行 AfxWinTerm,结束程序。

MFC的运行顺序

MFC的运行顺序

很多刚学MFC的人都会被MFC给弄的晕头转向。

以前传统的C语言中的main ()不见了,window sdk api 中的WinMain()函数也不见了,到底用MFC编写的程序是如何开始运行的呢?到底MFC有没有遵从最基本的C++的标准呢?到底MFC的代码运行的顺序又是怎么样的呢?那么多个文件,那么多函数,到底哪一个先运行,哪一个后运行,哪一个调用哪一个,哪一个又被哪一个调用(你看晕了吧?那么多“哪一个”^_^)?这里这么复杂,到底最真是的是怎么一回事呢?我开始学习的时候,也是一头雾水,什么都不明白,但是为了能先学习一些其他的,我囫囵吞枣的看了过去,先学习了CDIALOG和CVIEW的一些用法,并能编出了一个很简单的程序。

前几天,上网的时候,看到好多人都在看《孙鑫vc++讲座》视频教程,好像大家反应还不错,于是,我就去找个地方下载下来看了。

刚好今天看到了MFC 的运行机制,里面讲到了MFC的运行顺序。

孙同学在视频中是利用实例,利用断点,然后不断的进行调试运行,以实事(实事胜于雄辩啊!!!)告诉我们,MFC 是如何开始运行的。

下面,我就根据我看到的教程,和网上一些前辈整理出来的材料在整理:重点:MFC运行机制执行顺序各个函数用途以及调用顺序孙同学在视频中反复说明的是:MFC的程序和C语言的程序,从执行原理上说,是完全一致的。

抓住这一点,那么对于理解MFC程序的运行机制也就相对于简单了。

C中的main函数就相当于MFC中的WinMain函数。

感兴趣的可以利用VC的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。

一、C语言程序执行步骤在C语言中,大约的步骤如下:1,全局变量内存分配例子如下:#include <iostream.h>int a=88;main(){cout<<a<<endl;}如果我们在main前设置断点,我们就会发现,在进入main之前,a就已经存在了。

MFC流程

MFC流程

MFC流程MFC程序文件名为Test.所以产生的5个类分别为1、CAboutDlg继承于CDialog2、CMainFrame继承于CFrameWnd1、CTestApp继承于CWinApp1、CTestDoc继承于CDocument1、CTestView继承于CView一、窗口产生流程1、设计窗口类2、注册窗口类3、产生窗口4、显示窗口5、更新窗口二、MFC中的细节1、WinMain函数的地址在C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC\APPMODUL.CPP文件中extern "C" int WINAPI_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){// call shared/exported WinMainreturn AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);}其中_tWinMain是WinMain的宏定义如下: (此定义在文件C:\Program Files\Microsoft VisualStudio\VC98\Include\TCHAR.H中)#define _tWinMain WinMain而_tWinMain调用的是AfxWinMain.2、theApp全局对象先于WinMain运行产生全局对象,在程序入口函数WinMain加载时,系统就已经为全局变量或全局对象分配了存储空间,并为它们赋了初始值。

存放在静态数据区。

每一个MFC程序有且仅有一个从应用程序类(CWinApp)派生的类。

每一个MFC程序实例有且仅有一个该派生类的实例化对象,也就是theApp全局对象。

该对象表示应用程序本身。

由于在子类的构造之前会先调用其父类的构造函数。

窗口Z轴顺序--MFC

窗口Z轴顺序--MFC

CWnd::SetWindowPosBOOL SetWindowPos( const CWnd* pWndInsertAfter, int x, int y, int cx , int cy,UINT nFlags );返回值如果函数成功,则返回非零值;否则返回0。

参数pWndInsertAfter标识了在Z轴次序上位于这个CWnd对象之前的CWnd对象。

这个参数可以是指向CWnd对象的指针,也可以是指向下列值的指针:l wndBottom 将窗口放在Z轴次序的底部。

如果这个CWnd是一个顶层窗口,则窗口将失去它的顶层状态;系统将这个窗口放在其它所有窗口的底部。

wndTop 将窗口放在Z轴次序的顶部。

wndTopMost 将窗口放在所有非顶层窗口的上面。

这个窗口将保持它的顶层位置,即使它失去了活动状态。

wndNoTopMost 将窗口重新定位到所有非顶层窗口的顶部(这意味着在所有的顶层窗口之下)。

这个标志对那些已经是非顶层窗口的窗口没有作用。

有关这个函数以及这些参数的使用规则参见说明部分。

x指定了窗口左边的新位置。

y指定了窗口顶部的新位置。

cx指定了窗口的新宽度。

cy指定了窗口的新高度。

nFlags指定了大小和位置选项。

这个参数可以是下列值的组合:l SWP_DRA WFRAME 围绕窗口画出边框(在创建窗口的时候定义)。

l SWP_FRAMECHANGED 向窗口发送一条WM_NCCALCSIZE消息,即使窗口的大小不会改变。

如果没有指定这个标志,则仅当窗口的大小发生变化时才发送WM_NCCALCSIZE消息。

l SWP_HIDEWINDOW 隐藏窗口。

SWP_NOACTIV A TE 不激活窗口。

如果没有设置这个标志,则窗口将被激活并移动到顶层或非顶层窗口组(依赖于pWndInsertAfter参数的设置)的顶部。

l SWP_NOCOPYBITS 废弃这个客户区的内容。

如果没有指定这个参数,则客户区的有效内容将被保存,并在窗口的大小或位置改变以后被拷贝回客户区。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

CMainFrame::PreCreateWindow()//反复调用一次是给我们修改窗口属性的机会
CFrameWnd::Create()
(3) 消息循环
PumpMessage()
补充1:
在MFC中,由于涉及到(窗口)类定义,所以定义全局变量的时候,需要进行更多的步骤。
说明:每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身。在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。在基于MFC应用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。
3,通过构造应用程序对象过程中调用基类CWinApp的构造函数,在CWinApp的构造函数中对程序包括运行时一些初始化工作完成了。
CWinApp构造函数:MFC|SRC|APPCORE.CPP
CWinApp::CWinApp(LPCTSTR lpszAppName){...}//带参数,而CTEApp构造函数没有显式向父类传参,难道CWinApp()有默认参数 见下:
全局变量涉及到类定义(类似于C中的类型定义)的话,那么需要遵循以下步骤(以MFC的窗口类为例,这是在SDK 里面经常用到的,有用api编写过函数的,应该都知道)
1) 设计一个窗口类
2) 注册窗口类
3) 创建窗口
4) 显示及更新窗口
5) 消息循环
补充2:本课涉及到MFC函数的源文件位置
说明:设计窗口类:在MFC中事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。
调试:CWinApp::CWinApp();->CTEApp theApp;(-> CTEApp ::CTEApp())-> CWinApp::CWinApp() -> CTEApp ::CTEApp() -> _tWinMain(){}//进入程序
调用pThread->InitInstance()
说明:pThread也指向theApp,由于基类中virtual BOOL InitApplication()定义为虚函数,所以调用pThread->InitInstance()时候,调用的是派生类CTEApp的InitInstance()函数。
//把注册后的窗口类名赋给cs.lpszClass
}
if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
cs.style |= FWS_PREFIXTITLE;
if (afxData.bWin4)
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
nReturnCode = pThread->Run();
说明:pThread->Run()完成了消息循环。
5,注册窗口类:AfxEndDeferRegisterClass();
AfxEndDeferRegisterClass()函数所在文件:MFC|SRC|APPCORE.CPP
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister){...}
CXXApp ::CXXApp(){}
3)进入Winmain函数(_tWinMain为宏,值为WinMain)(这个函数不是我们自己写的,而且是隐藏在一个比较隐蔽的文件里面,D:\Program Files\Microsoft Visual Studio\VC98\MFC\src\WINMAIN.CPP里面。)
return FALSE;
return TRUE;
}
说明:
CFrameWnd::PreCreateWindow()函数所在文件:MFC|SRC|WINFRM.CPP
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
对于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口
(1) 注册窗口类
AfxEndDeferRegisterClass()(相当于SDK里面的RegisterClass()函数)
(2)创建窗口
前几天,上网的时候,看到好多人都在看《孙鑫vc++讲座》视频教程,好像大家反应还不错,于是,我就去找个地方下载下来看了。刚好今天看到了MFC的运行机制,里面讲到了MFC的运行顺序。孙同学在视频中是利用实例,利用断点,然后不断的进行调试运行,以实事(实事胜于雄辩啊!!!)告诉我们,MFC是如何开始运行的。下面,我就根据我看到的教程,和网上一些前辈整理出来的材料在整理:
(在CWinApp类定义中, CWinApp(LPCTSTR lpszAppName = NULL); )
注意:CWinApp()函数中:
pThreadState->m_pCurrentWinThread = this;
pModuleState->m_pCurrentWinApp = this
重点:MFC运行机制 执行顺序 各个函数用途以及调用顺序
孙同学在视频中反复说明的是:MFC的程序和C语言的程序,从执行原理上说,是完全一致的。
抓住这一点,那么对于理解MFC程序的运行机制也就相对于简单了。
C中的main函数就相当于MFC中的WinMain函数。
感兴趣的可以利用VC的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。
2, 进入main函数
二、MFC程序的运行步骤(主要是初始化)
打开一个MFC APPWizard(exe)工程,跟踪其执行步骤,可以发现,是以下顺序:
1)CXXApp中的全局变量定义(在WinMain()函数之前定义的全局变量)
CXXApp theApp;
2)调用CXXApp构造函数(当然,创建一个类,它首先会调用自己的构造函数,这时WinMain()还没有运行呢,呵呵奇怪吧?跟上面例子的变量a,其实是差不多的。)
6,PreCreateWindow()://主要是注册窗口类,提供这个函数主要是允许程序对窗口的参数进行多次的修改,而且这个函数也是反复调用的。
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
根目录
找到您安装VC98下MFC的位置,比如我的机子上为:D:\Program Files\Microsoft Visual Studio\VC98\MFC。下面提供的就是相对路径了。在安装目录下找到MFC文件夹下的SRC文件夹,SRC下是MFC源代码。
1,寻找WinMain人口:
路径:MFC|SRC|APPMODUL.CPP:
(this指向的是派生类CTEApp对象,即theApp)
调试:CTEApp theApp;( -> CTEApp ::CTEApp())-> CWinApp::CWinApp() (先调用基类初始化函数) -> CTEApp ::CTEApp() -> _tWinMain(){}(红色箭头表示依次运行的顺序)
4,_tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。
AfxWinMain()函数路径:MFC|SRC|WINMAIN.CPP:
-> AfxWinMain(); -> pApp->InitApplication();-> pThread->InitInstance()//父类InitInstance虚函数;->CTEApp::InitInstance()//子类实现函数; -> AfxEndDeferRegisterClass(LONG fToRegister)//注册所选择的窗口类(出于文档管理,注册提前,正常的应在PreCreateWindow中进行注册)//之后进入创建窗口阶段(以下再不在C语言中,大约的步骤如下:
1, 全局变量内存分配 例子如下:
#include <iostream.h>
int a=88;
main(){
cout<<a<<endl;
}
如果我们在main前设置断点,我们就会发现,在进入main之前,a就已经存在了。也就是说像a这样的全局变量在进入main函数前已经创建,并初始化。
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
//判断AFX_WNDFRAMEORVIEW_REG型号窗口类是否注册,如果没有注册则注册
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
相关文档
最新文档