Windows编程全套课件_第1页
Windows编程全套课件_第2页
Windows编程全套课件_第3页
Windows编程全套课件_第4页
Windows编程全套课件_第5页
已阅读5页,还剩452页未读 继续免费阅读

下载本文档

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

文档简介

Windows编程

第一章语言基础知识C++的发展历程C++是既适合于开发操作系统,也适合于编写应用软件。它是一种既面向对象又面向过程的混合型程序设计语言,它是在C语言的基础之上发展起来的。开发语言的发展:汇编语言、C语言、C++语言、很多其它语言各种C++编译系统:Apple,Sun,Borland和Microsoft等C++语言的类库:标准类库、非标准类库#include<iostream.h> //包含头文件voidmain() //main函数,程序入口,{

char

str_greet[]="Welcome!";//定义数组并初始化

cout<<str_greet<<endl;//在屏幕上输出并换行}//同样功能的C程序:#include<stdio.h>//包含头文件voidmain() //main函数,程序入口{

char

str_greet[]="Welcome!";//定义数组并初始化

printf("%s\n",str_greet);//在屏幕上输出并换行}用C++编写的程序和用C编写的程序在程序结构上基本是相同的,都是以main函数作为程序的入口;两者都是以一对{}把函数中的语句括起来;两者都是以分号作为语句的结束标志。但是,两者也有一些不同之处,C++中是以iostream.h文件作为标准输入输出头文件,C中是以stdio.h作为标准输入输出头文件;C++中采用符号“<<”作为标准输出,而不是通过printf函数来实现。通过上面的例子,可以看出,C++语言和C语言两者之间既有紧密的联系,又各有自己的特点。C++中提供了几种复合数据类型,这些复合数据类型包括数组、结构体、共用体、枚举、类和用户自定义类型。数组数组是具有统一数据类型的对象的集合。每一个单独的对象并没有名字,但是它们可以通过其在数据中的位置来确定。例如:下面的语句定义了一个名为Array的数组,该数组共有10个元素。程序中通过数据元素在数组中的索引值来访问数组元素。

inti,Array[10];

//定义数组,注意,在

//数组中元素的下标是从0开始Array[2]=30;

//为数组元素赋值i=Array[2];

//读取数组元素中的值,

//把它赋给变量i二维数组下面的语句定义了二维数组,该数组的第一维共有10个元素,第二维共有20个元素。intArray[10][20];在二维数组中第一个下标称为行下标,第二个下标称为列下标,上面定义的数组Array相当于是一个具有10行20列的矩阵。数组在定义时,系统将自动为它分配一块连续的内存空间。此时,数组名指向这块空间的起始点,并且在程序中不可改变。也就是说,一个数组名相当于一个常量。结构体在程序设计中,有时需要将某些相关的具有不同类型的数据组织到一个数据类型中。为此,C++中提供了这样一种复合数据类型,它被称为结构体。定义一个结构体类型的一般形式为:

struct结构体名

