孙鑫vc视频学习笔记整理中110_第1页
孙鑫vc视频学习笔记整理中110_第2页
孙鑫vc视频学习笔记整理中110_第3页
孙鑫vc视频学习笔记整理中110_第4页
孙鑫vc视频学习笔记整理中110_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

目录Lesson1:Windows程序运行原理及程序编写流程,窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与cdecl调用规范的比较,初学者常犯错误及注意事项。Lesson2:C++经典语法与应用,类的编写与应用,构造与析构函数,函数的重载,类的继承,函数覆盖,基类与派生类的构造函数、析构函数先后调用顺序,如何在派生类构造函数中向基类的构造函数传递参数,this成员变量,类型转换的内幕,虚拟函数与多态性,引用和指针变量的区别与共同处。VC工程的编译原理与过程,将工程中不同的类拆分到不同的文件中,每一个类由一个.h和.cpp文件共同完成,头文件重复定义问题的解决,培养了学员良好的编程习惯,也为以后分析MFCAppWizard生成的工程奠定了良好基础。Lesson3:讲述MFCAppWizard的原理与MFC程序框架的剖析。AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的PreCreateWidow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。Lesson4:MFC消息映射机制的剖析,讲述如何运用ClassWizard,,理解发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的函数进行响应的。掌握设备描述表及其封装类CDC的使用,CDC是如何与具体的设备发生关联的,融合具体的画图程序进行分析。如何设置封闭图形的填充刷子(位图画刷与透明画刷的使用)。Lesson5:掌握CDC的文字处理程序的编写,如何产生自定义字体和自定义插入符,熟悉对CString类的使用。通过对卡拉OK程序的编写,讲解定时器的使用和DrawText函数的巧妙运用。讲解如何使用CDC的裁减功能。Lesson6:菜单的工作原理及编写应用,菜单命令消息在MFC框架程序的几个类中的传递顺序和处理过程。标记菜单、缺省菜单的实现原理、图形菜单的实现及常犯错误的分析,GetSystemMetrics的应用,快捷弹出菜单的实现方式及其命令响应函数有效范围(与弹出菜单时所指定的父窗口有密切的关系,最底层的子窗口具有最优先的处理机会)。动态菜单的编写,如何让程序在运行时产生新的菜单项及如何手工为这些新产生的菜单命令安排处理函数,如何在顶层窗口中截获对菜单命令的处理,更进一步掌握CString类的应用。Lesson7:对话框用户界面程序的编写,如何向对话框控件关联数据成员及其实现机理,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数)。如何在程序运行时产生和销毁控件。对话框控件的几种操作方式的优劣比较分析。如何实现对话框的部分收缩和展开。如何让对话框上的文本框在程序启动后立即获得焦点,如何利用SetWindowLong改变窗口的回调函数,通过改变文本框的默认回车处理方式进行演示。实现多个输入文本框间通过回车逐一向下传递焦点的另一种巧妙方法(用缺省按钮来处理)。Lesson8:逃跑按钮的巧妙实现。如何制作属性页对话框和向导对话框,融合讲解组合框(如何调整组合框的大小)、列表框、单选按钮、复选按钮等常用对话框控件的多种使用方法。如何限制用户在不满足设定的条件时切换到其他属性页和向导页。Lesson9:如何修改MFCAppWizard向导生成的框架程序的外观和大小,修改图标、光标、背景的三种方法。如何增加和删除工具栏按钮,如何给应用程序增加工具栏,如何显示和隐藏工具栏。定制状态栏,在状态栏中添加时钟显示,CTime类及其用法。在状态栏中添加进度条(主窗口产生后立即产生进度条的巧妙思想,不能在OnCreate函数中直接处理,要用到自定义消息的方法)。鼠标坐标显示,在CView中获取状态栏对象的几种方式。如何为应用程序添加启动画面。Lesson10:图形的绘制,如何使用自定义画笔(颜色,线宽,线型)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,对按钮控件的特殊处理。如何在窗口中显示一幅位图。Lesson11:如何让CDC上输出的文字、图形具有保持功能,集合类CPtrArray的使用,CPaintDC与CClientDC的区别与应用,OnPaint与OnDraw在CView中的关系及实现内幕,滚动窗口的实现,坐标空间,映射方式,设备坐标与逻辑坐标的转换。元文件设备描述表的使用,如何利用兼容DC实现图形的保存和再现。Lesson12:constchar*与char*const的区别。C语言对文件读写的支持,FILE指针;文本文件和二进制文件的区别。用文本方式读写文件和以二进制方式读写文件的注意事项。C++对文件读写的支持,ofstream和ifstream的用法。Win32SDK对文件读写的支持,CreateFile函数、WriteFile函数、ReadFile函数的使用;MFC对文件读写的支持,CFile类和CFileDialog的使用,文件过滤器的设置。win.ini文件和注册表的读写方式及相关知识点。Lesson13:使用CArchive类对文件进行操作。MFC框架程序提供的文件新建与打开功能内部的实现机制。如何利用CDocument类的串行化存储功能保存与加载数据。如何实现类对串行化的支持,CObArray的串行化实现内幕。删除文档数据时常犯的错误。MFC框架程序的文档类和视类的关系,以及如何获得相互的指针引用。Lesson14:网络的相关知识,网络程序的编写,Socket是连接应用程序与网络驱动程序的桥梁,Socket在应用程序中创建,通过bind与驱动程序建立关系。此后,应用程序送给Socket的数据,由Socket交给驱动程序向网络上发送出去。计算机从网络上收到与该Socket绑定的IP+Port相关的数据后,由驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据。网络应用程序就是这样通过socket进行数据的发送与接收的。TCP与UDP的工作原理与编写过程,如何在程序中链接库文件。一个字符界面的聊天程序。Lesson15:多线程程序的编写,多线程应用中容易出现的问题。互斥对象的讲解,如何使用互斥对象来实现多线程的同步。如何利用命名互斥对象保证应用程序只有一个实例运行。应用多线程编写网络聊天室程序。Lesson16:事件内核对象、关键代码段(临界区)的讲解,以及在多线程同步中的应用。在Windows下编写基于消息的网络应用程序,掌握阻塞与非阻塞网络程序的编写,理解在Windows平台下,采用异步选择机制可以提高网络应用程序的性能。Lesson17:详细讲解进程间通讯的四种方式:剪贴板、匿名管道、命名管道和邮槽。并比较分析这几种进程间通信的优点和缺点。Lesson18:ActiveX控件的应用与工作原理。ActiveX控件的编写,如何为控件安排属性,方法,事件,属性页,持久性存储,控件如何通知容器自身属性的改变。如何注册控件与取消控件注册。在VB和VC中访问ActiveX控件。Lesson19:动态链接库程序的编写。静态库与动态库的区别,以及调用程序在链接静态库和动态库时的区别。如何利用工具查看动态链接库输出的函数,Depends工具的使用,C++编译器名字改编技术对动态链接库输出函数的影响,extern"C"的用法,利用模块定义文件来解决C++名字改编的问题。用typedef定义指向函数的指针类型,如何获得动态连接库里的函数的指针。Lesson20:Hook编程。如何安装钩子过程,如何编写全局钩子,动态连接库里的全局变量数据共享问题分析。ADO数据库编程。在VB中利用ADO控件和ADO对象访问数据库,在VC中利用ADO技术访问数据库。

