随笔 - 108,  文章 - 0,  评论 - 7,  阅读 - 78982
新建一个MFC单文档项目,后面选项都可以默认。

 

然后程序会自动给我们生成基础代码,可以直接运行得到如下图的结果:

(在MFC中,以Afx开头的函数,大多是MFC中的全局函数;以::开头的函数,大都是Win32的API函数) 
在(初识MFC,一个简单的窗口程序)中,了解到,窗口程序大致有七个步骤,那么这个自动生成的程序是否也是这样,此处剖析代码,寻找相同之处。
1.程序执行顺序,先到theApp全局对象定义处,然后是MFCApplicationApp(***App,你自己的项目名)构造函数处,然后才是WinMain函数。
对于MFC程序来说,通过产生一个应用程序类的对象来唯一标识应用程序的实例。每一个MFC程序有且仅有一个从应用程序类(CWinApp)派生的类,每一个MFC程序实例有且仅有一个该派生类的实例化对象,也就是theApp全局对象,该对象就表示了应用程序本身。
2.WinMain函数通过调用AfxWinMAin函数实现。其中有两个变量分别指向theApp,并且调用不同的函数,pApp->InitApplication();(主要实现MFC内部管理方面的工作,----  我也不知道具体做了什么工作)pThread->InitInstance();(实现设计窗口类、注册、创建、显示、更新窗口)pThread->Run();(消息循环)
3.InitInstance()函数:参考下面函数中的注解,
以下是CMy0714MFCApplication1App类(CMy0714MFCApplication1.cpp)的部分代码,主要是InitInstance()函数。
复制代码
 1 // 唯一的一个 CMy0714MFCApplication1App 对象
 2 CMy0714MFCApplication1App theApp;
 3 
 4 // CMy0714MFCApplication1App 初始化
 5 
 6 BOOL CMy0714MFCApplication1App::InitInstance()                // 实现到窗口的显示与更新
 7 {
 8     // 如果一个运行在 Windows XP 上的应用程序清单指定要
 9     // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
10     //则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
11     INITCOMMONCONTROLSEX InitCtrls;
12     InitCtrls.dwSize = sizeof(InitCtrls);
13     // 将它设置为包括所有要在应用程序中使用的
14     // 公共控件类。
15     InitCtrls.dwICC = ICC_WIN95_CLASSES;
16     InitCommonControlsEx(&InitCtrls);
17 
18     CWinAppEx::InitInstance();
19 
20 
21     // 初始化 OLE 库
22     if (!AfxOleInit())
23     {
24         AfxMessageBox(IDP_OLE_INIT_FAILED);
25         return FALSE;
26     }
27 
28     AfxEnableControlContainer();
29 
30     EnableTaskbarInteraction(FALSE);
31 
32     // 使用 RichEdit 控件需要 AfxInitRichEdit2()    
33     // AfxInitRichEdit2();
34 
35     // 标准初始化
36     // 如果未使用这些功能并希望减小
37     // 最终可执行文件的大小,则应移除下列
38     // 不需要的特定初始化例程
39     // 更改用于存储设置的注册表项
40     // TODO: 应适当修改该字符串,
41     // 例如修改为公司或组织名
42     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
43     LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)
44 
45 
46     InitContextMenuManager();
47 
48     InitKeyboardManager();
49 
50     InitTooltipManager();
51     CMFCToolTipInfo ttParams;
52     ttParams.m_bVislManagerTheme = TRUE;
53     theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
54         RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);
55 
56     // 注册应用程序的文档模板。  文档模板
57     // 将用作文档、框架窗口和视图之间的连接
58     CSingleDocTemplate* pDocTemplate;                            // 注册与创建窗口应当是这一块,2022/07/14
59     pDocTemplate = new CSingleDocTemplate(                        // pDocTemplate把文档对象/框架对象/视类对象有机地组织在一起
60         IDR_MAINFRAME,
61         RUNTIME_CLASS(CMy0714MFCApplication1Doc),
62         RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
63         RUNTIME_CLASS(CMy0714MFCApplication1View));
64     // 是在这里创建窗口的,RUNTIME_CLASS(CMainFrame), 就是创建主框架窗口,RUNTIME_CLASS(CTestView)创建视图子窗口。
65     // 这个RUNTIME_CLASS是宏实现, 其实就是动态创建运行类的实例,返回实例指针
66     if (!pDocTemplate)
67         return FALSE;
68     AddDocTemplate(pDocTemplate);
69 
70 
71     // 分析标准 shell 命令、DDE、打开文件操作的命令行
72     CCommandLineInfo cmdInfo;
73     ParseCommandLine(cmdInfo);
74 
75 
76     // 调度在命令行中指定的命令。  如果
77     // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
78     if (!ProcessShellCommand(cmdInfo))
79         return FALSE;
80 
81     // 唯一的一个窗口已初始化,因此显示它并对其进行更新
82     m_pMainWnd->ShowWindow(SW_SHOW);                            // 窗口显示与更新
83     m_pMainWnd->UpdateWindow();                                    // m_pMainWnd是CWnd类型的指针,指向CMainFrame对象的指针
84     return TRUE;
85 }
复制代码