{

成员表列;

};下面的语句中定义了一个有关学生的名为student的结构体,它包括学生的学号、姓名、性别和年龄等不同数据类型的信息。structstudent{ intStuNo;

//学生学号

charStuName[20];

//学生姓名

charGender;

//学生性别

intAge;

//学生年龄};应当注意:structstudent是程序设计者自己定义的类型名。它和系统已定义的标准类型(如int,char,float和double等)一样可以用来作为定义变量的类型。定义了结构体类型后,还必须定义该结构体类型的变量,才能使用该结构体。定义结构体变量的方法有以下三种先定义结构体类型再定义变量名(普遍使用)例如,上面已定义一个结构体类型struct

student,可以用它来定义结构体student的两个变量stu1,stu2。structstudentstu1,stu2;变量stu1、stu2为structstudent类型变量,即它们具有structstudent类型的结构。在定义类型的同时定义变量下面的语句在定义结构体类型student的同时定义了stu1、stu2两个变量。structstudent{ intStuNo; charStuName[20]; charGender; intAge;}stu1,stu2;直接定义结构体变量下面的语句中直接定义了两个结构体变量stu1和stu2但没有出现结构体类型名。(很少使用)struct

//此处省略了结构体名{ intStuNo; charStuName[20]; charGender; intAge;}stu1,stu2;结构体成员可以嵌套,即结构体可以包含另一个结构体变量。共用体在程序设计中,有时需要使几种不同类型的变量存放在同一内存单元中。这种使几种不同的数据类型的变量共占同一段内存的结构,称为“共用体”(有时也称“联合体”)类型的结构。“共用体”类型变量的定义形式为:

union共用体名

{

成员列表;

};下面的语句中定义一个名为data的共用体,并定义了i和ch两个data共用体的成员及u1和u2两个共用体变量。

uniondata { inti; charch; };

datau1,u2;

可以看出,共用体和结构体的定义相似。但它们的含义是不同的,二者区别:结构体变量所占内存长度是各成员占内存长度之和。每个成员分别有其自己的内存单元。共用体变量所占内存等于最长成员的长度。枚举如果一个变量只有几种可能的值,可以定义为枚举类型。枚举是指将变量的值一一列举出来,变量的值只限于在列举出来的值的范围内。下面的语句定义一个名为color的枚举类型,并定义了一个枚举类型的变量My_color。enumcolor{Red,Green,Blue,Yellow};enumcolor

My_color;定义的枚举变量My_color是枚举变量,它的值只能是Red到Yellow之一。例如:下面的语句给枚举变量My_color赋值。My_color=Red;用户自定义数据类型在C++中可以用typedef定义新的类型名来代替已有的类型名。用typedef来重新定义数据类型可以提高程序的可靠性和可移植性。习惯上常把typedef定义的类型名用大写字母表示,以便与系统提供的标准类型标识符相区别。以下选自windef.htypedefunsignedlongDWORD;typedefint BOOL;typedefunsignedcharBYTE;typedefunsignedshortWORD;typedefstructtagPOINT{LONGx;LONGy;}POINT,*PPOINT;typedefstructtagRECT{LONGleft;LONGtop;LONGright;LONGbottom;}RECT,*PRECT;常量及其定义常量是指用以表达有固定数值或字符值的单词符号,在程序中不允许修改。通过使用关键字const,将能使一个变量定义为一个常量。例如:下面的语句中定义了一个表示缓冲区大小的常量。

constintbufSize=1024;

上面这一语句将使bufSize被定义为一个符号常量并初始化为1024,如果在程序中试图改变bufSize的值,则将引起一个错误。由于一个const类型的量一经定义后就不能改变它的值,因此在定义时必须同时初始化。变量为了使不同的程序员设计的程序能构很好地互相交流,在基于Windows的VC程序中广泛采用匈牙利记法来标识变量。匈牙利表示法用小写字母作为变量名的前缀,以说明变量的数据类型,其余部分描述该变量的意义与功能。例如:HANDLEhWnd;常用匈牙利表示法前缀的类型及其说明前缀类型说明chchar字符bBOOL布尔值n(I)int整数wWORD16位无符号数lLONG32位有符号数dwDWORD32位无符号数lpszLPTSTR指向字符串的32位指针hHANDLE窗口对象句柄指针与引用一个指针变量所存储的信息是一个对象在内存中的地址。通过指针,可以间接地访问对象。每一个指针都有一个相应的类型。该类型用以说明指针所指地址中存放的数据类型。一个指针所占的内存空间大小与一个内存地址所占空间相等。也就是说,一个int指针与一个double型指针占用同样大小的内存空间。在定义指针时,应在指针变量名前冠以星号“*”。下面的语句定义一个整型变量,并用该整型变量的地址初始化一个指针变量。intStu_No=6002;int*ipStu_No=&Stu_No;

//使指针变量

//ipStu_No取得变量Stu_No的地址*ipStu_No=6003;//使用指针修改了变量

//Stu_No的值最常用的指针类型是char*。这是因为C++中,所有有关字符串的操作都是通过字符指针来完成的。

字符串常量的类型是一指向该字符串中第一个字符的字符指针。也就是说所有字符串常量都是类型char*的对象。程序员可以说明一个char*型的变量,并用一个字符串给它初始化。例如:下面就是一个定义字符串指针并加以初始化的例子。char*stExample=“Theexampleofstring!”;指针的运算指针可以让它的地址值增加或减少一个整数值,这类指针操作被称为指针的算术运算(pointerarithmetic),指针加2意味着给指针持有的地址值增加了该类型两个对象的长度,例如假设一个char是一个字节,一个int是4个字节。指向同一个数组的指针可以进行比较运算。voidmain(){

int

array[5]={1,2,3,4,5};

int*pArrayBegin=array;

int*pArrayEnd=array+5;

for(;pArrayBegin<pArrayEnd;pArrayBegin++){

cout<<*pArrayBegin<<"的地址是:";

cout<<pArrayBegin<<endl;}}某次运行的结果如下:1的地址是:0x0012FF6C2的地址是:0x0012FF703的地址是:0x0012FF744的地址是:0x0012FF78

的地址是:0x0012FF7CPressanykeytocontinue引用引用是变量的一个别名,当建立引用时,程序用另一个变量或对象的名字初始化它,对引用的改动,实际上是对目标的改动。引用类型是指对给定类型对象的引用。定义格式如下:

T&标识符=左值表达式它建立了标识符与左值表达式所标识的对象之间的映射关系,值得注意的是,对引用对象的定义必须初始化。下面的语句中定义了两个引用类型合法定义

intvalue; int&Value1=value;//合法定义引用类型

//声明value1是对整数的引用

//初始化为引用value非法的定义

int&Value2;

//非法定义引用类型一个引用类型通常被认为是另一变量的别名,在使用时当作某个对象的第二个名字。所有在引用变量上施加的操作实际上都作用到被引用变量的身上。例如:

inta; int&r1=a; int&r2=r1; r2=10;

//这里r2也引用对象a,对象a被更新为10函数一个程序可以分成一系列“单一功能模块”的集合。在C++中,“单一功能模块”就是函数。一个完整的C++程序一般包含一个主函数和若干个子函数,主函数可以调用其它的子函数,子函数之间也可以互相调用。函数定义的一般形式如下:

类型标识符函数名(形参列表)

{

函数体;

}在形参列表中,程序员必须指定每一个参数的数据类型。在调用函数时,大多数情况下,主调函数和被调函数之间有参数传递的关系。因此,程序中广泛使用的函数还是有参数的函数。在有参数的函数中,在定义函数时的函数名后的括号中的变量名被称为“形式参数”(简称“形参”),在调用函数时,函数名后面括号中的表达式称为“实际参数”(简称“实参”)。struct

student

{

int

No;

char

Name[20];

int

Age;};bool

print1(student

st){

cout<<"学号:"<<st.No<<endl;

cout<<"姓名:"<<st.Name<<endl;

cout<<"年龄:"<<st.Age<<endl;

return

true;}bool

print2(student*st){

cout<<"学号:"<<(*st).No<<endl;

cout<<"姓名:"<<(*st).Name<<endl;

cout<<"年龄:"<<(*st).Age<<endl;

return

true;}bool

print3(student*st){

cout<<"学号:"<<st->No<<endl;

cout<<"姓名:"<<st->Name<<endl;

cout<<"年龄:"<<st->Age<<endl;

return

true;}bool

set(student&st){

cout<<"学号:"<<endl;cin>>st.No;

cout<<"姓名:"<<endl;cin>>st.Name;

cout<<"年龄:"<<endl;cin>>st.Age;

return

true;}void

add(int

x,int

y,int*z){ *z=x+y;}void

setname(struct

student*p,char*p1){

strcpy(p->Name,p1);}void

main(){

int

i=100,j=200,k=500,l=10;

int*p;

void(*p1)(int

x,int

y,int*z);

p=&k;

add(i,j,p);

p1=add;

p1(400,500,&l);

int

index;

struct

student

st[sum];

for(index=begin;index<sum;index++) {

cout<<"学号:"<<endl;cin>>st[index].No;

cout<<"姓名:"<<endl;cin>>st[index].Name;

cout<<"年龄:"<<endl;cin>>st[index].Age; }

for(index=begin;index<sum;index++) {

print1(st[index]); }

set(st[2]);

print2(&st[2]);

struct

student

st1,st2;

st1.Age=18;

st1.No=1;

strcpy(st1.Name,"nana");

struct

student*ps;

ps=&st2;

ps->Age=20;

ps->No=2;

setname(ps,"mingming");

print3(ps);

print3(&st1);}401VisualC++简介是Windows环境下最主要的应用开发系统之一是C++语言的集成开发环境与Win32紧密相连强大的调试功能为大型复杂软件的开发提供了有效的排错手段2可视化指软件开发阶段的可视化利用计算机图形技术和方法一、VisualC++6.0简介及开发环境的构成413开发环境开发环境是程序员同VC++的交互界面通过它,可以创建工程文件访问资源编辑器使用内部调试器访问程序源代码424菜单简介Edit菜单File菜单View菜单Insert菜单43Project菜单Build菜单Tools菜单Windows菜单44File->New->Files(1)VC++的菜单栏File菜单45File->New->Projects46断点作用:中断程序的执行过程,以便检查程序代码、变量和寄存器值位置断点数据断点消息断点用来设置删除和查看断点(a)Breakpoints选项(2)VC++的菜单栏Edit菜单47位置断点通常在源代码的指定行、函数的开始或指定的内存地址处设置,当程序执行到指定位置时,位置断点将中断程序的执行在位置断点中还可以设置断点条件,此时必须先指定位置,然后再设置条件断点数据断点是在变量或表达式上设置,当变量或表达式的值改变时,数据断点将中断程序的执行消息断点是在窗口函数WndProc上设置,当接收到指定的消息时,消息断点将中断程序的执行48(b)ListMembers选项利用此选项,可减轻输入代码的工作量。如在变量名之后键入“.”或“->”,系统就会自动显示所有有效的成员名供选择(c)TypeInfo选项

如果在源代码中将鼠标指针停在某一变量或函数上,那么系统将显示所指变量或函数等的语法提供有效的成员名49(d)ParameterInfo选项

当输入代码时,若在输入函数名之后键入左括号,系统将显示该函数的完整原型,并用黑体显示其第一个参数。输入第一个参数之后,接着就会出现第二个参数,依此类推(e)CompleteWord选项

系统自动完成当前语句其余部分的输入。如果不能自动完成,则给出适当的提示辅助用户完成50在View菜单中可以:改变窗口改变工具栏的显示方式检查源代码激活调试等View->ClassWizard选项(a)ClassWizard选项(3)VC++的菜单栏View菜单51(a-1)ClassWizard中的MessageMaps选项卡为窗口、对话框、控件、菜单选项和加速键等对象映射消息创建或删除消息处理函数查看消息处理函数的代码52(a-2)MemberVariables选项卡:定义成员变量用于自动初始化其中:

ControlIDs是映射到成员变量的控件ID值

Type是成员变量的类型

Member是成员变量名53(a-3)Automation选项卡:

此选项卡主要将在创建新类时,添加自动化方法和属性列出已经添加到当前类中的方法和属性的名称Externalnames中的方法和属性的实现方法54(a-4)ClassInfo选项卡:提供有关类的信息55(b)ResourceSymbols选项该选项将打开资源符号浏览器,从中可以浏览资源编辑符号资源编辑符号是映射到整数值上的一串字符,相当于资源的一个代号,在同一个程序中,资源编辑符号不能重复56(c)ResourceIncludes选项

该对话框包含资源符号头文件名和预处理指令。57(d)Workspace选项

如果工作区没有显示或者不是处于当前状态,则选择该项将显示工作区窗口。(e)Output选项

在输出窗口中显示程序建立过程(如编译、链接等)的有关信息或错误信息,并且显示调试运行时的输出结果。58(a)NewClass选项该选项用来创建新类并添加到项目中(4)VC++的菜单栏Insert菜单59(b)NewForm选项该选项用来创建新的表单并添加到项目中(c)Resource选项该选项将打开InsertResource对话框,用以创建新的资源或插入资源文件中(d)ResourceCopy选项要选中该选项必须先选中某个资源,否则呈灰色。该选项用于复制选定的资源60(e)NewATLObject选项该选项将启动ATLObjectWizard,以便添加新的ATL对象61使用Project可以创建、修改和存储正在编辑的工程文件

工程文件组合了一个应用程序的所有源文件的组成部分。工程文件包含在扩展名为.MAK的文件中。(5)VC++的菜单栏Project菜单62(b)AddToProject选项

选择该选项将打开一个级联子菜单通过级连子菜单,可以把文件、文件夹、数据链接以及VC组件或控件添加到当前工程文件中在该子菜单中可以进行如下操作:(1)New:创建新的文件;(2)NewFolder:插入新的文件夹;(3)Files:插入已有文件;(4)DataConnection:添加数据链接;(5)ComponentandControls:通过该项将可以插入VC组件或者已注册的ActiveX控件。插入时相当于插入相关的头文件(.h文件)和实现文件(.cpp文件),并且更新工作区窗口的信息。(a)SetActiveProject选项设定指定的项目为工作区的活动项目63(c)Settings选项选择该选项将弹出ProjectSettings对话框,其中General选项卡用来设置基础类用法和目录指出应用程序与MFC的链接方式指出所建立的应用程序的缺省位置为Debug目录输出文件的位置64Build菜单用于编译、建立和执行应用程序(b)Build选项对最后修改过的源文件进行编译和链接(a)Compile选项只编译当前文件而不调用链接器或其它工具。输出窗口将显示编译过程检查出的错误或警告信息,在错误信息处单击鼠标右键,可以得到错误代码的位置(c)

RebuildAll选项该选项允许用户编译所有的源文件,而不管它们何时曾经被修改过(6)VC++的菜单栏Build菜单65(d)BatchBuild选项

该选项能单步重新建立多个工程文件,并允许用户指定要建立的项目类型Win32Release(发行版)、Win32Debug(调试版)。VC提供了两种应用程序类型66(e)

StartDebug选项从当前语句开始执行程序直到遇到断点或遇到程序结束单步执行程序,并在遇到函数调用时进入函数内部再从头单步执行使程序在运行到当前光标所在位置时停止(相当于设置一个临时断点)调试过程中直接进入到正在运行的进程中67(a)SourceBrowse选项

编译器在建立项目时会创建与项目中每一程序文件信息有关的.SBR文件。BSCMAKE程序将这些.SBR文件汇编为单个浏览信息数据库

选择SourceBrowse将弹出浏览窗口,它显示与程序中所有符号(类、函数、数据、宏和类型)有关的信息Tools菜单允许用户快速地访问多个不同的开发工具(7)VC++的菜单栏Tools菜单68(b)VisualComponentManager选项

该工具可以在某个工程中组织、寻找和插入相关组件,而且还可以识别已存在的且可利用的对象。选择该选项将弹出如图所示的窗口69在工作区中添加项目:

用File->Open选项可打开已存在的项目;通过New对话框的Projects选项卡创建新的项目,并选择Addtocurrentworkspace复选框。

VC以项目工作区的形式来组织文件、项目和项目配置1.创建新的项目工作区创建新的空工作区步骤:(a)File->New->Workspaces->输入工作区名字并指定工作区目录二、项目与项目工作区702.项目工作区窗口简介

VC项目工作区由ClassView、ResourceView及FileView三个面板组成71在VC中,源代码或资源编辑器为了引用资源和用户自定义的其它对象,于是就引入了一种与资源一一对应的符号即资源符号,使之能够以字符串的方式被引用。

资源符号是映射到整数值上的一串字符,是一种标识符。每当创建一个新的资源或资源对象时,系统就会为其提供一个缺省的资源符号名称并赋一个整数值,该定义保存在resource.h文件中。资源图标光标菜单位图对话框资源是一种界面元素,用户可以从中获得信息并在其中执行某个动作三、资源及资源编辑器72单击New按钮新建资源符号输入新资源符号的名称由于资源符号不能重复,因此应按照一种标准来定义资源符号进行符号定义View->ResourceSymbols(1)资源的建立73资源符号的取值范围一般为0~32767(2)资源符号定义的常用前缀

74程序调试工具包括源程序语法检查、可执行程序修改和运行监视等应用程序Help和Setup开发工具包系统函数库和系统函数开发工具资源管理器包括图形化窗口及组成元素的多种对象的编辑器可选择并构成具体语句或源程序结构的例程库及Help源程序编辑器和编译器可视化开发系统集成了一系列系统可用资源和开发工具一、Windows编程基础75采用交互式方法时,可视化开发平台给出了许多选用的对象,程序员可选择所需对象并确定其属性,由此搭建起应用程序的“大框架”,并可根据需要进一步编写必要的细节代码段,最后构成完整的应用程序Windows的程序设计语言VCVBVJ都是“面向对象”的程序设计语言对象是Windows的规范部件窗口菜单按钮对话框程序模块编写Windows程序相当一部分工作是在创建对象和为对象属性赋值对象特征:具有规范形态和操作模式编程方法传统编写法-->API交互式方法-->MFC76APIAPI函数的功能为应用程序提供Windows系统特殊函数及数据结构Win应用程序可以利用标准大量API函数调用系统功能是Win系统与Win应用程序间的标准程序接口窗口管理函数实现窗口的创建、移动和修改功能系统服务函数:实现与操作系统有关的多种功能图形设备(GDI)函数:实现与设备无关的图形操作功能77

利用Windows

API函数编写Windows应用程序必须首先了解以下内容:(1)窗口的概念(2)事件驱动的概念(3)句柄(4)消息78(1)窗口 一个应用程序的窗口一般包含下列成分:窗口边界工作区控制菜单框下拉菜单水平滚动条垂直滚动条最大化按钮最小化按钮标题栏79编写一个Windows应用程序首先应创建一个或多个窗口,随后应用程序的运行过程即是窗口内部、窗口与窗口之间、窗口与系统之间进行数据处理与数据交换的过程。应用程序与用户之间交互的接口环境系统管理应用程序的基本单位Win应用程序基本的操作单元80Windows程序设计是针对事件或消息的处理进行

消息是描述事件发生的信息(如按下鼠标或键盘)事件驱动编程方法对于编写交互式程序很有用处,它避免了死板的操作模式Windows程序的执行顺序取决于事件发生的顺序,程序的执行顺序是由顺序产生的消息驱动的,但是消息的产生往往并不要求有次序之分。(2)事件驱动

81常用句柄类型及其说明句柄是一个4字节长的数值,用于标识应用程序中不同的对象和同类对象中不同的实例窗口按钮图标滚动条输出设备控制文件(3)句柄应用程序通过句柄访问相应的对象信息HWND 窗口句柄 HDC 设备环境句柄HBITMAP 位图句柄 HCURSOR 光标句柄HICON 图标句柄 HFONT 字体句柄HMENU 菜单句柄 HPEN 画笔句柄HFILE 文件句柄 HBRUSH 画刷句柄

HINSTANCE 当前实例句柄82

Windows应用程序利用Windows消息(Message)与应用程序及系统进行信息交换。typedefstructtagMSG

{HWNDhwnd; 窗口句柄,为null,则可检索所有驻留在消息队列中的消息

UINTmessage;消息值,由Windows.h头文件中的宏定义来标识

WPARAMwParam;包含有关消息的附加信息,不同消息其值有所不同

LPARAMlParam;

DWORDtime;指定消息送至队列的时间

POINTpt;指定消息发送时屏幕光标的位置,其数据类型POINT也是一个结构体}MSG;消息号:由事先定义好的消息名标识字参数(wParam):用于提供消息的附加信息长字参数(lParam):用于提供消息的附加信息消息附加信息与具体消息号的值有关,在Win中消息用结构体MSG表示typedefstructtagPOINT{LONGx;

LONGy;}POINT;(4)消息83(4)消息

VC中存在几种系统定义的消息分类,不同的前缀符号经常用于消息宏识别消息附属的分类,系统定义的消息宏前缀如下:BM 表示按钮控制消息CB 表示组合框控制消息DM 表示默认下压式按钮控制消息EM 表示编辑控制消息LB 表示列表框控制消息SBM 表示滚动条控制消息WM 表示窗口消息窗口管理消息初始化消息输入消息系统消息剪贴板消息控制处理消息控制通知消息滚动条通知消息非用户区消息MDI消息DDE消息应用程序自定义的消息Windows编程常用消息84二、Windows应用程序常用消息1.WM_LBUTTONDOWN:产生单击鼠标左键的消息此外,相似的消息还有:WM_LBUTTONUP:放开鼠标左键时产生;WM_RBUTTONDOWN:单击鼠标右键时产生;WM_RBUTTONUP:放开鼠标右键时产生;WM_LBUTTONDBLCLK:双击鼠标左键时产生;WM_RBUTTONDBLCLK:双击鼠标右键时产生。1Param高字节包含当前光标的Y坐标值低字节包含当前光标的X坐标值wParam包含一整数值以标识鼠标键的按下状态MK_LBUTTON 按下鼠标左键MK_MBUTTON 按下鼠标中键MK_RBUTTON 按下鼠标右键852.WM_KEYDOWN:按下一个非系统键时产生的消息

系统键是指实现系统操作的组合键,例如Alt与某个功能键的组合以实现系统菜单操作等。3.WM_CHAR:按下一个非系统键时产生的消息wParam为按键的ASCII码1Param与WM_KEYDOWN的相同wParam:按下键的虚拟键码,用以标识按下或释放的键1Param:记录了按键的重复次数、扫描码、转移代码、先前键的状态等信息。相似的消息还有WM_KEYUP,在放开非系统键时产生如F1的虚拟键码在Windows.h文件中定义为VK_F186系统键的消息经常由与Alt相组合的按键产生,这些按键启动程序菜单或者系统菜单上的选项,或者用于切换活动窗口等系统功能(Alt-Tab或者Alt-Esc),也可以用作系统菜单加速键(Alt键与一个功能键相结合,例如Alt-F4用于关闭应用程序)。应用程序通常忽略这些消息,并将它们传送到DefWindowProc。由于Windows要处理所有Alt键的功能,一般无需拦截这些消息。87这里特别提醒要注意WM_KEYDOWN,WM_KEYUP与WM_CHAR消息在使用上是有区别的。在前两个消息中,伴随消息传递的是按键的虚拟键码,所以这两个消息可以处理非打印字符,如方向键,功能键等。而伴随WM_CHAR消息的参数是所按的键的ASCII码,ASCII码是可以区分字母的大小写的。而虚拟键码是不能区分大小写的。884.WM_CREATE:由CreateWindow函数发出的消息wParam:未用1Param:包含一个指向CREATESTRUCT数据结构的指针5.WM_CLOSE:关闭窗口时产生的消息wParam和1Param均未用。6.WM_DESTROY:由DestroyWiodow函数发出的消息wParam和1Param均未用。897.WM_QUIT:由PostQuitMessage函数发出的消息退出应用程序时发出的消息wParam:含退出代码,标识程序退出运行时的有关信息1Param:未用8.WM_PAINT用户区移动或显示用户窗口改变大小程序通过滚动条滚动窗口下拉式菜单关闭并需要恢复被覆盖的部分Windows清除对话框等对象,并需要恢复被覆盖的部分均产生WM_PAINT消息909.WM_MOVE,WM_SIZE

当窗口移动的时候产生WM_MOVE消息,窗口的大小改变的时候产生WM_SIZE消息。

91三、Windows中的事件驱动程序设计启动输入姓名输入第一次测试成绩输入第二次测试成绩输入第三次测试成绩计算平均成绩结束过程驱动方法计算平均成绩启动消息处理结束输入姓名输入第一次成绩输入第二次成绩输入第三次成绩计算平均成绩事件驱动方法计算平均成绩92四、Windows应用程序组成及编程步骤

1.

应用程序的组成一个完整的Windows应用程序通常由五种类型的文件组成。1.C语言源程序文件2.头文件 3.模块定义文件 4.资源描述文件 5.项目文件 932.源程序组成结构入口函数WinMain窗口函数WndProcWindows应用程序构成基本框架包含各种数据类型、数据结构与函数等1.所有应用程序的入口,类似Main函数,2.完成一系列的定义和初始化,并产生消息循环WinMain和WinProc是Windows应用程序的主体94(1)WinMain函数三个基本的组成部分:函数说明、初始化和消息循环功能注册窗口类,建立窗口及执行必要的初始化进入消息循环,据接受的消息调用相应的处理过程当消息循环检索到WM_QUIT时终止程序运行WinMain函数WinMain函数说明WinMain函数的说明如下:intWINAPIWinMain(

HINSTANCEhThisInst, ∥应用程序当前实例句柄

HINSTANCehPrevInst, ∥应用程序其他实例句柄

LPSTRlpszCmdLine, ∥指向程序命令行参数的指针

IntnCmdShow ∥应用程序开始执行时窗口显示方式的整数值标识)注意!Win是多任务管理的,同一应用程序的多个窗口可能会同时存在,系统对每个窗口的执行称为一个实例,并用一个实例句柄来唯一标识95(2)初始化(a)窗口类定义

通过给窗口类数据结构WNDCLASS赋值完成,该数据结构中包含窗口类的各种属性。窗口类定义常用以下函数:LoadIcon的作用是在应用程序中加载一个窗口图标。其原型为:HICONLoadIcon(HINSTANCEhInstance,LPCTSTRlpIconName)图标资源名或系统预定义图标标识名图标资源所在的模块句柄,NULL则使用系统预定义图标初始化显示窗口创建窗口实例窗口类的注册:窗口类必须先注册后使用窗口类的定义:定义窗口的形式与功能LoadIconLoadCursorGetStockObjectRegisterClassCreateWindow

ShowWindow,UpdateWindow96LoadCursor的作用是在应用程序中加载一个窗口光标HCURSORLoadCursor(HINSTANCEhInstance, LPCTSTRlpCursorName)光标资源所在的模块句柄,NULL则使用系统预定义光标光标资源名或系统预定义光标标识名应用程序调用函数GetStockObject获取系统提供的背景刷HBRUSHGetStockObject(intnBrush);97(b)注册窗口类Win系统本身提供部分预定义的窗口类,程序员也可以自定义窗口类,窗口类必须先注册后使用。窗口类的注册由函数RegisterClass()实现。

RegisterClass(&wndclass);//wndclass为窗口类结构

RegisterClass函数的返回为布尔值,注册成功则返回真98(c)创建窗口实例创建一个窗口类的实例由函数CreateWindow()实现函数原型如下:HWNDCreateWindow(

LPCTSTRlpszClassName,∥窗口类名

LPCTSTRlpszTitle, ∥窗口标题名

DWORDdwStyle, ∥创建窗口的样式

intx,y, ∥窗口左上角坐标

intnWidth,nHeight, ∥窗口宽度和度高

HWNDhwndParent, ∥该窗口的父窗口句柄

HWENUhMenu, ∥窗口主菜单句柄

HINSTANCEhInstance,∥创建窗口的应用程序当前句柄

LPVOIDlpParam ∥指向一个传递给窗口的参数值的指针

)99100(d)显示窗口窗口类的显示由ShowWindow和UpdateWindow函数实现。应用程序调用ShowWindow函数在屏幕上显示窗口ShowWindow(hwnd,nCmdshow);//nCmdshow为窗口显示形式标识显示窗口后,应用程序调用UpdateWindow更新并绘制用户区,并发出WM_PAINT消息。

UpdateWindow(hwnd);101(3)消息循环消息循环的常见格式如下:MSGMsg;…while(GetMessage(&Msg,NULL,0,0)){

TranslateMessage(&Msg);

DispatchMessage(&Msg);

}将消息的虚拟键转换为字符信息将消息传送到指定窗口函数从消息队列中读取一条消息,并将消息放在MSG结构中

其中函数GetMessage形式为:GetMessage(lpMSG, //指向MSG结构的指针

hwnd,

nMsgFilteMin,//用于消息过滤的最小消息号值

nMsgFilterMax//用于消息过滤的最大消息号值)返回零值,即检索到WM_QUIT消息,程序结束循环并退出将消息传递给窗口函数的相应过程处理消息队列Windows将产生的消息WinMain函数1022.窗口函数WinProcWinProc函数由一个或多个switch语句组成。每一条case语句对应一种消息,当应用程序接收到一个消息时,相应的case语句被激活并执行相应的响应程序模块。WinProc包含了对各种可能接收到的消息的处理过程定义了应用程序对接收到的不同消息的响应103窗口函数的一般形式如下:LRESULTCALLBACKWndProc( HWNDhwnd,UINTmessgae,WPARAMwParam,LPARAMlParam){…∥message为标识的消息

switch(message)

{

case… …break;…

caseWM_DESTROY:

PostQuitMessage(0);

default:returnDefWindowProc(hwnd,message,wParam,lParam);

}return(0);}

在消息处理程序段中一般都有对WM_DESTROY的处理,该消息是关闭窗口时发出的。它向应用程序发出WM_QUIT消息,请求退出处理函数:

voidPostQuitMessage(intnExitCode)

//nExitCode为应用程序的退出代码为未定义处理过程的消息提供缺省处理1043.数据类型

在Windows.h中定义了Windows

应用程序中包含种类繁多的数据类型1054.一些重要的数据结构MSG:包含一个消息的全部信息,是消息发送的格式WINDCLASS:包含一个窗口类的全部信息及属性POINT:定义了屏幕上或窗口中的一个点的X和Y坐标RECT:定义了一个矩形区域及其左上角和右下角的坐标几种重要的结构106五、应用程序举例【例2-1】创建应用程序框架。本例的目的在于说明创建Windows应用程序的方法及过程#include<windows.h> //包含应用程序中所需的数据类型和数据结构的定义LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//窗口函数说明//以下初始化窗口类intWINAPIWinMain(HINSTANCEhInstance, HINSTANCEhPrevInst,LPSTRlpszCmdLine,intnCmdShow){

HWNDhwnd;

MSGMsg;

WNDCLASSwndclass;

charlpszClassName[]="窗口"; //窗口类名

charlpszTitle[]="My_Windows"; //窗口标题名107

//窗口类的定义wndclass.style=0; //窗口类型为缺省类型wndclass.lpfnWndProc=WndProc; //定义窗口处理函数wndclass.cbClsExtra=0; //窗口类无扩展wndclass.cbWndExtra=0; //窗口实例无扩展wndclass.hInstance=hInstance; //当前实例句柄wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION); //窗口的最小化图标为缺省图标wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); //窗口采用箭头光标wndclass.hbrBackground=GetStockObject(WHITE_BRUSH); //窗口背景为白色wndclass.lpszMenuName=NULL; //窗口中无菜单wndclass.lpszClassName=lpszClassName; //窗口类名为"窗口"108

//以下进行窗口类的注册if(!RegisterClass(&wndclass))//如果注册失败则发出警告

{

MessageBeep(0);

returnFALSE;

}//创建窗口

hwnd=CreateWindow (

lpszClassName, //窗口类名

lpszTitle, //窗口实例的标题名

WS_OVERLAPPEDWINDOW, //窗口的风格

CW_USEDEFAULT, CW_USEDEFAULT, //窗口左上角坐标为缺省值

CW_USEDEFAULT, CW_USEDEFAULT,, //窗口的高和宽为缺省值

NULL, //此窗口无父窗口

NULL, //此窗口无主菜单

hInstance, //创建此窗口的应用程序的当前句柄

NULL //不使用该值

);109//显示窗口ShowWindow(hwnd,nCmdShow);//绘制用户区UpdateWindow(hwnd);//消息循环

while(GetMessage(&Msg,NULL,0,0)){

TranslateMessage(&Msg);

DispatchMessage(&Msg);}returnMsg.wParam;//消息循环结束即程序终止时将信息返回系统}110/窗口函数LRESULTCALLBACKWndProc( HWNDhwnd, UINTmessage, WPARAMwParam, LPARAMlParam){switch(message){

caseWM_DESTROY: PostQuitMessage(0);

default: //缺省时采用系统消息缺省处理函数

returnDefWindowProc(hwnd,message,wParam,lParam);

}return(0);}调用PostQuitMessage发出WM_QUIT消息1111121.程序初始化过程中调用CreateWindow,为程序建立了一个窗口,做为程序的舞台。CreateWindow产生窗口之后会送出WM_CREATE直接给窗口函数,后者于是可以在此时机做些初始化动作(例如配置内存、打开文件、读初始数据...)。2.程序活着的过程中,不断以GetMessage从消息队列中抓取消息。如果这个消息是WM_QUIT,GetMessage会传回0而结束while循环,进而结束整个程序。1133.DispatchMessage透过WindowsUSER模块的协助与监督,把消息分派至窗口消息。消息将在该处被判别并处理。4.程序不断进行2.和3.的动作。5.当使用者按下系统菜单中的Close命令项,系统送出WM_CLOSE。通常程序的窗口函数不拦截此消息,于是DefWindowProc处理它。6.DefWindowProc收到WM_CLOSE后,调用DestroyWindow把窗口清除。1.GDI的一些基本概念

