VC++深入详解学习笔记(非常全面)_第1页
VC++深入详解学习笔记(非常全面)_第2页
VC++深入详解学习笔记(非常全面)_第3页
VC++深入详解学习笔记(非常全面)_第4页
VC++深入详解学习笔记(非常全面)_第5页
已阅读5页,还剩68页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、孙鑫孙鑫VC+舰频笔记歹U表(全)简介第一课Windows程序内部运行机制第二课MFC程序框架的剖析第三课MFC消息映射机制和DC的获取第四课简单字处理软件第五课菜单编程第六课对话框编程1第七课对话框编程2第八课MFC中各类指针的获取第九课应用程序外观修改第十课图形绘制与通用对话框第十一课图形保存和重绘第十二课文件操作第十三课文档和串行化第十四课网络编程第十五课多线程和简单聊天室制作第十六课线程同步与异步套接字编程第十七课进程间通信第十八课ActiveX控件第十九课动态链接库第二十课Hook钩子函数第0章简介Lessonl:Windows程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息

2、队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC+的若干小技巧,stdcall与cdecl调用规范的比较,初学者常犯错误及注意事项。Lesson2:C+蟀典语法与应用,类的编写与应用,构造与析构函数,函数的重载,类的继承,函数覆盖,基类与派生类的构造函数、析构函数先后调用顺序,如何在派生类构造函数中向基类的构造函数传递参数,this成员变量,类型转换的内幕,虚拟函数与多态性,引用和指针变量的区别与共同处。VC工程的编译原理与过程,将工程中不同的类拆分到不同的文件中,每一个类由一个.h和.cpp文件共同完成,头文件重复定义问题的解决,培养了学员良好的编程习惯,也为以后分析MFCAppW

3、izard生成的工程奠定了良好基础。Lesson3:讲述MFCAppWizard的原理与”5牌序框架白剖析。AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC匡架中的几个类的作用与相互关系,MFC1架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C+用白CWnct的关系。Lesson4:MFCW息映射机制的剖析,讲述如彳S运用ClassWizard,理解发送给窗口的消息是如何被MFC1架通过窗口句柄映射表和消息映

4、射表来用窗口类的函数进行响应的。掌握设备描述表及其封装类CDC勺使用,CD比如何与具体的设备发生关联的,融合具体的画图程序进行分析。如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用)。Lesson5:掌握CDC勺文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。通过对卡拉OK程序的编写,讲解定时器的使用和DrawText函数的巧妙运用。讲解如何使用CDC勺裁减功能。Lesson6:菜单的工作原理及编写应用,菜单命令消息在MFC匡架程序的几个类中的传递顺序和处理过程。标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,GetSystemMetric

5、s的应用,快捷弹出菜单的实现方式及其命令响应函数有效范围(与弹出菜单时所指定的父窗口有密切的关系,最底层的子窗口具有最优先的处理机会)。动态菜单的编写,如何让程序在运行时产生新的菜单项及如何手工为这些新产生的菜单命令安排处理函数,如何在顶层窗口中截获对菜单命令的处理,更进一步掌握CString类的应用。Lesson7:对话框用户界面程序的编写,如何向对话框控件关联数据成员及其实现机理,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数)。如何在程序运行时产生和销毁控件。对话框控件的几种操作方式的优劣比较分析。如何

6、实现对话框的部分收缩和展开。如何让对话框上的文本框在程序启动后立即获得焦点,如何利用SetWindowLong改变窗口的回调函数,通过改变文本框的默认回车处理方式进行演示。实现多个输入文本框间通过回车逐一向下传递焦点的另一种巧妙方法(用缺省按钮来处理)。Lesson8:逃跑按钮的巧妙实现。如何制作属性页对话框和向导对话框,融合讲解组合框(如何调整组合框的大小)、列表框、单选按钮、复选按钮等常用对话框控件的多种使用方法。如何限制用户在不满足设定的条件时切换到其他属性页和向导页。Lesson9:如何修改MFCAppWizard向导生成的框架程序的外观和大小,修改图标、光标、背景的三种方法。如何增加