Lesson1:Windows程序运行原理及程序编写流程主要内容:窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系。使用VC++的若干小技巧,stdcall与Lessonecl调用规范的比较,初学者常犯错误及注意事项。1.

WindowsAPI与Win32SDK操作系统提供了各种方便开发Windows应用程序的编程接口,所的函数都在Windows.h头文件中声明。Win32SDK(SoftwareDevelopmentKit):即Windows32位平台下的软件开发包,包括API函数,帮助文档,微软提供的一些辅助开发工具。2.

窗口与句柄窗口是是屏幕上一块矩形区域,是Windows应用程序与用户进行交互的接口。窗口分为客户区和非客户区。在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的,要对某个窗口进行操作,首先就要得到这个窗口的句柄。其它各种资源(窗口,图标,光标等),系统在创建这些资源时会为它们分配内在,并返回标识这些资源的标识号,即句柄。-->光标句柄(HCURSOR),图标句柄(HICON)。3.

消息与消息队列Windows程序设计是一种基于消息的事件驱动方式的程序设计模式。

消息:在Windows中由结构体MSG来表示,typedefstructtagMSG{ HWNDhwnd;//消息所属的窗口句柄UINT

message;//消息本身标识符,由一数值表示,系统对消息定义为WM_XXX宏(WM为WindowsMessage缩写)

WPARAM

wParam;

//随消息的不同附加信息也不同

LPARAM

lParam;

//消息的附加参数

DWORDtime;

//消息投递的时间

POINT

pt;

//鼠标当前位置}消息队列:每当一个Windows应用程序创建后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序一的窗口的消息,消息产生后被投递到消息队列中,应用程序通过一个消息循环不断的消息队列中取出消息进行响应。响应过程由系统向应用程序发送消息,实际就是调用应用程序的消息处理函数。4.

创建一个完整的Win32程序,该程序实现创建一个窗口,其中主要步骤为A.

WinMain函数的定义B.

创建一个窗口

创建一个完整的窗口的四个步骤SDK,1设计窗口类,2注册窗口类,3创建窗口,4显示窗口C.

进行消息循环D.

编写窗口过程函数回调函数的实现机制:(1)

定义一个回调函数(2)

提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者(3)

当特定的事件或条件发和的时候,调用使用函数指针调用回调函数对事件进行处理针对Windows的消息处理机制,窗口过程函数被调用的过程如下:A.

在设计窗口类的时候,将窗口赛程函数的地址赋值给lpfnWndProc成员变量B.

调用RegisterClass(&wndclass)注册窗口类,那么系统就有了我们所编写的窗口过程函数的地址C.

当应用程序接收到某一窗口的消息,调用DispatchMessage(&msg)将消息加值给系统。系统则利用先前注册窗口类时得到函数指针,调用窗口过程函数对消息进行处理。HICONLoadIcon(HINSTANCEhInstance,LPCTSTRlpIconName);//加载窗图标,返回系统分配给该图标的句柄,LPCTSTR被定义为CONSTCHAR*(指向常量的字符指针),图标的ID是一个常数,要使用MAKEINTRESOUCE宏把资源ID标识转换为需要的LPCTSTR类型5.

sprintf格式化字符,其头文件为stdio。h,在MFC中格式化字符用CString。Format6.

GetDC()与ReleaseDC()要成对使用,否则会内存泄漏。同样,BeginPaint()与EndPaint(),这两个Parint只能在影响WM_PAINT消息中调用。7.

GetStockObject()得到画笔、画刷、字体、调色板的句柄,使用时必须用类型转换。如:hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH)//创建空画刷8.

什么时候用NULL,什么时候用0。答,对指针赋值时用NULL,对变量赋值时用0。9.