设备描述表即为设备环境的属性的集合应用程序与输出设备之间的桥梁Win系统外设直接访问不允许统一的设备环境(DC)提供使应用程序与设备相连用户为确保图形输出的设备无关性应用程序设备描述表及其属性通过设备描述表的句柄来间接地存取应用程序每一次图形操作均参照设备描述表中的属性执行2.图形刷新图形刷新是绘图过程中必须考虑的重要问题刷新请求对刷新请求的响应刷新方法包括(1)刷新请求

应用程序在窗口中绘制了一个椭圆,颜色列表框覆盖了椭圆的一部分关闭颜色选框后,应用程序需要恢复被覆盖部分的颜色和形状窗口大小的调整窗口移动被覆盖后的恢复(2)系统对刷新请求的响应

当用户区的内容需要刷新时,系统向应用程序消息队列发送WM_PAINT消息,系统在应用程序的消息队列中加入该消息,以通知窗口函数执行刷新处理三种刷新窗口移动后的刷新被覆盖区域的刷新对象穿越后的刷新(系统自动完成)用户区移动或显示用户窗口大小改变程序通过滚动条滚动窗口窗口被另一个窗口覆盖的恢复如下拉式菜单关闭等光标穿过用户区图标拖过用户区窗口被另一个窗口覆盖的区域称为无效区域。系统为每个窗口建立了一个PAINTSTRUCT结构,该结构中包含了包围无效区域的一个最小矩形的结构RECT,应用程序可以根据这个无效矩形执行刷新操作。TypedefstructtagPAINTSTRUCT{HDChdc; //设备环境句柄

BOOLfErase; //一般取真值,表示擦除无效矩形的背景

RECTrcPaint; //无效矩形标识

BOOLfRestore; //系统保留

BOOLfIncUpdate; //系统保留

BYTErgbReserved[16];//系统保留

}PAINTSTRUCT;rcPaint为标准的RECT数据结构,其作用是标识无效矩形,它包含了无效矩形的左上角和右下角的坐标常用的Windows应用程序刷新窗口的方法保存副本。刷新时将副本拷贝到相应的窗口中记录事件。刷新时重新执行这个曾经发生的事件重新绘制。将图形绘制处理程序放在消息WM_PAINT响应模块中,刷新时重绘图形(3)有效的刷新方法3.获取设备环境的方法获取设备环境是应用程序输出图形的先决条件,常用的两种方法是调用函数BeginPaint或GetDC(1)调用BeginPaint函数应用程序响应WM_PAINT消息进行图形刷新时,主要通过调用BeginPaint函数获取设备环境