7、和删除工具栏按钮,如何给应用程序增加工具栏,如何显示和隐藏工具栏。定制状态栏,在状态栏中添加时钟显示,CTime类及其用法。在状态栏中添加进度条(主窗口产生后立即产生进度条的巧妙思想,不能在OnCreate函数中直接处理,要用到自定义消息的方法)。鼠标坐标显示,在CView中获取状态栏对象的几种方式。如何为应用程序添加启动画面。Lesson10:图形的绘制,如何使用自定义画笔(颜色,线宽,线型)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜

8、色,对按钮控件的特殊处理。如何在窗口中显示一幅位图。Lessonll:如何让CDC输出的文字、图形具有保持功能,集合类CPtrArray的使用,CPaintDC与CClientDC的区别与应用,OnPaint与OnDraw在CView中的关系及实现内幕,滚动窗口的实现,坐标空间,映射方式,设备坐标与逻辑坐标的转换。元文件设备描述表的使用,如何利用兼容DC实现图形的保存和再现。Lesson12:constchar*与char*const的区别。C语言对文件读写的支持,FILE指针;文本文件和二进制文件的区别。用文本方式读写文件和以二进制方式读写文件的注意事项。C+以寸文件读写的支持,ofstre

9、am和ifstream的用法。Win32SDK对文件读写的支持,CreateFile函数、WriteFile函数、ReadFile函数的使用;MFC对文件读写的支持,CFile类和CFileDialog的使用,文件过滤器的设置。win.ini文件和注册表的读写方式及相关知识点。Lesson13:使用CArchive类对文件进行操作。MFC1架程序提供的文件新建与打开功能内部的实现机制。如何利用CDocument类的串行化存储功能保存与加载数据。如何实现类对串行化的支持,CObArray的串行化实现内幕。删除文档数据时常犯的错误。MFC匡架程序的文档类和视类的关系,以及如何获得相互的指针引用。L

10、esson14:网络的相关知识,网络程序的编写,Socket是连接应用程序与网络驱动程序的桥梁,Socket在应用程序中创建,通过bind与驱动程序建立关系。此后,应用程序送给Socket的数据,由Socket交给驱动程序向网络上发送出去。计算机从网络上收到与该Socket绑定的IP+Port相关的数据后,由驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据。网络应用程序就是这样通过socket进行数据的发送与接收的。TCP与UDP的工作原理与编写过程,如何在程序中链接库文件。一个字符界面的聊天程序。Lesson15:多线程程序的编写,多线程应用中容易出现的问题。互斥对象

11、的讲解,如何使用互斥对象来实现多线程的同步。如何利用命名互斥对象保证应用程序只有一个实例运行。应用多线程编写网络聊天室程序。Lesson16:事件内核对象、关键代码段(临界区)的讲解,以及在多线程同步中的应用。在Windows下编写基于消息的网络应用程序,掌握阻塞与非阻塞网络程序的编写,理解在Windows平台下,采用异步选择机制可以提高网络应用程序的性能。Lesson17:详细讲解进程间通讯的四种方式:剪贴板、匿名管道、命名管道和邮槽。并比较分析这几种进程间通信的优点和缺点。Lesson18:ActiveX控件的应用与工作原理。ActiveX控件的编写,如何为控件安排属性,方法,事件,属性页

12、,持久性存储,控件如何通知容器自身属性的改变。如何注册控件与取消控件注册。在VB和VC中访问ActiveX控件。Lesson19:动态链接库程序的编写。静态库与动态库的区别,以及调用程序在链接静态库和动态库时的区别。如何利用工具查看动态链接库输出的函数,Depends工具的使用,C+编译器名字改编技术对动态链接库输出函数的影响,externC的用法,利用模块定义文件来解决C+W字改编的问题。用typedef定义指向函数的指针类型,如何获得动态连接库里的函数的指针。Lesson20:Hook编程。如何安装钩子过程,如何编写全局钩子,动态连接库里的全局变量数据共享问题分析。ADO数据库编程。在VB