什么是野指针?答:将指针指向的变量的内存释放后,此指针即变成野指针!如何避免野指针?答:将此指针指向NULL即可。p=NULL;

#include<stdio.h>#include<windows.h>#include<stdexcept>usingnamespacestd;

//回调函数原型声明,返回长整形的结果码,CALLBACK是表示stdcall调用LRESULTCALLBACKWinProc(

HWNDhwnd,

//handletowindow

UINTuMsg,

//messageidentifier

WPARAMwParam,

//firstmessageparameter

LPARAMlParam

//secondmessageparameter);

//(1)WinMain函数,程序入口点函数intWINAPIWinMain(

HINSTANCEhInstance,

//handletocurrentinstance

HINSTANCEhPrevInstance,

//handletopreviousinstance

LPSTRlpCmdLine,

//commandline

intnCmdShow

//showstate

){

//(2)

//一.设计一个窗口类,类似填空题,使用窗口结构体

WNDCLASSwnd;

wnd.cbClsExtra=0;//类的额外内存

wnd.cbWndExtra=0;

//窗口的额外内存

wnd.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH);//创建一个空画刷填充背景

//加载游标,如果是加载标准游标,则第一个实例标识设置为空

wnd.hCursor=LoadCursor(NULL,IDC_CROSS);

wnd.hIcon=LoadIcon(NULL,IDI_ERROR);

wnd.hInstance=hInstance;//实例句柄赋值为程序启动系统分配的句柄值

wnd.lpfnWndProc=WinProc;//消息响应函数

wnd.lpszClassName="gaojun";//窗口类的名子,在注册时会使用到

wnd.lpszMenuName=NULL;//默认为NULL没有标题栏

wnd.style=CS_HREDRAW|CS_VREDRAW;//定义为水平和垂直重画

//二.注册窗口类

RegisterClass(&wnd);

//三.根据定制的窗口类创建窗口

HWNDhwnd;//保存创建窗口后的生成窗口句柄用于显示

//如果是多文档程序,则最后一个参数lParam必须指向一个CLIENTCREATESTRUCT结构体

hwnd=CreateWindow("gaojun","WIN32应用程序",WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,CW_USEDEFAULT,800,600,NULL,NULL,hInstance,NULL);

//四.显示窗口

ShowWindow(hwnd,SW_SHOWDEFAULT);

//五.更新窗口

UpdateWindow(hwnd);

//(3).消息循环

MSGmsg;//消息结构体

//如果消息出错,返回值是-1,当GetMessage从消息队列中取到是WM_QUIT消息时,返回值是0

//也可以使用PeekMessage函数从消息队列中取出消息

BOOLbSet;