hdc=BeginPaint(hwnd,&ps);//ps为PAINTSTRUCT类型结构定义方式为:PAINTSTRUCTps;

系统获取设备环境的同时填写ps结构,以标识无效矩形区由BeginPaint函数获取的设备环境要用EndPaint函数释放voidEndPaint(HWNDhwnd,PAINTSTRUCT&ps)(2)调用GetDC函数

如果绘图工作并非由WM_PAINT消息驱动,则调用GetDC函数获取设备环境。hdc=GetDC(hwnd);

由GetDC函数获取的设备环境必须用ReleaseDC函数释放

voidReleaseDC(HWNDhwnd);4.映像模式 映像模式定义了将逻辑单位转化为设备的度量单位以及设备的x方向和y方向,程序员可在一个统一的逻辑坐标系中操作而不必考虑输出设备的坐标系情况窗口:对应逻辑坐标系上程序员设定的区域视口:对应实际输出设备上程序员设定的区域窗口和视口如何映射?缺省的映射模式将窗口中的对称图形映射到视口时仍为对称图形按照窗口和视口的坐标比例进行映射坐标系统逻辑坐标系统设备坐标系统屏幕坐标系统窗口坐标系统用户区坐标系统

应用程序可获取设备环境的当前映像模式,并根据需要设置映像模式。相关函数设置设备环境的映像模式SetMapMode(hdc,nMapMode);