13、中利用ADO控件和ADO寸象访问数据库,在VC中利用ADO支术访问数据库。第一章Windows程序内部运行机制这一章比较零散,笔记也很零散1、 、windows是事件驱动方式的程序设计windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。2、 消息队列每个应用程序OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程

14、序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。3、 Window程序入口WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。4、 创建一个完整的窗口需要经过下面四个操作步骤1,设计一个窗口类。如:WNDCLASSwndcls2,注册窗口类。如:RegisterClass(&wndcls)。3,创建窗口。如:CreateWindow(),CreateWindowEX();4,显示及更新窗口。如:ShowWindow(),UpdateWindow();其他值得注意的地方1,消息结构接

15、收消息的窗口句柄。和哪个窗口相关联。 消息标识。消息本身是什么。 消息的附加信息。具体取决于消息本身。消息投递时间。 消息投递时,光标在屏幕上的位置。typedefstructtagMSG/msgHWNDhwnd;/UINTmessage;/WPARAMwParam;/LPARAMlParam;DWORDtime;/POINTpt;/MSG;2,掌握windows的消息机制需要掌握两方面:(1)消息本身。不同消息所代表的用户操作和应用程序的状态。(2)对于某个特定的消息来说,要让。砒行某个特定的功能去响应消息。3,Window入口函数说明intWINAPIWinMain(HINSTANCE h

16、Instance, / HINSTANCE hPrevInstance, LPSTR lpCmdLine, / int nCmdShow /当前事例句柄。先前事例句柄。32位系统中此值都为NULL命令行指针);要带参调用 WinMain, 类似于命令行的功能,在arguments 项填写参数4, Windows 提供的窗口类详解Projectesetting eDebug 页 e Programtypedef struct _WNDCLASS UINT style; /窗口的类型WNDPROC lpfnWndProc; /窗口过程函数指针(回调函数)(窗口)显示的状态int cbClsExtr

17、a; /int cbWndExtra; /HANDLE hInstance; /HICON hIcon; /HCURSOR hCursor; /窗口类附加字节,为该类窗口所共享。通常0。窗口附加字节。通常设为0。当前应用程序事例句柄。图标句柄LoadIcon();光标句柄LoadCursor();画刷句柄 (HBRUSH)GetStockObject();菜单名字类的名字HBRUSHhbrBackground;/LPCTSTRlpszMenuName;/LPCTSTRlpszClassName;/WNDCLASS;5,消息循环:MSGmsg;while(GetMessage(&msg,.)/从

18、消息队列中取出一条消息TranslateMessage(&msg);/进行消息(如键盘消息)转换DispatchMessage(&msg);/分派消息到窗口的回调函数处理,(OS调用窗口回调函数进行处理)。6,回调函数LRESULTCALLBACKWindowProc(/这里WindowProc是个代号名字。HWNDhwnd,/handletowindowUINTuMsg,/messageidentifierWPARAMwParam,/firstmessageparameterLPARAMlParam/secondmessageparameter);说明:两种函数调用约定(_stdcall和_

19、cdecl):#defineCALLBACK_stdcall/_stdcall标准调用预定,是PASCAL调用约定,象DELPHI使用的就是标准调用约定#defineWINAPIV_cdecl/_cdecl是C语言形式的调用约定。主要区别:函数参数传递顺序和对堆栈的清除上。问题:除了那些可变参数的函数调用外,其余的一般都是_stdcall约定。但C/C+编译默然的是_cdecl约定。所以如果在VC等环境中调用_stdcall约定的函数,必须要在函数声明的时加上_stdcall修饰符,以便对这个函数的调用是使用_stdcall约定(如使用DELPHI编写的DLL时候)。(VC中可通过这途径修改:

20、projectesettings也/c+scategary选CodeGeneration,出现Callconvention选项,修改之)7,DC句柄的使用(1)使用BeginPaint(),EndPaint()对。注意只能在响应WM_PAIN稍息时使用。(2)使用GetDc(),ReleaseDC()对。注意他们不能在响应WM_PAIN并使用。8,其它(1)函数名代表函数的首地址。(2)创建窗口的时候一定要基于已经注册的窗口类.第二章MFC程序框架的剖析说明:本课对应教学视频的第三课,第二课是C+,被我跳过去。C+钺打算另外在用多点的篇幅来讨论。重点:MFC1行机制提示:对于不想理解内部运行过

