第一讲WINDOWS程序设计.docx
《第一讲WINDOWS程序设计.docx》由会员分享,可在线阅读,更多相关《第一讲WINDOWS程序设计.docx(26页珍藏版)》请在冰点文库上搜索。
第一讲WINDOWS程序设计
WINDOWS程序设计
●为什么要学习Windows程序设计
1.软件产业的发展,需要人们在Windows下编程。
2.过程驱动的程序设计、面向对象的程序设计、事件驱动的程序设计的区别。
3.理解Windows原理。
●学习Windows程序设计的入口点
本课程是学习在Windows下编程的入门级课程,它通过讲授在Windows下编程的最基本的概念使我们对在Windows下编程的基本原理有一个透彻的理解,在此基础上,为我们进一步学习高级的软件开发工具VC、VB等打下坚实的基础,如果在没有对在Windows下编程的基本概念有一个比较全面的了解之前,就贸然地去学习VC、VB等开发工具,你会发现有很多概念你根本就不明白是怎么回事,你会遇到很大的障碍,其结果是事倍功半。
著名专家CharlesPetzold主张学习在Windows下的编程的最佳入口点是从学习WindowsAPI开始,他指出“Windows是一个复杂的系统,在API上增加一个编程层并未减少它的复杂性,仅仅是掩盖了它,早晚您会碰到它,了解API会给您更好的补救机会”。
●参考书:
WindowsProgramming(Ver.5)
CharlesPetzold
MicrosoftPress
Windows程序设计
北京大学出版社,1999年11月
第一讲:
基本概念
●ProgramWindowsElements
每一个Windows程序窗口一般都有一个标题条、菜单条、系统菜单框、窗口最小化框、窗口恢复框、窗口删除框、窗口客户区、窗口边框。
●Windows程序框架结构
HELLOWIN.C
/*------------------------------------------------------------
HELLOWIN.C--Displays"Hello,Windows98!
"inclientarea
(c)CharlesPetzold,1998
------------------------------------------------------------*/
#include
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,
PSTRszCmdLine,intiCmdShow)
{staticTCHARszAppName[]=TEXT("HelloWin");
HWNDhwnd;
MSGmsg;
WNDCLASSwndclass;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
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=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=szAppName;
if(!
RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("ThisprogramrequiresWindowsNT!
"),
szAppName,MB_ICONERROR);
return0;
}
hwnd=CreateWindow(szAppName,//windowclassname
TEXT("TheHelloProgram"),//windowcaption
WS_OVERLAPPEDWINDOW,//windowstyle
CW_USEDEFAULT,//initialxposition
CW_USEDEFAULT,//initialyposition
CW_USEDEFAULT,//initialxsize
CW_USEDEFAULT,//initialysize
NULL,//parentwindowhandle
NULL,//windowmenuhandle
hInstance,//programinstancehandle
NULL);//creationparameters
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
returnmsg.wParam;
}
LRESULTCALLBACKWndProc(HWNDhwnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
HDChdc;
PAINTSTRUCTps;
RECTrect;
switch(message)
{
caseWM_CREATE:
PlaySound(TEXT("hellowin.wav"),NULL,SND_FILENAME|SND_ASYNC);
return0;
caseWM_PAINT:
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rect);
DrawText(hdc,TEXT("Hello,Windows98!
"),-1,&rect,
DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
return0;
caseWM_DESTROY:
PostQuitMessage(0);
return0;
}
returnDefWindowProc(hwnd,message,wParam,lParam);
}
1.程序入口点:
一个Windows程序有且只有一个WinMain函数。
其中在文件windows.h中定义了在Windows下编程的所有的函数原型、数据类型和系统常数,CALLBACK、WINAPI是关键词,一些数据类型在windows.h中定义如下:
typedefunsignedintUINT;
typedefUINTWPARAM;
typedefLONGLPARAM;
typedefLONGLRESULT;
PSTR是指向字符串的指针类型,相当于char*;
HINSTANCE是程序实例句柄类型;
HWND是窗口句柄类型;
2.窗口:
窗口是一个对象,其代码是窗口过程;数据是在窗口过程和窗口类中保存的信息,每一个窗口都有一个窗口句柄。
3.窗口类:
窗口是在窗口类的基础上创建的,窗口类标识了处理窗口消息的窗口过程。
使用窗口类使多个窗口能够基于同一个窗口类,并且使用同一个窗口过程。
4.句柄:
句柄是一个整数,它代表一个对象。
如窗口句柄指向一个窗口对象。
5.消息:
消息是实现不同对象之间通讯的一种机制。
6.消息队列:
Windows程序开始执行后,Windows为该程序创建一个消息队列,这个消息队列用来存放该程序可能创建的各种不同的消息。
●Windows程序的执行过程
●窗口过程
1.处理的消息,必须返回0;即return0;
2.不处理的消息,由DefWindowProc()处理。
3.WM_CREATE消息的产生与处理只一次。
4.WM_PAINT消息:
当窗口客户区域的一部分或全部变成“无效”,以致必须刷新时,系统将产生这个消息;
(1)当窗口被最初创建时,整个客户区域都是无效的,第一个WM_PAINT消息通常是在WinMain()中调用UpdateWindow()直接发送给窗口过程函数;
(2)当窗口的大小发生变化时,整个客户区域都变得无效;
(3)当窗口区域的一部分不再被其他窗口遮盖之后,先前被遮盖的客户区域将变得无效;
(4)BeginPaint()和EndPaint():
处理WM_PAINT消息,必须使用BeginPaint()和EndPaint(),在BeginPaint()调用中,它使用注册窗口类的WNDCLASS结构的hbrBackGround域中指定的刷子来删除背景,BeginPaint()调用使整个客户区域有效,BeginPaint()和EndPaint()必须成对出现。
(5)设备描述表:
指物理输出设备。
(6)如果窗口过程不处理WM_PAINT消息,则必须把它传给DefWindowProc()来处理,DefWindowProc()函数依次调用BeginPaint()和EndPaint()以使整个客户区域有效。
5.WM_DESTROY消息:
这个消息指示,Windows正在根据用户的输入来清除窗口,PostQuitMessage(0)在程序的消息队列里放入WM_QUIT消息。
6.入队消息和不入队消息:
不入队的消息直接发向窗口过程,下列函数产生不入队消息
CreateWindow()WM_CREATE
ShowWindow()WM_SIZE
UpdateWindow()WM_PAINT;
7.消息循环与窗口过程不是并发执行的;
8.窗口过程是可重入的;
9.ASCII与UNICODE:
ASCII用8位表示一个字符,UNICODE用16位表示一个字符;
ASCII:
TCHARchar,一个字符只占一个字节;
UNICODE:
TCHARwchar_t,一个字符只占两个字节;
TEXT()是系统定义的宏代换,当用ASCII码表示字符时,编译程序自动把TEXT()包含的字符串用8位表示一个字符,当用UNICODE表示字符时,编译程序自动把TEXT()包含的字符串用16位表示一个字符;
●上机步骤
1.创建新工程:
File/new/Win32Application
2.projectName:
输入工程名
3.选择:
AnemptyProject
4.加入源代码:
1)project/addtoproject/new/C++SourceFile在File域输入文件名
2)File/New/C++SourceFile在File域输入文件名
3)project/addtoproject/Files在对话框中选择要加入的文件
5.Build/RebuildAll/execute
6.加入多媒体库文件:
Project/settings/link在object/librarymodules域winmm.lib
附录(原文阅读):
为了让大家理解更深刻一些,特把原书部分章节整理如下,内容写的很详细,仅供参考。
RegisteringtheWindowClass
Awindowisalwayscreatedbasedonawindowclass.Thewindowclassidentifiesthewindowprocedurethatprocessesmessagestothewindow.
Morethanonewindowcanbecreatedbasedonasinglewindowclass.Thewindowclassdefinesthewindowprocedureandsomeothercharacteristicsofthewindowsthatarecreatedbasedonthatclass.Whenyoucreateawindow,youdefineadditionalcharacteristicsofthewindowthatareuniquetothatwindow.
Beforeyoucreateanapplicationwindow,youmustregisterawindowclassbycallingRegisterClass.Thisfunctionrequiresasingleparameter,whichisapointertoastructureoftypeWNDCLASS.
typedefstruct
{
UINTstyle;
WNDPROClpfnWndProc;
intcbClsExtra;
intcbWndExtra;
HINSTANCEhInstance;
HICONhIcon;
HCURSORhCursor;
HBRUSHhbrBackground;
LPCTSTRlpszMenuName;
LPCTSTRlpszClassName;
}
WNDCLASS,*PWNDCLASS;
InWinMain,youdefineastructureoftypeWNDCLASS,generallylikethis:
WNDCLASSwndclass;
Youtheninitializethe10fieldsofthestructureandcallRegisterClass.
ThetwomostimportantfieldsintheWNDCLASSstructurearethesecondandthelast.Thesecondfield(lpfnWndProc)istheaddressofawindowprocedureusedforallwindowsbasedonthisclass.InHELLOWIN.C,thiswindowprocedureisWndProc.Thelastfieldisthetextnameofthewindowclass.Thiscanbewhateveryouwant.Inprogramsthatcreateonlyonewindow,thewindowclassnameiscommonlysettothenameoftheprogram.
Theotherfieldsdescribesomecharacteristicsofthewindowclass,asdescribedbelow.Let'stakealookateachfieldoftheWNDCLASSstructureinorder.
Thestatement
wndclass.style=CS_HREDRAW|CS_VREDRAW;
combinestwo32-bit"classstyle"identifierswithaCbitwiseORoperator.TheWINUSER.HheaderfilesdefinesawholecollectionofidentifierswiththeCSprefix:
#defineCS_VREDRAW0x0001
#defineCS_HREDRAW0x0002
#defineCS_KEYCVTWINDOW0x0004
#defineCS_DBLCLKS0x0008
#defineCS_OWNDC0x0020
#defineCS_CLASSDC0x0040
#defineCS_PARENTDC0x0080
#defineCS_NOKEYCVT0x0100
#defineCS_NOCLOSE0x0200
#defineCS_SAVEBITS0x0800
#defineCS_BYTEALIGNCLIENT0x1000
#defineCS_BYTEALIGNWINDOW0x2000
#defineCS_GLOBALCLASS0x4000
#defineCS_IME0x00010000
Identifiersdefinedinthiswayareoftencalled"bitflags"becauseeachidentifiersetsasinglebitinacompositevalue.Onlyafewoftheseclassstylesarecommonlyused.ThetwoidentifiersusedinHELLOWINindicatethatallwindowscreatedbasedonthisclassaretobecompletelyrepaintedwheneverthehorizontalwindowsize(CS_HREDRAW)ortheverticalwindowsize(CS_VREDRAW)changes.IfyouresizeHELLOWIN'swindow,you'llseethatthetextstringisredrawntobeinthenewcenterofthewindow.Thesetwoidentifiersensurethatthishappens.We'llseeshortlyhowthewindowprocedureisnotifiedofthischangeinwindowsize.
ThesecondfieldoftheWNDCLASSstructureisinitializedbythestatement:
wndclass.lpfnWndProc=WndProc;
ThissetsthewindowprocedureforthiswindowclasstoWndProc,whichisthesecondfunctioninHELLOWIN.C.Thiswindowprocedurewillprocessallmessagestoallwindowscreatedbasedonthiswindowclass.InC,whenyouuseafunctionnameinastatementlikethis,you'rereallyreferringtoapointertoafunction.
ThenexttwofieldsareusedtoreservesomeextraspaceintheclassstructureandthewindowstructurethatWindowsmaintainsinternally:
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
Aprogramcanusethisextraspaceforitsownpurposes.HELLOWINdoesnotusethisfeature,so0isspecified.Otherwise,astheHungariannotationindicates,thefieldwouldbesettoa"countofbytes."(I'llusethecbWndExtrafieldintheCHECKER3programshowninChapter7.)
Thenextfieldissimplytheinstancehandleoftheprogram(whichisoneoftheparameterstoWinMain):
wndclass.hInstance=hInstance;
Thestatement
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
setsaniconforallwindowscreatedbasedonthiswindowclass.Theiconisasmallbitmappicturethatrepresentstheprogramtotheuser.Whentheprogramisrunning,theiconappearsintheWindowstaskbarandattheleftsideoftheprogramwindow'stitlebar.Laterinthisbook,you'lllearnhowtocreatecustomizediconsforyourWindowsprograms.Rightnow,we'lltakeaneasyapproachanduseapredefinedicon.
Toobtainahandletoapredefinedicon,youcallLoadIconwiththefirstargumentsettoNULL.Whenyou'reloadingyourowncustomizediconsthatarestoredinyourprogram's.EXEfileondisk,thisargumentwouldbesettohInstance,theinstancehandleoftheprogram.Thesecondargumentidentifiestheicon.Forthepredefinedicons,thisargumentisanidentif