




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VC编程心得1、 MFC程序的来龙去脉MFC程序也是Windows程序,所以它也有一个WinMain,但是我们在程序中看不到它的踪影。实际上,在程序进入点之前,有一个(而且只有一个)全局对象(在Hello程序中名为theApp),这是所谓的application object,当操作系统将程序加载并激活时,这个全局对象获得配置,其构造函数会先执行,比WinMain更早。 书中所举Hello程序,是一个简单的MFC程序,其主体在于WinMain和WndProc,而这两个部分其实都有相当程度的不变性。MFC就是把有着相当固定行为的WinMain内部操作封装在CWinApp中;把有着相当固定行为的WndProc内部操作封装在CFrameWnd中。也就是说,CWinApp代表程序本体,CFrameWnd代表一个主框窗口 虽然WinMain和WndProc内部操作有相当程度的不变性,但面对不同应用程序也需有变化,所以必须以这两个类为基础,派生自己的类,并改写其中一部分成员函数。 CWinApp-取代WinMain的地位 传统上SDK程序的WinMain所完成的工作现由CWinApp的三个函数完成:virtual BOOL InitApplication( );virtual BOOL InitInstance( );virtual BOOL Run( );CFrameWnd-取代WndProc的地位 CFrameWnd主要用来掌握一个窗口引爆器-Application object 当执行Hello程序时,这个全局对象产生,于是构造函数(见APPCORE.CPP)执行起来,CWinApp之中的成员变量将因为这个全局对象的诞生而获得配置与初值,配置完成后,WinMain(MFC早已准备好,并由链接器直接加到应用程序中去的)登场。 AfxWinInit:是继CWinApp构造函数之后的第一个操作; 此后的操作是pApp-InitApplication(其中的pApp指向CMyWinApp对象,即本例中的theApp),因为CMyWinApp继承自CWinApp,而InitApplication又是CWinApp的一个虚拟函数,我们没有改写它(大部分情况下也不需要改它),所以上述操作相当于调用CWinApp:InitApplication。此程序的代码出现在APPCORE.CPP中; 继InitApplication之后,AfxWinMain调用pApp-InitInstance,InitInstance是CWinApp的一个虚拟函数(应用程序一定要改写这个函数,因为它在CWinApp中是个空函数,没有任何默任操作),我们改写了它,所以上述操作就是调有我们自己的这个InitInstance函数,我们将在该处展开我们的主窗口生命。 CMyWinApp:InitInstance一开始new了一个CMyFrameWnd对象,new会引发构造函数CmyFrameWnd:CMyFrameWnd,其中调用了CFrameWnd的成员函数Create,它将产生一个窗口。 Create函数共八个参数,第一个,指定WNDCLASS窗口类,如果放置NULL,表示要以MFC内建的窗口类产生一个标准的外框窗口(Create函数在产生窗口之前会引发窗口类的注册操作,下一段讲述这一内容);第二个,指定窗口标题;第三个,指定窗口风格,默认是WS-OVERLAPPEDWINDOW,如果你不想要窗口右上角的极大极小钮,可以改成WS-OVERLAPPED|WS-CAPTION|WS-SYSMENU|WS-THICKFRAME|WS-MINIMIZEBOX|WS-MAXIMIZEBOX,如果希望有垂直滚动条,再加上WS-VSCROLL;第四个参数,指定窗口的位置与大小,默认值rectDefault ;第五个,指定父窗口,第六个指定菜单;第七个,为扩充风格,唯有以:CreateWindowEx(而非:CreateWindow)函数才能完成,事实上,CFrameWnd:Create最终调用的正是:CreateWindowEx;第八个,是一个指向CCreateContext结构的指针,framework利用它,在具备Document/View结构的程序中初始化外框窗口,默认值NULL CFrameWnd:Create在函数中调用CreateEx(CWnd有这个成员函数,但其派生类CFrameWnd并没有,所以这里调用的实际上是CWnd:CreateEx);后者又调用PreCreateWindow虚拟函数(它在CWnd及其派生类CFrameWnd都有定义,所以实际上调用的是CFrameWnd:PreCreateWindow),这个函数调用了AfxDeferRegisterClass宏,它表示如果变量afxRegisteredClass的值显示系统已经注册了fClass 这种窗口类,MFC啥也不做,否则就调用AfxEndDeferRegisterClass(fClass)它调用两个函数完成实际的窗口类注册操作,一个是RegisterWithIcon,一个是AfxRegisterClass,准备注册之。 窗口显示与更新CMyFrameWnd:CMyFrameWnd结束后,窗口已经诞生出来;程序又回到CMyWinApp:InitInstance,于是调用ShowWindow函数令窗口显示出来,并调用UpdateWindow函数令Hello程序送出WM-PAINT CWinApp:Run-程序生命的活水源头 Run又是CWinApp的一个虚拟函数,我们没有改写它(大部分情况下也不需要改它),所以上述操作相当于调用CWinApp:Run WinMain已由MFC提供,窗口类已由MFC注册完成,连窗口函数也都由MFC提供 把消息与处理函数连接在一起:Message Map机制 MFC提供给应用程序使用的“很方便的接口”是两组宏,以Hello为例,第一个操作是在Hello.h的CMyFrameWnd加上DECLARE-MESSAGE-MAP;第二个操作是在Hello.cpp的任何位置(当然不能在函数内)使用宏 BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_COMMAND(IDM_ABOUT, OnAbout) ON_WM_PAINT() END_MESSAGE_MAP() 来龙去脉总整理 程序的诞生 Application object 产生, 内存于是获得配置,初值亦设立了。 AfxWinMain执行AfxWinInit,后者又调有AfxInitThread,把消息队列尽量加 大到96 AfxWinMain执行InitApplication。这是CWinApp的虚拟函数,我们通常不改写它 AfxWinMain执行InitInstance。这是CWinApp的虚拟函数,我们必须改写它 CMyWinApp:InitInstance “new”了一个CMyFrameWnd对象 CmyFrameWnd构造函数调用Create,产生主窗口。我们在Create参数中指定的窗口类是NULL,于是MFC根据窗口种类,自行为我们注册一个名为“AfxFrameOrView42d”的窗口类。 回到InitInstance中继续执行ShowWindow,显示窗口 执行UpdateWindow,于是发出WM-PAINT 回到AfxWinMain,执行Run,进入消息循环。 程序开始运行: 程序获得WM-PAINT消息(由CWinApp:Run中的:GetMessage循环) WM-PAINT经由:DispatchMessage送到窗口函数CWnd:DefWindowProc中。 CWnd:DefWindowProc将消息传递到消息映射表格 传递过程中发现有相符项目,于是调用项目中对应的函数。此函数是利用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之间的宏设立起来的。 标准消息的处理程序亦有标准命名,例如WM-PAINT必由OnPaint处理 程序的死亡: 使用者单击File/Close,于是发出WM-CLOSE CMyFrameWnd并没有设置WM-CLOSE处理程序,于是交给默认的处理程序 默认函数对于WM-CLOSE的处理方式是调用:DestroyWindow,并因而发出WM-DESTROY 默认的WM-DESTROY处理方式是调用:PostQuitMessage,因此发出WM-QUIT CWinApp:Run收到WM-QUIT后会结束内部之消息循环,然后调用ExitInstance,这是CWinApp的一个虚拟函数;如果CMyWinApp改写了ExitInstance,那么CWinApp:Run所调用的就是CMyWinApp:ExitInstance,否则就是CWinApp:ExitInstance 最后回到AfxWinMain,执行AfxWinTerm,结束程序 附Hello程序部分代码: Hello.cpp #include Stdafx.h #include Hello.h #include Resource.h CMyWinApp theApp; / application object /- / CMyWinApps member /- BOOL CMyWinApp:InitInstance() m_pMainWnd = new CMyFrameWnd(); m_pMainWnd-ShowWindow(m_nCmdShow); m_pMainWnd-UpdateWindow(); return TRUE; /- / CMyWinApps member /- BOOL CMyWinApp:OnIdle(LONG lCount) CMyFrameWnd* pWnd = (CMyFrameWnd*)m_pMainWnd; pWnd-IdleTimeHandler(lCount); return TRUE; /- / CMyFrameWnds member /- CMyFrameWnd:CMyFrameWnd() Create(NULL, Hello MFC, WS_OVERLAPPEDWINDOW, rectDefault, NULL, MainMenu); /- BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_COMMAND(IDM_ABOUT, OnAbout) ON_WM_PAINT() END_MESSAGE_MAP() /- void CMyFrameWnd:OnPaint() CPaintDC dc(this); CRect rect; GetClientRect(rect); dc.SetTextAlign(TA_BOTTOM | TA_CENTER); :LineDDA(rect.right/2, 0, rect.right/2, rect.bottom/2, (LINEDDAPROC) LineDDACallback, (LPARAM) (LPVOID) &dc); /- VOID CALLBACK CMyFrameWnd:LineDDACallback(int x, int y, LPARAM lpdc) static char szText = Hello, MFC; (CDC*)lpdc)-TextOut(x, y, szText, sizeof(szText)-1); for(int i=1; iDrawText(str, &rect, DT_LEFT | DT_TOP); Hello.h class CMyWinApp : public CWinApp public: virtual BOOL InitInstance(); / virtual BOOL OnIdle(LONG lCount); / OnIdle e ; /- class CMyFrameWnd : public CFrameWnd public: CMyFrameWnd(); / constructor afx_msg v
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 养护安全培训照片墙课件
- 农业学安全培训课件
- 农业农村法律法规课件
- 化工企业安全培训脚本课件
- 农业农机安全培训会课件
- 银行展厅营销活动方案(3篇)
- 化学用品安全培训内容课件
- 创造宣言课件制作
- 内科消化性溃疡课件
- 先横后竖课件
- 职高课件模板
- 【生物】第四节 激素调节课件-2025-2026学年人教版生物八年级上册
- 卫生院安全生产培训课件
- 物流紧急事件应急预案方案
- 期中专题复习-词汇句型训练-2025-2026学年 译林版2024 英语八年级上册 原卷
- 2025年全国中小学校科普知识竞赛题库(+答案)
- 2.2创新永无止境教学课件 2025-2026学年度九年级上册 道德与法治 统编版
- 矿山爆破作业安全培训课件
- 2025-2026学年九年级英语上学期第一次月考 (四川成都专用) 2025-2026学年九年级英语上学期第一次月考 (四川成都专用)解析卷
- 高陡边坡稳定性控制技术及其工程实践
- 河南省委党校在职研究生入学考试真题及答案
评论
0/150
提交评论