21、程的,可以不看这一章,可以看了后面的界面设计再回头来看这一章,可能感觉更深刻。这一次课和上一次的课的重点就是MFC勺窗口类创建过程,而要反复说明的就是:MFC勺程序和C语言的程序,从执行原理上说,是完全一致的。抓住这一点,那么对于理解MFO序的运行机制也就相对于简单了。C中的main函数就相当于MFC白WWinMain函数。感兴趣的可以利用VC的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。一、C语言程序执行步骤在C语言中,大约的步骤如下:1, 全局变量内存分配2, 进入main函数二、MFCg序的运行步骤(主要是初始化)打开一个MFCAPPWizard(exe)工程,跟踪其执行步

22、骤,可以发现,是以下顺序:1) CXXApp中的全局变量定义CXXApptheApp;2) 调用CXXApp勾造函数CXXApp:CXXApp()3) 进入Winmain函数(_tWinMain为宏,值为WinMain)_tWinMain()4) 完成初始化工作:包括窗口类注册、窗口产生、显示和更新pThread-InitInstance()对于“5组序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口(1) 注册窗口类AfxEndDeferRegisterClass(2)创建窗口CMainFrame

23、:PreCreateWindow()/反复调用一次是给我们修改窗口属性的机会CFrameWnd:Create()(3)消息循环PumpMessage()补充1:在MFC中,由于涉及到(窗口)类定义,所以定义全局变量的时候,需要进行更多的步骤。全局变量涉及到类定义(类似于C中的类型定义)的话,那么需要遵循以下步骤(以MFC的窗口类为例)1)设计一个窗口类2) 注册窗口类3) 创建窗口4) 显示及更新窗口5) 消息循环补充2:其他需要注意的几点1,每一个MFC序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身。在WIN32程序当中,表示应

24、用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。在基于MFCS用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。2,_tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。3,设计窗口类:在MF计事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。4,Pr

25、eCreateWindow()是个虚函数,如果子类有则调用子类的。5,CreateWindowEx()函数参数与CREATESTRUCT构体成员完全一致,CreateWindowEx()函数与CREATESTRUC转构体参数的对应关系,使我们在创建窗口之前通过可PreCreateWindow(cs)修改cs结构体成员来修改所要的窗口外观。6,注意两个函数。:TranslateMessage(&m_msgCur)函数进行消息(如键盘消息)转换:DispatchMessage(&m_msgCur)函数分派消息到窗口的回调函数处理(实际上分派的消息经过消息映射,交由消息响应函数进行处理。)7,可以认

26、为View类窗口是CMainFram类窗口的子窗口。DOCumen我是文档类。DOC-VIEW结构将数据本身与它的显示分离开。文档类用于数据的存储,加载;视类用于数据的显示,修改8,CTEApp:InitInstance()函数中通过文档模板将文档类,视类,框架类的有机组织一起。语句如下:CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CTEDoc),RUNTIME_CLASS(CMainFrame),/mainSDIframewindowRUNTIME

27、_CLASS(CTEView);AddDocTemplate(pDocTemplate);/增加到模板补充3:本课涉及到MFC数的源文件位置根目录找到您安装VC98下MFC勺位置,比如我白机子上为:D:ProgramFilesMicrosoftVisualStudioVC98MFC。下面提供的就是相对路径了。CWinApp构造函数:MFCeSRCAPPCORE.CPPAfxWinMain:MFCSRQWINMAIN.CPPAfxEndDeferRegisterClass:MFCeSR金APPCORE.CPPCFrameWnd:PreCreateWindow()函数所在文件:MFCSRCWINF