while((bSet=GetMessage(&msg,NULL,0,0))!=0){

if(-1==

bSet)

{

return-1;

}

else{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

return0;//程序结束,返回0}

//消息循环中对不同的消息各类进行不同的响应LRESULTCALLBACKWinProc(

HWNDhwnd,

//handletowindow

UINTuMsg,

//messageidentifier

WPARAMwParam,

//firstmessageparameter

LPARAMlParam

//secondmessageparameter

){

switch(uMsg)

{

caseWM_CHAR://字符按键消息

charszChar[20];

sprintf(szChar,"charis%d;",wParam);//格式化操作

MessageBox(hwnd,szChar,"gaojun",0);//输出操作中

break;

caseWM_LBUTTONDOWN://鼠标左键按下消息

MessageBox(hwnd,"thisisclickevent!","点击",0);

HDChdc;

hdc=GetDC(hwnd);//获取设备上下文句柄,用来输出文字

//在x=0,y=50(像素)的地方输出文字

TextOut(hdc,0,50,"响应WM_LBUTTONDONW消息!",strlen("响应WM_LBUTTONDONW消息!"));

ReleaseDC(hwnd,hdc);//在使用完DC后一定要注意释放

break;

caseWM_PAINT://窗口重给时报消息响应

HDChDc;

PAINTSTRUCTps;

hDc=BeginPaint(hwnd,&ps);

TextOut(hDc,0,0,"这是一个Paint事件!",strlen("这是一个Paint事件!"));

EndPaint(hwnd,&ps);

break;

caseWM_CLOSE://关闭消息

if(IDYES==MessageBox(hwnd,"确定要关闭当前窗口?","提示",MB_YESNO))

{

DestroyWindow(hwnd);//销毁窗口

}

break;

caseWM_DESTROY:

PostQuitMessage(0);//在响应消息后,投递一个退出的消息使用程序安全退出

break;

default:

returnDefWindowProc(hwnd,uMsg,wParam,lParam);//调用缺省的消息处理过程函数

}

return0;}

Lesson2:掌握C++基本语法主要内容:三性分析一些编程习惯1.

C++主要特点:封装性(Encapsulation):把数据与操作数据的函数组织在一起,使程序结构更加紧凑,提高类内部数据的安全性。继承性(Inheritance):增加了软件的可扩充性及代码重用性;多态性(Polymorphism):使设计人员在设计程序时可以对问题进行更好的抽象,有利于代码的维护和可重用2.

C++中几个特性的实现技术和其它要注意的地方:构造函数,析构函数,覆盖,隐藏,重载,继承,多态(迟绑定)等技术,算法类的编写与应用以下是部分资料:1。定义结构体和类时。例如ClassPoint{intx;inty;};要注意一定加上分号,结构体定义默认成员是public,而Class定义默认为private2。#include<xxx.h>与#include"xxx.h"的区别:<>不查找运行时目录,""查找运行时目录!(#include<xxx>引入是源文件,要用上usingnamespacexxx;)3。类的定义中,如果未指明成员类型,则缺省为private。而结构体中则缺省为public。4。引用:引用经常用在函数的传参上。另外数值交换函数也经常用引用。例change(int&x,int&y){inttemp;temp=x;x=y;y=x}调用时即可以用inta=3;intb=4;change(a,b);一般不用指针来作为参数进行数值交换。因为会引起歧义。5。通常将类的定义放h文件,而将其实现放在cpp文件中,别忘记了在cpp文件中#include"xxx。h"6。如何防止类的重复定义?#ifndefPoint_H_H#definePoint_H_HclassPoint{};#endif7。源文件cpp文件单独编译成obj文件。最后由链接器将与将要使用到的C++标准库类链接成exe文件,头文件不参加编译。所以在cpp文件中别忘记了加入#include"xxx.h"8。函数的覆盖,在子类中重写父类的函数,此时采用早期绑定的方法。如果加入了virtual,则将采用迟绑定的技术,在运行时根据对象的类型确定调用哪一个函数。此迟绑定技术是MFC的类的继承的精髓。9。强制类型转换。如果CFish从CAnimal派生而来。则可以将鱼的对象转换为CAnimal的对象,而反之则不行。从现实中理解也是正常的,鱼可以是动物,而动物却不是鱼。再如int可以强制转换成char型。而反之则出错。

Lesson3:MFC框架程序剖析主要内容:MFC建立工程CButton类1.

MFC简介:MFC(MicrosoftFoundationClass,微软基础类库)是微软为了简化程序员的开发工作所开发的一套C++类的集合,是一套面向对象的函数库,以为的方式提供给用户使用.利用这些类,可以有效发帮助程序员完成Windows应用程序的开发MFCAppWizard是一个辅助生成源代码的向导工具,它可以帮助我们自动生成基于MFC框架的源代码.在向导的每一个步骤中,我们可以根据需要来选择各种特性,从而实现定制应用程序.2.

窗口类,窗口对象与窗口关系窗口类中定义一个类型为HWND成员变量,用来保存与之相关的窗口句柄值,可以用一个窗口类的实例即窗口对象来对应一个创建的窗口(是一种资源),窗口对象与窗口之间的关系是:C++窗口类对象与窗口并不是一回事,它们之间唯一的关系是C++窗口类对象内部定义了一个窗口句柄变量,保存了与这个C++窗口类对象相关的那个窗口的句柄.窗口销毁时,与之对应的C++窗口类对象销毁与否,要看其生命周期是否结束,但C++窗口类对象销毁时,与之相关的窗口将销毁,因为它们之间的纽带(m_hWnd)已经断了,因此这时要回收窗口资源.窗口销毁时调用DestroyWindow函数,窗口类对象销毁即将m_hWnd变量设置为NULL。一些常用操作快捷方式:功能分类快捷键说明File(文件)Ctrl+NNew新建工程Ctrl+OOpen打开文件Find(查找)Alt+F3/Ctrl+F弹出查找对话框F3查找下一个Shift+F3查找上一个Ctrl+H替换Ctrl+]/Ctrl+E寻找下一半括弧F4寻找下一个错误/警告位置Shift+F4寻找上一个错误/警告位置格式Ctrl+U将选定区域转换成小写Ctrl+Shift+U将选定区域转换成大写Alt+F8自动格式重排Build(建立)F7Build(编绎并链接成exe文件)Ctrl+F7Compile(编译)Ctrl+F5Execute(编译+链接+运行)Ctrl+Shift+F5Restartstheprogram(重新运行程序)Debug(调试)F5Go(顺序执行)F11stepinto(顺序执行,进入循环或函数)F10stepover(顺序执行,不进入循环或函数)Ctrl+F10Runtocursor(自动执行到用户光标所指的语句前)Shift+F5StopDebugging(停止调试)F9Insert/Removebreakpoint(在当前行插入/去掉断点)Ctrl+Shift+F9去掉所有断点

1.在main或WinMain之前,全局变量已经被分配内存并初始化了。2.在MFC中在WinMain之前有个theApp全局变量先被构造并被初始化,而由于子类构造函数执行前,其父类的构造函数先被执行,所以CTestApp的父类CWinAPP的构造函数先执行。产生了theApp对象后,在WinMain()中的指针*pThread和*pApp就有了内容。大致流程:CTestApptheApp;//构造全局对象WinMain(){AfxWinMain();//调用下面的函数}AfxWinMain(){pThread->Initinstance();//初始化工作和注册窗口类,窗口显示和更新pThread->Run();//消息循环}而在BOOLCTestApp::InitInstance()中的代码CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CTestDoc),

RUNTIME_CLASS(CMainFrame),

//mainSDIframewindow

RUNTIME_CLASS(CTestView));AddDocTemplate(pDocTemplate);完成了将这三个类关联起来的工作。4.如何在单文档文件中显示一个CButton的对象?在CMainFrame::OnCreate()中定义一个CButton的对象btn;然后调用btn.Create("维新",WS_DISABLED

|WS_CHILD|WS_VISIBLE|BS_AUTO3STATE,

CRect(0,0,300,100),/*GetParent(),*/this,123);注意点:(1).此处btn不能是局部变量,否则它的生命周期太短,将不能显示。(2).在CBUTTON类的Create函数的第二个参数中加入WS_VISIBLE参数才行。否则必须调用ShowWindow也可以在view的OnCreate消息响应函数中加入(3).CButton类的定义头文件在中,而包含了afxwin.h,所以可以直接使用。因为MFC中的每一个类中都有#include"stdafx.h"的声明。

