[4]c++语言 为什么mfc的入口是InitInstance()而没有WinMain()(课前必知)
MFC中的InitApplication和InitInstance函数解析
请注意:在下面程序中,RegisterClass被我封装在InitApplication函数之中,CreateWindow 则被我封装在InitInstance函数之中。
两个函数(InitApplication和InitInstance)的名称别具意义:
·在Windows 3.x时代,窗口类只需注册一次,即可供同一程序的后续每一个实例(instance)使用(之所以如此,是因为所有进程同在一个地址空间中),所以我们把RegisterClass这个操作安排在“只有第一个实例才会进入”的InitApplication函数中。
·产生窗口,是每一个实例都得进行的操作,所以我们把CreateWindow这个操作安排在“任何实例都会进入”的InitInstance函数中。
以上情况在Windows NT和Windows 9x中略有变化。
由于Win32程序的每一个实例有自己的地址空间,故共享同一窗口类已不可能。
但是由于win32系统令hPrevInstance永远为0,所以我们任然得以把RegisterClass和CreateWindow按旧习惯安排。
这样,既符合了新环境的要求,又兼顾到了与旧程序代码的兼容。
MFC程序执行过程
很是空闲最近.转载一些东西吧..就当是复习...再不看看,就忘光了MFC 应用程序的操作步骤可归结为四步:(1) 创建应用程序对象theApp(2) 执行MFC提供的WinMain()函数(3) WinMain()调用InitInstance()函数,此函数创建文档模板,主框架窗口,文档和视图(4) WinMain()调用Run()函数,此函数执行主消息循环,以获取和分派Windows消息。
WinMain()是函数的入口点,该函数的主要任务是完成一些初始化的工作和维护了一个消息循环。
他们的工作流程如下:入口(WinMain())---->MyRegisterClass()---->InitInstance ()--->while消息循环。
函数由入口开始执行,之后调用 MyRegisterClass()注册窗口类,之后InitInstance ()生成并显示窗口,这样之后,就完成了一个窗口的初始化工作了(当然,在MyRegisterClass(),InitInstance ()中都需要调用相应的API函数来具体的实现),然后就是维护消息循环,至此,程序的基本结构就差不多建立了。
以后程序的运作就靠个消息循环来推动了.1、创建Application object对象theApp程序一开始生产一个(且只有一个)Application object对象theApp,也即一个CWinApp对象,这个全局对象一产生,便执行其构造函数,因为并没有定义CMyWinApp构造函数,所以即执行CWinApp类的构造函数。
该函数定义于APPCORE.CPP第75行,你可以自己搜出来啃一啃,因此,CWinApp之中的成员变量将因为theApp这个全局对象的诞生而获得配置与初值。
2、WinMain登场用SDK编程序时,程序的入口点是WinMain函数,而在MFC程序里我们并没有看到WinMain函数,哦!~ 原来她是被隐藏在MFC代码里面了。
MFC学习笔记-窗口创建
MFChierarchy chart(类库列表)MFC与Win321 win32:函数,使用API一步一步搭建应用程序。
(常使用FileView操作)2 MFC编程:实现仍然调用API函数,但是是用类封装API函数,使用向导自动生成应用程序框架。
(常使用ClassView操作)2.1需要掌握的技能2.1.1断点调试2.1.2堆栈调用的查看MFC课程内容1 MFC:MFC的六大机制,文档式架构,常用的MFC类,(10--12)。
2 COM(组件对象模型):COM的原理和应用(6)。
3 ADO/Socket:MFC访问数据库以及一些简单的网络编程。
MFC应用程序编程1 MFC的历史:92(VC1)98(VC6)……………………….2 MFC库基础:2.1 MFC库,微软基础类库。
封装了Windows应用程序编程的各种API以及相关机制的C++类库3 类库的相关头文件件★afx-application framework(应用程序框架x)3.1<stdafx.h>-不是类库头文件,是项目的头文件,称为VC下编译的预编译头文件,用来提高编译速度的。
(*.pch)(头文件是不参加编译的但是他参与生成*.pch)3.2<afxwin.h>-几乎包含了各种常用的MFC有文件3.3 <afxext.h>-提供扩展窗口类的支持(创建工具栏,状态栏等………)MFC应用程序的类型1 支持MFC的控制台应用程序(控制台的第四个选项)1.1 多了一个CWinApp(应用程序类,封装类应用程序启动过沉重所涉及到得相关信息)的全局对象(必须有,而且只能有一个)1.2主函数中多了一个AfxWinInit函数,初始化MFC库中的相关信息2 MFC库程序2.1 MFC支持的静态库2.2 MFC支持的动态库2.2.1 MFC规则库(shared MFC DLL)-可以被各种应用程序调用(非MFC程序,没有MFC类也可以调用)★还是有一个CWinApp派生的CMFC_DLLApp类对象2.2.2 MFC扩展库(using shared MFC DLL)-只能被MFC库所编写的应用程序所调用(对原有的MFC类扩展)★DllMain主函数只能被MFC程序调用3 MFC应用程序-----(注意看父类,子类名字可能不一样)3.1单文档视图应用程序★CWinApp 应用程序类★CAboutDlg(对话框-生成关于窗口-和框架没有任何关系)★CMainFrame(父类是:CFrameWnd)(应用程序主框架窗口类-生成应用程序的主框架-负责各个对象的协调工作)★CDocument(它是父类)(文档类-看不到的很重要-管理数据)★CView(它是父类)(视图类-显示数据并和用户进行交互)★CSingleDocApp(父类是CWinApp)-(使用前面的3个类来创建对象)3.2多文档视图架构★CWinApp 应用程序类★CAboutDlg(对话框-生成关于窗口-和框架没有任何关系)★CView(它是父类)(视图类-显示数据并和用户进行交互)★CDocument(它是父类)(文档类-看不到的很重要-管理数据)★CMDIChildWnd(子框架窗口类,父类)★CMDIFrameWnd(主框架窗口类,父类)我们看到的子窗体其实是★CView和★CMDIChildWnd叠加的3.3基于对话框的应用程序★CWinApp 应用程序类★CDialog(对话框窗口类)★★m_pMainWnd保存主窗口地址DoModal 显示对话框MFC相关类的说明1继承自CObject1.1 CObject类:绝大多数MFC类的父类,提供了MFC库的一些机制1 new/delete操作符,定义了与构造函数相关的内存分配函数2 assert和dump调试,堆调试的支持★3 运行时类信息-属于哪个类,还有类的层次结构★4 动态创建★5 序列化1.2 CWinThread: 线程类。
C++程序启动入口函数main还是winmain?
1.菜单中选择 Project->Properties, 弹出Property Pages窗口
2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项,要么 _CONSOLE要么_WINDOWS.
网络错误503请刷新页面重试持续报错请尝试更换浏览器或网络环境
C++程序启动入口函数 main还是 winmain?
C++ 程序启动入口函数main还是winmain? 2007-06-19 11:17 两个都可以,如果是main,则用win32的处理器,是console的程序编译方式,预处理器应该选在WIN32;_DEBUG,链接器是 Console(/SUBSYSTEM:WINDOWS)
3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项要么为 Windows(/SUBSYSTEM:WINDOWS),Console(/SUBSYSTEM:WINDOWS)
如果是winmain,则用windows的预编译方式,链接器是Windows(/SUBSYSTEM:WINDOWS)
如果匹配出错,error LNK2001: unresolved external symbol _WinMain@16 debug/main.exe:fatal error 1120:1 unresolved externals error executing link.exe;
mfc初始化函数
mfc初始化函数
MFC初始化函数是指在使用MFC框架编写程序时,首先执行的一段代码块,通常用于在程序启动时初始化一些全局变量和资源,为后续程序运行做好准备。
MFC提供了三种初始化函数:
1. InitInstance()函数:在程序启动时调用,用于初始化应用程序的主窗口和其他资源。
2. ExitInstance()函数:在程序结束时调用,用于释放应用程序占用的资源。
3. OnAppInit()函数:在程序启动时调用,用于初始化框架级别的资源,例如全局共享内存和线程。
除了以上三个函数,MFC还提供了一些其他的初始化函数,例如OnCmdLine()函数,用于在程序启动时处理命令行参数。
在编写MFC 程序时,我们需要根据具体需求选择合适的初始化函数,并编写相应的代码进行初始化操作。
- 1 -。
VC中对于Dialog,OnCreate()和OnInitDialog()是什么关系
VC中对于Dialog,OnCreate()和OnInitDialog()是什么关系 OnCreate是对话框在被创建时的消息,这时候对话框还没有被显⽰在屏幕上。
⽽且对话框中的控件都还没有被创建。
⽽OnInitDialog()是对话框创建完成,即对话框上的控件也全部被创建后第⼀次激活显⽰在屏幕上产⽣的消息。
在此时可以对话框中的控件进⾏初始化操作。
《在VC2005⾥添加OnInitDialog()函数》
OnInitDialog()函数可以在对话框出现之前对对话框进⾏初始化。
有时候会很有⽤。
⽤MFC向导创建的对话框会⾃动⽣成OnInitDialog()函数。
但是⼿动添加的对话框或者创建⼦对话框时就不会⽣成OnInitDialog()。
我写了⼀个⼦对话框,⾥⾯有⼀个List Control,需要在⼦对话框弹出来之前对List Control进⾏⼀些操作。
这些操作放在构造函数⾥不⾏,只能放在OnInitDialog()函数⾥。
VC2005添加该函数的⽅法如下:
1. 打开需要添加OnInitDialog()的对话框的头⽂件;
2. 查看该头⽂件属性菜单。
在属性菜单上有⼀个“重写”图标,单击该图标出现函数列表,列表⾥有OnInitDialog(),添加该函数,然后就可以直接编辑这个函数了。
深入浅出话vc(2)mfc本质
一、引言上一专题中,纯手动地完成了一个Windows应用程序,然而,在实际开发中,我们大多数都是使用已有的类库来开发Windows应用程序。
MFC(Microsoft Foundation Class, 微软基础类库)是微软为了简化程序员的开发工作而将Windows API 封装到C++类中,利用这些类,程序员可以有效地完成Windows平台下应用程序的开发。
本专题将详细剖析它。
二、利用向导创建一个MFC程序用于帮助有效地开发Windows应用程序的类库除了MFC外,还有其他开源类库提供,比如说QT,只是QT不是微软开发的罢了,为了更好地剖析MFC,下面让我们用Visual Studio 中的MFC模板和向导工具来创建一个基于MFC的单文档(SDI)应用程序。
1.启动Visual studio 2010,单击文件(FIle)菜单——>新建项目——>项目,在出现的项目窗口中选择Visual C++ 语言,然后选择MFC应用程序,并输入项目的名称为SDIMFC,具体如下图所示。
2.输入项目名称后点击确定按钮,将出现MFC应用程序向导窗口,点击下一步,应用程序类型选择:单个文档,如下图所示:3. 点击下一步,出现MFC向导的第三个对话框,复合文档支持保持默认选择,然后在出现的对话框中一直点击下一步来完成一个单文档MFC应用程序的创建。
下面,按下Ctrl+F5来运行MFC应用程序,之后将看到我们创建的MFC 应用程序界面,具体如下图所示:在上面的程序中,我们并没有编写任何代码,运行它后就生成了一个带标题栏,系统菜单,具有最大化、最小化框和一个可调边框的应用程序,这一切的工作都是由MFC的向导工具帮我们完成,即该向导工具为我们生成了很多代码,下面就以这个简单的MFC程序来分析下MFC框架。
三、MFC框架详细解析我们看下用MFC向导工具帮我们生成的哪些代码。
你可以在VS中点击类视图选项卡(如果VS界面上没有看到类视图的,可以通过菜单栏视图—>类视图的方式显示出来),就可以看到如下图所示的类。
如何使用visualstudio2019创建简单的MFC窗口(使用C++)
如何使⽤visualstudio2019创建简单的MFC窗⼝(使⽤C++)本⽂介绍了如何使⽤visual studio2019创建简单的MFC窗⼝(使⽤C++)```cpp使⽤visual studio 2019 创建过程请参考Bili的上⼀篇⽂章⬇⬇→!使⽤visual studio 2019 创建简单的MFC窗⼝「使⽤底层的C语⾔」#include<windows.h> //底层实现窗⼝的头⽂件//6.处理窗⼝过程//CALLBACK 代表_stdcall 参数的传递顺序:从右到左依次⼊栈,并且函数返回前清空堆栈LRESULT CALLBACK WindowProc(HWND hand, //消息所属窗⼝句柄UINT uMsg, //具体消息名称 WM_XXXX消息名WPARAM wParam, //键盘附加消息LPARAM lParam) { //⿏标附加消息switch (uMsg){case WM_CLOSE://所有以XXXXWindow为结尾的⽅法,都不会进⼊到消息队列中,⽽是直接执⾏DestroyWindow(hand);//发送另⼀个消息WM_DESTROYbreak;case WM_DESTROY:PostQuitMessage(0);break;case WM_LBUTTONDOWN://⿏标左键按下{int xPos = LOWORD(lParam);int yPos = HIWORD(lParam);char buf[1024];wsprintf(buf, TEXT("x = %d,y = %d"),xPos,yPos);MessageBox(hand, buf, TEXT("按下⿏标左键"), MB_OK);break;}case WM_KEYDOWN: //键盘{MessageBox(hand, TEXT("键盘"), TEXT("按下键盘"), MB_OK);break;}case WM_PAINT: //画图{PAINTSTRUCT ps; //画图结构体HDC hdc = BeginPaint(hand, &ps);TextOut(hdc, 100, 100,TEXT("hello"), strlen("hello"));EndPaint(hand, &ps);break;}default:break;}//返回值⽤默认处理⽅式return DefWindowProc(hand, uMsg, wParam, lParam);}/*程序⼊⼝函数_In_ HINSTANCE hInstance,//应⽤程序实例句柄_In_opt_ HINSTANCE hPrevInstance,//上⼀个应⽤程序句柄,在WIN32环境下⼀般为NULL,不起作⽤了_In_ LPSTR lpCmdLine,//char * argv[]_In_ int nShowCmd//显⽰命令最⼤化、最⼩化、正常WINAPI 代表_stdcall 参数的传递顺序:从右到左依次⼊栈,并且函数返回前清空堆栈*/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd ) {/*1.设计窗⼝2.注册窗⼝3.创建窗⼝4.显⽰和更新5.通过循环取消息6.处理消息(窗⼝过程)*///1.设计窗⼝WNDCLASS wc;wc.cbClsExtra = 0; //类的额外的内存wc.cbWndExtra = 0; //窗⼝额外的内存wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景wc.hCursor = LoadCursor(NULL, IDC_HAND); //设置光标,如果第⼀个参数为null,代表使⽤系统提供的光标wc.hIcon = LoadIcon(NULL, IDI_ERROR); //图标,如果第⼀个参数为null,代表使⽤系统提供的图标wc.hInstance = hInstance; //应⽤程序的实例句柄,传⼊winmain的形参即可wc.lpfnWndProc = WindowProc; //回调函数窗⼝过程wc.lpszClassName = TEXT("WIN"); //指定窗⼝名称wc.lpszMenuName = NULL; //菜单名称wc.style = 0; //显⽰风格,0代表默认//2.注册窗⼝RegisterClass(&wc);//3.创建窗⼝/*lpszClassName,//类名lpWindowName, //标题名dwStyle, //风格 WC_OVERLAPPEDWINDOWx, //坐标 CW_USERDEFAULTy, //坐标nWidth, //宽nHeight, //⾼hWndParent, //⽗窗⼝ nullhMenu, //菜单 nullhInstance, //实例句柄lpParam //附加值⿏标附加值*/HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("WINDOWS"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); //4.显⽰和更新ShowWindow(hwnd, SW_SHOWNORMAL);UpdateWindow(hwnd);/*HWND hwnd; //主窗⼝句柄UINT message; //具体消息名称WPARAM wParam; //附加消息键盘消息LPARAM lParam; //附加消息⿏标消息DWORD time; //消息产⽣时间POINT pt;*/ //附加消息⿏标消息 x,y//5.通过循环取消息MSG msg;/*_Out_ LPMSG lpMsg, //消息_In_opt_ HWND hWnd, //捕获窗⼝填null表⽰捕获所有窗⼝_In_ UINT wMsgFilterMin, //最⼤和最⼩的过滤消息⼀般填0_In_ UINT wMsgFilterMax);*/while (GetMessage(&msg, NULL, 0, 0)){/*if (GetMessage(&msg, NULL, 0, 0) == FALSE) {break;}*///翻译消息TranslateMessage(&msg);//不是false//分发消息DispatchMessage(&msg);}return 0;}划重点:项⽬->属性->常规->⾼级->将MFC的使⽤设置为在“共享dll中使⽤mfc”头⽂件mfc.h#include <afxwin.h>//mfc头⽂件class MyApp:public CWinApp{public:virtual BOOL InitInstance();};class MyFrame :public CFrameWnd {//窗⼝框架类public:MyFrame();//声明宏提⽰消息映射机制DECLARE_MESSAGE_MAP();afx_msg void OnLButtonDown(UINT,CPoint);afx_msg void OnChar(UINT,UINT,UINT);afx_msg void OnPaint();};源⽂件mfc.cpp#include “mfc.h”MyApp app;BOOL MyApp::InitInstance() {//创建窗⼝MyFrame* frame = new MyFrame;//显⽰和更新frame->ShowWindow(SW_SHOWNORMAL);frame->UpdateWindow();m_pMainWnd = frame;//保存指向应⽤程序的主窗⼝的指针return TRUE;//返回正常初始化}//分界宏BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)ON_WM_LBUTTONDOWN()//⿏标左键按下ON_WM_CHAR()ON_WM_PAINT()END_MESSAGE_MAP()MyFrame::MyFrame(){Create(NULL,TEXT(“windows”));}void MyFrame::OnLButtonDown(UINT, CPoint point){//TCHAR buf[1024];//wsprintf(buf, TEXT(“x = %d,y = %d”), point.x, point.y);//MessageBox(buf);CString str;str.Format(TEXT(“x = %d,y = %d”),point.x,point.y);MessageBox(str);}void MyFrame::OnChar(UINT key, UINT, UINT){CString str;str.Format(TEXT(“按下了%c键”),key);MessageBox(str);}void MyFrame::OnPaint(){CPaintDC dc(this);dc.TextOutW(100,100,TEXT(“为了部落”));dc.Ellipse(10,10,100,100);}到此这篇关于如何使⽤visual studio2019创建简单的MFC窗⼝(使⽤C++)的⽂章就介绍到这了,更多相关vs2019创建MFC窗⼝内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
mfc原理和消息映射
MFC思想win32程序中创建一个窗口的过程:设计窗口阶段(由WNDCLASS结构描述部分)、窗口的注册及创建显示过程、消息循环部分。
win32用标准的C语言代码实现,是面向过程的。
在MFC中采用了面向对象的思想,即用面向对象的C++思想对以上代码进行了封装,也就是说将一些对窗口进行操作的API的函数封装到了一个类中,以下我将用简短的代码来演示一下这个过程:class CWnd{public:HWND m_hWnd;BOOL Create();BOOL ShowWindow();};BOOL CWnd::Create(){WNDCLASS wndClass;wndClass.style=CS_HREDRAW;wndClass.lpfnWndProc=(WNDPROC)DefWndProc;wndClass.cbClsExtra=0;wndClass.cbWndExtra=0;wndClass.hInstance=hInstance;wndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));wndClass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CURSOR1));LOGBRUSH lgbr;lgbr.lbStyle=BS_SOLID;lgbr.lbColor=RGB(192,192,0);lgbr.lbHatch=0;wndClass.hbrBackground=CreateBrushIndirect(&lgbr);wndClass.lpszMenuName=NULL;wndClass.lpszClassName="mycls";RegisterClass(&wndClass);HWND hWnd;m_hWnd=CreateWindow("mycls","窗口标题",WS_OVERLAPPEDWINDOW,0,NULL,NULL,hInstance,NULL);if(m_hWnd!=NULL)return true;elsereturn false;}BOOL CWnd::ShowWindow(){return ShowWindow(hWnd,nCmdShow);}为了保证代码和以前的执行方式一样,Winmain()函数可以写成如下形式:int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){CMyWnd m_wnd;m_wnd.Create();m_wnd.ShowWindow();MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return true;}此时,如果再写一个新的类来对剩下的代码进行封装,代码如下:class CWinApp{public:CWnd * m_pMainWnd;BOOL InitInstance();BOOL Run();CWinApp ();};CWinApp:: CWinApp (){if(InitInstance())Run();}BOOL CWinApp::InitInstance(){CWnd m_wnd;m_pMainWnd=&m_wnd;m_pMainWnd->Create();m_pMainWnd->ShowWindow();return true;}BOOL CWinApp::Run(){MSG msg;while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return true;}CWinApp theApp;int PASCAL WinMain() {}Windows消息的产生:1用户按键或者鼠标操作可以产生消息,如WM_KEYDOWN,WM_LBUTTONDOWN等;2系统可以自己产生消息,如,创建窗口的时候会产生WM_CREATE,WM_TIMER等;3应用程序间可以定义自己的消息,在应用程序间进行消息通讯;Windows消息的分类:1窗口消息(Windows Message):通常跟窗口的移动、创建,关闭等操作有关。
mfc面试知识点
MFC面试知识点介绍MFC(Microsoft Foundation Classes)是微软公司推出的一套用于开发Windows桌面应用程序的C++类库。
它提供了一系列的类和函数,使开发者能够快速地构建Windows应用程序。
在MFC面试中,了解和掌握MFC的知识点是非常重要的。
本文将介绍一些常见的MFC面试知识点,帮助你提前准备。
MFC基础知识1. 什么是MFC?MFC是微软公司开发的一套C++类库,用于快速开发Windows桌面应用程序。
它提供了一系列的类和函数,简化了Windows应用程序的开发过程。
2. MFC和Windows API有什么区别?MFC是对Windows API的封装,提供了更高级的接口和更方便的开发方式。
使用MFC可以更快速地开发Windows应用程序,而Windows API则提供了更底层的系统调用接口。
3. MFC的优点是什么?•提供了丰富的类和函数,简化了Windows应用程序的开发过程。
•可以利用MFC的资源管理器进行资源的管理和调用。
•可以通过MFC的消息映射机制处理Windows消息。
•提供了可视化的界面设计工具,如Visual Studio。
4. MFC的缺点是什么?•MFC基于C++,对于C++不熟悉的开发者来说,上手难度较大。
•MFC的应用程序比较庞大,对系统资源要求较高。
•MFC的界面设计工具功能相对简单,不如其他专门的界面设计工具强大。
MFC应用程序的创建和运行1. 如何创建一个MFC应用程序?•使用Visual Studio新建一个MFC应用程序项目。
•在项目设置中选择需要的选项,如应用程序类型和预编译头文件。
•编写代码并进行编译、调试。
2. MFC应用程序的入口函数是什么?MFC应用程序的入口函数是CWinApp::InitInstance(),该函数负责初始化应用程序实例,并创建主窗口。
3. MFC应用程序的消息循环是如何处理的?MFC应用程序的消息循环是通过CWinApp::Run()函数实现的。
cef3嵌入mfc的代码
cef3嵌入mfc的代码全文共四篇示例,供读者参考第一篇示例:CEF3是一个开源的用于构建浏览器的框架,而MFC是微软的一种视窗类库,用于构建Windows平台下的图形用户界面。
将CEF3嵌入到MFC程序中可以让程序拥有更强大的浏览器功能,同时保持原有的用户界面。
一般来说,将CEF3嵌入到MFC程序中需要经历以下几个步骤:1. 下载CEF3库文件:首先需要从CEF官方网站上下载CEF3的库文件,这些文件包括CEF3的动态链接库、头文件、资源文件等。
2. 导入CEF3库文件:将下载的CEF3库文件导入到MFC工程中,这样程序才能调用CEF3的相关函数和资源。
3. 初始化CEF3:在MFC程序中初始化CEF3,包括创建CEF3的主界面窗口、设置CEF3的参数等。
4. 加载网页:通过CEF3提供的接口加载网页,在MFC程序中显示网页内容。
5. 处理CEF3消息:处理CEF3发送的消息,以实现与CEF3的交互。
6. 释放CEF3资源:在程序结束时释放CEF3占用的资源,以确保程序正常退出。
```cpp#include "stdafx.h"#include "MyApp.h"CMyApp::CMyApp(){}BOOL CMyApp::InitInstance(){CWinAppEx::InitInstance();return TRUE;}在上面的示例中,我们首先在InitInstance函数中初始化CEF3,然后创建一个MFC的主窗口,并在主窗口中显示CEF3加载的网页内容。
在ExitInstance函数中,我们释放CEF3的资源,保证程序正常退出。
通过以上步骤,我们可以将CEF3成功嵌入到MFC程序中,并实现一个具有浏览器功能的Windows应用。
要实现更复杂的功能还需要进一步学习CEF3的使用方法和MFC的开发技巧。
希望本文对读者有所帮助,谢谢!第二篇示例:CEF3(Chromium Embedded Framework)是一个开源的用于嵌入Chromium浏览器的框架,可以在第三方应用程序中实现浏览器功能。
mfc中create窗口,句柄为空
MFC(Microsoft Foundation Class)是一种用于Windows应用程序开发的C++框架。
在MFC中,使用Create函数可以创建窗口。
但是有时候会出现创建窗口时返回的句柄为空的情况。
下面我们来分析一下这个问题,以及可能的解决方法。
一、问题描述在使用MFC中的Create函数创建窗口时,有时候会遇到返回的句柄为空的情况。
这种情况通常会导致窗口无法正常显示或者无法响应用户操作,给程序的运行和用户体验带来影响。
二、可能的原因1. 调用顺序问题在使用MFC的Create函数创建窗口时,可能存在一些调用顺序上的问题,导致返回的句柄为空。
比如在调用Create函数之前没有正确设置好窗口类的属性,或者在Create函数之后立即进行了一些操作,这些情况都有可能导致句柄为空的问题。
2. 窗口类注册问题窗口类的注册是窗口创建的重要步骤,如果在注册窗口类时出现了错误,就有可能导致Create函数返回的句柄为空。
比如窗口类的属性设置不正确、窗口过程函数指定错误等。
3. 窗口样式问题在调用Create函数创建窗口时,指定的窗口样式可能会影响到句柄的返回。
如果指定的样式不正确,就有可能导致句柄为空的问题。
4. 其他原因除了上述几种可能的原因外,还有一些其他一些可能性,比如内存不足、系统环境问题等。
三、解决方法针对上述可能的原因,可以采取以下一些解决方法:1. 细致分析代码首先需要仔细分析代码,确保调用顺序正确、窗口类注册正确、窗口样式设置正确等。
通过仔细分析代码,查找可能存在的问题点。
2. 检查窗口类注册代码检查窗口类注册的代码,确保窗口类的属性设置正确、窗口过程函数指定正确等。
如果发现问题,及时进行修改。
3. 调试程序可以通过调试工具对程序进行调试,观察在调用Create函数时的情况,以便发现问题所在。
4. 测试环境在不同的系统环境下进行测试,以确定是否是系统环境问题导致的句柄为空的情况。
5. 寻求帮助如果以上方法都无法解决问题,可以寻求相关领域的专家或者论坛上的朋友进行求助,也许可以得到一些新的思路和解决方法。
面向对象程序设计C++复习题
面向对象程序设计C++复习题一、单选题1.对类成员访问权限的控制,是通过设置成员的访问控制属性实现的,下列不是访问控制属性的是(D )A. 公有类型B. 私有类型C. 保护类型D. 友元类型2.下列关于多态性的描述,错误的是( C )A. C++语言的多态性分为编译时的多态性和运行时的多态性B. 编译时的多态性可通过函数重载实现C. 运行时的多态性可通过模板和虚函数实现D. 实现运行时多态性的机制称为动态绑定3.在C++语言中,数据封装要解决的问题是( D )A. 数据的规范化B. 便于数据转换C. 避免数据丢失D. 防止不同模块之间数据的非法访问4.使用private修饰的成员变量,以下说法正确的是(A )A. 只能由本类中的函数使用,不能被外面的程序所访问。
B.可以由本类中的函数使用,也可以被外面的程序所访问。
C. 只能由本类和派生类中的函数使用。
D. 可以在主函数中使用。
5.对类的构造函数和析构函数描述正确的是(A )A.构造函数可以重载,析构函数不能重载B.构造函数不能重载,析构函数可以重载C.构造函数可以重载,析构函数也可以重载D.构造函数不能重载,析构函数也不能重载6.下面对静态数据成员的描述中,正确的是(A )A. 静态数据成员是类的所有对象共享的数据B.类的每个对象都有自己的静态数据成员C.类的不同对象有不同的静态数据成员值D.静态数据成员不能通过类的对象调用7.在VC++语言类体系中,不能被派生类继承的有(B )A. 转换函数B.构造函数C.虚函数D.静态成员函数8.下面关于句柄正确的说法是(A )A. 句柄是一个标识Windows资源和设备等对象的变量。
B. 句柄是用户程序自定义的数据类型。
C. 用户程序使用句柄时不需要定义。
D. 句柄仅仅是一个抽象的概念,程序中不能使用句柄。
9.下面关于动态链接库正确的说法是(B )A. 动态链接库提供的函数,在编译阶段能够连接到应用程序中。
entry函数
entry函数Entry函数在计算机科学中,entry函数是指程序的入口点。
它是程序开始执行的第一个函数,也是操作系统加载可执行文件时调用的第一个函数。
在本文中,我们将详细介绍entry函数的定义、作用和实现方法。
定义entry函数是一种特殊类型的函数,它没有参数和返回值。
它通常被用作程序的入口点,以便操作系统能够正确地加载和启动程序。
在C语言中,entry函数通常被称为main函数。
作用entry函数的主要作用是初始化程序并开始执行其余代码。
它负责设置程序所需的环境变量、初始化全局变量、分配内存等任务。
一旦这些任务完成,entry函数就会调用其他函数或方法来执行实际的业务逻辑。
实现方法在不同平台上,entry函数的实现方法可能会有所不同。
下面我们将介绍几种常见平台上entry函数的实现方法。
Windows平台在Windows平台上,entry函数通常被称为WinMain或wWinMain。
它有三个参数:HINSTANCE、HINSTANCE和LPSTR。
HINSTANCE 表示当前应用程序实例句柄;HINSTANCE表示先前实例句柄;LPSTR表示命令行参数(字符串)。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){// 初始化代码return 0;}Linux平台在Linux平台上,entry函数通常被称为main。
它没有参数和返回值。
int main(){// 初始化代码return 0;}macOS平台在macOS平台上,entry函数通常被称为main。
它有两个参数:int 和char **。
int表示命令行参数的数量;char **表示命令行参数的数组。
int main(int argc, char **argv){// 初始化代码return 0;}总结在本文中,我们介绍了entry函数的定义、作用和实现方法。
mfcdll显示非模态对话框问题(转)
mfcdll显示非模态对话框问题(转)
在mfc dll的InitInstance()方法中创建对话框实力并且进行显示,但是窗体会一闪而过,
CDLGTEST *dlg;
BOOL CTestApp::InitInstance()
{
dlg=new CDLGTEST;
dlg->Create(IDD_DIA_TEST);
dlg->ShowWindow(SW_SHOWNORMAL);
return CWinApp::InitInstance();
}
后来查阅资料说是得加入消息循环,代码如下:
CDLGTEST *dlg;
BOOL CTestApp::InitInstance()
{
dlg=new CDLGTEST;
dlg->Create(IDD_DIA_TEST);
dlg->ShowWindow(true);
while(::GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return CWinApp::InitInstance();
}
似乎问题还是解决不了,一闪而过的问题没了,但是这样下来被注入的程序(记事本无响应),注入程序也是无响应,有相应的只有IDD_DIA_TEST窗体,好像主线程进入了while后,一直在处理消息问题,后来用线程来处理消息循环,更是得不到消息信息,困扰几天的问题,实在解决不了了,还请师哥师姐们多多指点。
小弟万分感激。
谢谢。
WinMain函数
WinMain函数现在讨论MFC应用程序如何启动。
WinMain函数是MFC提供的应用程序入口。
进入WinMain前,全局应用程序对象已经生成。
WinMain 流程如图5-3所示。
图中,灰色框是对被调用的虚拟函数的注释,程序员可以或必须覆盖它以实现MFC要求的或用户希望的功能;大括号所包含的图示是相应函数流程的细化,有应用程序对象App的初始化、Run函数的实现、PumpMessage的流程,等等。
从图中可以看出:(1)一些虚拟函数被调用的时机对应用程序类(线程类)的InitIntance、ExitInstance、Run、ProcessMessageFilter、OnIdle、PreTranslateMessage来说,InitInstance在应用程序初始化时调用,ExitInstance在程序退出时调用,Run在程序初始化之后调用导致程序进入消息循环,ProcessMessageFilter、OnIdle、PreTranslateMessage在消息循环时被调用,分别用来过滤消息、进行Idle处理、让窗口预处理消息。
(2)应用程序对象的角色首先,应用程序对象的成员函数InitInstance被WinMain调用。
对程序员来说,它就是程序的入口点(真正的入口点是WinMain,但MFC向程序员隐藏了WinMain的存在)。
由于MFC没有提供InitInstance的缺省实现,用户必须自己实现它。
稍后将讨论该函数的实现。
其次,通过应用程序对象的Run函数,程序进入消息循环。
实际上,消息循环的实现是通过CWinThread::Run来实现的,图中所示的是CWinThread::Run的实现,因为CWinApp没有覆盖Run的实现,程序员的应用程序类一般也不用覆盖该函数。
(3)Run所实现的消息循环它调用PumpMessage来实现消息循环,如果没消息,则进行空闲(Idle)处理。
如果是WM_QUIT消息,则调用ExitInstance后退出消息循环。
MFC教程 MFC的DLL
7. MFC的DLL一般的,在介绍Windows编程的书中讲述DLL的有关知识较多,而介绍MFC的书则比较少地提到。
即使使用MFC来编写动态链接库,对于初步接触DLL的程序员来说,了解DLL的背景知识是必要的。
另外,MFC提供了新的手段来帮助编写DLL程序。
所以,本节先简洁的介绍有关概念。
1. DLL的背景知识1. 静态链接和动态链接当前链接的目标代码(.obj)如果引用了一个函数却没有定义它,链接程序可能通过两种途径来解决这种从外部对该函数的引用:● 静态链接链接程序搜索一个或者多个库文件(标准库.lib),直到在某个库中找到了含有所引用函数的对象模块,然后链接程序把这个对象模块拷贝到结果可执行文件(.exe)中。
链接程序维护对该函数的所有引用,使它们指向该程序中现在含有该函数拷贝的地方。
● 动态链接链接程序也是搜索一个或者多个库文件(输入库.lib),当在某个库中找到了所引用函数的输入记录时,便把输入记录拷贝到结果可执行文件中,产生一次对该函数的动态链接。
这里,输入记录不包含函数的代码或者数据,而是指定一个包含该函数代码以及该函数的顺序号或函数名的动态链接库。
当程序运行时,Windows装入程序,并寻找文件中出现的任意动态链接。
对于每个动态链接,Windows装入指定的DLL并且把它映射到调用进程的虚拟地址空间(如果没有映射的话)。
因此,调用和目标函数之间的实际链接不是在链接应用程序时一次完成的(静态),相反,是运行该程序时由Windows完成的(动态)。
这种动态链接称为加载时动态链接。
还有一种动态链接方式下面会谈到。
1. 动态链接的方法链接动态链接库里的函数的方法如下:● 加载时动态链接(Load_time dynamic linking)如上所述。
Windows搜索要装入的DLL时,按以下顺序:应用程序所在目录→当前目录→Windows SYSTEM目录→Windows目录→PATH环境变量指定的路径。
mfc 命令行参数
mfc 命令行参数MFC(Microsoft Foundation Classes)是微软开发的一套在Windows环境下使用C++进行图形化应用程序开发的类库。
MFC命令行参数是指在运行MFC应用程序时传递给程序的额外参数。
在MFC应用程序中,可以通过覆盖CWinApp类的InitInstance函数来获取命令行参数。
InitInstance函数的原型如下:virtual BOOL InitInstance();可以在InitInstance函数中使用GetCommandLine函数来获取完整的命令行参数字符串。
该函数的原型如下:LPWSTR GetCommandLine();接下来,可以使用CommandLineToArgvW函数将命令行参数字符串分割成一个个独立的参数。
该函数的原型如下:LPWSTR* CommandLineToArgvW(LPCWSTR lpCmdLine,int *pNumArgs);这样,就可以获得一个包含所有命令行参数的字符串数组,通过遍历该数组可以获取每个具体的命令行参数。
同时,MFC还提供了一个ParseCommandLine函数,可以将命令行参数解析到MFC应用程序的成员变量中。
该函数的原型如下:void ParseCommandLine(CCommandLineInfo& rCmdInfo);在使用ParseCommandLine函数之前,需要先创建一个CCommandLineInfo对象,并将其传递给ParseCommandLine 函数。
ParseCommandLine函数会根据命令行参数的格式将参数解析到CCommandLineInfo对象的成员变量中,例如,解析"-silent"参数到CCommandLineInfo的m_bSilent成员变量中。
这些是MFC中处理命令行参数的一些常用方法。
根据具体的需求,您可以选择适合的方法来处理命令行参数。
MFC原理(PPT)
MFC应用程序运行后各函数的调用关系 应用程序运行后各函数的调用关系
InitInstance()函数是派生类唯一需要重载的函数,它负 责应用程序的初始化,如初始化数据,创建文档模板,处理 命令行以及显示应用程序主窗口.
6.3.3 常用的 常用的MFC文件和库文件 文件和库文件
文件名称 afxwin.h afxext.h afxdisp.h afxdtctl.h afxcmn.h Mfc42.lib Mfc42D.lib MfcS42.lib MfcS42D.lib Mfc42U.lib 声明MFC核心类 MFC扩展文件,声明工具栏,状态栏,拆分窗口等类 声明OLE类 声明支持IE 4公用控件的MFC类,如CImageList等 声明Windows公共控件类 MFCxx.DLL的导入函数库(Release版) MFCxx.DLL的导入函数库(Debug版) MFCSxx.DLL的导入函数库(Static Release版) MFCSxxD.DLL的导入函数库(Static Debug版) MFCxxU.DLL的导入函数库(Unicode Release版) 说 明
MFC应用程序对象之间的关系 应用程序对象之间的关系
6.3.2 MFC应用程序的生与死 应用程序的生与死
在MFC应用程序的CWinApp派生类对象theApp是一个全局 变量,代表了应用程序运行的主线程.它在程序整个运行 期间都存在,它的销毁意味着运行程序的消亡. MFC应用程序启动时,首先创建应用程序对象theApp,这 时将自动调用应用程序类的构造函数初始化对象theApp, 然后由应用程序框架调用MFC提供的AfxWinMain()主函数. AfxWinMain()主函数首先通过调用全局函数AfxGetApp()获 取应用程序对象theApp的指针pApp,然后通过pApp调用应 用程序对象的有关成员函数,完成程序的初始化和启动工 作,最后调用成员函数Run(),进入消息循环. 程序运行后将收到WM_PAINT消息,调用OnPaint()函数绘 制客户区窗口.如果Run()收到WM_QUIT消息,则结束消 息循环,然后调用函数ExitInstance(),结束程序运行.
MFC期末复习简答题及答案
MFC 期末复习及答案1 简述MFC 应用程序的执行过程。
2 简述文档/视图与其他类对象的关系。
3 简述MFC 消息映射机制。
4 消息WM_LBUTTONDOWN 的消息映射宏和消息处理函数是什么?5 如何自定义消息?如何发送自定义消息?6 GDI 创建哪几种类型的图形输出?7 什么是设备环境?它的主要功能有哪些?8 什么是GDI,它有什么功能?MFC 将GDI 函数封装在哪个类中?9 请叙述设备无关性的含义,实现设备无关性需要哪几个环节?10 MFC 提供了哪几种设备环境类?它们各自有什么用途?11 简述传统的SDK 获取设备环境的方法。
12 简述创建和使用自定义画笔的步骤。
13 简述采用MFC 方法编程时,显示一个DDB 位图的步骤。
14 简述菜单设计的主要步骤。
15 为应用程序创建快捷菜单主要有哪些方法?16 如何动态创建菜单?17 创建工具栏的基本步骤有哪些?18 简述MFC 创建状态栏所做的工作。
19 简述创建和使用模态对话框的主要步骤。
20 如何向对话框模板资源添加控件?如何添加与控件关联的成员变量?21 什么是DDX 和DDV?编程时如何使用MFC 提供的DDX 功能?22 简述创建属性页对话框的主要步骤。
23 在应用程序中访问控件的方法有哪些?24 单选按钮控件如何成组?25 组合框与列表框相比有什么不同?如何给组合框添加初始的列表项?26 通过哪几个主要成员函数完成文档与视图之间的相互作用?并简述这些成员函数的功能。
27 简述文档序列化与一般文件处理的区别。
28.如何让用户定义的类支持序列化?1 简述MFC 应用程序的执行过程。
MFC 应用程序启动时,首先创建应用程序对象theApp。
这时将自动调用应用程序类的构造函数初始化对象theApp,然后由应用程序框架调用MFC 提供的WinMain( )主函数。
在WinMain( )主函数中,首先通过调用全局函数GetApp( )来获取theApp 的指针pApp,然后通过该指针调用theApp 的成员函数InitInstance( )来初始化应用程序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为什么mfc的入口是InitInstance()而没有WinMain()学过PE文件格式,就明白,程序在进入WinMain之前要做很多事情,比如初始Dos头,分配函数表,初始化全局变量,之后才进入程序入口(WinMain)MFC对WindowsAPI进行了封装。
在用向导编译成的二进时代码,MFC编译器链接器把源文件编译成PE文件格式存储在磁盘上。
程序执行的时候,从PE文件头开始执行,在进入Winmain函数之前,进行一系列的必备的初始化。
MFC对这一系列的过程进行了封装。
提供给编程人员的第一个裸露程序入口就是CW inApp的InitInstance(),其实程序的入口依然是WinMain()函数。
大家都知道,每个程序都有拥有一个进程,每个进程至少有一个线程就是主线程。
这个主线程就是在WinMain函数中创建的,包括UI线程和工作者线程。
MFC用来封装线程的是CWinThread类,因此每个MFC程序至少使用一个C WinThread派生类。
被MFC程序员熟知的CWinApp应用类就从这里派生。
InitInstance是CWinThread的一个虚函数,InitInstance就是“初始化实例”的意思,可见,它是在实例创建时首先被调用的。
应用程序总要重载这个虚函数,进行系统设置,创建运行环境。
例如,主窗口一定要在InitInstance()中创建,因为该函数退出后就进入该线程的消息循环。
MFC大致流程:1、初始化全局变量WinMain之前有个theApp全局变量(全局对象)先被构造并被初始化,而由于子类构造函数执行前,其父类的构造函数先被执行,所以CTestApp的父类CWinAPP的构造函数先执行.产生了theApp对象后,在WinMain()中的指针*pThread和*pApp就有了内容._tWinMain(WinMain的别名,用define宏替换的)-》AfxWinMain->初始化线程,调用InitInstance初始化窗口,调用Run函数进入消息循环。
2、具体程序代码反应在如下几处:微软在MFC底层框架类中封装了这些每一个应用程序都需要的步骤,目的是为了简化程序员的开发工作。
在编译过程中WinMain函数并没有出现,它是由连接器将该函数连接到 Test(我自己开发的项目名称)程序中的。
在Microsoft Visual Studio 6.0安装目录D:\Program Files\Microsoft Visual Studio\VC98\MFC\ SRC下APPMODUL.CPP文件中可以找到如下这段代码:_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){// call shared/exported WinMainreturn AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);}Test这个MFC程序,在程序编译后进行链接时,WinMain函数就成为该程序的一部分。
到_tWinMain函数的定义处#define _tWinMain WinMain发现_tWinMain实际上是一个宏,展开之后就是WinMain函数。
MFC程序中的类是如何与WinMain函数关联起来的呢?双击ClassView标签页中的CTestApp类(该程序的主类:应用程序类),跳转到该类的定义文件(Test.h)中。
可以发现CTestApp派生于CWinApp类,后者表示应用程序类。
我们在ClassView 标签页中打开CTestApp类前面的“+”符号,双击该类的构造函数,就跳转到该类的源文件(Test.cpp)中。
在CTestApp构造函数处设置一个断点,然后调试运行Test程序,将发现程序首先停在CTestApp 类的构造函数处,继续运行该程序。
这时程序才进入WinMain函数,即停在先前我们在WinMain函数中设置的断点处。
为什么程序会首先调用CTestApp类的构造函数呢?看一下CTestApp的源文件,可以发现程序中定义了一个CTestApp类型的全局对象:theApp。
代码如下:// The one and only CTestApp objectCTestApp theApp;// MFC程序的全局变量都放置在ClassView标签页的Globals分支下,展开该分支即可看到程序当前所有的全局变量。
程序执行的顺序依次是:theApp全局对象定义处、TestApp构造函数,然后才是WinMain函数。
在程序入口WinMain函数加载时,系统早就已经为全局变量或全局对象分配了存储空间,并为它们赋了初始值。
为什么要定义一个全局对象theApp,让它在WinMain函数之前执行呢?该对象的作用是什么呢?而对MFC程序来说,每一个MFC程序有且仅有一个从应用程序类(CWinApp)派生的类。
每一个MFC程序实例有且仅有一个该派生类的实例化对象,也就是theApp全局对象。
该对象就表示了应用程序本身。
(一个子类在构造之前会先调用其父类的构造函数。
因此theApp对象的构造函数CTestApp在调用之前,会调用其父类CWinApp的构造函数,从而就把我们程序自己创建的类与Microsoft提供的基类关联起来了。
CWinApp的构造函数完成程序运行时的一些初始化工作。
)CWinApp构造函数的代码如下:CWinApp::CWinApp(LPCTSTR lpszAppName){if (lpszAppName != NULL)m_pszAppName = _tcsdup(lpszAppName);elsem_pszAppName = NULL;// initialize CWinThread stateAFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;ASSERT(AfxGetThread() == NULL);pThreadState->m_pCurrentWinThread = this;ASSERT(AfxGetThread() == this);m_hThread = ::GetCurrentThread();m_nThreadID = ::GetCurrentThreadId();// initialize CWinApp stateASSERT(afxCurrentWinApp == NULL); // only one CWinApp object pleasepModuleState->m_pCurrentWinApp = this;ASSERT(AfxGetApp() == this);// in non-running state until WinMainm_hInstance = NULL;m_pszHelpFilePath = NULL;m_pszProfileName = NULL;m_pszRegistryKey = NULL;m_pszExeName = NULL;m_pRecentFileList = NULL;m_pDocManager = NULL;m_atomApp = m_atomSystemTopic = NULL;m_lpCmdLine = NULL;m_pCmdInfo = NULL;// initialize wait cursor statem_nWaitCursorCount = 0;m_hcurWaitCursorRestore = NULL;// initialize current printer statem_hDevMode = NULL;m_hDevNames = NULL;m_nNumPreviewPages = 0; // not specified (defaults to 1)// initialize DAO statem_lpfnDaoTerm = NULL; // will be set if AfxDaoInit called// other initializationm_bHelpMode = FALSE;m_nSafetyPoolSize = 512; // default size}上述CWinApp的构造函数中有这样一句代码:pModuleState->m_pCurrentWinApp = this;根据C++继承性原理,这个this对象代表的是子类CTestApp的对象,即theApp。
同时,可以发现CWinApp的构造函数有一个LPCTSTR类型的形参:lpszAppName。
但是我们程序中CTestApp的构造函数是没有参数的。
如果基类的构造函数带有一个形参,那么子类构造函数需要显式地调用基类带参数的构造函数。
那么,为什么我们程序中的CTestApp构造函数没有这么做呢?我们知道,如果某个函数的参数有默认值,那么在调用该函数时可以传递该参数的值,也可以不传递,直接使用默认值即可。
CWinApp类的定义中部分代码如下:class CWinApp : public CWinThread{DECLARE_DYNAMIC(CWinApp)public:// ConstructorCWinApp(LPCTSTR lpszAppName = NULL); // app name defaults to EXE name……CWinApp构造函数的形参确实有一个默认值(NULL)。
这样,在调用CWinApp类的构造函数时,就不用显式地去传递这个参数的值。
CTestApp theApp;//主函数之前先构造全局对象WinMain(){AfxWinMain();//调用下面的函数}AfxWinMain(){pThread->Initinstance();//初始化工作和注册窗口类,窗口显示和更新pThread->Run();//消息循环}而在BOOL CTestApp::InitInstance()中的代码CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CTestDoc),RUNTIME_CLASS(CMainFrame), // main SDI frame windowRUNTIME_CLASS(CTestView));AddDocTemplate(pDocTemplate);完成了将这三个类关联起来的工作.。