28、RM.CPPCFrameWnd:Create()函数路径:MFCSRCWINFRM.CPPCWnd:CreateEx()函数路径:MFQSRCWINCORE.CPPCWinThread:Run()方法路径:MFCSRCTHRDCORE.CPP第三章MFC消息映射机制和绘图DC的获取我们假设您已经:1 ,知道如何创建一个单文档的AppWizard2 ,知道C+类、函数重载等简单知识3 ,知道如何给View类或者Doc文档添加成员变量4 ,会用MFC勺IDE调试工具最好,那么本文的程序您可以copy去调试我们在上一节讲了MFCH架App类、View类、MainFrame类和Doc类的关系,那么,基

29、于消息的windowsMFC程序设计是如何进行消息映射的呢?在进行下一节之前,我们来复习一下。对于一个MFCAPPWizard运用程序,CMainFrame和View是窗口类,并且是父子关系,Doc一般用于数据的加载和存储,View用于图像的显示,App中是包括一些(窗口)初始化之类的东西。我们开始这一节的内容。1、 消息映射机制windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。在左边View类处点右键,在出现的菜单里点击“AddWin

30、dowsMessageHandler”,在出现的对话框里选择“WM_LBUTTONDOWN加消息映射函数。回到原文件,我们将看到三处进行了修改:1,在头文件(View.h)中声明消息响应函数原型。/AFX_MSG(CDrawView)/注释宏afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);/AFX_MSG/注释宏afx_msg宏表示声明的是一个消息响应函数。2,在源文件(View.cpp)中进行消息映射。BEGIN_MESSAGE_MAP(CDrawView,CView)AFX_MSG_MAP(CDrawView)ON_WM_LBUTTONDO

31、WN()AFX_MSG_MAP在宏BEGIN_MESSAGE_MAP()END_MESSAGE_MAP(网进行消息映射。宏ON_WM_LBUTTONDOWl()BWM_LBUTTONDOWN的响应函数OnLButtonDown()相关联。这样一旦有消息的产生,就会自动调用相关联的消息响应函数去处理。宏ON_WM_LBUTTONDOWN)如下:#defineON_WM_LBUTTONDOWN()WM_LBUTTONDOWN,0,0,0,AfxSig_vwp,(AFX_PMSG)(AFX_PMSGW)(void(AFX_MSG_CALLCWnd:*)(UINT,CPoint)&OnLButtonD

32、own,3,源文件中进行消息响应函数处理。voidCDrawView:OnLButtonDown(UINTnFlags,CPointpoint)/TODO:Addyourmessagehandlercodehereand/orcalldefaultCView:OnLButtonDown(nFlags,point);说明:可见当增加一个消息响应处理,在以上三处进行了修改。可在消息响应函数里添加消息处理代码完成对消息的响应、处理。消息响应的可能方式:1)在基类中针对每种消息做一个虚函数,当子类对消息响应时候,只要在子类中重写这个虚函数即可。缺点:MFC派生层次很多,如果在基类对每个消息进行虚函数处

33、理,那么从基类派生的每个子类都将背负一个庞大的虚表,这样浪费内存,故MFC有采取这中方式而采取消息映射方式。2)消息映射方式:MFC后台维护了一个句柄和C+对象指针对照表,当收到一个消息后,通过消息结构里资源句柄(查对照表)就可找到与它对应的一个C+寸象指针,然后把这个指针传给基类,基类利用这个指针调用WindowProc()函数对消息进行处理,WindowProc()函数中调用OnWndMsg()l数,真正的消息路由及处理是由OnWndMsg()l数完成的。由于WindowProc()和OnWndMsg()TB是虚函数,而且是用派生类对象指针调用的,由多态性知最总终调用子类的。在OnWndM