Lesson4:消息映射与简单绘图主要内容:消息映射机制CDC类、CBrush类我们在上一节讲了MFC框架App类、View类、MainFrame类和Doc类的关系,那么,基于消息的windowsMFC程序设计是如何进行消息映射的呢?1.

在单文档中view挡在MainFrame的前面。此时如果编写针对MainFrame的mouseClick事件,将不会有反应。因为MFC视类窗口是覆盖在框架窗口上的,因此框架窗口不能感到鼠标消息。2.

MFC的消息映射机制: 在左边View类处点右键,在出现的菜单里点击“AddWindowsMessageHandler”,在出现的对话框里选择“WM_LBUTTONDOWN”,添加消息映射函数。1),消息响应函数:(例:在CDrawView类响应鼠标左键按下消息)a)在头文件(DrawView.h)中声明消息响应函数原型。//{{AFX_MSG(CDrawView)//注释宏afx_msgvoidOnLButtonDown(UINTnFlags,CPointpoint);//}}AFX_MSG//注释宏说明:在注释宏之间的声明在VC中灰色显示。afx_msg宏表示声明的是一个消息响应函数。b)在源文件(DrawView.cpp)中进行消息映射。BEGIN_MESSAGE_MAP(CDrawView,CView)//{{AFX_MSG_MAP(CDrawView)ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAP//StandardprintingcommandsON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)END_MESSAGE_MAP()说明:在宏BEGIN_MESSAGE_MAP()与END_MESSAGE_MAP()之间进行消息映射。宏ON_WM_LBUTTONDOWN()把消息WM_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))&OnLButtonDown},c)源文件中进行消息响应函数处理。(DrawView.cpp中自动生成OnLButtonDown函数轮廓,如下)voidCDrawView::OnLButtonDown(UINTnFlags,CPointpoint){//TODO:Addyourmessagehandlercodehereand/orcalldefaultCView::OnLButtonDown(nFlags,point);}说明:可见当增加一个消息响应处理,在以上三处进行了修改。可在消息响应函数里添加消息处理代码完成对消息的响应、处理。2),消息响应的方式:a)在基类中针对每种消息做一个虚函数,当子类对消息响应时候,只要在子类中重写这个虚函数即可。缺点:MFC类派生层次很多,如果在基类对每个消息进行虚函数处理,那么从基类派生的每个子类都将背负一个庞大的虚表,这样浪费内存,故MFC没有采取这中方式而采取消息映射方式。b)消息映射方式:MFC在后台维护了一个句柄和C++对象指针对照表,当收到一个消息后,通过消息结构里资源句柄(查对照表)就可找到与它对应的一个C++对象指针,然后把这个指针传给基类,基类利用这个指针调用WindowProc()函数对消息进行处理,WindowProc()函数中调用OnWndMsg()函数,真正的消息路由及处理是由OnWndMsg()函数完成的。由于WindowProc()和OnWndMsg()都是虚函数,而且是用派生类对象指针调用的,由多态性知最总终调用子类的。在OnWndMsg()函数处理的时候,根据消息种类去查找消息映射,判断所发的消息有没有响应函数,具体方式是到相关的头文件和源文件中寻找消息响应函数声明(从注释宏//{{AFX_MSG(CDrawView)...//}}AFX_MSG之间寻找),消息映射(从宏BEGIN_MESSAGE_MAP(...)END_MESSAGE_MAP()之间寻找),最终找到对应的消息处理函数。当然,如果子类中没有对消息进行处理,则消息交由基类处理。说明:virtualLRESULTWindowProc(UINTmessage,WPARAMwParam,LPARAMlParam);virtualBOOLOnWndMsg(UINTmessage,WPARAMwParam,LPARAMlParam,LRESULT*pResult);3.有关绘图a),使用SDK获取DC句柄:HDChdc;hdc=::GetDc(m_hWnd);//获取DC句柄MoveToEx(hdc,m_ptOrigin.x,m_ptOrigin.y,NULL);LineTo(hdc,point.x,point.y);::ReleaseDC(m_hWnd,hdc);//释放DCb),利用CDC类指针和CWin类成员函数获取DC。CDC*pDC=GetDC();pDC->MoveTo(m_ptOrigin);pDC->LineTo(point);ReleaseDC(pDC);c),利用CClientDC对象。(CClientDC类从CDC类派生来的)CClientDCdc(this);dc.MoveTo(m_ptOrigin);dc.LineTo(point);说明:TheCClientDCclassisderivedfromCDCandtakescareofcallingtheWindowsfunctionsGetDCatconstructiontimeandReleaseDCatdestructiontime.ThismeansthatthedevicecontextassociatedwithaCClientDCobjectistheclientareaofawindow.d),利用CWindowDC对象。(CWindowDC类从CDC类派生来的)CWindowDCdc(this);//dc.MoveTo(m_ptOrigin);dc.LineTo(point);说明:TheCWindowDCclassisderivedfromCDC.ItcallstheWindowsfunctionsGetWindowDCatconstructiontimeandReleaseDCatdestructiontime.ThismeansthataCWindowDCobjectaccessestheentirescreenareaofaCWnd(bothclientandnonclientareas).e),GetParent()得到父窗口指针;GetDesktopWindow()得到屏幕窗口指针。f),利用画笔改变线条颜色和类型:CPenpen(PS_DOT,1,RGB(0,255,0));//构造画笔对象CClientDCdc(this);CPen*pOldPen=dc.SelectObject(&pen);//将画笔选入DCdc.MoveTo(m_ptOrigin);dc.LineTo(point);dc.SelectObject(pOldPen);//恢复先前的画笔g),使用画刷(通常利用画刷去填充矩形区域):使用单色画刷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_ptOrigin,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);//释放透明画刷说明:TheGetStockObjectfunctionretrievesahandletooneofthepredefinedstockpens,brushes,fonts,orpalettes.HGDIOBJGetStockObject(intfnObject//typeofstockobject);ReturnsapointertoaCBrushobjectwhengivenahandletoaWindowsHBRUSHobject.staticCBrush*PASCALFromHandle(HBRUSHhBrush);//FromHandle是一个静态方法,故可用CBrush::FromHandle()形式调用。注意点:1)静态方法不属于某一个具体对象,而属于类本身,在类加载的时候就已经为类静态方法分配了代码去,故可用CBrush::FromHandle()形式调用。2)静态方法中,不能引用非静态的数据成员和方法。3)静态数据成员需要在类外单独做初始化,形式如:变量类型类名::变量名=初始值;h),CDC::SetROP2方法:intSetROP2(intnDrawMode);Setsthecurrentdrawingmode.以下绘图程序,参考代码的注释可解决部分绘图问题voidCLesson3View::OnLButtonUp(UINTnFlags,CPointpoint){