4.窗口过程函数的指定隐藏在AfxEndDeferRegisterClass函数之中。

 

最后,做一些相关的笔记整理:
1.MFC--microsoft foundation class,微软基础类库,C++面向对象的函数库,类的方式提供,帮助开发windows应用程序。
2.MFC中后缀名为ex的函数 均为扩展函数
3.CWinAPP应用程序类,负责管理应用程序的流程
CFrameWnd框架窗口类,负责管理框架窗口
CView视图窗口类,负责显示数据
CDocument文档类,负责管理数据
CDialog对话框窗口类
4.使用MFC编程的程序员刚开始都会提出这样一个问题:我的程序是从哪儿开始执行的?回答是:从WinMain()开始执行的。提出这样的问题是由于在他们所编写的MFC应用中看不到WinMain()函数。这个函数是隐藏在MFC框架中,MFC的设计者将它作得很通用(这主要得益于Window的消息驱动的编程机制,使得作一个通用的WinMain()很容易),因此在一般情况下,无需更改WinMain()的代码,MFC的设计者也不提倡程序员修改WinMain()的代码。在MFC中,实际实现WinMain()的代码是AfxWinMain()函数(根据其前缀Afx就知道这是一个全局的MFC函数)。    ---------------    (深入浅出MFC)
一个Win32应用程序(或进程)是由一个或多个并发的线程组成的,其中第一个启动的线程称为主线程,在Window下,一般将线程分成两大类,界面线程和工作线程,工作线程就是一般的线程,它没有窗口,没有消息队列等,界面线程拥有一个或多个窗口,拥有一个消息队列和其他专属于界面线程的元素。在讨论AfxWinMain()之前,首先要简略提一下MFC中的两个重要的类,CWinThread和CWinApp,CWinThread是用来封装界面线程的类,CWinApp是从CWinThread派生而来的。在CWinThread中,有两个很重要的虚拟函数InitInstance()和ExitInistance(),MFC的程序员应该对这两个函数应该很熟悉。在CWinApp中,增加了另外一个虚拟函数InitApplication(),讨论AfxWinMain()的主要目的是看这些函数是如何被调用的。 ---  (深入浅出MFC)
5.虚拟函数InitInstance()和ExitInistance() ------------->>>>>>>>>  应用程序启动时初始化及退出前清除变量等的地方。
6.框架应用程序将大部分时间花在CWinApp类的Run成员函数中。 初始化后, WinMain 调用 Run 以处理消息循环。
Run 遍历消息循环,并检查消息队列中的可用消息。 如果有可用的消息, Run 则调度该消息以进行操作。 如果没有可用的消息(通常为 true), Run 则调用 OnIdle 以执行你或框架可能需要完成的任何空闲时间处理。 如果没有要执行的消息和空闲处理,则应用程序将进行等待,直到发生某些情况。 当应用程序终止时, Run 调用 ExitInstance 。 OnIdle 成员函数中的数字显示了消息循环中的操作序列。    --------- (深入浅出MFC?应该是的吧,忘记了)
7.视类窗口始终覆盖在框架类窗口之上------->>>>所有操作,包括鼠标单击、鼠标移动、等操作只能由视类窗口捕获,所以框架类窗口收不到鼠标左键单机的消息
8.C++窗口类对象与窗口并不是一回事。它们之间的唯一关系是C++窗口类对象内部定义了一个变量成员,用于保存和这个C++窗口类对象相关的那个窗口的句柄。窗口销毁时,与之对应的C++窗口类对象是否销毁,要看其生命周期是否结束。但是当C++窗口类对象销毁时,与之相关的窗口会销毁。
9.很多窗口类的函数调用不需要传递窗口句柄,因为它们在内部维护了一个窗口句柄成员变量。
10.在窗口中显示按钮: 即框架上和视图上显示按钮。

 

2022-08-01(0714--拖延症晚期)

posted on   夜_归_人  阅读(642)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示