34、sg(两数处理的时候,根据消息种类去查找消息映射,判断所发的消息有没有响应函数,具体方式是到相关的头文件和源文件中寻找消息响应函数声明(从注释宏/AFX_MSG(CDrawView)/AFX_MSG之间寻找),消息映射(从宏BEGIN_MESSAGE_MAP().END_MESSAGE_MAPa间寻找),最终找到对应的消息处理函数。当然,如果子类中没有对消息进行处理,则消息交由基类处理。说明:virtualLRESULTWindowProc(UINTmessage,WPARAMwParam,LPARAMIParam);virtualBOOLOnWndMsg(UINTmessage,WPARAM

35、wParam,LPARAMlParam,LRESULT*pResult);2、 绘图DC的获取说明:在View类添加WM_LBUTTONDOWWM_LBUTTONUP肖息处理函数,我们将用来演示各种DC的获取,以及显示效果。View类添加全局变量CPointm_ptOrigin用来存储左键按下点坐标。下面集中来关注OnLButtonUp中的绘图程序和效果。以下语句添加于OnLButtonUp函数中,可以查看不同的效果。1,使用SDK获取DC句柄:HDChdc;hdc=:GetDc(m_hWnd);获取DC句柄MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL

36、);LineTo(hdc,point.x,point.y);:ReleaseDC(m_hWnd,hdc);释放DC2,利用CDC指针和CWin类成员函数获取DGCDC*pDC=GetDC();pDC-MoveTo(m_ptOrigin);pDC-LineTo(point);ReleaseDC(pDC);3,利用CClientDC对象。(CClientDC类从CD或派生来的)CClientDCdc(this);dc.MoveTo(m_ptOrigin);dc.LineTo(point);4,利用CWindowDC寸象。(CWindowDCt从CD1派生来的)CWindowDCdc(this);/

37、dc.MoveTo(m_ptOrigin);dc.LineTo(point);5,父窗口(MainFrame框架)和屏幕指针。将上面的dc(this)分别改成GetParent()和GetDesktopWindow(),就可以得到父窗口指针和屏幕窗口指针。可以分别试验画线效果。6,利用画笔改变线条颜色和类型:CPenpen(PS_DOT,1,RGB(0,255,0);构造画笔对象CClientDCdc(this);CPen*pOldPen=dc.SelectObject(&pen);将画笔选入DCdc.MoveTo(m_ptOrigin);dc.LineTo(point);dc.SelectO

38、bject(pOldPen);/恢复先前的画笔7,使用画刷(通常利用画刷去填充矩形区域):使用单色画刷CBrushbrush(RGB(255,0,0);构造画刷对象CClientDCdc(this);dc.FillRect(CRect(m_ptOrigin,point),&brush);用指定的画刷去填充矩形区域使用位图画刷CBitmapbitmap;/构造位图对象(使用前需要初试化)bitmap.LoadBitmap(IDB_BITMAP1);初试化位图对象CBrushbrush(&bitmap);/构造位图画刷CClientDCdc(this);dc.FillRect(CRect(m_pt

39、Origin,point),&brush);用指定的位图画刷去填充矩形区域使用透明画刷CBrush*pBrush=CBrush:FromHandle(HBRUSH)GetStockObject(NULL_BRUSH);获取透明画刷对象指针CClientDCdc(this);CBrush*pOldBrush=dc.SelectObject(pBrush);/将透明画刷选入DCdc.Rectangle(CRect(m_ptOrigin,point);dc.SelectObject(pOldBrush);/释放透明画刷8,注意点:1)静态方法不属于某一个具体对象,而属于类本身,在类加载的时候就已经为

40、类静态方法分配了代码去,故可用CBrush:FromHandle()形式调用。2)静态方法中,不能引用非静态的数据成员和方法。3)静态数据成员需要在类外单独做初始化,形式如:变量类型类名二变量名=初始值;第四章文本编辑和字处理软件这一节我们主要讲述文本编辑方面的知识,孙鑫老师的视频就是一个简单字处理软件的制作过程,所以我也是按照顺序,叙述此过程。在MF计CEditView和cRichEditView类已经完成了初步的文字处理。可以让应用程序的View类以CEditView和cRichEditView类为基类。下面我们以单文档视图为例一、创建插入符。文字在插入符后插入(正如Word中闪烁的光标)