//TODO:Addyourmessagehandlercodehereand/orcalldefault

//作图

/*调用SDK函数获取设备上下文句柄

HDChdc;

hdc=::GetDC(m_hWnd);//这个m_hWnd是CWnd类中的保护成员,保存窗口句柄,

//而CLesson3View类是从CWnd类继承来的,所以也有这个成员

MoveToEx(hdc,m_ptnOrigin.x,m_ptnOrigin.y,NULL);

LineTo(hdc,point.x,point.y);

::ReleaseDC(m_hWnd,hdc);//在使用完设备上下文句柄后一定注意释放*/

/*使用CDC(MFC)关于作图对HDC一个封装*///

CDC*pDc;//

pDc=GetDC();//

pDc->MoveTo(m_ptnOrigin);//

pDc->LineTo(point);//

ReleaseDC(pDc);

/*使用客户区绘图类,这个是比较常用的*/

//CClientDCdc(this);//CClientDC的构造函数,使用当前窗口句柄值做为参数

//CClientDCdc(GetParent());//得到关于父类窗口一个设备上下文//

dc.MoveTo(m_ptnOrigin);//

dc.LineTo(point);

//CClientDC类在构造时调用GetDC,然后在释放时又调用ReleaseDC所以不用手动释放

//利用MFC的CWindowDC绘图/好处是可以访问整个窗口区域,包括框架窗口客户区和非客户区,桌面等,//

CWindowDCdc(this);//

CWindowDCdc(GetParent());//

dc.MoveTo(m_ptnOrigin);//

dc.LineTo(point);//

CWindowDCdc(GetDesktopWindow());//这个可以画到桌面上其它地方//

dc.MoveTo(m_ptnOrigin);//

dc.LineTo(point);

//以上所画的线条颜色都是黑色的,因为在设备描述表中使用默认的画笔(黑色),

//要改变线条颜色则需要自己生成一个新的画笔对象,//将它选到设备描述表中,再画就使用新画笔来绘图//

CPenm_pen(PS_DASH,2,RGB(255,0,0));//生成新的画笔//

CClientDCdc(this);//

CPen*pOldPen=dc.SelectObject(&m_pen);//选择进设备描述表中//

dc.MoveTo(m_ptnOrigin);//

dc.LineTo(point);//

dc.SelectObject(pOldPen);//在使用完新的画笔后,要将原来的画笔重新选择时设备描述表

//使用画刷来填充矩形//

CBrushm_brush(RGB(120,0,23));//

CClientDCdc(this);//

dc.FillRect(CRect(m_ptnOrigin,point),&m_brush);

//使用位图画刷来填充矩形

//创建一个位图对象//

CBitmapm_bitmap;//

m_bitmap.LoadBitmap(IDB_MyBitmap);//

CBrushm_Brush(&m_bitmap);//

CClientDCdc(this);//

dc.FillRect(CRect(m_ptnOrigin,point),&m_Brush);

//透明画刷

//首先使用Win32的API函数GetStockObject来获取一个NULL_BRUSH画刷

CClientDCdc(this);

CBrush*pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

//是静态成员函数,从句柄获取对象的指针

CBrush*pOldBrush=dc.SelectObject(pBrush);

dc.Rectangle(CRect(m_ptnOrigin,point));

dc.SelectObject(pOldBrush);

bIsMouseDown=FALSE;

CView::OnLButtonUp(nFlags,point);}类的静态成员函数可以由类名直接调用,也可以由对象调用。可以认为静态成员函数并不属于某个对象,它属于类本身。程序运行伊始,即使没有实例化类的对象,静态成员函数和静态成员变量已然有其内存空间。静态成员函数不能访问非静态成员变量!静态成员变量必须在类的外部初始化。当然如果并不打算用到静态成员变量,此时你可以不初始它。4.

理解代码区,数据区,堆,栈!()对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