nMapMode为映像模式的整型标识符获取当前设备环境的映像模式nMapMode=GetMapMode(hdc);窗口区域的定义由SetWindowExtEx函数完成,其函数原型形为:BOOLSetWindowExtEx(HDChdc, intnHeight,nWidth,//以逻辑单位表示的窗口区域高宽度

LPSIZElpSize,//函数调用前窗口区域尺寸的SIZE结构地址);视口区域的定义由SetViewportExtEx函数完成,函数原型为:BOOLSetViewportExtEx(HDChdc, intnHeight,nWidth,//以物理设备单位表示的新视口区域高宽度LPSIZElpSize );只有在映射模式为MM_ANISOTROPIC和MM_ISOTROPIC时才有意义视口的缺省原点和窗口的缺省原点均为(0,0)。可通过调用函数SetViewportOrgEx和SetWindowOrgEx设定窗口与视口的原点。SetWindowOrgEx函数的原形为:BOOLSetWindowOrgEx(HDChdc,intX,Y, //以逻辑单位表示的窗口原点坐标LPPOINTlpPoint //函数调用前原点坐标的POINT结构的地址);只有在映射模式为MM_ANISOTROPIC和MM_ISOTROPIC时才有意义127MM_TEXT映射方式假设显示区域为cxClient个像素宽和cyClient个像素高。如果想将逻辑点(0,0)定义为显示区域的中心,调用SetViewportOrgEx(hdc,cxClient/2,cyClient/2,NULL)SetViewportOrgEx的参数总是使用设备单位。现在,逻辑点(0,0)将映射为设备点(cxClient/2,cyClient/2),而显示区域的座标系变成如下形状:129用下面的SetWindowOrgEx叙述可以获得与上面使用SetViewportOrgEx同样的效果:SetWindowOrgEx(hdc,-cxClient/2,-cyClient/2,NULL);SetWindowOrgEx的参数总是使用逻辑单位。在这个调用之后,逻辑点(-cxClient/2,-cyClient/2)映射为设备点(0,0),即显示区域的左上角。二、绘图工具与颜色1.画笔(1)画笔的创建使用画笔之前必须事先定义一个画笔句柄。形式如下:HPENhP;然后调用函数GetStockObject获取Windows系统定义的四种画笔例如获取画笔BLACK_PEN的形式如下:

hP=GetStockObject(BLACK_PEN);WHITE_PENBLACK_PENNULL_PEN画笔的操作创建画笔将画笔选入设备环境删除画笔(2)创建新画笔,形式如下:hP=CreatePen(intnPenStyle, //确定画笔样式intnWidth, //画笔宽度COLORREFrgbColor//画笔颜色);创建画笔后,必须调用SelectObject函数将其选入设备环境。

SelectObject(hdc,hP);//hP为所创建或获取的画笔句柄不再使用当前画笔时,需删除画笔,以免占内存

DeleteObject(hP);PS_DASH: 虚线 PS_DASHDOT: 点划线 PS_DASHDOTDOT:双点划线PS_DOT: 点线 PS_INSIDEFRAME: 实线PS_NULL: 无 PS_SOLID: 实线2.画刷画刷的创建与应用与画笔很相似,操作画刷也包括创建、选入设备环境和删除。(1)画刷的创建使用画刷需事先定义一个画刷句柄。形式如下:

HBRUSHhBr;//hBr为画刷句柄

然后调用函数GetStockObject获取Windows系统提供的7种画刷

hBr=(HBRUSH)GetStockObject(nBrushStyle)画刷样式BLACK_BRUSH 黑色画刷DKGRAY_BRUSH 深灰色画刷GRAY_BRUSH 灰色画刷HOLLOW_BRUSH 虚画刷LTGRAY_BRUSH 亮灰色画刷NULL_BRUSH 空画刷 WHITE_BRUSH 白色画刷指定颜色画刷如何获得?可调用函数CreateSolidBrush和CreateHatchBrush创建画刷,hBr=CreateSolidBrush(rgbColor);

创建具有指定颜色的单色画刷创建指定阴影图案和颜色的画刷(2)选入设备环境

创建画刷后,通过SelectObject(hdc,hBr);将其选入设备环境(3)删除画刷不使用画刷时,可用DeleteObject(hBr);删除画刷,释放内存hBr=CreateHatchBrush(intnHctchStyle,COLORREFrgbColor );HS_BDIAGONAL45度从左上到右下HS_DIAGCROSS45度叉线 HS_FDIAGONAL45度从左下到右上HS_CROSS 垂直相交的阴影线HS_HORIZONTAL水平阴影线HS_VERTICAL 垂直阴影线3.颜色Windows使用宏RGB定义绘图的颜色,其形式为:

RGB(nRed,nGreen,nBlue)

红色值蓝色值绿色值RGB(255,0,0)RGB(0,255,0)RGB(0,0,255)三、常用绘图函数1.设置画笔当前位置的函数MoveToEx,

BOOLMoveToEx(HDChdc,intX,Y, //X、Y分别为新位置的逻辑坐标

LPPOINTlpPoint //存放原画笔位置的POINT结构地址)2.从当前位置向指定坐标点画直线的函数LineTo,BOOLLineTo(HDChdc,intX,intY)//X和Y为线段的终点坐标3.从当前位置开始,依次用线段连接lpPoints中指定的各点BOOLPolyline(HDChdc,LPPOINTlpPoints,//指向包含各点坐标的POINT结构数组的指针

intnCount //nCount为POINT数组中点的个数)4.绘制椭圆弧线的函数Arc,BOOLArc(HDChdc,intX1,intY1, //边框矩形左上角的逻辑坐标intX2,intY2, //边框矩形右下角的逻

温馨提示

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

评论

0/150

提交评论