41、1, 添加View类的WM_CREATE息响应函数2, 在CXXXView:OnCreate()中添加/获得当前文本度量/字体信息CClientDCdc(this);TEXTMETRICtm;dc.GetTextMetrics(&tm);/根据当前字体,设置插入符/光标CreateSolidCaret(20,100);/*ShowCaret();3, 创建图形插入符1),为View类添加成员变量m_bmp;2),把上面的*行用如下语句替换m_bmp.LoadBitmap(IDB_BITMAP1);CreateCaret(&bitmap);4,、输出文字在OnDraw函数中添加如下代码1),简单

42、输出文字CStringstr;str=维新科学技术培训中心;pDC-TextOut(50,50,str);2),获取文字框大小备用CSizesz=pDC-GetTextExtent(str);3),给str重新赋值,以区别于上一个内容。当然,之前需要在StringTable中添加IDS_WEIXINstr.LoadString(IDS_WEIXIN);pDC-TextOut(0,200,str);4),添加路径层当作图的时候,如果想要在整幅图形其中的某个部分和其它部分有所区别,我们可以把这部分图形放到路径层当中,然后指定调用指定互操作模式调用SelectClipPath(intnMode)函数

43、来使路径层和覆盖在其上新绘图剪切区域进行互操作,达到特殊效果。pDC-BeginPath();pDC-Rectangle(50,50,50+sz.cx,50+sz.cy);路径层的坐标依赖于上面的文字位置pDC-EndPath();pDC-SelectClipPath(RGN_DIFF);5),画一些方格,看看路径层的效果。for(inti=0;iMoveTo(0,i);pDC-LineTo(300,i);pDC-MoveTo(i,0);pDC-LineTo(i,300);三、鼠标移动插入符CPoint m_ptOrigin用于保存鼠标移动引给View增加两个成员变量:CStringm_str

44、Line用于存储当前输入行的内容;起插入符改变时的新行开始位置在OnLButtonDown函数中添加如下内容SetCaretPos(point);/设置插入符位置m_strLine.Empty();m_ptOrigin=point;/保存此位置另外,给View添加两个变量四、响应键盘输入键盘响应需要考虑如下内容:1, 鼠标点击键盘输入一个字符,显示到键盘上,插入符/光标后移一位。2, 回车之后,光标下移一行3, 删除/退格键的响应卜面是程序内容:1,给View类添加WM_CHAR息响应函数2,在OnChar函数中添加如下语句CClientDCdc(this);CFontfont;font.Cr

45、eatePointFont(300,”华文行楷”,NULL);CFont*pOldFont=dc.SelectObject(&font);TEXTMETRICtm;dc.GetTextMetrics(&tm);if(0x0d=nChar)/回车键响应程序段m_strLine.Empty();m_ptOrigin.y+=tm.tmHeight;elseif(0x08=nChar)/用背景色模拟最后一个字符的消失COLORREFclr=dc.SetTextColor(dc.GetBkColor();dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);m_

46、strLine=m_strLine.Left(m_strLine.GetLength()-1);dc.SetTextColor(clr);elsem_strLine+=nChar;CSizesz=dc.GetTextExtent(m_strLine);CPointpt;pt.x=m_ptOrigin.x+sz.cx;pt.y=m_ptOrigin.y;SetCaretPos(pt);dc.TextOut(m_ptOrigin.x,m_ptOrigin.y,m_strLine);dc.SelectObject(pOldFont);五、平滑变色-类似卡拉OJ跟唱文字颜色改变CDC:TextOut(

47、)是一个字母一个字母的输出,达不到平滑效果。CDC:DrawText():将文字的输出局限于一个矩形区域,超出矩形区域的文字都被截断。利用这一特点,可每隔些时间增加矩形大小,从而可实现人眼中的平滑效果。1,设置定时器。在View中OnCreate或者其他地方添加SetTimer(1,100,NULL);2,给View类添加WM_TIMER!息响应函数3,给View添加成员变量m_nWidth用于保存颜色随时间流逝变化的起点4,在OnTimer中添加如下代码m_nWidth+=5;/每次位置增加CClientDCdc(this);TEXTMETRICtm;dc.GetTextMetrics(&t

48、m);/获取字体属性CRectrect(0,200,m_nWidth,200+tm.tmHeight);dc.SetTextColor(RGB(255,0,0);CStringstr;str.LoadString(IDS_WEIXIN);dc.DrawText(str,rect,DT_LEFT);rect.top=150;rect.bottom=rect.top+tm.tmHeight;dc.DrawText(str,rect,DT_RIGHT);CSizesz=dc.GetTextExtent(str);if(m_nWidthsz.cx)m_nWidth=0;dc.SetTextColor(

49、RGB(0,255,0);dc.TextOut(0,200,str);简单字处理软件大功告成!第五章VC菜单相关编程阅读本文前,我们假设您已经:1 ,知道如何创建一个单文档的AppWizard2 ,知道C+类、函数重载等简单知识3 ,知道如何给View类或者Doc文档添加成员变量4 ,会用MFC勺IDE调试工具最好,那么本文的程序您可以copy去调试5 ,知道如何为某个框架类添加虚函数或消息处理函数一、消息的分类:消息的分类:标准消息,命令消息,通告消息。标准消息:除WM_COMMAND,所有以WM开头的消息。命令消息:来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND。在M

50、FC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。通告消息:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND呈现。注息:1)从CWncM生的类,都可以接收到标准消息、命令消息和通告消息。2)从CCmdTarget派生的类,都可以接收到命令消息和通告消息。3)CCmdTarget是CWnd勺父类二、菜单消息传递过程MFC中菜单项消息如果利用ClassWizard来对菜单项消息分别在上述四个类中进行响应,则菜单消息传递顺序:View类6Doc类eCMa

51、inFrame类(!App类。菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFrame框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。如果CMainFrame类查看至UCMainFrame类中也没对该消息做响应,则最终交给App类进

52、行处理。三、菜单指针的获取,及相关设置在CMainFrame:OnCreate下可以直接实验以下操作几个相关和重要的函数CMenu*GetMenu();/CWnd:GetMenu得到窗口菜单栏对象指针。CMenu*GetSubMenu();/CMenu:GetSubMenu获得指向弹出菜单对象指针UINTCheckMenuItem();CMenu:CheckMenuItemAddscheckmarkstoorremovescheckmarksfrommenuitemsinthepop-upmenu.BOOLSetDefaultItem();/CMenu:SetDefaultItemSetsth

53、edefaultmenuitemforthespecifiedmenu.BOOLSetMenuItemBitmaps(力CMenu:SetMenuItemBitmaps设置位图标题菜单。UINTEnableMenuItem();CMenu:EnableMenuItem使菜单项有效,无效,或变灰。BOOLSetMenu(CMenu*pMenu);/CWnd:SetMenu在当前窗口上设置新菜单或移除菜单。HMENUDetach(力CMenu:DetachDetachesaWindowsmenufromaCMenuobjectandreturnsthehandle.获取菜单的宽和高:GetSyst

54、emMetrics(SM_CXMENUCHECK),GetSystemMetrics(SM_CYMENUCHECK)例子:1,给菜单项打上标记GetMenu()-GetSubMenu(0)-CheckMenuItem(0,MF_BYPOSITION|MF_CHECKED);GetMenu()-GetSubMenu(0)-CheckMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_CHECKED);2, 设置缺省菜单项GetMenu()-GetSubMenu(0)-SetDefaultItem(1,TRUE);GetMenu()-GetSubMenu(0)-SetDefa

55、ultItem(ID_FILE_OPEN);3, 图形标记菜单先创建图形,注意底色不要是白色m_bitmap.LoadBitmap(IDB_BITMAP1);GetMenuO-GetSubMenu(0)-SetMenuItemBitmaps(0,MF_BYPOSITION,&m_bitmap,&m_bitmaP);4, 屏蔽菜单,使之不能用(需要在CMainFrame:CMainFrame()中设置m_bAutoMenuEnable=FALSE;)GetMenu()-GetSubMenu(0)-EnableMenuItem(1,MF_BYPOSITION|MF_DISABLED|MF_GRAYED);5, 取消和加载菜单用此功能,可以动态的修改菜单SetMenu(NULL);/取消菜单项CMenumenu;menu.LoadMenu(IDR_MAINFRAME);SetMenu(&menu);menu.Detach();/菜单句柄和对象断开,使对象析构时不销毁菜单四、命令更新机制菜单项状态的维护是依赖于CN_UPDATE_C

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论