Lesson5:文本编程主要内容:Caret、CDC类、CString类路径定时器1,创建插入符:voidCreateSolidCaret(intnWidth,intnHeight);//创建插入符voidCreateCaret(CBitmap*pBitmap);//创建位图插入符voidShowCaret();//显示插入符voidHideCaret();//隐藏插入符staticvoidPASCALSetCaretPos(POINTpoint);//移动插入符号说明:1)创建插入符要在窗口创建完成之后,CreateSolidCaret函数创建的插入符被初始化为隐藏,所以需要调用ShowCaret()将其显示。2)使用CreateCaret函数创建位图插入符的时候,不能使用局部的位图对象关联位图资源。(与资源相关联的C++对象,当它析构的时候会同时把与它相关联的资源销毁。)2,获取当前字体信息的度量:CDC::GetTextMetricsBOOLGetTextMetrics(LPTEXTMETRIClpMetrics)const;说明:typedefstructtagTEXTMETRIC{

/*tm*/

int

tmHeight;//字体高度。Specifiestheheight(ascent+descent)ofcharacters.

int

tmAscent;//基线以上的字体高度

int

tmDescent;//基线以下的字体高度

int

tmInternalLeading;

int

tmExternalLeading;

int

tmAveCharWidth;//字符平均宽度

int

tmMaxCharWidth;

int

tmWeight;

BYTEtmItalic;

BYTEtmUnderlined;

BYTEtmStruckOut;

BYTEtmFirstChar;

BYTEtmLastChar;

BYTEtmDefaultChar;

BYTEtmBreakChar;

BYTEtmPitchAndFamily;

BYTEtmCharSet;

int

tmOverhang;

int

tmDigitizedAspectX;

int

tmDigitizedAspectY;}TEXTMETRIC;//创建设备描述表

CClientDCdc(this);

//定义文本信息结构体变量

TEXTMETRICtm;

//获得设备描述表中的文本信息

dc.GetTextMetrics(&tm);

//根据字体大小,创建合适的插入符

CreateSolidCaret(tm.tmAveCharWidth/8,tm.tmHeight);

ShowCaret();3,OnDraw函数:virtualvoidOnDraw(CDC*pDC)当窗口(从无到有或尺寸大小改变等)要求重绘的时候,会发送WM_PAIN消息,调用OnDraw函数进行重绘。在客户区的绘图如果想保持不变也可以在这个函数中进行编写,每次重绘的时候会再次执行代码,生成绘图。4,获取某字符串的高度和宽度(区别字符串的长度,长度表示字符个数):CDC::GetTextExtentCSizeGetTextExtent(LPCTSTRlpszString,intnCount)const;CSizeGetTextExtent(constCString&str)const;说明://TheCSizeclassissimilartotheWindowsSIZEstructure。typedefstructtagSIZE{

intcx;//thex-extent

intcy;//they-extent}SIZE;

5,路径层:BOOLBeginPath();//CDC中函数//在这作图定义路径层剪切区域BOOLEndPath();BOOLSelectClipPath(intnMode);//调用这个函数来使当前路径层剪切区域与新剪切区域进行互操作。

//在这覆盖作图(包含前定义的路径层区域)定义新的剪切区域说明:1)SelectClipPath函数用于剪切区间的互操作,使用nMode来实现相交、融合等操作。nMode:RGN_AND,RGN_COPY,RGN_DIFF,RGN_OR,RGN_XOR2)应用:当作图的时候,如果想要在整幅图形其中的某个部分和其它部分有所区别,我们可以把这部分图形放到路径层当中,然后指定调用指定互操作模式调用SelectClipPath(intnMode)函数来使路径层和覆盖在其上新绘图剪切区域进行互操作,达到特殊效果。6,关于文本字符串一些函数:COLORREFGetBkColor()const;//得到背景颜色virtualCOLORREFSetBkColor(COLORREFcrColor);//设置背景颜色BOOLSetTextBkColor(COLORREFcr);//设置文本背景颜色virtualCOLORREFSetTextColor(COLORREFcrColor);//设置文本颜色virtualBOOLCDC::TextOut(intx,inty,LPCTSTRlpszString,intnCount);//输出文本BOOLCDC::TextOut(intx,inty,constCString&str);//在x,y所指定坐标处输出strCStringCString::Left(intnCount)const;//得到字符串左边nCount个字符intCString::GetLength()const;//得到字符串长度strlen()7,字体CFont::CFontCFont();//构造函数//ConstructsaCFontobject.TheresultingobjectmustbeinitializedwithCreateFont,CreateFontIndirect,CreatePointFont,orCreatePointFontIndirectbeforeitcanbeused.选用字体事例代码组:CClientDCdc(this);CFontfont;//构造字体对象font.CreatePointFont(300,"华文行楷",NULL);//初始化字体对象,与字体资源相关联CFont*pOldFont=dc.SelectObject(&font);//将新字体选入DC...dc.SelectObject(pOldFont);//恢复原字体说明:1)构造字体对象时候,必须初始化。(初始化是将字体对象与字体资源相关联)。2)初始化对象时候,选用的字体也可以是系统字体,但不一定都有效,据测试选用。8,在MFC中CEditView和cRichEditView类已经完成了初步的文字处理。可以让应用程序的View类以CEditView和cRichEditView类为基类。在创建工程中的第六步可以选择。9,平滑变色CDC::TextOut()是一个字母一个字母的输出,达不到平滑效果。CDC::DrawText():将文字的输出局限于一个矩形区域,超出矩形区域的文字都被截断。利用这一特点,可每隔一些时间增加矩形大小,从而可实现人眼中的平滑效果。CWnd::SetTimer():设置定时器。按设定的时间定时发送WM_TIMER消息。说明:UINTSetTimer(UINTnIDEvent,UINTnElapse,void(CALLBACKEXPORT*lpfnTimer)(HWND,UINT,UINT,DWORD));//nIDEvent定时器标示,nElapse消息发送间隔时间,void(CALLBACKEXPORT*lpfnTimer)(HWND,UINT,UINT,DWORD)设置回调函数,如果设置则由设置的回调函数处理WM_TIMER消息,如果没有设置回调函数设为NULL,这时发送的WM_TIMER消息将压入消息队列,交由相关联的窗口处理(添加WM_TIMER消息处理函数OnTimer())。1,设置定时器。在View中OnCreate或者其他地方添加SetTimer(1,100,NULL);2,给View类添加WM_TIMER消息响应函数afx_msgvoidOnTimer(UINTnIDEvent); //响应WM_TIMER消息, //nIDEvent为消息对应定时器标示(可以设置不同的定时器发送WM_TIMER消息)3,给View添加成员变量m_nWidth用于保存颜色随时间流逝变化的起点4,在OnTimer中添加如下代码m_nWidth+=5;//每次位置增加CClientDCdc(this);TEXTMETRICtm;dc.GetTextMetrics(&tm);//获取字体属性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_nWidth>sz.cx){m_nWidth=0;dc.SetTextColor(RGB(0,255,0));dc.TextOut(0,200,str);}简单字处理软件大功告成!问题:1、在CCareView类中添加WM_CREATE消息响应函数OnCreate(),WM_CREATE消息是在什么时候被检查到而被响应的呢?(猜测:添加WM_CREATE消息后,消息被压入消息队列,然后经过消息循环进行分发到具体窗口,从而进行响应)2、现有一文本文件内容已经读入串STR中,要求在视图客户区按原先文本文件中的格式输出。问题是,利用CDC的TextOut()来在CView类派生类窗口中输出串时,忽略了串中的TAB、回车换行等格式,无论串有多长均在一行上输出。这其中是CDC类成员函数TextOut()忽略串中格式的,还是CView类派生类窗口设置从中做怪呢?怎么解决

