已阅读5页,还剩72页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第0章 你一定要知道的本书结构需要的技术基础一些名词的统一理解范例程序说明在那个MFC程序文件夹里!其他章节的例子说明见原书!第一章win32基本程序概念win32程序开发流程windows程序分为”程序代码”和”UI(用户接口)资源”两部分, 两部分最后以LINKER链接器整合为一个完整的exe档案。所谓UI资源是指功能菜单, 对话框外貌, 程序图标, 光标开关等等东西, 这此UI资源的实际内容(二进制代码)是借助各种工具产生, 并以各种扩展名的文件存在的, 如.ico, .bmp, .cur等等, 程序员必须在一个所谓的资源描述文档(.rc)中描述它们, RC编译器(RC.EXE)读取RC文件的描述后将所有UI资源文件集中制作出一个.RES文件。所谓的程序代码就是指的头文件.h和源文件.cpp了,它们经过编译器的编译形成.obj文件。.res文件与.obj文件还有.def文件经过链接器的作用结合在一起, 这才是一个完整的windows可执行文件。win32程序需要什么函数库(.lib)C Runtimes函数:Windowns API:需要什么头文件如果想用命令行的方式来编译和运行Windows程序,则在环境变量里应该设好这些东西。但是我设的不成功。windows程序的观点以消息为基础,以事件驱动之message based,event driven见下图:一个具体而微的win32程序一个小例子关于makefile关于具体的例子:Make file:Generic的头文件Generic源文件:Winmain入口函数主要的工作:注意这里包含了window.h头文件,这样就可以调用操作系统的api了。这里的黑体的函数都是Win32的Api函数。InitApplication初始化应用程序,注册窗口类。InitInstance初始化实例,利用前面注册好的窗口类产生窗口。GetMessage进行消息循环。资源文件,会被编译成res文件。例程序说明:Windows应用程序的执行过程牵涉到操作系统执行应用程序的过程!:两个阶段:应用程序被加载阶段消息循环阶段应用程序衩加载的阶段:程序的入口点WinMain函数:注意这里包含了window.h头文件,这样就可以调用操作系统的api了。这里的黑体的函数都是Win32的Api函数。Winmain函数中的主要工作:InitApplication初始化应用程序,注册窗口类。InitInstance初始化实例,利用前面注册好的窗口类产生窗口,并将窗口显示出来。GetMessage进行消息循环。应用程序被加载完毕之后就进入了消息循环:关于消息消息循环背后有太多的自动化了!窗口中的一个控件有一个ID,当发生鼠标事件的时候,就产生一个消息,将产生的消息对象中加入此消息属于哪个窗口的信息,即将这条消息封装在一个消息结构体中,然后OS利用User模块获得这个消息,并将消息放在应用程序的消息队列里。应用程序的WinMain函数通过消息循环中的GetMessage函数获得这个消息,得到消息产生的容器类,然后再根据这个窗口类的窗口函数信息将消息交给回调函数。循环消息循环的各个阶段产生消息阶段OS将消息放在应用程序队列里应用程序WinMain函数通过消息循环获取消息阶段应用程序WinMain函数通过消息循环dispatch消息阶段消息交给了回调函数处理阶段。消息结构体:typedef struct tagMSG HWND hwnd; /消息结构体中保存的关于产生消息的窗口的信息 UINT message; /代表的是消息!eg: WM_OK WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; MSG, *PMSG;typedef struct _WNDCLASS UINT style; WNDPROC lpfnWndProc;/窗口类注册时在窗口类中保存的关于回调函数的信息 int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; WNDCLASS, *PWNDCLASS;关于窗口函数回调函数:关于回调函数中的消息映射:将窗口函数中的内容设计得更加模块化:将这里的例程序与VC下用MFC生成的程序进行对比:1. 一个win32的程序的结构:入口是winMain函数,在winMain函数里主要的工作有:InitApplication初始化应用程序,注册窗口类。InitInstance初始化实例,利用前面注册好的窗口类产生窗口,并将窗口显示出来。GetMessage进行消息循环,交给了窗口回调函数来执行。消息的产生是利用资源文件.rc中的资源句柄。2一个在VC下用MFC生成的程序:由appwizard生成应用程序,不用初始化应用程序,注册窗口类,也不用初始化实例,要做的是写好各个窗口和对话框类的各个函数,这些函数包括了类的初始化函数,还有的是消息响应函数。但是其实整个程序的运行还是和win32程序一样,只不过是因为MFC将好多东西都隐藏了。注意在MFC中将消息映射进行了结构化的封装,即在MFC中看不到回调函数,只能看到模块化之后的OnCommand等函数。因此我们一定要注意消息映射。这个消息映射机制的作用是注册消息地图,使程序更加地结构化。在MFC中也看不到WinMain函数,所以InitApplication,InitInstance ,GetMessage,都是在背后完成的,在MFC中我们能看到的是一些窗口类,对话框类。要注意消息的产生是利用窗口中相应控件的句柄!关于MFC下的消息映射有四个地方相关:自定义消息:例如StudentInfo老师的那个程序里面:第一, 头文件中1:#define WM_ADD_NEW WM_USER+5/自定义的新增学生档案消息#define WM_MODIFY_OLD WM_USER+6/自定义的修改学生档案消息第二, 头文件中2:class CStudentInfoView : public CListView。protected:/AFX_MSG(CStudentInfoView)afx_msg void OnDblclk(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnAddNewCommand();afx_msg void OnMenuFileread();afx_msg void OnMenuFilewrite();afx_msg void OnMenuLstudent();/AFX_MSGafx_msg void OnAddNew(WPARAM wParam, LPARAM lParam);afx_msg void OnModifyOld(WPARAM wParam, LPARAM lParam);DECLARE_MESSAGE_MAP();第三, 源文件中1:/消息映射宏BEGIN_MESSAGE_MAP(CStudentInfoView, CListView)/AFX_MSG_MAP(CStudentInfoView)ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)ON_COMMAND(ID_MENU_ADDNEW, OnAddNewCommand)ON_COMMAND(ID_MENU_FILEREAD, OnMenuFileread)ON_COMMAND(ID_MENU_FILEWRITE, OnMenuFilewrite)ON_COMMAND(ID_MENU_LSTUDENT, OnMenuLstudent)/AFX_MSG_MAPON_MESSAGE(WM_ADD_NEW,OnAddNew)/新增学生档案的消息映射ON_MESSAGE(WM_MODIFY_OLD,OnModifyOld)/修改学生档案的消息映射END_MESSAGE_MAP()第四, 源文件中2:/新增学生档案 菜单命令消息void CStudentInfoView:OnAddNewCommand() / TODO: Add your command handler code here。/自定义的修改学生档案消息响应函数void CStudentInfoView:OnModifyOld(WPARAM wParam, LPARAM lParam)。关于自定义消息的调用:if (str=确认)m_pView-PostMessage(WM_ADD_NEW,IDOK);if (str=修改)m_pView-PostMessage(WM_MODIFY_OLD,IDOK);而利用wizard生成的按键响应函数则自动将资源句柄作为了消息的message(UINT类型)参数。生成相关语句在四处:第一处 资源文件.rc中:IDD_STUDY1_DIALOG DIALOGEX 0, 0, 320, 200STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENUEXSTYLE WS_EX_APPWINDOWCAPTION study1FONT 9, 宋体BEGIN DEFPUSHBUTTON 确定,IDOK,260,7,50,14 PUSHBUTTON 取消,IDCANCEL,260,23,50,14 PUSHBUTTON Button1,IDC_BUTTON1,131,66,79,31END第二处 在对话框头文件中:class CStudy1Dlg : public CDialog。/ Implementationprotected:HICON m_hIcon;/ Generated message map functions/AFX_MSG(CStudy1Dlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();virtual void OnOK();afx_msg void OnButton1();/AFX_MSGDECLARE_MESSAGE_MAP();第三处 对话框源文件中1:BEGIN_MESSAGE_MAP(CStudy1Dlg, CDialog)/AFX_MSG_MAP(CStudy1Dlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON1, OnButton1)/AFX_MSG_MAPEND_MESSAGE_MAP()第四处 对话框源文件中2:void CStudy1Dlg:OnButton1() / TODO: Add your control notification handler code hereMessageBox(i love you);关于对话框的运行:资源描述文件Windows程序的生与死空闲时间的处理Console程序Console程序与dos程序的差别注意nmake *.mak指令的使用方法首先要搭建好VC的环境。怎么搭呢?我的不对什么是C Runtime 函数库的多线程版本在VC中的配置如下: Project-Setting-C/C+里的Project Options里面。进程与执行线程 Process and Thead核心对象进程与线程的区别什么是核心对象:上面这句话说明了process与thead的区别中,即进程与线程的区别一个进程的诞生与死亡操作系统调用一个应用程序的过程。操作系统调用一个应用程序的过程:分为下面几个阶段,其中线程的诞生见后面一两节,关于windows程序的调用,见第一章中的windows应用程序的执行过程一节,对应下面的6,7,8,9。关于应用程序内存的分配见第二章的四种不同对象的生存方式一节。产生子进程CreateProcess的返回值是bool,创建进程成功的时候此函数会将产生的进程对象和执行线程对象的句柄保存在最后一个参数之中!例如一个实例:最后一个参数是一个指向PROCESS_INFORMATION结构的指针:当一个进程想结束自己的生命的时候,只要调用:一个执行线程的诞生与死亡注意CreateThread函数的返回值是产生的线程的句柄HANDLE类型,创建线程成功的时候将这个线程的ID保存在第五个参数里面。什么是执行线程函数呢?举一个实例:以_beginthreadex取代CreateThread执行线程优先级(Priority)还有微调。多线程程序设计实例部分代码:。case WM_COMMAND: switch (LOWORD(wParam) case IDM_RESUME: / 琵 threads 秨磅 。 case IDM_SUSPEND: / 既氨 threads 磅 。第二章 C+的重要性质虚拟函数与多态性三个结论在MFC中出现的重要的虚拟函数与多态性应用的场景:关于纯虚拟函数抽象类别不能产生出对象实体,但是我们可以拥有指向抽象类型的指针,以便于操作抽象类型的各个衍生类别。类别与对象大重要,重要,很重要解剖虚拟函数是怎样得到实现的?这个问题牵涉到一个对象的内存空间结构。重要,重要,很重要注意:这里的意思是,类的普通成员函数不在类对象的内存当中!但是这个普通成员函数加了一个参数(this指针!)Object Slicing与虚拟函数重要,重要,很重要虚拟函数另一个极重要的行为模式:关于类型转换如果强制类型转换的对象是指针:没有进行Object Slicing,只是指针的类型转换了而已,只能通过指针调用转换后的类别中的接口函数。但是由于vptr没有改变的原因,如果函数是虚拟函数,则仍然可以通过转换后的指针来调用派生类的接口函数。如果强制类型转换的对象是一个对象:进行了Object Slicing,原来的对象被转换了,生成了一个临时对象,意味着vptr已经改变了,只能通过这个对象调用转换后的类型的接口函数举一个例子:有如下的继承关系:。执行的结果如下:静态成员(变量与函数)什么情况下要静态成员:静态成员变量的初始化:静态成员变量的读取三种方式:第三种方式:关于静态成员函数C程序的生与死:兼谈构造式与析构式对于四种不同的对象,他们的构造式和析构式调用的时机是不同的四种不同的对象生存方式(in stack, in heap, global, local static操作系统调用一个应用程序的过程(序)操作系统调用一个应用程序的过程(序):当操作系统创建好了进程对象和线程对象之后,开始调用Startup Code,然后进入WinMain函数,于是就开始根据程序的需要进行分配内存空间了。只构造一次!局部静态变量。关于Unwinding执行时期类别信息(RTTI这里有关于MFC的RTTI的实现!)只有新近的较先进的编译器如Visual C+ 4.0和Borland C+ 5.0才开始广泛支持。以下是一个实例:。关于在MFC中的RTTI:动态生成(Dynamic Creation)关于在MFC中的动态生成与持久性:异常处理(Exception Handling)C+中导入了三个新的exception保留字:try, catch和throw一个例子MFC中的exception机制MFC的exceptions机制是以宏和exception types为基础。这些宏类似C+的exception保留字,动作也满像。以下是一个具体应用时的例子:Template为什么需要用到Template当重载函数显得太多余的时候,因为它们意味着你必须在你的程序的许多地方维护完全相同的算法。我们可以利用template来让我们有比较清爽的程序代码。C+的template有两种,一种针对function,另一种针对classTemplates的编译与联结在C+ primer里也有关于这段的说明。第三章 MFC六大关键技术之仿真六大技术MFC类别阶层MFC程序的初始化过程重要,重要,很重要,这里有虚拟函数的重要特性的一个应用:this指针指向的对象的类型决定了虚拟函数的调用(通过vptr)!函数在调用的过程中传递的不只是参数而已,传递的还有this指针!MFC程序也是一个windows程序,它的内部一定也像第一章所述的那样,有窗口注册动作,有窗口产生动作,有消息循环动作,也有窗口函数。如上所述,一个MFC程序的执行过程如下(参照操作系统调用应用程序的过程):(1) 操作系统通过shell模块创建一个进程(2) 分配4GB的地址空间给这个进程(3) 将应用程序及其所需要的.dll文件,lib装载到这个已经分配好的地址空间里面(4) 创建一个主执行线程(5) 设置好线程的context(6) 为线程分配好堆栈空间(7) 操作系统的shell模块判断应用程序的类型,识别得到是一个windows程序(8) 系统调用C Runtime函数库里的Startup Code(9) Startup Code初始化全局对象theApp(10) Startup Code调用应用程序的WinMain函数a) 在WinMain里通过全局函数AfxGetApp获取全局对象theAppb) 利用得到的theApp对象指针来调用InitApplication(),初始化应用程序,做的工作主要是定义各个窗口类,并且对这些窗口类进行注册。c) 利用得到的theApp对象指针来调用InitInstance(),初始化应用程序实例,做的工作主要是创建各个窗口对象,并且将它们显示出来。(11) 进入消息循环用VC生成的基于MFC的应用程序里有一个App类,它里面也只改写了InitInstance()这里的Run()函数使应用程序进入了消息循环。这里有关于虚拟函数的一个重要特征,一定要注意:CFrameWnd的Create函数中调用了CreateEx函数,这时这个函数所附带的this指针是CFrameWnd类的。由于CreateEx是虚拟函数,CFrameWnd类未改写,所以调用CWnd类的CreateEx,注意这时CWnd的CreateEx函数所附带的指针是CFrameWnd类的,又由于PreCreateWindwow函数被CFrameWnd类所改写,所以调用PreCreateWindwow()的时候,会调用CFrameWnd类的PreCreateWindwow所以可以得出一个结论:theApp对象调用InitInstance时,定义了CFrame对象(因为它是应用程序的框架),而CFrame的构造函数其实就是调用它的PreCreateWindwow函数。RTTI(运行时类型识别)需求实现的思路类别型录网与CRuntimeClass具体的实现DECLARE_DYNAMIC /IMPLEMENT_DYNAMIC宏注意这里的_init_CView是一个对象, 而不是一个函数调用, AFX_CLASSINIT是一个类, 这里调用了这个类的构造函数, 这个构造函数的作用是将CRuntimeClass的static CRuntimeClass* pfirstClass; 成员和m_pNextClass成员进行了初始化:调用方法:IsKindOf( 类型识别函数)注意这里的GetRuntimeClass()是虚拟函数,返回的是最后一个构造的对象。动态生成(Dynamic Creation)基础有了,做什么都好,有了上述的类别型录网,各种应用纷至沓来,一个应用就是解决棘手的动态生成问题。实现思路在CRuntimeClass结构体中加一个成员函数具体的实现:注意在MFC中没有这个Load函数。这里要注意这里的CreateObject函数和CRuntimeClass结构体中的CreateObject函数是不一样的!后者代表的是CRuntimeClass当中的CreateObject函数,我们的目的是通过这个结构体的函数CreateObject来调用每一个类中具体的CRuntimeCl
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 水泥混凝土路面施工质量控制方案
- 食品标签合规自查报告范文
- 法律助理工作职责与案例分析
- 2025甘肃陇南市科技技工学校招聘3人考试笔试参考题库附答案解析
- 人事专员岗位职责及工作流程详解
- 初中历史与社会人教版 (新课标)九年级上册2.第一次世界大战教学设计
- 北京理工大学出版社教学设计-2025-2026学年中职中职专业课财务会计类73 财经商贸大类
- 2025下半年四川乐山市沐川县赴电子科技大学考核招聘急需紧缺专业技术人员1人考试笔试参考题库附答案解析
- 医院感染控制与防护措施报告
- 2025下半年广东东莞市招聘事业编制教师87人(华东地区专场)笔试考试参考试题及答案解析
- 《为什么家庭会生病》读书笔记思维导图PPT模板下载
- 八个正确的心态
- 培训2.0材料mncrm pcmtpm财务部分
- SB/T 11016-2013足部保健按摩服务规范
- GB/T 4062-2013三氧化二锑
- 科学出版社专著编写要求
- DB63-T 1806-2020金属非金属露天矿山企业安全生产风险分级管控和隐患排查治理实施指南
- 江苏省南通市通州区川姜镇公开招考4名人力资源和社会保障基层公共服务平台工作人员【共500题附答案解析】模拟试卷
- 企业风险管理-战略与绩效整合(中文版)
- 董事、监事的责任、权利和义务
- 阀门安装施工方案
评论
0/150
提交评论