1、1孙鑫 VC+视频笔记列表(全)简 介第一课 Windows 程序内部运行机制 第二课 MFC 程序框架的剖析 第三课 MFC 消息映射机制和 DC 的获取 第四课 简单字处理软件 第五课 菜单编程 第六课 对话框编程 1 第七课 对话框编程 2 第八课 MFC 中各类指针的获取 第九课 应用程序外观修改 第十课 图形绘制与通用对话框 第十一课 图形保存和重绘 第十二课 文件操作第十三课 文档和串行化 第十四课 网络编程 第十五课 多线程和简单聊天室制作 第十六课 线程同步与异步套接字编程 第十七课 进程间通信 第十八课 ActiveX 控件 第十九课 动态链接库 第二十课 Hook 钩子函数
2、 2第 0 章 简介Lesson1:Windows 程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用 VC+的若干小技巧,stdcall与 cdecl 调用规范的比较,初学者常犯错误及注意事项。Lesson2:C+ 经典语法与应用,类的编写与应用,构造与析构函数,函数的重载,类的继承,函数覆盖,基类与派生类的构造函数、析构函数先后调用顺序,如何在派生类构造函数中向基类的构造函数传递参数,this 成员变量,类型转换的内幕,虚拟函数与多态性,引用和指针变量的区别与共同处。VC 工程的编译原理与过程,将工程中不同的类拆分到不同的文件中,
3、每一个类由一个.h 和.cpp 文件共同完成,头文件重复定义问题的解决,培养了学员良好的编程习惯,也为以后分析 MFC AppWizard 生成的工程奠定了良好基础。Lesson3:讲述 MFC AppWizard 的原理与 MFC 程序框架的剖析。 AppWizard 是一个源代码生成工具,是计算机辅助程序设计工具,WinMain 在 MFC 程序中是如何从源程序中被隐藏的,theApp 全局变量是如何被分配的,MFC 框架中的几个类的作用与相互关系,MFC 框架窗口是如何产生和销毁的,对窗口类的 PreCreateWidow 和 OnCreate 两个函数的着重分析,Windows 窗口与
4、 C+中的 CWnd 类的关系。 Lesson4:MFC 消息映射机制的剖析,讲述如何运用 ClassWizard, ,理解发送给窗口的消息是如何被 MFC 框架通过窗口句柄映射表和消息映射表来用窗口类的函数进行响应的。掌握设备描述表及其封装类 CDC 的使用,CDC 是如何与具体的设备发生关联的,融合具体的画图程序进行分析。如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用) 。Lesson5:掌握 CDC 的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对 CString 类的使用。通过对卡拉 OK 程序的编写,讲解定时器的使用和 DrawText 函数的巧妙运用。讲解如何使
5、用 CDC 的裁减功能。 Lesson6:菜单的工作原理及编写应用,菜单命令消息在 MFC 框架程序的几个类中的传递顺序和处理过程。标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,GetSystemMetrics 的应用,快捷弹出菜单的实现方式及其命令响应函数有效范围(与弹出菜单时所指定的父窗口有密切的关系,最底层的子窗口具有最优先的处理机会) 。动态菜单的编写,如何让程序在运行时产生新的菜单项及如何手工为这些新产生的菜单命令安排处理函数,如何在顶层窗口中截获对菜单命令的处理,更进一步掌握 CString 类的应用。Lesson7:对话框用户界面程序的编写,如何向对话框控件关联数
6、据成员及其实现机理,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数) 。如何在程序运行时产生和销毁控件。对话框控件的几种操作方式的优劣比较分析。如何实现对话框的部分收缩和展开。如何让对话框上的文本框在程序启动后立即获得焦点,如何利用 SetWindowLong 改变窗口的回调函数,通过改变文本框的默认回车处理方式进行演示。实现多个输入文本框间通过回车逐一向下传递焦点的另一种巧妙方法(用缺省按钮来处理) 。 Lesson8:逃跑按钮的巧妙实现。如何制作属性页对话框和向导对话框,融合讲解组合框(如何调整组合框的大
7、小) 、列表框、单选按钮、复选按钮等常用对话框控件的多种使用方法。如何限制用户在不满足设定的条件时切换到其他属性页和向导页。 Lesson9:如何修改 MFC AppWizard 向导生成的框架程序的外观和大小,修改图标、光标、背景的三种方法。如何增加和删除工具栏按钮,如何给应用程序增加工具栏,如何显示和隐藏工具栏。定制状态栏,在状态栏中添加时钟显示,CTime 类及其用法。在状态栏中添加进度条(主窗口产生后立即产生进度条的巧妙思想,不能在 OnCreate 函数中直接处3理,要用到自定义消息的方法) 。鼠标坐标显示,在 CView 中获取状态栏对象的几种方式。如何为应用程序添加启动画面。Le
8、sson10: 图形的绘制,如何使用自定义画笔(颜色,线宽,线型) 。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,对按钮控件的特殊处理。如何在窗口中显示一幅位图。Lesson11: 如何让 CDC 上输出的文字、图形具有保持功能,集合类 CPtrArray 的使用,CPaintDC 与 CClientDC 的区别与应用,OnPaint 与 OnDraw 在 CView 中的关系及实现内幕,滚动窗口的实现,坐标空间,映射方式,设备坐标与逻
9、辑坐标的转换。元文件设备描述表的使用,如何利用兼容 DC 实现图形的保存和再现。 Lesson12: const char *与 char * const 的区别。C 语言对文件读写的支持,FILE 指针;文本文件和二进制文件的区别。用文本方式读写文件和以二进制方式读写文件的注意事项。C+对文件读写的支持,ofstream 和 ifstream 的用法。Win32 SDK 对文件读写的支持,CreateFile 函数、WriteFile 函数、ReadFile 函数的使用;MFC 对文件读写的支持,CFile 类和 CFileDialog 的使用,文件过滤器的设置。win.ini 文件和注册表
10、的读写方式及相关知识点。Lesson13: 使用 CArchive 类对文件进行操作。MFC 框架程序提供的文件新建与打开功能内部的实现机制。如何利用 CDocument 类的串行化存储功能保存与加载数据。如何实现类对串行化的支持,CObArray 的串行化实现内幕。删除文档数据时常犯的错误。MFC 框架程序的文档类和视类的关系,以及如何获得相互的指针引用。 Lesson14: 网络的相关知识,网络程序的编写,Socket 是连接应用程序与网络驱动程序的桥梁,Socket 在应用程序中创建,通过 bind 与驱动程序建立关系。此后,应用程序送给Socket 的数据,由 Socket 交给驱动程
11、序向网络上发送出去。计算机从网络上收到与该Socket 绑定的 IP+Port 相关的数据后,由驱动程序交给 Socket,应用程序便可从该 Socket中提取接收到的数据。网络应用程序就是这样通过 socket 进行数据的发送与接收的。TCP与 UDP 的工作原理与编写过程,如何在程序中链接库文件。一个字符界面的聊天程序。 Lesson15: 多线程程序的编写,多线程应用中容易出现的问题。互斥对象的讲解,如何使用互斥对象来实现多线程的同步。如何利用命名互斥对象保证应用程序只有一个实例运行。应用多线程编写网络聊天室程序。Lesson16: 事件内核对象、关键代码段(临界区)的讲解,以及在多线程
12、同步中的应用。在 Windows 下编写基于消息的网络应用程序,掌握阻塞与非阻塞网络程序的编写,理解在Windows 平台下,采用异步选择机制可以提高网络应用程序的性能。 Lesson17: 详细讲解进程间通讯的四种方式:剪贴板、匿名管道、命名管道和邮槽。并比较分析这几种进程间通信的优点和缺点。Lesson18: ActiveX 控件的应用与工作原理。 ActiveX 控件的编写,如何为控件安排属性,方法,事件,属性页,持久性存储,控件如何通知容器自身属性的改变。如何注册控件与取消控件注册。在 VB 和 VC 中访问 ActiveX 控件。Lesson19: 动态链接库程序的编写。静态库与动态
13、库的区别,以及调用程序在链接静态库和动态库时的区别。如何利用工具查看动态链接库输出的函数,Depends 工具的使用,C+编译器名字改编技术对动态链接库输出函数的影响,extern “C“的用法,利用模块定义文件来解决 C+名字改编的问题。用 typedef 定义指向函数的指针类型,如何获得动态连接库里的函数的指针。Lesson20: Hook 编程。如何安装钩子过程,如何编写全局钩子,动态连接库里的全局4变量数据共享问题分析。ADO 数据库编程。在 VB 中利用 ADO 控件和 ADO 对象访问数据库,在 VC 中利用 ADO 技术访问数据库。 第一章 Windows 程序内部运行机制这一章
14、比较零散,笔记也很零散 一、windows 是事件驱动方式的程序设计windows 程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用 OS 某种支持,然后 OS 将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。二、消息队列每个应用程序 OS 都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS 将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。三、Windo
15、w 程序入口WinMain 函数是 Windows 程序入口点函数,由 OS 调用,当 OS 启动应用程序的时候,winmain 函数的参数由 OS 传递的。四、创建一个完整的窗口需要经过下面四个操作步骤1, 设计一个窗口类。如:WNDCLASS wndcls。2, 注册窗口类。如:RegisterClass(4, 显示及更新窗口。如:ShowWindow(),UpdateWindow();其他值得注意的地方1, 消息结构typedef struct tagMSG / msg HWND hwnd; /接收消息的窗口句柄。和哪个窗口相关联。UINT message; /消息标识。消息本身是什么。
16、WPARAM wParam; /消息的附加信息。具体取决于消息本身。 LPARAM lParam; DWORD time; /消息投递时间。 POINT pt; /消息投递时,光标在屏幕上的位置。 MSG;2, 掌握 windows 的消息机制需要掌握两方面:(1)消息本身。不同消息所代表的用户操作和应用程序的状态。(2)对于某个特定的消息来说,要让 OS 执行某个特定的功能去响应消息。3, Window 入口函数说明int WINAPI WinMain(HINSTANCE hInstance, / 当前事例句柄。HINSTANCE hPrevInstance, / 先前事例句柄。32 位系统
17、中此值都为 NULLLPSTR lpCmdLine, / 命令行指针5int nCmdShow / (窗口)显示的状态);要带参调用 WinMain,类似于命令行的功能,在 ProjectsettingDebug 页 Program arguments 项填写参数4, Windows 提供的窗口类详解typedef struct _WNDCLASS UINT style; /窗口的类型WNDPROC lpfnWndProc; /窗口过程函数指针(回调函数)int cbClsExtra; /窗口类附加字节,为该类窗口所共享。通常 0。int cbWndExtra; /窗口附加字节。通常设为 0。
18、HANDLE hInstance; /当前应用程序事例句柄。HICON hIcon; /图标句柄 LoadIcon();HCURSOR hCursor; /光标句柄 LoadCursor();HBRUSH hbrBackground; /画刷句柄 (HBRUSH)GetStockObject();LPCTSTR lpszMenuName; /菜单名字LPCTSTR lpszClassName; /类的名字 WNDCLASS;5, 消息循环:MSG msg;while(GetMessage( /进行消息(如键盘消息)转换DispatchMessage( /分派消息到窗口的回调函数处理,(OS 调
19、用窗口回调函数进行处理) 。6, 回调函数LRESULT CALLBACK WindowProc( /这里 WindowProc 是个代号名字。HWND hwnd, / handle to windowUINT uMsg, / message identifierWPARAM wParam, / first message parameterLPARAM lParam / second message parameter);说明:两种函数调用约定(_stdcall 和 _cdecl):#define CALLBACK _stdcall /_stdcall 标准调用预定,是 PASCAL 调用约
20、定,象 DELPHI 使用的就是标准调用约定#define WINAPIV _cdecl / _cdecl 是 C 语言形式的调用约定。主要区别:函数参数传递顺序 和 对堆栈的清除上。问题:除了那些可变参数的函数调用外,其余的一般都是_stdcall 约定。但 C/C+编译默然的是_cdecl 约定。所以如果在 VC 等环境中调用_stdcall 约定的函数,必须要在函数声明的时加上 _stdcall 修饰符,以便对这个函数的调用是使用_stdcall 约定(如使用6DELPHI 编写的 DLL 时候) 。(VC 中可通过这途径修改:projectsettingsc/c+categary 选”
21、Code Generation”,出现Call convention 选项,修改之)7, DC 句柄的使用(1)使用 BeginPaint(),EndPaint()对。注意只能在响应 WM_PAINT 消息时使用。(2)使用 GetDc(),ReleaseDC()对。注意他们不能在响应 WM_PAINT 中使用。8, 其它(1)函数名代表函数的首地址。(2)创建窗口的时候一定要基于已经注册的窗口类.7第二章 MFC 程序框架的剖析说明:本课对应教学视频的第三课,第二课是 C+,被我跳过去。C+ 我打算另外在用多点的篇幅来讨论。重点:MFC 运行机制提示:对于不想理解内部运行过程的,可以不看这一
22、章,可以看了后面的界面设计再回头来看这一章,可能感觉更深刻。这一次课和上一次的课的重点就是 MFC 的窗口类创建过程,而要反复说明的就是: MFC的程序和 C 语言的程序,从执行原理上说,是完全一致的。抓住这一点,那么对于理解 MFC 程序的运行机制也就相对于简单了。C 中的 main 函数就相当于 MFC 中的 WinMain 函数。感兴趣的可以利用 VC 的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。一、C 语言程序执行步骤在 C 语言中,大约的步骤如下:1, 全局变量内存分配2, 进入 main 函数二、MFC 程序的运行步骤(主要是初始化)打开一个 MFC APPWiza
23、rd(exe)工程,跟踪其执行步骤,可以发现,是以下顺序:1) CXXApp 中的全局变量定义CXXApp theApp;2) 调用 CXXApp 构造函数CXXApp :CXXApp()3) 进入 Winmain 函数(_tWinMain 为宏,值为 WinMain)_tWinMain()4) 完成初始化工作:包括窗口类注册、窗口产生、显示和更新pThread-InitInstance()对于 MFC 程序,MainFrame,View,ToolBar ,Controlbar 等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口(1) 注册窗口类AfxEndDefer
24、RegisterClass(2) 创建窗口CMainFrame:PreCreateWindow()/反复调用一次是给我们修改窗口属性的机会8CFrameWnd:Create()(3) 消息循环PumpMessage()补充 1:在 MFC 中,由于涉及到(窗口)类定义,所以定义全局变量的时候,需要进行更多的步骤。全局变量涉及到类定义(类似于 C 中的类型定义)的话,那么需要遵循以下步骤(以 MFC的窗口类为例)1) 设计一个窗口类2) 注册窗口类3) 创建窗口4) 显示及更新窗口5) 消息循环补充 2:其他需要注意的几点1, 每一个 MFC 程序,有且只有一个从 WinApp 类派生的类(应用
25、程序类) ,也只有一个从应用程序类所事例化的对象,表示应用程序本身。在 WIN32 程序当中,表示应用程序是通过 WINMAIN 入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的) 。在基于 MFC 应用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。2, _tWinMain 函数中通过调用 AfxWinMain()函数来完成它要完成的功能。 (Afx* 前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序) 。3, 设计窗口类:在 MFC 中事先设计好了几
26、种缺省的窗口类,根据不同的应用程序的选择,调用 AfxEndDeferRegisterClass()函数注册所选择的窗口类。4, PreCreateWindow()是个虚函数 ,如果子类有则调用子类的。5, CreateWindowEx()函数参数与 CREATESTRUCT 结构体成员完全一致,CreateWindowEx()函数与 CREATESTRUCT 结构体参数的对应关系,使我们在创建窗口之前通过可 PreCreateWindow(cs)修改 cs 结构体成员来修改所要的窗口外观。6,注意两个函数。:TranslateMessage(pDocTemplate = new CSingl
27、eDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CTEDoc),RUNTIME_CLASS(CMainFrame), / main SDI frame windowRUNTIME_CLASS(CTEView);AddDocTemplate(pDocTemplate);/增加到模板补充 3:本课涉及到 MFC 函数的源文件位置根目录找到您安装 VC98 下 MFC 的位置,比如我的机子上为:D:Program FilesMicrosoft Visual StudioVC98MFC。下面提供的就是相对路径了。CWinApp 构造函数: MFCSRCAPPCORE.
28、CPPAfxWinMain:MFCSRCWINMAIN.CPPAfxEndDeferRegisterClass: MFCSRCAPPCORE.CPPCFrameWnd:PreCreateWindow()函数所在文件:MFCSRCWINFRM.CPPCFrameWnd:Create()函数路径: MFCSRCWINFRM.CPPCWnd:CreateEx()函数路径:MFCSRC WINCORE.CPPCWinThread:Run()方法路径:MFCSRCTHRDCORE.CPP10第三章 MFC 消息映射机制和绘图 DC 的获取我们假设您已经:1,知道如何创建一个单文档的 App Wizard
29、2,知道 C+ 类、函数重载等简单知识3,知道如何给 View 类或者 Doc 文档添加成员变量4,会用 MFC 的 IDE 调试工具最好,那么本文的程序您可以 copy 去调试我们在上一节讲了 MFC 框架 App 类、View 类、MainFrame 类和 Doc 类的关系,那么,基于消息的 windows MFC 程序设计是如何进行消息映射的呢?在进行下一节之前,我们来复习一下。对于一个 MFC APPWizard 运用程序,CMainFrame 和 View 是窗口类,并且是父子关系,Doc 一般用于数据的加载和存储,View 用于图像的显示,App 中是包括一些(窗口)初始化之类的东
30、西。我们开始这一节的内容。一、 消息映射机制windows 程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用 OS 某种支持,然后 OS 将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。在左边 View 类处点右键,在出现的菜单里点击“Add Windows Message Handler”,在出现的对话框里选择“WM_LBUTTONDOWN ”,添加消息映射函数。回到原文件,我们将看到三处进行了修改:1, 在头文件(View.h)中声明消息响应函数原型。/AFX_MSG(CDrawView) /注释宏afx_msg void OnLButtonDown(UINT nFlags, CPoint point);/AFX_MSG /注释宏afx_msg 宏表示声明的是一个消息响应函数。2, 在源文件(View.cpp)中进行消息映射。BEGIN_MESSAGE_MAP(CDrawView, CView)/AFX_MSG_MAP(CDrawView)ON_WM_LBUTTONDOWN()