Lesson6:菜单编程主要内容:消息类型及响应菜单类CMenu,静态/动态菜单CArray类1.

MFC中的顶层菜单默认为弹出菜单(Pop-up),它是不能用来作命令响应的,当取消Pop-up选项后可接受命令响应。2.

消息的分类:标准消息,命令消息,通告消息。[标准消息]:除WM_COMMAND之外,所有以WM_开头的消息。从CWnd类派生的类都可以接收到这一消息[命令消息]:来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND呈现。在MFC中,通过菜单项的标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。从CCmdTarget(CWnd的父类)派生的类都可以接收到这一类消息[通告消息]:由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息,为的是向其父窗口(通常是对话框)通知事件的发生。这类消息也是以WM_COMMAND形式呈现。从CCmdTarget(CWnd的父类)派生的类都可以接收到这一类消息总结:凡是从CWnd派生的类,既可以接收标准消息,也要以接收命令消息和通告消息。而对于那些从CCmdTarget派生的类,则只能接收命令消息和通告消息,不能接收标准消息。注意:1)从CWnd派生的类,都可以接收到[标准消息]、[命令消息]和[通告消息]。2)从CCmdTarget派生的类,都可以接收到[命令消息]和[通告消息]。3)CCmdTarget是CWnd的父类3.

MFC中菜单项消息如果利用ClassWizard来对菜单项消息分别在上述四个类中进行响应,则菜单消息传递顺序:View类--Doc类--CMainFrame类--App类。菜单消息一旦在其中一个类中响应则不再在其它类中查找响应函数。菜单消息与前面介绍的标准消息的实现机制是相类似的,都是在消息响应函数原型(头文件),消息映射宏(源文件)和消息函数实现(源文件)中添加代码。注意:文档类与应用程序类都是由CCmndTarget类派生,所以可以接收菜单命令消息,但不能接收标准消息(只能由CWnd类派生才可以)。具体消息路由过程:当点击一个菜单项的时候,最先接受到菜单项消息的是CMainFrame框架类,CMainFrame框架类将会把菜单项消息交给它的子窗口View类,由View类首先进行处理;如果View类检测到没对该菜单项消息做响应,则View类把菜单项消息交由文档类Doc类进行处理;如果Doc类检测到Doc类中也没对该菜单项消息做响应,则Doc类又把该菜单项消息交还给View类,由View类再交还给CMainFrame类处理。如果CMainFrame类查看到CMainFrame类中也没对该消息做响应,则最终交给App类进行处理。4.

一个菜单栏可以有若干个子菜单,一个子菜单又可以有若干个菜单项等。对菜单栏的子菜单由左至右建立从0开始的索引。对特定子菜单的菜单项由上至下建立了从0开始的索引。访问子菜单和菜单项均可以通过其索引或标识(如果有标识的话)进行。相关重要函数:CMenu*GetMenu();//CWnd::GetMenu得到窗口菜单栏对象指针。CMenu*GetSubMenu(

);//CMenu::GetSubMenu获得指向弹出菜单对象指针 UINTCheckMenuItem();//CMenu::CheckMenuItem添加选中标识BOOLSetDefaultItem();//CMenu::SetDefaultItem为指定菜单设置缺省菜单项BOOLSetMenuItemBitmaps();//CMenu::SetMenuItemBitmaps设置位图标题菜单。UINTEnableMenuItem();//CMenu::EnableMenuItem使菜单项有效,无效,或变灰。BOOLSetMenu(CMenu*pMenu);//CWnd::SetMenu在当前窗口上设置新菜单或移除菜单。HMENUDetach();//CMenu::Detach;断

温馨提示

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

评论

0/150

提交评论