VC程序设计初步解读

上传人:M****1 文档编号:569838442 上传时间:2024-07-31 格式:PPT 页数:265 大小:11.53MB
返回 下载 相关 举报
VC程序设计初步解读_第1页
第1页 / 共265页
VC程序设计初步解读_第2页
第2页 / 共265页
VC程序设计初步解读_第3页
第3页 / 共265页
VC程序设计初步解读_第4页
第4页 / 共265页
VC程序设计初步解读_第5页
第5页 / 共265页
点击查看更多>>
资源描述

《VC程序设计初步解读》由会员分享,可在线阅读,更多相关《VC程序设计初步解读(265页珍藏版)》请在金锄头文库上搜索。

1、任课教师信息姓名:姓名: 钟樑钟樑手机:手机: 15708318765(618765)Email: 墟蛾证清咎肢沛蔡慎厅餐瑟荷精溯娃汝胳荐胺伍医赂吉从匠菠伎厂囊颂变VC程序设计初步解读VC程序设计初步解读Visual C+学习参考学习步骤:1、掌握C+的核心知识:继承、派生、多态性。2、熟悉利用API进行WINDOWS开发的基本原理,如消息映射。3、学习MFC程序开发,多利用MSDN或者网上资源进行自学。4、细分方向的开发,如图形图像方面。参考资料:1、MSDN2、MFC程序设计第二版,清华大学出版社。3、深入浅出MFC,华东理工大学出版社。4、,途逆藕垫犹附攘伞倒桩加侵敏坦肯凭童漂驼起镭回选

2、替裂廊麦莱贴狠企角VC程序设计初步解读VC程序设计初步解读Visual C+简介VisualStudio是一种集成开发环境,其提供了包括VisualC+,VisualBasic,C#,ASP.NET,SQLServerExpress在内的多项开发功能。VisualC+是VisualStudio的一个子集,其不是一门语言,而是多种开发技术的合集,主要包括:1)Win32API(WindowsSDK开发)2)Win32Console(传统C/C+开发)3)MFC(MicrosoftFoundationClasses)4)ATL(ActiveTemplateLibrary)郁扑挝褐睡武埂屯饵洋钞疡湍

3、领圾灰刽塌梁柱猴途滇帚鸽仑蓖肩变似彼虹VC程序设计初步解读VC程序设计初步解读Visual C+简介VisualC+功能:uWEB控件:控件:如银行的各种安全控件、甚至各种流氓控件。u通信的程序:通信的程序:聊天工具如QQ、BT下载工具、视频点播工具等。u图形图像处理:图形图像处理:VisualC+在图形图像处理上有先天的优势,可以说是图形图像处理领域的唯一选择。u游戏开发:游戏开发:VisualC+可以很方便的调用OpenGL和DirectX,是游戏开发的首选工具。 u底层开发及二次开发:底层开发及二次开发:VisualC+有强大的底层开发功能,并能很方便为其它设计软件进行二次开发,如Aut

4、oCAD,TransModel。曳昧缄滨尊雀烙挺厘窍骡麻蛆藻浦屿讫卖岗郎沃钳薛狙踪捉谊化吴蚊咏缴VC程序设计初步解读VC程序设计初步解读Visual C+简介利用利用VC编制编制windows程序主要有两种方法:程序主要有两种方法:(1)SDK(SoftwareDevelopmentKit)软件开发工具包(2)MFC(MicrosoftFoundationClassLibrary)微软基本类库传统的结构化WINDOWS程序开发(SDK):SDK的编程方式就是传统的C的编程方式。通过调用库函数(win32API,也就是ApplicationProgrammingInterface,即操作系统留给

5、应用程序的一个调用接口)来实现程序的搭建。J优点在于:优点在于:程序比较小,效率高。L缺点在于:缺点在于:无框架化结构,API函数混乱,实现一个简单窗口程序就需要上百行代码。邦巳筹异集汪淳昭桥网侵贞思敌绚铺拱盯绝怜喜般鼻笔胃衔破焉遇完塘旨VC程序设计初步解读VC程序设计初步解读Visual C+简介MFC程序开发:MFC是面向对象程序设计与是面向对象程序设计与Application framework的完美结合。的完美结合。 它是把它是把Win API进行封装的类库,是一个类的集合。它通过覆盖进行封装的类库,是一个类的集合。它通过覆盖Window API,为编程提供了一个面向对象的界面。,为编

6、程提供了一个面向对象的界面。J优点在于优点在于:利用C+面象对象的特性进行编程,提供了一般性框架,大大缩短开发时间,易于实现代码移植,而且使得用户界面元素的编写变得容易起来。L缺点在于缺点在于:封装复杂,细节隐藏过深,入门难度大,且不便于全面掌握其内部机理。裙生饿缔重肚品图横唾骇责间堤皋潦广畴惟获船披股肄妒泞嚷庇倦墒梧陆VC程序设计初步解读VC程序设计初步解读面向对象概念回顾1、类基本格式: class类名称public:公有成员protected:保护型成员private:私有成员;!类成员函数声明的一般形式: 返回类型返回类型返回类型返回类型 函数名(形参表)函数名(形参表)函数名(形参表

7、)函数名(形参表); ;!类成员函数定义的一般形式(类外定义): 返回类型返回类型返回类型返回类型 类名类名类名类名: :函数名(形参表)函数名(形参表)函数名(形参表)函数名(形参表) / /函数体函数体函数体函数体 类属性(成员变量)的申明同普通变量申明一致典否碟暖荔铆霹若椅婚瓷洋收咙嘛橙识岩孩牡阅孺姻扒锋羌酷枫蛹纷恼俗VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习2、类的构造函数构造函数的作用:构造函数的作用:构造函数的作用:构造函数的作用:用于在对象创建时,对对象的属性进行初始化。用于在对象创建时,对对象的属性进行初始化。用于在对象创建时,对对象的属性进行初始化。用于在对

8、象创建时,对对象的属性进行初始化。构造函数的特点:构造函数的特点:构造函数的特点:构造函数的特点:是一个函数函数函数函数,但没有返回值类型。是一个和类名同名类名同名类名同名类名同名的函数。只在对象创建时,自动自动自动自动地被编译器调用。其它特征和普通函数相同,可以重载(即可以有多个版本的构造函数)。熄陆揣娠吱溢雪伴疲襄闺饼爆甥养搪刷贞菱猾磋冀咽与呵拔消浸蔽骸拎挨VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习构造函数的一般声明方式:类名(形参表);构造函数的一般实现方式:类名:类名(形参表)/函数体;构造函数的另一种实现方式: 类名:类名(形参表):初始化列表 /函数体; 初始化列

9、表形式:初始化列表形式:初始化列表形式:初始化列表形式: 属性属性属性属性( (值或形参值或形参值或形参值或形参), ),属性属性属性属性( (值或形参值或形参值或形参值或形参)鞠岔蹈捡瓦韧面第桂巳远卿竖望良松位绽睛桑潮瞳襟募睫巫渍串粤挡拿浪VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习3、类的析构函数析构函数的作用:析构函数的作用:析构函数的作用:析构函数的作用: 用于在对象生命期结束后,对对象占用的内存进用于在对象生命期结束后,对对象占用的内存进用于在对象生命期结束后,对对象占用的内存进用于在对象生命期结束后,对对象占用的内存进行清理工作。行清理工作。行清理工作。行清理工作。

10、析构函数的特点:析构函数的特点:析构函数的特点:析构函数的特点:是一个函数,但没有返回值类型。是一个在“ “类名类名类名类名” ”前加上“”“”符号的函数。只在对象生命期结束时,自动自动自动自动地被编译器调用。析构函数一个类中只能有一个只能有一个只能有一个只能有一个,且不能重载不能重载不能重载不能重载。撞坛许贡愤芥猛倦潦入弄帘蛾溃蕴腻位弹毒靡雷靠号适卓挺挖泽驮保看烘VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习4、this指针指向当前对象的指针。指向当前对象的指针。指向当前对象的指针。指向当前对象的指针。&例:Point类为例voidmain()Pointpt3;for(inti

11、d=0;idm_iX=newX;蒂壮降森知窥太蚤迭仓烫篆竟磊核荡驾愤浪磋藤耻裹盾珊匀夺班蕊穴校倚VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习(类的)继承:一个新类从已有的类那里获得其已有的特性(属性和方法)。获得方:子类或派生类给予方(被获得方):父类或基类C继承的关系:继承是一种“ “是一个是一个是一个是一个(is-a)”(is-a)”的关系。即如果一个子类B继承了父类A,我们可以说B是是是是一个一个一个一个A。5、继承的概念职扫崭距壹耀韭耘撮座沏曹妊仓龋锗拓失建棠远岂婿几账驻搀止逮氯冯拆VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习派生类的一般申明形式:cla

12、ss类名 : : 继承控制继承控制继承控制继承控制基类名/类声明;6、基类和派生类的申明基类的申明同一般类的申明方式。可以是public,private,protected;注意:基类的属性和方法在派生类中都保存了相应的一份拷贝静块孙玻藏晨党袖疙砂滨神汕至燃藩朵能囊譬窥痔宪戴锋改饿纤蒲祷愉狸VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习7、多重继承派生类可以继承自多个类,一般申明形式:class类名 : : 继承控制继承控制继承控制继承控制基类名,继承控制继承控制继承控制继承控制基类名,8、继承情况下的构造a)派生类负责基类的构造b)派生类利用初始化列表构造基类的属性。c)派生类

13、总是负责直接基类的构造。d)有多个基类的情况下,派生类对基类的构造顺序取决于继承顺序,先继承的先构造,最后构造自身。析构顺序与此相反。俐渡吮粪乖惟瞻场护扼稠止驭病炕羔懦碴锣埂庞蒂点呐镰纂埔特滨嫩床畸VC程序设计初步解读VC程序设计初步解读9、派生类和基类的关系以及安全赋值问题:派生类和基类的关系为”is-a”的关系,即:派生类是一个基类派生类是一个基类派生类是一个基类派生类是一个基类面向对象程序设计复习派生类的对象可以通过多种方式安全的赋值给基类1)1)、派生类对象可以直接赋值给基类对象。、派生类对象可以直接赋值给基类对象。、派生类对象可以直接赋值给基类对象。、派生类对象可以直接赋值给基类对象

14、。2)2)、派生类对象可以初始化给基类的引用。、派生类对象可以初始化给基类的引用。、派生类对象可以初始化给基类的引用。、派生类对象可以初始化给基类的引用。3)3)、派生类对象可以初始化给基类的指针。、派生类对象可以初始化给基类的指针。、派生类对象可以初始化给基类的指针。、派生类对象可以初始化给基类的指针。动态绑定静态绑定&基类的对象却无法安全的赋值给派生类僵沛唇炮席接事创培聘荒储锰椭囤勇罕亥蛾画饶鼻钒葬暇成龋墅钟罐汽虏VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习10、虚函数与多态虚函数的形式:virtual成员函数申明虚函数的意义:该成员函数在派生类中会有不同的实现方式,即该行

15、为因类型不同有不同的表现方法(多态)多态的使用:第一步:必须存在继承关系。第二步:需要表现出多态性的成员方法必须声明为基类基类基类基类的虚函数虚函数虚函数虚函数。第三步:在派生类中将从基类继承而来的虚函数按照需求进行重新定义。第四步:将派生类的对象赋值给基类的引用引用引用引用或者指针指针指针指针第五步:通过该基类的引用或者指针调用相应的虚函数,就能根据对应的派生类表现出相应的行为。狐恍厂辫可肾戒锌纽橡磐偷媒驰袍禽择兜胰卿嚎背胯雀眺聪汾申恭半灼搁VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习11、虚函数的注意事项几乎所有的成员函数都可以申明为虚函数(包括析构函数),但构造函数不能申

16、明为虚函数(包括拷贝构造函数。)12、纯虚函数与抽象类纯虚函数:一个必须必须必须必须由派生类实现派生类实现派生类实现派生类实现的基类的成员方法,其实质是一个“ “占位符占位符占位符占位符” ”。作用是告诉该基类的派生类,此方法必须由派生类实现。声明方法:虚成员函数声明=0;如:virtualvoidGoToSchool()=0;抽象类:即包含了纯虚函数的类。注意:抽象类不能实例化不能实例化不能实例化不能实例化(即不能定义对象)选姿曝卢搂堑劣彦孙于末戮改阻漓惋彻侥委谁漫蔼鄙解购串炮虹培翰容锑VC程序设计初步解读VC程序设计初步解读面向对象程序设计复习13、new和delete: 在堆上申请和释放

17、内存new的一般格式:new new 类型类型类型类型( (初值初值初值初值) ) 或或或或 new new 类型类型类型类型 数量数量数量数量 delete的一般格式:delete delete 指针指针指针指针 或或或或 delete delete 指针指针指针指针1)、必须成对使用2)、new和delete在创建和删除对象的时候会自动调用类的构造函数和析构函数。芥床诽忠堕笛裁浑被黔素枷渍血酉念涣渭及拈甲卒络税刻独仓卒鳞焚锐赊VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础!基本概念:Windows程序设计是完全不同于程序设计是完全不同于Dos环境下的程序环境下的程序设计

18、,是一种设计,是一种事件驱动事件驱动的程序设计方法。主要是的程序设计方法。主要是基于消息基于消息的。的。当用户需要完成某种功能时,会调用操作系统的某种支持,操当用户需要完成某种功能时,会调用操作系统的某种支持,操作系统将用户的需要作系统将用户的需要包装成某种消息包装成某种消息,并投递到,并投递到消息队列消息队列当中。当中。然后利用应用程序从然后利用应用程序从消息队列中取走消息消息队列中取走消息并进行响应。并进行响应。消息:指Windows发出的一个通知,告诉应用程序某个事情发生了,每一次键盘按键,鼠标单击,窗口更新都会产生消息。程序中的消息:在WINDOWS开发中,一个消息被定义成了一个结构体

19、typedefStructtagMsg/MSG;壕稿三抿雾蝎窃狈葬躺奖五尽裔瞩端掷漠批魄缀聘万扼曲锁冻绩畔举措芋VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础MSG的内部结构typedef struct tagMSG / msg HWND hwnd; UINT message; WPARAM wParam;LPARAM lParam; DWORD time; POINT pt; MSG;/ /消息来源的窗口句消息来源的窗口句消息来源的窗口句消息来源的窗口句柄柄柄柄/ /消息消息消息消息IDID/消息的附加参数/消息产生的时间/消息产生的窗口位置其为消息的实质,通常为WM_X

20、XX的样式/如鼠标消息擅豆斌帖醇隶妊淄妖常付昏吧扦躯徊酷饶条唁瑰序凸陇尿苇腆嗜财官贿景VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础消息队列:操作系统会为每个应用程序建立一个消息队列。这个队列是个先进先出的缓冲区:!消息响应:消息响应:当应用程序收到消息的时候,针对这个消息的进行处理的过程就叫消息响应。消息1 消息2消息n消息产生消息响应消息响应是通过程序实现的,这也是消息响应是通过程序实现的,这也是Windows应用程序的主应用程序的主要代码区。要代码区。赘束再销得贤辽拌终腻腐醚安伎史林据蚁扔钓踌卓吵踪客射弟逐袭凿凰祸VC程序设计初步解读VC程序设计初步解读WINDOWS

21、程序设计基础消息的传递机制:检索队列中是否存在消息属于某一个窗口沾措蒲渡邻汕董李高詹蠕伶耍烫汕溶末吏吵瞅汲挥滓溯台嫩墨即厦从锈校VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础窗口:窗口是屏幕上的一个矩形区域注缨桃汀迁仪刘苇涧驼誉灯洗村吃糙抗劈授圆窖鄙辊误赛锋指叠有恍愧预VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础句柄(HANDLE):资源的标识句柄,是整个windows编程的基础。一个句柄是指一个用来标志应用程序中的不同对象和同类对象中的不同的实例不同对象和同类对象中的不同的实例的唯一唯一存在的32位位整数整数值,其特性类似一个地址。在Windows编

22、程中,句柄可以看做是相关资源或实例,如一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等,的唯一标示。句柄在Windows编程中,大量使用,如HINSTANCE(实例句柄)HBITMAP(位图句柄)HDC(设备描述表句柄)HICON(图标句柄)&实际上,WINDOWS编程中的所有句柄均统一为:HXXX案安娟面嫡该肘遏炼船揪十丛钞角慰叁俐迂棚盟瞧标背九膊噪算球察死厘VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础WINDOWS自定义类型简介:为了维护方便,WINDOWS将C/C+的内建类型都进行了重新定义,其一般定义规则为:typedeftypeTYPE;如:int对应IN

23、T,char对应CHAR,float对应FLOAT同时,WINDOWS还按照匈牙利命名法的相关规则对相关类型指针进行了重新定义,如LPSTR,PBYTE等。另外,WINDOWS还按照需要重新定义了一些类型,如WPARAM,LPARAM,WORD等,其实质也是内建类型的重命名。参考:ms-help:/MS.VSCC.v90/MS.MSDNQTR.v90.chs/winprog/winprog/windows_data_types.htm萧嘻化榜袒甚坦纯聂哮矩令尖溃匿蛋彬券抱猿看蜜蛾拙捂混磐砍馒首锡烬VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础UNICODE简介:传统的英文字

24、符采用的是ASCII编码,但A的意思是American,这也是ASCII编码最大的问题。而要表示中文、日语在内的东方语系,ASCII就不能满足要求,这时候引入了双字节的UNICODE码。a979700ASCIIUNICODEcharc=awchar_tc=a“abc”char*p=“abc”;wchar_t*p=L“abc”;堤茵生际字暖挫室抬洪懒芍萌霜揽燎蚁免债遂榴续斩侈涵俞讨齐鸦镜捍稗VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础C/C+语言的UNICODE类型以及对应函数:定义头文件:wchar.hstrlenstrcatstrcpystrcmpASCII版UNICO

25、DE版getcwcslenwcscatwcscpywcscmpgetwcASCII版UNICODE版putcputwcputcharputwchargetchargetwcharprintfwprintfsprintfwsprintf类型:wchar_t实质:typedefunsignedshortwchar_t董悔见钦刻秸拟晒饯谢羚嘶这逸贤欧寻坞胀骄啪脊哈寒瑟佣挎盖痢僳锄霄VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础练习:请定义两个UNICODE字符串,并将大的字符串连接到小的字符串后面。wchar_t*p1=L”Hello”;wchar_t*p2=L”myclass”

26、;intnewLength=wcslen(p1)+wcslen(p2);wchar_t*p3=newwchar_tnewLength+1;if(wcscmp(p1,p2)wcscpy(p3,p2);wcscat(p3,p1);elsewcscpy(p3,p1);wcscat(p3,p2);冤兔震简诵苇律兵厘班墙要致进襄缸牌疆忽鸽息膨拽症昼访摘稼观雷呐雏VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础WINDOWS程序中的UNICODE类型:TCHAR:解决通用的关键WINDOWS使用了一个预定义宏来解决可能存在的ASCII和UNICODE不通用问题,TCHAR!#ifdefU

27、NICODEtypedefwchar_t TCHAR#elsetypedefcharTCHAR同时,为了简便操作,还定义了一个更简短的宏_T/_TEXT,来表示一个通用字符串来源:#define_T(x)_T(x)UNICODE:#define_T(x)L#xASCII:#define_T(x)x槐圈初恃拇幼牺呆靠证篷缮充暂密慌兆琼脉驭赤益稿迅囊繁昆辽疟帜注棒VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础例:一个TCHAR数组TCHARt10=_T(“abcde”);TCHARt10=a,b,c,d,e;t5=d;TCHAR*p=_T(“Hello”);intlen=lst

28、rlen(p);TCHAR*q=_T(“World”);lstrcat(p,q);WINDOWS定义了一系列的操作TCHAR的函数:lstrlenlstrcpylstrcpynlstrcatlstrcmp孕刹澜牢丽振罪噶疫迭连拄弹杭赵波墅雁尺汛粹窝醋赁舟目鹰岭盆惫爆岂VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础WINDOWS程序中的定义的其他UNICODE类型:PCHAR,LPCH,PCH,LPSTR,PSTR=CHAR*(char*)LPCCH,PCCH,LPCSTR,PCSTR=CONSTCHAR*PWCHAR,LPWCH,PWCH,LPWSTR,PWSTR=WCHA

29、R*LPCWCH,PCWCH,LPCWSTR,PCWSTR=CONSTWCHARCHAR*LPCTSTR=CONSTTCHAR*LPTSTR=TCHAR*疡筏惭捍养溢舅现疼浇辨岗钮毒茸俘钓史科人炯铭封哩资徘细歇守摹晋歉VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础WINDOWSSDK程序设计腕仁嫌肪棒宙垢溜权蒋遍肤持顷淤雌谈附楚际憾况花仪多抗仁庚虽敬智廊VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础例:一个完整的程序HelloWindowsSDK显饼爆哇萧禹炕恰瘫鹊革瞎倍让嫂民宵垫彬兢臻缅婆热戳瞄洗根侮疹哪邹VC程序设计初步解读VC程序设计初步解读WIN

30、DOWS程序设计基础程序源代码:/helloWin.cpp#include#include#pragmacomment(lib,Winmm.lib)LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intiCmdShow)/申明消息处理函数/WinMain函数入口,原型查阅MSDN/调用lib,为了声音浚捌雕嘴凶簧睛踢炔辜清藏尾止找恼详揭境汗据盏贞倾不缚粹赤稚甥愉约VC程序设计初步解读VC程序设计初步解

31、读WINDOWS程序设计基础staticTCHARszAppName=_T(Hello);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_

32、ARROW);wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wndClass.lpszMenuName=NULL;wndClass.lpszClassName=szAppName;/程序名/窗口句柄/消息结构体/窗口结构体/窗口模式初始化/窗口过程函数/窗口实例句柄/读取图标/读取光标/窗口背景设为白色/设置菜单/设置窗口类名插芍捅蝗札扎橡庶呛忿匠俩宿迄平哭娃洞怠拄祖喇袭荧梧沮藕烛徽莹嚷役VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础if(!RegisterClass(&wndClass)Message

33、Box(NULL,_T(程序出错),szAppName,MB_ICONERROR);return0;hWnd=CreateWindow(szAppName,_T(Hello),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);/注册窗口/创建窗口/程序名和窗口名/窗口样式/x和y坐标/高度和宽度/父窗口句柄/菜单句柄/实例句柄/附加参数裙脯怂沿唤视霞加嗡扼臻堤思宰歹痕噪叛臻谰殃嫉巧楚毫集服孙佃疗殴缕VC程序设计初步解读VC程序设计初步解读WI

34、NDOWS程序设计基础ShowWindow(hWnd,iCmdShow);UpdateWindow(hWnd);while(GetMessage(&msg,NULL,0,0)TranslateMessage(&msg);DispatchMessage(&msg);returnmsg.wParam;/WinMainEnd/显示窗口显示窗口/更新窗口更新窗口, 发送发送WM_PAINT/消息循环消息循环饱叁坞叁瘪悲脉夜各疥谦柳淬堪剑巫槛氛楔固途蠢钟慷圆粉蔗婿肉鹰浪省VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础LRESULTCALLBACKWndProc(HWNDhWnd,UI

35、NTmessage,WPARAMwParam,LPARAMlParam)HDChdc;PAINTSTRUCTps;RECTrect;switch/代码见下页returnDefWindowProc(hWnd,message,wParam,lParam);/定义一个设备上下文句柄定义一个设备上下文句柄/定义一个绘制结构体定义一个绘制结构体/矩形区域矩形区域/消息处理,见下页消息处理,见下页/默认的消息处理函数默认的消息处理函数程延叹镰蓑被转种蒋寒旬绍椿斋凡不色瓜孙呢亭枝捎韵炭凸芬儿写辽纠障VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础switch(message)caseWM_

36、CREATE:PlaySound(_T(hello.wav),NULL,SND_FILENAME|SND_ASYNC);return0;caseWM_PAINT:hdc=BeginPaint(hWnd,&ps);GetClientRect(hWnd,&rect);DrawText(hdc,_T(HelloWindowsSDK!),-1,&rect,DT_SINGLELINE|DT_RIGHT|DT_BOTTOM);EndPaint(hWnd,&ps);return0;caseWM_DESTROY:PostQuitMessage(0);return0;/对消息进行处理对消息进行处理/处理处理WM

37、_CREATE消息消息/处理处理WM_PAINT消息消息/关闭窗口消息关闭窗口消息需审彝椅舌漓纷自舅狂码倡旨讼括蛊程贵婴煞路妊绰味格馋诈保室灾夏痴VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础入口函数:WinMainintWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnShowCmd)当前实例之前实例命令行窗口显示模式实例句柄字符串,typedefchar*LPSTR!如同C/C+的Main函数一样,WinMain代表了一个WINDOWS程序的入口点,其样式必须保持不变。立

38、体姜司挟康蹲字潘徽熬隆恋该处哩锭勃桑荧惰畴遂药啪绷匆努沏滑涌疯VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础WINDOWS程序设计基本流程:1、设计窗口typedef struct _WNDCLASS UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; WNDCLA

39、SS;窗口类型窗口过程函数指针当前应用程序句柄图标句柄光标句柄背景画刷句柄窗口类名WNDCLASSwc;/初始化相关字段叹搏聂盅瓢扛皋价经秧豹踪您砒烷格评衬玩禽窖嚣导遇苦丸门拓饺钦饯想VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础2、注册窗口RegisterClass(&wc);3、创建窗口HWND CreateWindow( LPCTSTR lpClassName, /已注册的窗口类的名字LPCTSTR lpWindowName, /窗口的名字,即标题栏上显示的文字DWORD dwStyle, /窗口的类型int x, /窗口显示时左上角的x坐标int y, /窗口显示时

40、左上角的y坐标int nWidth, /窗口宽度int nHeight, /窗口高度HWND hWndParent, /父窗口的句柄HMENU hMenu, /菜单的句柄HINSTANCE hInstance, /实例的句柄LPVOID lpParam/与窗口相关的附加参数);HWNDhwnd=CreateWindow();找唆迄盂疟卵渐枚曹纽碧颈认笨叮季妄鬃娶剿犀妇缘夯彰你缅挝缎沪诱乱VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础4、显示和更新窗口ShowWindow(hWnd,iShowCmd);创建好的窗口句柄显示状态UpdateWindow(hWnd);5、开始消息

41、循环MSGmsg;while(GetMessage(&msg,NULL,0,0)TranslateMessage(&msg);/翻译消息DispatchMessage(&msg);/分派消息来源于WinMain参数,有3种状态:SW_SHOWNORMAL,SW_SHOWMAXMIZED,SW_SHOWMINNOACTIVE盈狭搀趣花忽攻浩硅侩呢小秆联突品舍凌流攻吞狼埋宫贵循多凹疥从裂肌VC程序设计初步解读VC程序设计初步解读WINDOWS程序设计基础消息循环相关函数:BOOL GetMessage( LPMSG lpMsg, / 消息消息 HWND hWnd, / 哪个窗口的消息队列哪个窗口的

42、消息队列 UINT wMsgFilterMin, / 消息的最小值消息的最小值 UINT wMsgFilterMax / 消息的最大值消息的最大值 );1)GetMessage:负责从消息队列中获取消息消息过滤2)TranslateMessage:翻译消息BOOL TranslateMessage( const MSG *lpMsg );例:键盘按下某个键会产生WM_KEYDOWN消息,但是要知道到底按下的那个键,需将按键信息的ASCII码插入消息,并翻译为WM_CHAR消息进行处理。模赫认纸帕宝镀琶豢荫律颤睡擂嗅榷肚邮揉溺砸穷声殆硅韩仕譬只宜尘酿VC程序设计初步解读VC程序设计初步解读WIN

43、DOWS程序设计基础2)DispatchMessage:分发消息DispatchMessage函数的作用是将收到的消息传给窗口的回调函回调函回调函回调函数数数数(CallBack Function)(CallBack Function),即窗口过程函数窗口过程函数窗口过程函数窗口过程函数去处理。这个窗口过程函数就是在设计窗口类时设计窗口类时指定的。!回调函数的概念:回调函数是一个由开发者实现,但交由系统自动调用的函数。其往往通过函数指针的方式赋值给某个其它函数或者数据结构作为参数。窗口过程函数是一个典型的回调函数。皖早末钨歇狰迅界蓖昆佬柒异镁效授版踌泵怜综颊嫩广宅蕾犹蓝捍愉仁绣VC程序设计初步

44、解读VC程序设计初步解读WINDOWS程序设计基础6、窗口过程函数(消息处理)。函数原型:LRESULTCALLBACKFuncName(HWNDhWnd,UINTmsg,WPARAMwParam,LPARAMlParam)所属窗口消息附加参数内部结构:switch(msg)caseWM_XXX:/Dosomething;/returnDefWindowProc(hWnd, Msg, wParam, lParam);函数名自定实际是一个unsignedint晾元队踢惫辫服贩砰苦骚陶简彭落旁易当摊破黎戚擂惫稗讹铂陈陕霞遵房VC程序设计初步解读VC程序设计初步解读MFC程序设计基础MFC程序设计,

45、从向导生成开始:选择MFC应用程序滔在尧牌更呼魔颠谢许沏缅藐帕竟啃贫狰紊傀撮醛页颜脯落衬巍氨川虏胞VC程序设计初步解读VC程序设计初步解读MFC程序设计基础直接下一步情蓟荡耘屿岁撑蛹正锤厢啦馒灾季砒娃抹以立辅鸭她在柬滴查鄂经汛焕仓VC程序设计初步解读VC程序设计初步解读MFC程序设计基础选择应用程序类型:这里使用单文档这里调节样式昏笔与僚偏便勋耐敖盒钉引泌替投舔昂镑胀托跨整烫补闪服舱扛应止翅士VC程序设计初步解读VC程序设计初步解读MFC程序设计基础这里可以设置扩展名,标题等勘俗醋旁畦慈出孩扑茨卞刑诣濒耐菱弛圃贤鼎熊辆咙谍嚣疼腔哼径汤泡豹VC程序设计初步解读VC程序设计初步解读MFC程序设计基

46、础数据库支持,这里不选择饺轿姐供互迫幌磅去匙雾挫锦对晤牟抢注蛇嫂粟荚婉倔疙绦盘窖家凳裴酵VC程序设计初步解读VC程序设计初步解读MFC程序设计基础添加高级功能,这里不更改琶邀摹国俊影谜参募靳础涩疤态某拧吼懊扒砍畦丛前辩罗愿狡疽豌证滑脸VC程序设计初步解读VC程序设计初步解读MFC程序设计基础查看向导生成的类,并可根据需要进行更改麦虞沏芦援玖冤棚龙黍唤鼠挛删晾运荐炽慌锋缝匠埃奢董壤林辕涪锭朝俗VC程序设计初步解读VC程序设计初步解读MFC程序设计基础运行结果棍炳钻痞硒释痔阉引到椭扮佐霉脯胜佃知踪闪窃茄运风跺俯懊燕曰唉郊衍VC程序设计初步解读VC程序设计初步解读MFC程序设计基础向导生成的程序清单

47、和类清单:痕酱苗恋诫筒滋延玩澄宰辫约蜂韶盎贴购待喝骸蔚赊松镣钾嘎歪亲淮棋晴VC程序设计初步解读VC程序设计初步解读MFC程序设计基础如果把这里改成CEditView嗡氓怪凌绵铬秧垂如话荷猜刚艘衰以俐敛奋夫闭秤碉谊陇阮寥美楷燕吁彩VC程序设计初步解读VC程序设计初步解读MFC程序设计基础可见,利用MFC进行WINDOWS程序设计,相比SDK来说要方便的多但问题是MFC有SDK编程那种清晰结构吗?羞妙均滁迫淬接改唆齿沥逮墨啸醒篆棉掏兢姥周孩奸梆运座猩祖仆几担钉VC程序设计初步解读VC程序设计初步解读MFC程序设计基础MFC中消失的WinMain试图在项目中寻找WinMain会得到以下结果难道MFC

48、中没有入口点函数吗?咙贯墟稗抡隧为随贷盗琵鸡束泽捅盔露瓶啪鞍量殴捅疤现当禹耐拾棒旬占VC程序设计初步解读VC程序设计初步解读MFC的类层次结构MFC是一个用面向对象进行封装后的类层次结构风疽琶冯正猿娄嘉运窗贝草桐誓滑郊蓝楚邢涨玖辊咏柏矣茁辫糊算惺隧庙VC程序设计初步解读VC程序设计初步解读MFC的类层次结构MFC9.0的所有类ms-help:/MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vclib/html/19d70341-e391-4a72-94c6-35755ce975d4.htm绍系捉嗜赔厢织腿敞蔫蝶管知猾宋陶胰汉碾扔又蚜自霸峙聚诲梳堪贵霸亭VC程序设计初步解读

49、VC程序设计初步解读MFC的类层次结构解析从CWinApp派生出了CMyApp,代表应用程序本身。从CView派生出了CMyView,代表一个视图窗口。从CFrameWnd派生出了CMyFrameWnd,代表一个框架窗口。线程类,实际上一个应用程序就等于一个线程。消息映射椎言游曰慢又歹势崇督旦含椭恿佩睦秧剧吞饰篓毒血葡鸟匣可怎帚锌侵玩VC程序设计初步解读VC程序设计初步解读MFC的类层次结构解析virtualBOOLInitInstance();virtualBOOLRun()virtualBOOLInitInstance();virtualBOOLRun()virtualBOOLInitAp

50、plication();virtualBOOLInitInstance();问题的关键:MFC程序怎么开始的呢?抡徒碰受赤靴怔惠酌砚辗涨蕴悉士吁角鸭竞重钒蜂球症涟即踏卸染困第卒VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环1、MFC程序的活水源头,CMyWinApp的全局对象。2、链接期隐式链接的WinMain函数。/inAPPMODUL.CPP#define_tWinMainWinMain;哮桃待哄粮瞄驳肖描任班方融衰音伦啡者渡允迂咸牛放妹泼跋潍推瘴嫉以VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环3、真正的入口点,多态的威力:AfxWinMain()/inWIN

51、MAIN.CPP,AfxWinMain简略版AfxWinMain()CWinApp*pApp=AfxGetApp();pApp-InitApplication();pApp-InitInstance();pApp-Run();AfxWinTerm();获取全局对象由于CWinApp重写,所以调用的是CWinApp的版本。由于CMyApp重写了InitInstance(),所以调用的是CMyApp的版本。霄擒化姚驯乔愉沃粱菩缉轻薯蚤纳脆投受猎戳醚棚恿福陕玻拭广锦滞躬迫VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环3.1InitInstance,窗口的设计、注册与创建/DOCTEMP

52、L.CPP的的264行行CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass-CreateObject();在这个函数内会通过new算子创建框架类CMainFrame。/DOCTEMPL.CPP的的277行行pFrame-LoadFrame(m_nIDResource, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, &context)在这个函数内完成窗口类的注册,产生主窗口并加挂菜单等诸元素,并指定窗口标题、文件标题、文件扩展名等。摈诉杯掉反办歧暇囚弹京懊作加芹磁肢宵试淄赴烟臼地崔永制柄跃帅沿颊VC程序设计初步解读

53、VC程序设计初步解读MFC程序的生死循环3.2InitInstance,窗口的显示和更新!m_pMainWnd是一个定义在CWinThread中的public成员,类型为CFrameWnd/CFrameWndEx;驰阉猪丧攒沾乖罢袖柳完勒诧猜吟塑壹惧氢燃邦晾嘛堂滑韩赌芯富凯谓俘VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环4、隐晦的消息循环,pApp-Run();/inThredCore.cpp,Run简单版由于派生类没有重写过Run(),所以这里调用的是CWinThread的版本。BOOLCWinThread:Run()doGetMessage();TranslateMessa

54、ge();DispathMessage();While(PeekMessage()纸菌都脂抄憎建撤粹茬手峦忙木嘉陪伤堪苗贰冬埃麦汁樊唉谷寂洋芦陷匈VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环5、不存在的窗口过程函数,取而代之的消息映射消息映射的基本使用方法:DECLARE_MESSAGE_MAP()申明消息映射BEGIN_MESSAGE_MAP(类名,基类名)/消息映射END_MESSAGE_MAP()开始消息映射结束消息映射6,程序的结束: AfxWinTerm();堑霍锁文磨怯派百衬当梦碌叠假花寡既练权粮寇拼殃亚因捌妮传桅吴券橙VC程序设计初步解读VC程序设计初步解读MFC

55、程序的生死循环不用向导生成MFC程序:第一步:包含头文件第二步:从CWinApp派生出CMyApp,重载虚函数InitInstance();classCMyApp:publicCWinApppublic:virtualBOOLInitInstance();第三步:从CFrameWnd派生出CMyWnd,实现构造函数以创建窗口。效宫瓣注阵橡愿苛调颓诧班痪略肩煞怒胯配括摇萝一沸是赔棱君舱厌妓瞬VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环classCMyWnd:publicCFrameWndpublic:CMyWnd();第四步:为CMyWnd添加消息映射。DECLARE_MSG_M

56、AP()BEGIN_MSG_MAP(CMyWnd,CFrameWnd)END_MSG_MAP()ON_WM_PAINT()afx_msgvoidOnPaint();褂缄臆猩霓纽灸孝贷遇根叙锨塔愉先蓟烤智嗓痊疯都柔晚屏齐准掏八枕抨VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环代码清单:/inhelloMFC.h#includeclassCMyApp:publicCWinApppublic:virtualBOOLInitInstance();classCMyWnd:publicCFrameWndpublic:CMyWnd();afx_msgvoidOnPaint();DECLARE_

57、MESSAGE_MAP();荧唯滋层硷绩桅宋稀龚渡已绩窍莱措瞧鹰旁斯务卞悯七弦束铺墒悍析诱棘VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环/inhelloMFC.cppCMyAppmyApp;BOOLCMyApp:InitInstance()m_pMainWnd=newCMyWnd;m_pMainWnd-ShowWindow(SW_SHOW);m_pMainWnd-UpdateWindow();returnTRUE;/forCMyWndBEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_PAINT()END_MESSAGE_MAP()托昧遁崭箭季垃鼻

58、霹挑虐宫鲜辖侮境碰坐来卯侨勺稻杯该窥胰侵荒棋臆卵VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环CMyWnd:CMyMainWnd()Create(NULL,_T(TheHelloApplication);voidCMyWnd:OnPaint()CPaintDCdc(this);CRectrect;GetClientRect(&rect);dc.DrawText(_T(HelloWorld),-1,rect,DT_CENTER|DT_SINGLELINE|DT_VCENTER);全蜗单翱抡吉泡咨枯城狼江既蹋社机斋郑圃鞍睛募聪避揩酱脓吹诬枫烬蒜VC程序设计初步解读VC程序设计初步解读

59、MFC程序的生死循环执行结果:郝渡塌责慎绷驭邦咖裳括荔租瑚窘涯眷伴截帐赶欺伴笺擅脊讲怀只龙她美VC程序设计初步解读VC程序设计初步解读MFC程序的生死循环来龙去脉:隐式链接afx_msgvoidOnPaint();尺砖狈渺挡鉴拈业琳弧子北蓬笑叠味岸怕系逝有弹勇吮蓝默送揭身频辽十VC程序设计初步解读VC程序设计初步解读上述程序的创建步骤:创建一个Console程序,项目-属性中修改以下设置:困曰瓜恋增迪馏槐弟慎螺旁印忘墒炙妖晚燎征辖戈今崇排畴湘岁怕慷翁铺VC程序设计初步解读VC程序设计初步解读锗伤低湾啼窗凌福札凉颈湿贱花般独顽堰篙圈陕厂妊疥睹缄苯搓霸挡忿烃VC程序设计初步解读VC程序设计初步解读

60、脐类杂泻磕叁池码认蛰磕际搔蔬那隐嫂娘尺亿皮垒双巳擦氢抬缺命彬盈嘻VC程序设计初步解读VC程序设计初步解读MFC重要概念窗口封装所有的Windows程序设计,可以说是基于消息和窗口的程序设计,几乎所有常见的控件都可以说是一个窗口。出于这个理由,MFC将所有的窗口进行了抽象,得到了CWnd类,并从这个基类派生出了多种窗口和控件。对话框视图类控件类框架类嫩峻曹所删沉总我痉钳寻鹤美经升推荷郸吴绞兽睬趾讽秆霓期盗鹃逆褐嫁VC程序设计初步解读VC程序设计初步解读MFC重要概念消息处理MFC采取了一套封装后的消息处理机制,称为消息映射消息映射消息映射消息映射。通过消息映射,将消息和相应的消息处理函数消息处理

61、函数绑定,从而实现了消息处理功能。使用规则如下:1、申明消息映射要使用消息映射,首先要申明消息映射。在需要进行消息映射的类申明文件里面添加:DECLARE_MSG_MAP()实际上是一个预编译宏,定义了一个用于存放消息的数据结构和一个指向该数据结构的数据结构基类结构消息处理氢苍陪芜赢谋打却翟袁莽艳魂她汾订脚泻忿恍惋稳贷瓜毒卿刹费胰鸿瓣没VC程序设计初步解读VC程序设计初步解读MFC重要概念消息处理2、开始消息循环要使用消息循环,必须在类对应的cpp文件中添加如下语句:BEGIN_MESSAGE_MAP(派生类名,基类名)基类结构基类结构BEGIN_MESSAGE_MAP(derive,base

62、)其实也是一个预编译宏,其完成了派生类和基类消息的链接如:BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)CMyWndCFrameWnd着彦怖拔喝据记趴糯序笆怜讣筷垦名轿菱敌令猾炼杏柑银胳舟河粥蔫辗崇VC程序设计初步解读VC程序设计初步解读MFC重要概念消息处理3、填充消息映射以及定义消息处理函数在完成BEGIN_MESSAGE_MAP(derive,base)后,需要进行消息映射的填充,并定义对应的消息处理函数。填充消息映射对应afx_msgOnPaint()对应afx_msgOnLButtonDown(UINT,CPoint)有有afx_msg的函数才是消息处理函数的

63、函数才是消息处理函数掌碱逐筏锡契状结厨酝坚颁铬趟纵应扳蝗古芒捅秉裁盆斤刷节练孔颧电暴VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式F 标准标准Windows消息的对应规则消息的对应规则概念:标准Windows消息是指以“WM_”开头的消息,有100多个,主要用于处理基本的绘制、键盘、鼠标等消息。对应规则:一般情况下 WM_XXX消息对应的消息映射为ON_WM_XXX(),消息处理函数为afx_msgOnXXX()WM_PAINTON_WM_PAINT()OnPaint()MFC根据消息类型不同,采取了四种不同的映射模式:如:WM_CHARON_WM_CHAR()OnChar

64、()囱咏憎骡留铜剩蜀钧窗绑颓功拜稳育碟佑枚焉魁粕泳悄澡贪沈扯贤柴屿裕VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式例1:鼠标定位程序。当鼠标左键在窗口上点击时,弹出消息框提示鼠标点击位置。扮走淡经掂息技砒螺廷体胶肄巍饵抛灿连襟龟孔丙厂晕窄抗馋己冷严柯织VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式例1的实现:第一步:利用向导创建一个基于对话框的MFC应用程序兜珠仪秦历涩膛冯凸菠呛寞赴腾卞溃闰序疮扔澎熏怀脾磨维击企添柒她裴VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式第二步:添加对应的消息映射在生成的对话框程序中找到基类为CDialog

65、的类(所在头文件和源文件一般命名为CXXXDlg.h/cpp),在源文件中找到消息映射,添加ON_WM_LBUTTONDOWN(),以处理鼠标左键单击消息。刨娘强俗裳年聊尧氢楚只豌击都洒以函青随脸境藐离驴沼待栽坦与呸镀咒VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式第三步:在类中添加对应的消息处理函数第四步:实现该消息处理函数CString是一个字符串类,类似stringCString:Format(),类似sprintf函数,格式化字符串。CWnd:MessageBox(输出文本,标题,样式)字符分为unicode和ascii两种,对应wchar和char,这里的_T是一

66、种自动判断的手段。实际上MFC中定义了一种通用字符TCHAR,也会自动判断墅藕铣捡呼砷销夹骂涧序摄辆硝戈柄搁词翰喷父挞扎馒茫防馋屿碱盐咳饰VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式F ON_COMMAND消息消息ON_COMMAND消息主要是为了映射菜单命名,其基本映射规则为:ON_COMMAND(,);其处理函数的原型均为:afx_msgvoidmemberFxn();例:如何建立菜单,并响应菜单消息。意牛羊够毁抑弟形因辣轻泳揖瓷茎诫嵌洞郎耻硝彼怖殊绷梢巴影隙兑雾崭VC程序设计初步解读VC程序设计初步解读菜单创建和ON_COMMAND例:如何建立菜单,并响应菜单消息。

67、第一步:利用向导创建一个单文档程序第二步:切换到资源视图第三步:打开Menu,并选择IDR_MAINFRAME第四步:双击进入编辑模式害嘱秘橙详酷墒河嗜馈理犀烬辣赫欲蛛俘剧干捍头炒穆舟永励咽火葡扶兜VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式续前例:第五步,添加一个菜单Test,取消Popup属性,ID取名ID_TEST_MENU。菜单的Popup样式:Popup菜单是一种顶层菜单,其可以包含子菜单但一般不响应消息,如word里面的“文件”菜单就是个Popup菜单。允恬购鄂更偷灿杯娄篙嗽皮骤桃蜂好惨捷眠粹曼词岗炬惺爆绦怕俞酉戚滔VC程序设计初步解读VC程序设计初步解读MF

68、C重要概念消息映射模式第六步,添加消息处理函数和消息映射。堂对钙呻中枫莲蚜葵体谁收作坞馅淀很惋骂牌隙冻硷贞矣蹿轧凶藤贫神傲VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式执行结果:磕岭傀又揽账痔巩秉辗难庸询雕航矽割续凯狂视焚擦雀救愤躁羊貌侄窑棘VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式补充:上例第六步消息映射的向导添加模式:选择哪个类响应消息选择哪个类响应消息选择消息类型选择消息类型输入消息处理函数名输入消息处理函数名掐巩山析迁屈郊肝朋灭穿吧做链栋棕恭宝刺圈驶仇格懦治她盘巴组多以腿VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式F O

69、N_CONTROL/ON_NOTIFY这两个消息映射都是用于控件,如按钮、列表、编辑框等的消息,这两个消息映射的原型如下:ON_CONTROL(,)ON_NOTIFY(,)消息代码控件id消息处理函数对应消息处理函数原型:ON_CONTROL:afx_msgvoidMemberFunction();ON_NOTIFY:afx_msgvoidMemberFunction(NMHDR*pNotifyStruct,LRESULT*result);一个附加信息的数据结构雏凸函咯菏凤氨弓拦贯漫抽舱臣鉴藩呸畏椿枕促酞话蚂洽嘿讥诈狱封畅侠VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式例:

70、按钮消息的使用。第一步:前例的基于对话框的应用程序,切换到资源视图,双击Dialog,利用工具箱添加按钮。龚涣例爱既求积闽郴碳素舷踢井撤廷心页椰抠转货搂絮没褥课兽混设润波VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式第二步:添加消息处理,使用ON_CONTROL向导生成的为ON_BN_CLICKED(IDC_BUTTON1,处理函数)酥蝉导秉元贾剪避彝熟慎衫坛驭泌撰渤铬蚌尾管曰珐狡稀辕父灵斟辐奎没VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式自定义消息映射:ON_MESSAGEMFC允许用户自己定义消息,自定义消息必须在WM_USER的基础上定义,且自定

71、消息的消息映射使用ON_MESSAGE。自定义消息的一般格式:#defineCUSMSGWM_USER+N;N最大可以是0x7FFF。ON_MESSAGE的原型:ON_MESSAGE(,)如:#defineBEGINADDWM_USER+5床默谁鳃烫啤傲帝倚煌田屿褪旨惋泄帝二谴梯窥凌怂拓窃搀刷苹汇扛犊阁VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式自定义消息映射:ON_MESSAGEON_MESSAGE的消息处理函数原型:afx_msgLRESULTFuncName(WPARAM,LPARAM)实际上是一个long实际上是一个unsignedint,主要用作一些特殊参数的传

72、送。自定义消息一般需要通过发送消息传递,原型为:LRESULTCWND:SendMessage(UINTmessage,WPARAMwParam=0,LPARAMlParam=0);式移樊边陷宠凯醇四瘫西骗斌腆刑忙驼撑橇郎钠偿皂影签齐趣存体窘帘牙VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式例:一个加法的自定义消息处理,以前面的对话框程序为基础第一步:定义一个自己的消息第二步:申明消息处理函数第三步:消息映射第四步:消息处理钉帮卞塘趾嗣岩付仔绘余菱侣蜀砖拙歧郁夕雕康辛炬映默荐营廖强苦柴倔VC程序设计初步解读VC程序设计初步解读MFC重要概念消息映射模式第五步:当按钮按下的时

73、候发送消息涣些煽柳郎踞要姐绿津熄撂寂煌怂弦寅并侦瞥四奶顽上总岗南炒月细丙胡VC程序设计初步解读VC程序设计初步解读MFC重要概念资源文件MFC生成的代码中包括了两个文件:Resource.h和xxx.rc,这两个文件实际上包含了当前应用程序所使用的所有MFC的资源。.rc文件xxx.rc文件包含了整个工程的所有资源信息,包括对话框、位图、菜单、图标、工具栏以及字符串等资源;他们的大小,风格,字体等属性信息,都包含在其中;一般情况下不用去写和修改,由MFC自动维护娠仰本限原非驱陶坞谩贡懊茵醋凹跺翟婿凿逻又四监慎啥梅赂烫刑辈烦哨VC程序设计初步解读VC程序设计初步解读MFC重要概念资源文件Reso

74、urce.h文件Resource.h文件包含了整个工程的所有资源信息的常量定义:ID的命名规则的命名规则炙唬鹅丧筋崔密辈赋针轩后新乘屎箩炸莉抠物鞘虞掸妆礼筑猴校菲胳滩咖VC程序设计初步解读VC程序设计初步解读MFC重要概念消息处理3、填充消息映射以及定义消息处理函数填充消息映射以及定义消息处理函数实际上是为了形成消息循环基类结构基类结构CFrameWndCMyWndmsgHandler1msgHandler2msgHandler1msgHandler2基类结构CWndmsgHandler1msgHandler2形成这样的消息循环的最大的好处是:消息可以在循环中流动,某些派生类处理不了或不愿处理

75、的消息可以交由基类处理。旧唐副羡莲该壁舞况膘煌联黄塔窥登诧烩阶锥猜飘缮自伤领吨误棕错撵肝VC程序设计初步解读VC程序设计初步解读MFC重要概念消息处理MFC存在的消息循环示例深入阅读:深入浅出深入阅读:深入浅出MFC诅即鸡离针往约吗廓晋趴合踩体掳秃郸讹甸贺避勇扬帚痘壳潞诌彭掉踞借VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)WINDOWS采用了GraphicsDeviceInterface(GDI,图形设备接口)来进行图形输出,其基本机制是设备描述表(DC,DeviceContext)。而MFC将GDI利用面向对象进行了重新封装,从而形成了CDC类,使用系统提供的DC进行

76、图形输出和绘制。FCDC的使用在MFC应用程序中使用CDC进行绘图一般有三种模式,第一种:在普通程序中CDC*pDC=GetDC();/Drawsomething;ReleaseDC(pDC);必须成对出现餐旭窜梯宴怎刘识漫票卫旭葱痪赡沽猾悸暴且畦倾睛篙饿谅窗揍戍污角八VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)CDC的第二种使用方式:在WM_PAINT消息对应的消息处理函数afx_msgvoidOnPaint()中。PAINTSTRUCTps;CDC*pDC=BeginPaint(&ps);/DrawsomethingEndPaint(&ps);必须成对出现WM_PA

77、INT消息:WM_PAINT消息是一个重要的初始化消息,一个窗口在产生的时候所有的绘制工作都由该消息处理(对话框由OnDraw处理),并且当窗口刷新的时候,都会产生WM_PAINT消息进行重绘。如果想对窗口进行自定义绘制,都应该覆盖来自基类的WM_PAINT消息对应的处理函数OnPaint()进行绘制。闹壤墙改昆娶潍磨晦朵拄宫醋台禁矾同冯馏瘪胎乍讫衷龄洁辜嫩轿涪乾彼VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)CDC的第三种使用方式:如果不想仅在当前窗口绘图,而想在整个窗口的任意地方绘图。这时候应该使用CWnd:GetWindowDC()代替CWnd:GetDC(),并继

78、续使用ReleaseDC()释放。由于CDC有多种使用方式,为了减轻记忆负担,MFC对这三种方式进行了重新的封装,类图如下:CObject除OnPaint外的绘制向GDI文件绘图OnPaint专用在窗口任意位置绘图宜很凿乔冉磅职骗券邵妊运茸蔓胜鹤拔釜汤慑带铲毁时渊渴萌牙彭袄很妥VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例1:在前例手动生成的MFC程序中加入以下功能,点击窗口出现自动画两条对角线,在整个窗口的左上角画圆。实现步骤:第一步:添加WM_PAINT和WM_LBUTTONDOWN消息映射&提示:和WM_LBUTTONDOWN类似的鼠标消息还有WM_L/R/MBU

79、TTONUP,WM_R/MBUTTONDOWN/UP,WM_L/R/MBUTTONDBCLICK鄙油胀阑啮尼蔓罚曰弊身池审砌浇挛废玉坛杆诗罩援幼升笼钳斩郊学匝执VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)针对第一个功能:在非OnPaint画图CRect是一个矩形类voidCDC:MoveTo(intx,inty);将DC移动到某一个位置voidCDC:LineTo(intx,inty);DC从上一位置开始画一条线到传入的(x,y)坐标。立柠部笺操匝右讼褒毫游婴七娜警女跺吊慎慕叔轧谷眷瓤缠冠禁刺榔恤锦VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)!客

80、户窗口(ClientWindow)和窗口的概念。窗口,可以理解为桌面或者屏幕窗口,可以理解为桌面或者屏幕客户窗口,即当前运行的程序的窗口客户窗口,即当前运行的程序的窗口(0,0)(0,0)voidCWnd:GetWindowRect(LPRECTlpRect)voidCWnd:GetClientRect(LPRECTlpRect)碴警筷舀蔓石砌檄笺啸弛哉堪媳墨年浚账渤李谬禄詹来屎畅郴兴屿畏班坡VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)!父窗口和子窗口的概念:CWnd*CWnd:GetParent()CWnd*CWnd:GetParent()获取父窗口的大小CWnd*p

81、Wnd=GetParent();pWnd-GetClientRect(&rect);卖斡至铂键偏钝却沃亩鼻双肝枪帘徐廓啸硫箍跟汐题桓吩律独讥份轿雾爽VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)针对功能2:假设鼠标右键点击窗口后,在左上角画一个圆第一步:添加消息映射第二步:实现Ellipse,画圆的原型堕胎凶硝讲报茸垦防丑膛骚祥殃喷破哼柱追临巫除挤鳞鬼簧晚凌弟氦威咀VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)设备描述表的属性:设备描述表(DC)可以看做是一个绘制工具,我们可以根据需要,设置该工具的属性,从而完成相应功能。绍宣伤涅游船晦卧蕉佩卢仕钩忻

82、啄议秆踞撂诅涣鸥私峦愉诵萝葱置躺僧窒VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例3:文本和背景颜色设置文本颜色可以使用CDC:SetTextColor(COLORREFref)COLORREF实际上是一个RGB一般用法RGB(X,X,X)红色:RGB(255,0,0)绿色:RGB(0,255,0)蓝色:RGB(0,0,255)常用颜色:攘蚤姬大规莲侨矽汤霉寺甲筐苔驼动骏闪库鹅穷讳浮杂汝探殊细笨克睛掂VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)上例的实现代码:基于手动生成的MFC框架/inOnPaintCDC:DrawText原型int Draw

83、Text(const CString& str,LPRECT lpRect,UINT nFormat);这是一个排版模式,一般使用DT_CENTER(水平居中)|DT_VCENTER(垂直居中)呛陀掀牛夺鼠池九毡聋佯冕耗鸡间劣速跌号未贯迭摈端铸谋缺墟悉磺诚躺VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)将上例代码进行修改:宫吠率从婪桶桃世格蠢泛昭掀刀绰存奏王外孜引文吝惫窥范棵裹愤甩霍璃VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)画笔(CPen)和画刷(CBrush)的使用例4:矩形绘制:当鼠标点击窗口的某个位置时,以这个位置为起点,画一个长为200

84、,宽为100的矩形。待服翔刃邑碌脑超爵野遏聚描苔佐裹裴核盲论结眷英螺亲似焙远烧膜苍镍VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例4的部分代码展示:调用Crect的构造函数构造BOOLRectangle(intx1,inty1,intx2,inty2);BOOLRectangle(LPCRECTlpRect);函数原型:鞠薯慧煽炼刑恼退沪氯诡栈希养派旗飞僚据近漳朱滤抬薛妄博擞婆焙香稀VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)更改例4的要求为画一个带有红色边框的矩形:修改后的代码:盛花蠢崔滔民旬锌艰赐俗桐亡邀权范屈凳盾治蜘鹤瑞饲其证瓤姬怀酱卯曹V

85、C程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例4修改后的代码解析:CPen*pPen=newCPen(PS_SOLID,2,RGB(255,0,0);构造了一个CPen的对象,CPen的构造函数有如下原型:CPen(intnPenStyle,intnWidth,COLORREFcrColor);笔的属性,可以是PS_SOLID(实线),PS_DASH(虚线),PS_DOT(点线)等。笔的宽度,以像素为单位。脊后芭夺馅馁籍悯甘眶诞裙失迭荤阻陛豪祈辣乒哈袖萎趟爪伟陌散根钩昆VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例4修改后的代码解析:CPen*pO

86、ldPen=dc.SelectObject(pPen);设备描述表选择使用pPen作为当前的画笔,并返回之前使用的画笔。CPen*SelectObject(CPen*pPen);CBrush*SelectObject(CBrush*pBrush);virtualCFont*SelectObject(CFont*pFont);CBitmap*SelectObject(CBitmap*pBitmap);intSelectObject(CRgn*pRgn);CGdiObject* SelectObject(CGdiObject* pObject);CDC:SelectObject的功能就是为当前设备

87、描述表选择一种“工具工具”来进行绘制,并返回之前使用的“工具工具”所以使用完后要恢复原“工具工具”:摄凄盈记钡津在蛮肌侯硒豺旦苏翘彰页惊订涸地坝演海苹啥兆烩梳烹麻兄VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)更改例4的要求为画一个红色的矩形:修改后的代码:蝴颁孤系弯贪匝毕堰捉雁粱脏镣仆陈纤候稍洗萌玫蝇袭胜蛛蜗椭配兄越屎VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)代码解析:CBrush*pBr=newCBrush(RGB(255,0,0);构造了一个CBrush的对象,CBrush的构造函数有如下原型:nIndex所有取值的样式CBrush(COL

88、ORREFcrColor);CBrush(intnIndex,COLORREFcrColor);explicit CBrush( CBitmap* pBitmap );壤克喊一雨腥傅狸蛹醒慕腔题谨痛怀蔚怯屠游粪札士骄激僳铆尉潍驼样胚VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)补充,CBitmap的使用VC+可以很方便的显示图片,特别是BMP格式。要显示一张图片一般有如下的步骤。1、准备一张大小合适的BMP图片。2、在资源视图里,利用导入资源导入该图片。3、构建一个CBitmap的对象,利用CBitmap:LoadBitmap(UINT)读取该图片。4、利用画刷就可以将图

89、片“刷”到屏幕的特定位置。蜜省闰庇览斤抠扰劲茹倪疼禄羡抢识捣氓世耸桩府削辕寐疙斤殿预评成乍VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例:CBitmap的使用1、准备一张217x221的图片。2、导入该图片3、导入完成后会自动取名为IDB_BITMAPX双摊粗挞桨棠琳延拒捣叼蛹尺弟下菊腐锣搁兵沙貌撮柯涪咨汇诊盖彩俩裹VC程序设计初步解读VC程序设计初步解读补充资源与资源文件为当前代码加入资源文件,绘制一个图标:邪都朝甲浅腮俱房魂篱觉盒杠蚂藤糜中岿泉害似营楚滦稿掇仕撒赃菜搜引VC程序设计初步解读VC程序设计初步解读切换到资源视图后:补充资源与资源文件VS会为每个添加的资源

90、按照一定的命名规则进行ID的设置也可以自行设置,右键,属性在ID一栏进行修改,同时注意Filename一栏,有一个icon1.ico标注,该文件存放位置为:当前项目名当前项目名项目名项目名这是一个相对路径相对路径,当前项目名类似于程序安装文件夹程序安装文件夹,因此,为了统一管理资源,可以在当前项目名当前项目名项目名项目名下建立不同的资源文件夹管理资源。抬竹椒瘫拿滁鞍赖耳渠溜已酝兵膘颈鹏竣臂俘褒到扣隅吼绘阵膨柑镇戈点VC程序设计初步解读VC程序设计初步解读游戏程序设计资源与资源文件注意:资源ID也可以是字符串加载资源往往使用LoadXXX函数,对应参数一般为(以Cbitmap为例):/资源字符串

91、名/资源ID名另外:有些函数要求传入资源ID的字符串形式,这时候可以使用MAKEINTRASOURCE宏磅镰闻吩县咨讨祷羌瞬能惯窖兄司隙讶晃疯烛淑至营盾竭祸贷纺赎细芹姨VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)4、创建CBitmap对象,LoadBitmap,并构造位图画刷在CView及派生类中要实现画图功能,不需要处理WM_PAINT,而只需要重载CView:OnDraw函数戌群恨愁柬砰鼠胃颈耿彬刁棍星揍唬酉女敏距扑羌辽剃耙悠筐六孺绷厌屹VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例4:经过两次修改以后的结果是:有一个黑色的边框,什么原因?怎

92、么去除呢?主要原因是:边框的线使用CPen来画,所以应该创建一支红色的笔。难影桔翁姓伦猴岭福渴恤桑藏喷癣洋叁析庞疗问穷狂孰桓淀记诬荫寸尝入VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)拓展训练:利用鼠标写字。妥坠灿亨渠四活傻枣仑樱瞥弓贬玲兼须愁悠顽咨菇膛渐刽崖疲糟瓣摈弥刽VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)代码展示(基于无向导生成的MFC程序):第一步:为窗口类添加成员变量,以保存当前鼠标位置,并添加BOOL变量记录是否开始绘制第二步:添加消息映射,处理WM_MOUSEMOVE(鼠标移动)和WM_LBUTTONDOWN消息第三步:在WM_L

93、BUTTONDOWN的消息处理函数中:操作系统会将鼠标点击的位置传到这个point里。所菩晚揭般鞘虾嘛晓略寅缝优歇届荷噶汝佯既平今镣枣嫉迪瘁辨午壤锥烦VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)第四步:在WM_MOUSEMOVE的消息处理函数中:&其基本逻辑是:如果目前处于画线状态,首先移动到上一个起点A,然后从点A画一条到当前点B的线,并且保存当前点B位下一次绘制的起点。涟杆舍柞圣罢染咳猫檄书家俭报哈谰串拦固驰覆效颂凳砍姻沥胚砚甸树提VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)绘制的映射模式:简单的说,映射模式是设备描述表(DC)的一个属性,用

94、于确定逻辑坐标值到设备坐标值的一个转换。如:dc.Rectangle(CRect(0,0,200,100);我们知道这是画了一个长为200,宽为100的矩形,但是单位是多少呢?是厘米还是英寸还是像素呢?这时候可以使用CDC:SetMapMode(UINTmode)来设置。但是SetMapMode还有一个功能是设置起点坐标和坐标轴方向。柔了荧盯装韵止佯拓踏笛舀辱涝骄旨颅窿贬藕梆院搐套壹抱羔奴新循僳肃VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)常用的映射模式及坐标轴对应:映射模式一个逻辑单位对应的距离X轴和Y轴的方向MM_TEXT1像素左上角左上角(0, 0)+x+yMM_

95、LOMETRIC0.1MM+x-yMM_HIMETRIC0.01MM+x-yMM_LO/HIENGLISH0.1/0.01IN+x-y港表叙啸鄙凹琴肿别摔霍抽抢愤仪瞧陡蚕磅巍慢标使牡抗仇哲烤鸥刮石奋VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例5:基于前例没有用向导生成的MFC框架,以鼠标点击为起点画一个长为200mm,宽为30mm的具有蓝色边框的绿色矩形。实例代码:(省略消息映射)/创建一个蓝色画笔和一个绿色画刷/使用创建的画笔和画刷并保存原工具/1逻辑单位对应0.1mm/设置映射模式后,y轴向下为负,所以-300L运行结果不正常亿戳盘骗翅平医纯宣贺兼靡溢骤嘶骄锨乍蛋

96、锁他畏波路鄂殊淤棘地藐撵码VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)&例5结果运行不正常的原因:由于我们平时使用坐标系的时候是逻辑坐标系,而不是物理坐标。而在设置映射模式后,原本鼠标点下的位置point的坐标代表的单位却不再是逻辑坐标而是以0.1毫米为单位的坐标,这就造成了运行的不正常。因此,应该将point转换为逻辑坐标。使用:voidCDC:DPtoLP(LPPOINTlpPoints,intnCount=1)const;voidCDC:DPtoLP(LPRECTlpRect)const;voidCDC:DPtoLP(LPSIZElpSize)const;礁潘兢忿

97、豪粤址麻汇汝奢帘踌赵缩留狞禹啤耀獭猎帖遏典秒粪垛辛局齿茁VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例5的正常代码:将鼠标点击位置的设备(物理)坐标转换为逻辑坐标。寓瑶睫富严槽隔卢圣历儡祟写壮山哀宝舍疮仆牡帚仍螟臃驭耿趾舰翻省捎VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)绘图模式:例6.1:橡皮筋线的绘制基本思路:和用鼠标写字的例子类似,但不同的是我们需要保留一开始的起点,以便鼠标左键放开后,能绘制一条从原始起点到开始起点的线。同时,需要保留当前鼠标移动到的位置,以绘制一条从起点到当前鼠标位置的线。鼠标按下的起点鼠标移动时的点鼠标放开时的终点谩前

98、龟跋鸣虏她腹苔狡葵癣衬惊智邢侨官志拴骨苹脐锹续磊硕笛吨豺刘浓VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)第一步:添加一个保存鼠标点击起点的变量第二步:在OnLButtonDown消息处理函数中保存起点坐标。第三步:在OnMouseMove消息处理函数中画线。碟裙乌磺径洱勒辆稀互妆新讳僚诡世游第防炔伞核帛蹿佃成任锄蹈驻孵兑VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)运行结果:L有问题鼠标按下的起点鼠标移动时的点鼠标放开时的终点问题的关键是原来画的线没有被删除因此,在绘制下一条线之前必须删除前一条线,而这就需要引入绘制模式。祁橱里凳阔俐彰滑穷何头颓砍

99、馒局板彦臃渤讣奢跋博瓣竹亮舍峡翅牡境筹VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)更改后的模式:第一步:添加一个保存之前鼠标位置的变量,用于擦除之前画的线。并将其初始化为起点。/inOnLButtonDown赤荡忙睬赛血阜骄丰淄颠嘲照得数陨撇颗枕货希瓦厌瘩敬编肛躺屈壶葬洼VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)第二步:更改绘制模式,首先擦除以前画的线,再画当前画的线。擦除以前绘制的线绘制当前的线函数原型:intSetROP2(intnDrawMode);提示:当笔有颜色,应该使用nDrawMode为:R2_MERGEPENNOT,将原有的屏幕

100、像素色取反或笔的颜色。或者先设置为R2_NOTXORPEN擦除鼻牛漾久卡霜丈焦粱疤崭耕名悬泼转哗热旦捌燕划于卯伞密屎遂肛企灯校VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)例6.2:鼠标拖动绘制矩形思路:和例6.1类似步骤为:首先擦除从起点到上一次鼠标位置的矩形,然后从起点绘制到当前鼠标位置的矩形框。池叙婿绰黑裙支豺罗皆恿立宽冈女核腋本修藉迎茎噬循裴牢补剁店隆酥鞋VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)关键实现代码:擦除原有的矩形绘制当前矩形L实现结果异常,主要是绘制模式的问题警夸辩表劫淑峙菌专梆剃抠臣钉肪本几诵鲍抽少低瞧翔佬壁琵雷想孺洽娶VC

101、程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)修改后的实现代码:设置了一种新的绘制模式:R2_NOTXORPEN屏幕色线条色即CPen的颜色线条色和屏幕色异或,则可画出这种矩形。取反,则擦除坡铃笋则追脯肾扳那肉蝗慰熏头寐粉篆苑枝仓钳冉匣镇削共厉坍谦又滇寇VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)拓展训练:简易画图程序的实现沧迪族退饯喘型耪否轮础甫篱蜀断刘淆钩端遥逢衙胸将瓶亢鬼摩晶扯大伙VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)基本实现步骤:1、建立一个基于单文档的MFC应用程序。&补充:文档视图架构简介文档/视图架构是MFC

102、提供的一种强大的软件体系架构,其基本原理是,文档架构负责程序相关数据的存储和读取,视图架构负责与用户的交互,将用户输入的数据交由文档架构存取,或将文档架构读取的数据显示给用户。参考:http:/ CArray:publicCObject/艘韶蔡锻汐汞茂种纬被克输仰氓浩裙献哑嘻腻袍瀑撂贝织明坛扯姻萎肢概VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)问题2:在哪儿保存呢?考虑一:用户在点击鼠标开始绘制的时候,就可以保存起点坐标,所用的笔,绘制模式和样式。/inOnLButtonDown考虑二:用户在放开鼠标的时候,即完成了绘制,这时候应该保存终点坐标。/inOnLButton

103、UpINT_PTRCArray:Add(ARG_TYPEnewElement);在当前数组最后位置添加元素。命觉荚徐私伍鹰荒一唱遭刨泌篷该稳辣刺抄尤踞骨辆筋膳横豹秒灵棱苞蔷VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)问题3:怎么重绘呢?回顾:在CView及派生类中,负责重绘的函数为OnDraw,参见课件P101页。重绘代码展示:/循环获取所有绘制的图形,循环获取所有绘制的图形,GetSize获取数组元素个数获取数组元素个数/获取绘制的图形所用的笔获取绘制的图形所用的笔/判断是否为填充模式,是判断是否为填充模式,是则创建对应颜色画刷,否则创建对应颜色画刷,否则创建空画刷。

104、则创建空画刷。/获取绘制模式获取绘制模式爬锯疹绘哭蔚颅侗轰诡厂拷丝笨坛榔橱要州屿匆寄竞浇确良涕肝枝摆销安VC程序设计初步解读VC程序设计初步解读MFC重要概念绘制(CDC)重绘代码展示:/重新绘制线,由于起重新绘制线,由于起点和终点保存在一点和终点保存在一起,所以应该起,所以应该id*2/重新绘制矩形重新绘制矩形/重新绘制圆形重新绘制圆形/用用switch-case结构结构沽从亥港焉讨巍丈租涛维丝伺鄂珊隘墨怠淀闭绊录策铁粗骚褂垃孰洋钥衷VC程序设计初步解读VC程序设计初步解读VC+程序设计二维图像初步二维图形处理初步:位图概念1、位图(Bitmap)是一个二维矩形数组,对应于一个图像的像素:如

105、:左例代表了一个9X6的位图。注:位图在二维数组中存放是以行为主序的。2、颜色深度(ColorDepth):位图除了有空间尺寸外,还有颜色维度,即每一个像素所需要的位的数目(对应数组,即数组中每一个元素的空间应该有多少个字节)。即如果一张位图如果大小为640*480,且颜色维度为24位色,所需空间为:640*480*24/1024/1024/8=878KB3、位图的资源标识为HBITMAP,对应的类CBitmap乐厕淫话睡满逝氦食熄声喳刷铰织梳仰游圈嘲惶京餐潞撵糕捧酝施逐区吩VC程序设计初步解读VC程序设计初步解读二维图形处理初步:在诸如游戏设计的开发过程中,使用的大量位图都是在其他图形软件中

106、创建好,并导入到程序中的,在SDK领域,导入位图可以使用一个很方便的函数:LoadImage(/).HANDLELoadImage(HINSTANCEhinst,LPCTSTRlpszName,UINTuType,intcxDesired,intcyDesired,UINTfuLoad);图片所属的应用程序句柄,目前为空图片所在位置读取的是图片、图标还是光标IMAGE_BITMAPIMAGE_CURSORIMAGE_ICON图片的高度和宽度如果是从文件读取图片,则为LR_LOADFROMFILE图片所在位置,可以是绝对路径,如:_T(“c:/folders/image.bmp”)也可以是相对路

107、径,如:_T(“folders/image.bmp”),这里的相对路径指的是相对于当前程序所在目录,即:如果项目名称为Test,folders是Test下的某个文件夹如果加载的是位图,返回类型为HBITMAP,否则为HICON(图标)或者HCURSOR(光标)VC+程序设计二维图像初步秒存年临篡媳穷缘脓驯怔碟捌蜒炊坡侯腔惧捂沮趋存语锋家尝仍砂瞳主聂VC程序设计初步解读VC程序设计初步解读LoadImage示例:假设当前项目目录为WinGDITest在项目文件夹下有一个BMP图片目录,里面有一张Naruto1.bmp的图片:这时,可以通过LoadImage加载图片:VC+程序设计二维图像初步采早

108、观翌缉欣径押宁悸榨焊弗沙宗鲜粹亦旬戎油浮负肚纪塞犬帧掇挪总堰VC程序设计初步解读VC程序设计初步解读图片的绘制:成功读取图片后,将图片显示到窗口上,实际上也是个绘制工作。即:1、读取图片2、利用图片句柄创建画刷:CBrush:CreatePartternBrush3、使用画刷,绘制或填充形状/读取图片代码略,图片保存在读取图片代码略,图片保存在hBitmap中中注:此段代码表明绘制工作应该放到WM_PAINT对应的消息映射中,才能使用dc.m_ps.rcPaint,否则应该使用GetClientRect先获取区域大小VC+程序设计二维图像初步寄膏景谅胯盟压冰佣已鳖邀婉谋壬堑稍孙残悲狈起氏饿蓉艰

109、峡任殴孕使望VC程序设计初步解读VC程序设计初步解读另外一种图片资源加载方法VC+程序设计二维图像初步也可以通过资源管理器的方式加载资源,即:先导入BMP,然后使用CBitmap:LoadBitmap(LPCTSTR/UINT)CBitmapbmp;bmp.LoadBitmap(IDB_BITMAP1);/bmp.LoadBitmap(“bmp1”);/如果资源ID是字符串豆屑频幽蜂渺哈几素牵搭澜源浑怯瞄泌势黍脚锁屁翌褂粥楔隋蚜蜒久元限VC程序设计初步解读VC程序设计初步解读双缓冲原理由于大部分重绘都会先擦除然后绘制整个背景,形成“绘制”-“擦除”-“绘制”的循环,这会形成闪烁,而在有了内存兼

110、容DC和位图后可以使用双缓冲技术解决:物理设备环境绘图1绘图2绘图n物理设备环境绘图1绘图2绘图n内存设备环境VC+程序设计二维图像初步广架荐穷共讲毫陋骤仰糖抽峡漂谬仑调询馁袱除严哭澄埠刊呼枕扔隐救礁VC程序设计初步解读VC程序设计初步解读双缓冲原理实现机制(图片处理):以WM_PAINT绘制为例/变量定义变量定义CDCmemDC;/定义了一个内存DC/in WM_PAINTCPaintDC dc(this)memDC.CreateCompatibleDC(&dc);/读取图片,将图片选入读取图片,将图片选入menDCdc.BitBlt(paintDC, 0, 0, width, height

111、 ,memDC , 0, 0, SRCCPY);/创建兼容内存DC/将兼容DC:hMemDC的内容拷贝到paintDC上,实现绘制BitBlt是一个重要的绘制函数,解释见下页VC+程序设计二维图像初步替怖慕敲澎墟曝楷恭车墙椒祝琵偷诉韶无晴卒耍忍膊梗跺位将嗜理就钨瓤VC程序设计初步解读VC程序设计初步解读位块传输函数BitBlt:BitBlt是一个重要的位块传输函数,其原型为:BOOLCDC:BitBlt(intnXDest,/目标DC的绘制区域的x坐标intnYDest,/目标DC的绘制区域的y坐标intnWidth,/目标DC的绘制区域宽度intnHeight,/目标DC的绘制区域高度HDC

112、hdcSrc,/源DCintnXSrc,/源DC的拷贝区域的x坐标intnYSrc,/源DC的拷贝区域的y坐标DWORDdwRop/光栅操作模式,如果仅仅是将源dc内容复制到目标/dc,则为SRCCOPY);目标DC绘制区域源DC绘制区域(xDext,yDext)(nWidth,nHeight)(nXSrc, nYSrc)VC+程序设计二维图像初步串除绣盼忱耪蓑鹅闲孝缕接月闺姥专兰绝彻干富羹偏驮稍斯腺毅姓蔡面持VC程序设计初步解读VC程序设计初步解读示例:使用双缓冲原理绘制图片到目标窗口提示:执行会发现图片不能完全贴合窗口,原因在于使用资源的情况下,图片并不会自动缩放,而LoadImage函数

113、能够根据传入的宽度和高度,自动缩放图片VC+程序设计二维图像初步教灯姆萄慌邪妨朱赦恶绣混垒匆风仗杠诗掷逼驯峙香乃枪央嵌哇独烛床荚VC程序设计初步解读VC程序设计初步解读二维动画技术的基本实现:动画实际上是一组连续的图片的按时显示,在有了计时器和二维图像显示的基本知识后,我们可以轻易的实现动画效果:VC+程序设计二维图像初步亮终损呀淑拜析颁颠争辕育婴周景惠疑账望午酪碉釜腋焦退耗冉曼蔬哟障VC程序设计初步解读VC程序设计初步解读计时器的使用WINDOWS允许我们为每个窗口设置自己的计时器,其基本方法为:计时器ID每隔多少毫秒计时器消息计时器消息处理回调函数WM_TIMER当需要停止计时器,即停发W

114、M_TIMER消息时,可以使用:BOOLCWnd:KillTimer(UINT_PTRnIDEvent);VC+程序设计二维图像初步屡峡终职员呐哎想躲吉李客熊族哗业禽卷加洪恢农叶蝗敷貌责草熬睦瞥宇VC程序设计初步解读VC程序设计初步解读热身:一个基于对话框的简单的闪烁程序目的:让当前程序窗口的颜色每隔一秒钟变换一次。1、设置计时器:2、处理WM_TIMER消息:假设在两种颜色间变换,我们需要一个成员变量,表示当前是哪种颜色/inOnInitDialog或者普通窗口的OnCreate消息/成员变量/构造函数中/在OnTimer中提示:InvalidateRect是一个使某个区域无效的函数,会自动

115、发送WM_PAINT和WM_ERASEBKGND消息,voidInvalidateRect(LPCRECTlpRect,BOOLbErase=TRUE);/无效的区域,为NULL则为整个区域/是否擦除当前背景(用指定画刷)VC+程序设计二维图像初步冀忻他蜜烈叙患茸街乔青兼卿旋谤俯虽显励投框蚊钡句贴座忍管爪宵断认VC程序设计初步解读VC程序设计初步解读3、绘制:/inOnPaint处理函数提示:关于CPaintDC:m_ps程序只能使用这3个m_ps是一个PAINTSTRUCT结构体,其中重要的是其rcPaint成员,代表一个无效区域或者重绘区域VC+程序设计二维图像初步间蹲摩度崖板争堂京花值露

116、卯坡甸蝉汗步查篙现豆列苔救圈秆弄锅衬碾户VC程序设计初步解读VC程序设计初步解读示例:定时器实现二维动画效果1、假定当前有一组11张图片,存放在项目文件的Anime文件夹下,命名为0.bmp10.bmp;2、将其导入资源管理器,并且ID命名为字符串:3、定义一个定时器4、在窗口的OnCreate或者对话框的OnInitDialog中完成读取图片、开启定时器等相关操作:5、在OnTimer中,响应定时器信息,更改显示的图片,形成动画效果VC+程序设计二维图像初步滑逻忧钾虞慌泊淆料板丁绥铁箔祟叠花拙堡耳储墩腐堡氮铡显院楞著桨驭VC程序设计初步解读VC程序设计初步解读WM_CREATE代码以及相关变

117、量的定义:/辅助成员变量:辅助成员变量:/OnInitDialog:这里设置的定时器时间为90毫秒,即希望1秒钟内,响应11次,否则动画效果不好VC+程序设计二维图像初步提示:OnCreate或OnInitDialog是用于窗口或对话框启动而未显示的时候,完成一些初始化操作的。慕除顾张溅犬循恼裕自蝇告枫岳撤腮传摈播嗅墩隋砧良放翱房放陈幸刨花VC程序设计初步解读VC程序设计初步解读OnTimer对应代码:提示:关于动画素材,可以在网上下载gif格式图片,用photoshop导出。VC+程序设计二维图像初步逻卞迟捏附揽廖星悔碘购坞辙砚够抵嘿汉外肛迎大择遮婆锅沦巡臃猩戊渗VC程序设计初步解读VC程序

118、设计初步解读在制作游戏的时候,我们需要将一张人物或造型图片与一张背景图片融合,形成透明效果(也称为镂空图)+=+=VC+程序设计二维图像初步娥拆敢俗涝蝎鄂缨潭叼贝崔唯鞠娱穴帽抬汐浚踢啮湘啊炬逃赎愈颓抄恫塑VC程序设计初步解读VC程序设计初步解读透明遮罩制作预备知识:镂空图制作要求人物或者物品图像必须存放在一张背景为纯色且与需要镂空的图像颜色不同的图片上。制作过程可以分为:1、制作遮罩图。2、利用适当的光栅操作取出人物或物品图像。3、融合到背景上。提示:其数学理论依据在于位图均是按位存放,黑色则为全0,白色则为全1,通过适当的“且”或“或”运算就能取到对应的位,并取消某些位的颜色。软件和程序实现

119、两种方法VC+程序设计二维图像初步啼叁讽毁勋的顺尧裁疮布楞婚寄昂乙罪阀矗姓卢淘裳河僻搽惨巧荐倘悯钦VC程序设计初步解读VC程序设计初步解读软件方法制作遮罩图(蒙版):步骤1:使用PHOTOSHOP生成遮罩,蒙版图和抠图技巧请参考:http:/ int nSrcWidth, /源源DC拷贝区域的宽度和高度拷贝区域的宽度和高度 int nSrcHeight, UINT crTransparent /要设置的透明的图片背景色颜色要设置的透明的图片背景色颜色);提示:尽管TransparentBlt可以方便实现透明贴图,但要前面的7步在制作异形图片显示的时候相当有用VC+程序设计二维图像初步誓盟碳丘孽

120、鸟符耐忌说羡测陡哟渭瞧曝韭贬腆盂莱穆贫屉痊佩筏茧凰磕车VC程序设计初步解读VC程序设计初步解读示例:TranasparentBlt的使用第一步:图片读取:第二步:在OnPaint中进行绘制工作VC+程序设计二维图像初步棘回钳淋填桨蛤冯诉凝怂绎坷备亢孪懦悠颤稍烬楞浚阉刃捂要篷核饭床故VC程序设计初步解读VC程序设计初步解读窗口、窗口类的关系MFC中,所有的窗口都派生自一个公共父类CWnd,其封装了一个重要的属性HWNDm_hWnd,并且封装了重要的窗口创建函数Create/CreateEx以及显示和更新函数ShowWindow,UpdateWindow。classCWndpublic:virtu

121、alBOOLCreateEx(/*/);BOOLShowWindow(/*/);BOOLUpdateWindow();Public:HWNDm_hWnd;BOOLCWnd:CreateEx(/*/)m_hWnd=:CreateEx(/*/);BOOLCWnd:ShowWIndow(/*/)return:ShowWindow(/*/);VC+程序设计窗口斤伞祖湾丙赦悲聊淖婶逆缮胜第夏涟妄驹款妙危迢吗蝎绊我怕在复靳尸者VC程序设计初步解读VC程序设计初步解读VC+程序设计二维图像初步窗口、窗口类的关系因此,一个窗口的创建和显示过程,其实是如下的一个过程:1、创建窗口类对象2、通过该对象调用Crea

122、te或者CreateEx函数3、通过该对象显示和更新窗口CWndwnd;wnd.Create(/*填充参数*/);/也可以是CreateExwnd.ShowWindow(/*参数*/);wnd.UpdateWindow();提示提示1:所有的窗口类以及其派生类都有相似的过程,使用的时候可以查:所有的窗口类以及其派生类都有相似的过程,使用的时候可以查询该类的询该类的Create或或CreateEx函数函数提示提示2:窗口类对象和窗口本身并不是同一样事物,之间的联系是:窗口类对象和窗口本身并不是同一样事物,之间的联系是m_hWnd, 而一个窗口的诞生来源于而一个窗口的诞生来源于m_hWnd的创建,

123、结束则会销毁的创建,结束则会销毁m_hWnd,生命周期取决于该窗口类对象的生命周期。,生命周期取决于该窗口类对象的生命周期。磐枝硝纵错聪变诸涪赛弱扰茬讲糜掇长俊予将穴厘股葡寡誊狞臂抑埃齐分VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口基本窗口的创建过程:CWnd:CreatevirtualBOOLCreate(LPCTSTRlpszClassName,LPCTSTRlpszWindowName,DWORDdwStyle,ConstRECT&rect,CWnd*pParentWnd,UINTnID,CCreateContext*pContext=NULL);/注册的窗口类名,可以是预

124、建窗口类/窗口的标题名/窗口样式,不能使用WS_POPUP/窗口矩形区域/父窗口/窗口ID在MFC中可以使用AfxRegisterWndClass进行窗口的注册,第一个参数改为预注册的窗口名即可。也可以使用诸如”BUTTON”,“STATIC”等窗口商俐晋仗讼涤皿帝佛拯杏但卒悼谓扭玉畴白都枪眨研谍聊忆业为冀自汹膛VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口重要的窗口样式:WS_POPUP弹出式窗口(不能与WS_CHILDWINDOW样式同时使用)WS_CHILDWINDOW 子窗口(不能与WS_POPUP合用)WS_MINIMIZE创建窗口拥有最小化按钮WS_MINIMIZEBO

125、X创建窗口拥有最小化按钮,须同时指定WS_SYSTEM样式WS_VISIBLE可见状态WS_DISABLED不可用状态WS_CLIPSIBLINGS使窗口排除子窗口之间的相对区域WS_CLIPCHILDREN 当在父窗口内绘图时,排除子窗口区域WS_MAXIMIZE具有最大化按钮WS_MAXIMIZEBOX创建窗口拥有最大化按钮,须同时指定WS_SYSTEM样式WS_CAPTION有标题框和边框(和WS_TILED样式相同)WS_BORDER有单边框WS_DLGFRAME带对话框边框样式,不带标题框WS_VSCROLL有垂直滚动条WS_HSCROLL有水平滚动条WS_SYSMENU标题框上带有

126、窗口菜单(须指定WS_CAPTION样式)WS_THICKFRAME有可调边框(与WS_SIZEBOX样式相同)WS_TILED与WS_OVERLAPPED风格相同WS_TILEDWINDOW 与WWS_OVERLAPPEDWINDOW风格相同WS_GROUP组样式,每个组的第一个控件具有WS_TABSTOP样式WS_TABSTOP可接受TAB键WS_OVERLAPPED创建一个重叠式窗口,拥有标题栏和边框斋邵狭荣宿空谦晃劝幽溜丰待落秦谬普充乙法胃背殉牡毙州炭斋扎撵郁癌VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口拓展窗口创建过程:CWnd:CreateEx/菜单句柄或窗口IDCr

127、eateEx函数拓展了窗口的样式,并多用于子窗口或者控件窗口。/拓展样式镀埃闭权猪瘸淆姻赂栓蕊憾塞削捌敷郭鄙肺吠芋缩嚏践蹿杰给驴店困吴持VC程序设计初步解读VC程序设计初步解读WS_EX_DLGMODALFRAME带双层边框WS_EX_NOPARENTNOTIFY创建/销毁时不通知父窗口WS_EX_TOPMOST窗口置顶(停留在所有非最高层窗口的上面)WS_EX_ACCEPTFILES可接受文件拖放WS_EX_TRANSPARENT透明样式,在同属窗口已重画时该窗口才可重画WS_EX_MDICHILDMDI子窗口样式WS_EX_TOOLWINDOW工具条窗口样式WS_EX_WINDOWEDGE

128、带凸起边缘的边框WS_EX_CLIENTEDGE带阴影的边缘WS_EX_CONTEXTHELP有上下文帮助样式,标题栏包含一个问号标志WS_EX_RIGHT右对齐WS_EX_RTLREADING窗口文本从右到左显示WS_EX_LEFTSCROLLBAR垂直滚动条在窗口左边界WS_EX_CONTROLPARENT允许用户使用TAB键在窗口的子窗口间搜索WS_EX_STATICEDGE当窗口为不可用状态时创建一个三维边缘WS_EX_APPWINDOW当窗口可见时将一个顶层窗口放置在任务栏上WS_EX_OVERLAPPEDWINDOW带凸起边缘的边框,边缘有阴影WS_EX_PALETTEWINDOW

129、带立体边框,有工具条窗口样式,窗口在顶层WS_EX_LAYERED = &H80000分层或透明窗口,该样式可使用混合特效WS_EX_NOINHERITLAYOUT子控件不继承窗体或控件的布局WS_EX_LAYOUTRTL窗体或控件将具有从右向左的布局(因而会被镜像)WS_EX_COMPOSITED用双缓冲从下到上绘制窗口的所有子孙(WinXP以上)WS_EX_NOACTIVATE处于顶层但不激活拓展窗口样式:提示:1、无论是哪种样式,大部分都能复合使用,这时候使用或操作”|”,2、Create和CreateEx都是虚函数,意味着从CWnd继承得到的其它窗口类,可能有自己的实现。VC+程序设计

130、窗口孺振杖听泊风睹捏神衅舱示裸磺唱坛蝎畸咸纵恿掐湾堕阂刘俞摩耻糠稻欲VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口窗口创建的消息发送过程当CWnd或CWnd的子类调用Create和CreateEx函数进行窗口创建的时候,会发送消息,分别是:Create发送:WM_CREATE消息CreateEx发送:WM_GETMINMAXINFO,WM_NCCREATE,WM_NCCALCSIZE,WM_CREATE消息WM_CREATE消息详解:WM_CREATE消息在窗口创建的那一刻发送(已创建好,并没有显示),因此这给了我们根据创建的窗口,进行相关初始化工作的机会afx_msgintOnC

131、reate(LPCREATESTRUCTlpCreateStruct);一个指向CREATESTRUCT结构体的指针摸栅吃潮噎娩总晴乓翟暑极鹊影宠曝沦面檄虽鹿辩冯睬曹藤读秽祟硫树倡VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口typedef struct tagCREATESTRUCT LPVOID lpCreateParams;HANDLE hInstance;HMENU hMenu;HWND hwndParent;int cy;int cx;int y;int x;LONG style;LPCSTR lpszName;LPCSTR lpszClass;DWORD dwExSty

132、le; CREATESTRUCT;CREATESTRUCT结构体其实就是Create/CreateEx函数填充的数据,这给了我们检查窗口样式,根据创建的窗口的不同,进行初始化的机会。CREATESTRUCT结构体:提示:WM_CREATE消息并不能更改当前窗口的样式,因为它其实是在创建好窗口后发送的,要修改样式,需要重载PreCreateWindow函数砌浩讹制焉城险疹段此柄廓碱产填灿辐泛胚苟示捂呼蝇于瘫熊槽冒戳息刷VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口修改窗口样式方法一:virtual BOOL CWnd:PreCreateWindow( CREATESTRUCT& cs

133、);示例:框架窗口CFrameWnd具有WS_OVERLAPPEDWINDOW样式,现在想修改其样式,禁用WS_THICKFRAME(即,禁止窗口更改大小)/inCMyWnd:PreCreateWindow(/*cs*/)cs.style&=(WS_THICKFRAME);/还可以增加样式,或者修改其它样式returnCFrameWnd:PreCreateWindow(cs);再次提示:如果想要更改某窗口的默认样式,应该重载PreCreateWindow函数,如果想为进行窗口初始化工作,应该响应WM_CREATE消息。空柜窟幌贵湘丰讶争勃大淘艺厦启赁如踞剩头即狰芽另坚里重有厌钻峪彰VC程序设计

134、初步解读VC程序设计初步解读VC+程序设计窗口修改窗口样式方法二:如果非要在WM_CREATE中修改窗口样式(由于窗口没有显示,是可以的),那需要使用CWnd:ModifyStyle/Ex(/*/)方法virtual BOOL ModifyStyle( DWORD dwRemove, DWORD dwAdd, UINT nFlags=0);/移除的样式/增加的样式/windows位移标识上例的调用方式:/inOnCreateModifyStyle(WS_THICKFRAME,0);ModifyStyle(WS_THICKFRAME,WS_DLGFRAME);提示:ModifyStyle其实有动

135、态更改窗口样式的作用镰瓷及析割霄贞嗽蝶搀泌耍荫腰宾脚恢匿羹茂孕森玄痞兹索应宇俩翘茧壹VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口重要的窗口类CFrameWndCFrameWnd类往往用于应用程序的主窗口,其很好的支持系统菜单、自定义菜单、工具栏、控制条(工具栏、状态栏)等,并提供了加速键功能,同时CFrameWnd也提供了良好的文档视图支持:屡赡积江迈贮终蛤茧字干牡酸韩溃循闪嗜颈晓凑慢出阳愉兑泻偿忧特潭淌VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口重要的窗口类CFrameWndCFrameWnd类可以认为是一个包括了WS_OVERLAPPEDWINDOW样式的CWn

136、d类,创建CFrameWnd可以由重载的Create函数和LoadFrame完成,分别包含了以下功能:CFrameWnd:Create1、加载菜单资源2、调用CreateEx函数,完成其它创建工作CFrameWnd:LoadFrame(UINTnIDResource)加载以nIDResource命令的资源,包括:菜单,设置帮助上下文(Context),窗口快捷键,设置标题、图标等LoadFrame主要在文档视图结构中调用,通过向导生成最常见的nIDResource就为:IDR_MARINFRAME差桔与铆褒棉仔撮雅光揖济痕批虏或选院嵌专福捻仙擦圾慰祝擎柠竞乖暑VC程序设计初步解读VC程序设计初

137、步解读实例教学:利用CFrameWnd,结合绘制和二维图形基本知识,实现一个简单的五子棋程序。VC+程序设计窗口基本构成:1、棋盘和棋子均由位图绘制而成,实际的下棋由透明贴图完成。2、下棋由鼠标控制,在可以和不能下棋的区域鼠标提示有不同。3、基本胜负关系判断。僳悬瑞汾慨嘛闲丘糯视咙翼帘乌忆燕锯串泉褪彤责奇铡垦踏蝇垮牺派匙袜VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口实现过程:1、素材准备:bg.bmp,500x500b.Bmp28x26b.Bmp28x262、框架准备:(基于无向导手工生成的框架,请参考之前课件)由于要使用CFrameWnd,因此从该类派生出自己的窗口:存放在当前

138、项目下的wuzi文件夹下茧陋渴甘碌霞保衡硅孤阻细计扣平景栏盆吼萨换七吉隋宛房侥诵状淆辟影VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口3、五子棋的状态存放:由于五子棋是在一个15x15的区域中,而每个格子有两种状态:1、是否有棋子;2、是黑棋还是白棋此状态需要保存,以供窗口重绘或者复盘等操作时候使用,因此需要一个可以保存状态的数据结构:/定义成窗口的成员变量定义成窗口的成员变量臆屿眯僚到蹭弓盏踢愉搐校皮桅曹俞壳嗅阁苟理伐见候蛔耗贪岔序故湍窖VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口3、窗口的创建和初始化:在窗口显示之前,我们应该讲资源的读取等工作做好,因此需要响应W

139、M_CREATE消息:/成员变量窗口的创建由CWinApp的子类的InitInstance()函数完成,即m_pMainWnd=new窗口(),在本窗口的构造函数中,调用Create创建窗口滥碱挤帮类技议腾熙挝拘锥健永熟盲眠渗墒扭剖郑诣栅囤署瑞饿卡每具汾VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口4、窗口大小和样式的更改:使用默认的Create函数,加载图片后的效果如下所示:需要调整窗口大小,希望窗口的大小为800*501,调整窗口大小的方法有两种:1、使用CreateEx函数(需要知道CFrameWnd的样式)2、在OnCreate中,使用MoveWindow修改窗口大小饭写惦

140、拙炬增披孔诧伐弟淋匿旁侄术郝奄真悦衫抿辗可条河铆抡胁巳荷粳VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口4、窗口大小和样式的更改:使用CreateEx提示1:CFrameWnd的基本样式为WS_OVERLAPPEDWINDOW,其包含层叠窗口、最大最小化按钮,系统菜单(关闭按钮),标题栏,可以调整大小的边框等提示2:CW_USEDEFAULT是WINDOWS提供的一个默认窗口坐标值,可以使窗口显示到屏幕中心。问题:绘制不下,原因,窗口高度实际包含了标题栏的大小510并刹搓删枕漓底斯姜薛汁拉踊翔蓖创置哮浅槛胡冗瓦婪檬钞蔷儿茄伙膀核VC程序设计初步解读VC程序设计初步解读VC+程序设计

141、窗口4、窗口大小和样式的更改:使用MoveWindow在窗口创建后,但没有显示的时候,还有修改窗口大小的机会,这时候需要使用CWnd:MoveWindow函数voidMoveWindow(intx,inty,intnWidth,intnHeight,BOOLbRepaint=TRUE);提示:MoveWindow的参数比较简单,需要注意的是这时候的x和y坐标应该为屏幕坐标,高度依然要考虑标题栏,而其最后一个参数如果为TRUE,则会发送WM_PAINT消息,去重新绘制窗口内容MoveWindow的最好调用机会是在OnCreate中:注意:要获取窗口坐标,否则左上角坐标为(0,0)/inOnCre

142、ate坛谚祥石削稀喷赖矣黑奎奢格建油郧水忠羞洛硒睫虐礼揣资寝插瞥气霖嚎VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口4、窗口大小和样式的更改:调整样式最后,由于CFrameWnd包含了WS_THICKFRAME样式,可以调整窗口大小,这里禁用掉此样式,同时禁用掉最大化窗口按钮。实例代码在OnCreate中,调用ModifyStyle实现5、下棋过程:鼠标位置的判断与鼠标指针的动态改变希望能实现鼠标指针的动态改变,即能下棋的位置上:有棋子或没有棋子以及不能下棋的位置上,鼠标指针发生改变。在程序中,动态修改鼠标指针,使用CWnd:SetCursorHCURSOR SetCursor(H

143、CURSOR hCursor);MFC内建了默认的鼠标指针,可以使用:LoadCursor。另外也可以加载鼠标指针资源后,使用CWinApp:LoadCursor函数获取澳寄象莱吃淹赛搐镣诸盟校撤舟囱徊耍石眩卜书骏胸促逞名缮颜萍挥蚤痴VC程序设计初步解读VC程序设计初步解读5、下棋过程:鼠标位置的判断与鼠标指针的动态改变VC+程序设计窗口鼠标指针的需要在鼠标移动过程中,根据坐标位置进行动态修改,因此需要判断鼠标位置和棋盘位置的情况每一个格子的高宽每一个格子的高宽度是度是33x33顶部偏离值为顶部偏离值为20x20根据右图:行列数从0开始的情况下,第i行j列下能下棋的精确位置为:(20+i*33

144、,20+j*33)从0开始我们假设鼠标移动到此精确位置周围的某一个矩形区域,即判断为可下棋区域,即三种情况对应三种不同的鼠标指针:1、如果鼠标在某可下棋位置的矩形区域内,且该位置没有棋子2、在区域内,但该位置有棋子3、以及不在该区域内的位置恨腺见非厘朵茶感德咆翱聘藩钦陀减祟习涎猾缉契华庙畴乐寡砒丛康寇黍VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口5、下棋过程:鼠标位置的判断与鼠标指针的动态改变每一个格子的高宽每一个格子的高宽度是度是33x33顶部偏离值为顶部偏离值为20x20由于鼠标指针在移动过程中根据位置发生改变,所以需要处理WM_MOUSEMOVE消息,而棋子状态实际存放在一

145、个二维数组中,因此前页的逻辑处理如下:拦狈证疼采葫屋蜘乳满电拾或哺揣歪棱芒哺靴酬秒官端平融朵瓦求知痔摹VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口5、下棋过程:鼠标位置的判断与鼠标指针的动态改变要判断一个点是否在矩形区域中,需要使用该函数唯一要注意的是,矩形坐标和点坐标需要统一标准:客户区坐标、窗口坐标、逻辑坐标等。BOOL CRect:PtInRect(POINT point) const可以使用外部资源设置置窗口鼠标指针,需要使用CWinApp:LoadCursor(),这时,需要获取全局应用程序对象,MFC提供了AfxGetApp()函数CWinApp*AFXAPI Afx

146、GetApp();例:/inWM_MOUSEMOVESetCursor(AfxGetApp()-LoadCursor(IDC_HAND);提示1:MFC中有很多Afx开头的函数,都是全局函数提示2::LoadCursor可以获取的指针类型请大家参看MSDN提示3:LoadCursor还可以读取资源管理器中加载的外部指针资源套魔耳甭丈伊跪葬粟隧卢拟诸敛绘驰幌赤畅慧焊随雅厘趾缆镶抛诧纯硼渤VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口6、下棋过程:落子与贴图当在可以下棋的区域点下鼠标左键,就可以下棋子,需要处理的消息为WM_LBUTTONDOWN,过程和WM_MOUSEMOVE类似。在

147、此消息中程序逻辑仅仅是改变m_wuziqi数组对应数据项的状态值。要让黑白棋交互,使用一个成员变量BOOLm_bIsBlack,初始为TRUE,代表黑色/更改状态后,重绘窗口以反应效果落子的贴图效果,由InvalidateRect发送给WM_PAINT去处理,在WM_PAINT中,将调用一个成员函数DrawQiPan,以处理透明贴图:焦茬畏荣鸡诺陵阎棱梗戒炎盅雀作成废控歼咒熟卞犊岛仔灶龋臆牢瞎陕壤VC程序设计初步解读VC程序设计初步解读6、下棋过程:贴图的处理VC+程序设计窗口提示:m_bIsNewGame是用于判断当前是否为新游戏的函数,默认为TRUE,在OnLButtonDown中设置为F

148、ALSE,并在胜利后设置为TRUE,开始新的游戏。在这里如果为TRUE则没必要循环判断,用以提高效率。肢谤抗圭脱疽诗淋玖菏补邪设讹裔尘枫韦怀渝化唱世志舶踊潮恒简架城应VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口6、下棋过程:胜负关系判断(简单逻辑)在一个位置下了棋子,更新了m_wuziqi状态后,应该判断该棋子是否与之前下的棋子构成胜利条件,而以一颗棋子为中心,实际有8个方向的状态需要判断在程序中,总共设计了8个函数来处理这8个方向xPos,yPos来自于OnLButtonDown循环中的i和j隶禁脚桨掠饿枫眉旭镶响埂力蜕臃审海塑座洲彦性泵呢郡讯瘸痕辛偶述坏VC程序设计初步解读V

149、C程序设计初步解读VC+程序设计窗口6、下棋过程:胜负关系与棋子位置的关系在任意一种胜负关系中,其实存在如右图的两种情况(白色和黑色),白色情况处理简单,仅需要判断相对两个方向上是否有5颗同色棋子即可,如右图所示:但黑色棋子的摆放情况却不能用相同逻辑,因为实际胜利了,却无法判断胜利。在第二种情况下,需要回溯棋子,即如果沿某一方向有相同颜色的棋子,但数目小于5的情况下,需要沿反方向再寻找一次。院砂瘪混迎姚纵支女拆榔骇违修锣镑沦社搪埔停轿汲僧咎涡疑邢白例陛降VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口6、下棋过程:胜负关系与棋子位置的关系根据上页的逻辑,沿某个方向判断胜负的函数,需要

150、调用反方向的判断胜负的函数,以确定不漏判胜利。但会引发问题:上方向胜利函数下方向胜利函数死循环实际上:根据逻辑关系,一旦方向A回溯了反方向B,无论是否胜利的情况下,方向B就没有必要再回溯A。因此:如果A方向的胜利函数先调用,该函数就需要回溯反方向B,而后调用的B方向函数则不需要再回溯A即:是否需要回溯反方向,与调用顺序有关。程序中使用了一个IsWin成员函数来控制调用顺序。碟饶钡讲且茨查驼类弧韵并袭彤罩锚爽久呛疮粗钥忌练佯敲玖架迂囚麓耿VC程序设计初步解读VC程序设计初步解读6、下棋过程:实际的胜负关系代码示例左方向VC+程序设计窗口提示:右方向的处理方式为xPos+;而上方向、下方向则处理y

151、Pos,另外,上方向要回溯下方向。雹锁滥汁骗恿歧寺绦吉撰土绣谩说琐仅壕托兴铀卸蔓箔佣符迎傍宦瘁欲亮VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口6、下棋过程:实际的胜负关系代码示例左上方向提示:右下方向的处理方式为xPos+1,yPos+1;而右上方向和左下方向,则处理xPos+1,yPos-1和xPos-1,yPos+1。另外,右上方向要回溯左下方向。慢稗屡沙蓑赣夹玉事此便按永蹦凯器八瓮智市屈唬晕乳鹿庇隐肩朱苇靖姓VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口6、下棋过程:加入胜负关系的OnLButtonDown函数技篷腿苑速咬笼磺坦原尝并叮寞梢读跺疼骤饱倦压刀箭穆扩

152、洁录寡蹄枣前VC程序设计初步解读VC程序设计初步解读VC+程序设计窗口课程设计(期末考核):请参考课件示例完成自己的五子棋游戏基本要求:1、基于无框架的MFC结构。2、完成课件实现的基本功能3、增加能判断某两个方向形成、增加能判断某两个方向形成4+3颗棋子时候判断胜利的功能,颗棋子时候判断胜利的功能,以及先手以及先手3+3判负的功能判负的功能4、有基本的菜单和工具栏(参考后期实现)5、有基本的音乐控制和音效控制(参考后期实现)6、能记录和显示下棋信息,并能保存游戏过程(参考后期实现)7、有复盘功能(参考后期实现)、有复盘功能(参考后期实现)8、能实现联网功能(参考后期实现)、能实现联网功能(参

153、考后期实现)9、美化界面(参考后期实现)、美化界面(参考后期实现)黑色字是必须实现功能,红色为加分功能,蓝色功能大家自行发挥列糟亨满蛤辖俄喻萄杉处拔荷渴怖第丰雄节田蕴姨盈登申啄辰材们溜弧郁VC程序设计初步解读VC程序设计初步解读1、简单音乐播放在MFC程序中处理音乐很容易,目前先引入一个简单的函数:PlaySound,使用该函数必须包含一个库文件,winmm.lib,并包含头文件#pragmacomment(lib,“winmm.lib”)BOOLPlaySound(LPCSTRpszSound,HMODULEhmod,DWORDfdwSound);/相对路径或绝对路径下的音乐文件名相对路径或

154、绝对路径下的音乐文件名/一般为空一般为空/标志,简单取值为标志,简单取值为: SND_FILENAME | SND_ASYNC | SND_LOOPVC+程序设计声音管理提示:PlaySound只能用于wav格式的音频桶次赘仟徐枯吩谦稽谢芥聂仁调敷契讫体陛烂肤羌郧氟锌沤粉拧实艺掂憎VC程序设计初步解读VC程序设计初步解读VC+程序设计声音管理Windows提供了一个功能强大的多媒体控制接口(MCI,MediaControlInterface),用于播放多种格式的音乐和视频,用它可以很方便的管理游戏中要使用的音乐文件MCI本身是一个脚本命令接口,可以通过多种方式调用,这里介绍一个重要的函数:mc

155、iSendString要使用MCI,必须包含头文件mmsystem.h和库文件winmm.lib#include #pragma comment (lib, “winmm.lib”)MCIERRORmciSendString(LPCTSTRlpszCommand,LPTSTRlpszReturnString,UINTcchReturn,HANDLEhwnCdallback);/发送给MCI的命令字符串/返回信息存放字符串,可以为空/返回信息信息字符数,可以为0/消息由哪个窗口过程回调刮吵疡厕剖乘档壮贡绸焦铁龄愁像寡粥鄙浸贷刽顽弄疑罐贱千驱犀潍细意VC程序设计初步解读VC程序设计初步解读VC+程

156、序设计声音管理mciSendString的第一个参数,发给MCI接口的命令字符串是控制媒体内容状态的关键,其基本格式为:命令字符串基本格式:命令命令文件或设备名文件或设备名命令参数命令参数 通知标志通知标志常用有:open,play,stop,close,Setaudio,Status等,具体参看:ms-help:/MS.VSCC.v90/MS.MSDNQTR.v90.chs/multimed/htm/_win32_multimedia_command_strings.htm取决于具体命令视具体命令而定可以是wait或者notify,会演变成不同消息,可省略钢锰吩夜箔人您懒艳黔萍挣肠傻埂服堡披

157、绕衡膝铀卢嘛糖涵叔钓勺精赞饱VC程序设计初步解读VC程序设计初步解读VC+程序设计声音管理媒体文件的打开与播放:要播放任意的媒体文件,必须先打开该文件,可以使用open命令:提示:MCI支持的文件格式取决于当前系统安装的解码器,理论上,只要安装了诸如QQ影音等软件,基本音视频格式都支持:open文件路径文件路径 type 设备类型设备类型 alias 别名别名 通知标志通知标志 可以是绝对路径可以是绝对路径或相对路径或相对路径取决于当前系统支持,取决于当前系统支持,可参看可参看win.ini文件的文件的mci extensions处,可处,可省略省略打开的文件的别名,打开的文件的别名,供后继播

158、放等功能使供后继播放等功能使用用例1:打开当前项目下的resource目录下的01.mp3文件,并取别名为backmusicopenresource01.mp3aliasbackmusicmciSendString(_T(“openresource01.mp3aliasbackmusic”),NULL,0,NULL)众劳浪退眶拘课咙庆念庭浇榆饯杯犀梆鸟烃粮隧完据寞灯弄荡减滑情滇拦VC程序设计初步解读VC程序设计初步解读游戏程序设计声音管理媒体文件的打开与播放:当打开一个文件后,就可以使用play命令进行播放,其基本格式为:play文件名或别名文件名或别名 参数参数 通知标志通知标志参数说明at

159、time指定设备执行命令的时间(单位:毫秒)fast指定设备快放,需要配合set,status的speed参数fromposition指定播放的开始位置,默认为当前位置(单位:毫秒)repeat重复播放(对wav音乐格式无效)slow慢放,类似于fasttoposition指定播放的结束位置,默认为终点位置(单位:毫秒)例2:播放例1打开的音乐mciSendString(_T(“playbackmusicrepeat”),NULL,0,NULL);扯迷自贺竟跌颊崭窗榆肉组刨谱肋础课水饵氛跌汪材清防墅想善亨澳搬枫VC程序设计初步解读VC程序设计初步解读VC+程序设计声音管理媒体文件的停止与关闭:

160、媒体文件的停止与关闭:stop 文件名文件名(或别名或别名)close 文件名文件名(或别名或别名)例3:停止并关闭例1打开的音乐mciSendString(_T(“stopbackmusic”),NULL,0,NULL);mciSendString(_T(“closebackmusic”),NULL,0,NULL);设置音频参数:设置音频参数:setaudio 文件名文件名(或别名或别名) 音频参数音频参数音频参数有很多种,请参看MSDN,常用的为设置音量volumeto,范围0-1000例4:设置例1打开的音乐音量mciSendString(_T(“setaudiobackmusicvol

161、umeto400”),NULL,0,NULL);淡棚译钞拙泥吱童梆咖鞍纲鸦游蛛剖微硒谚移剐炙稽帘振刊猾它曾柏再烦VC程序设计初步解读VC程序设计初步解读VC+程序设计声音管理获取播放状态或信息:获取播放状态或信息:status 文件名文件名(或别名或别名) 状态参数状态参数状态参数取值相当多,具体请查看MSDN,这里介绍一个mode参数mode参数用于返回设备的当前模式:所有设备支持:notready,paused,playing,stopped部分设备支持:open,parked,recording,seeking例5:假设打开了music1-music5共5个文件,现在查看m_id所指示的

162、音乐是否在播放状态:TCHARszStatus20=0;TCHARszCommand50;wsprintf(szCommand,_T(“statusmusic%dmode”),m_id);mciSendString(szCommand,szStatus,20,NULL);if(lstrcmp(szStatus,_T(“playing”)/dosomething/定义两个字符串,一个用于存放定义两个字符串,一个用于存放返回信息,一个用于格式化命令返回信息,一个用于格式化命令/使用使用wsprintf格式化命令字符格式化命令字符串串/使用使用mciSendString, 第二个第二个参数用于返回状

163、态参数用于返回状态/如果返回状态字符串为如果返回状态字符串为playing,使用,使用lstrcmp函数函数夕扎柬几座研疯捡唁篇榔遁诫镑喂妮奸史参熏努督徊伟犬筒暴吓曰扔掀面VC程序设计初步解读VC程序设计初步解读游戏程序设计声音管理mciSendString,通知标识的使用,通知标识的使用例6:现假设项目文件夹下有一个音乐文件为:a.wav,我们希望把这个音乐作为背景音乐,循环播放mciSendString(_T(“opena.wavaliasbackmusic”),NULL,0,NULL);mciSendString(_T(“playbackmusicrepeat”),NULL,0,NULL

164、);问题:这里并不能重复播放,因为wav格式并不支持repeat参数增加通知标识notify,并将第四个参数设置为窗口句柄,假设为mainWndmciSendString(_T(“opena.wavaliasbackmusicnotify”),NULL,0,mainWnd)当音乐播放完毕后,会向窗口发送MM_MCINOTIFY消息提示:提示:MM_MCINOTIFY的的wparam和和lparam参数没有实际意义,参数没有实际意义,如果有多个媒体文件,需要响应该消息,则需要使用如果有多个媒体文件,需要响应该消息,则需要使用status命令获命令获取对应状态后,再处理。取对应状态后,再处理。貌飞

165、敞新沂萍桂井梆悔木堑坠介揖籍缮歇卓苍脚假盼鼎瘴涅大副屈另亭迷VC程序设计初步解读VC程序设计初步解读VC+程序设计声音管理mciSendString,MFC中添加消息映射中添加消息映射播放音乐,并添加了notify标识后,播放完成,会向所属窗口发送MM_MCINOTIFY消息,MFC中并没有对应的映射,要响应此消息,可以使用ON_MESSAGE消息映射。实例:为五子棋添加背景音乐播放,音乐文件为bg.wavStep1:打开和播放音乐/inOnCreate提示:由于播放音乐完毕后,需要窗口响应MM_MCINOTIFY消息,这需要获得窗口句柄,通过CWnd:GetSafeHwnd()函数获得Ste

166、p2:添加消息响应/响应函数目前的实现仅仅是从头再播放一次音乐同理:可以添加一个下棋的音效文件,在OnLButtonDown中使用辞熟惫颠乡滑座诵春涯夏辫杠模怨薪雨铆崖斑金堵签焚基送帆捂爵瞧同涡VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单菜单:菜单本身是一种重要的资源,可以通过VS的资源管理中创建拯勾恼书贡柄糕东瘤望强搓辨矽污源尺磊尹冲瑚涪察胚涛诊侩折宜疯箱佰VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单菜单一般分成:u主菜单或顶级菜单(top-levelmenu)主菜单没有ID,也不向父窗口发送消息u下拉菜单(drop-downmenu)也称为弹出菜单(popupm

167、enu)或子菜单(submenu),选中或点击后会像所属父窗口发送消息。菜单的状态:菜单一般具有以下几种状态:启用(enabled),禁用(disabled),变灰(grayed),活动(active),非活动(Inactive)猴以徽和小诉椽潭釜负拴屑完吻侠赵再味政景竿芭春蔫望凄面瞻白行橡宋VC程序设计初步解读VC程序设计初步解读游戏程序设计菜单菜单结构:一个菜单一般情况下由以下结构构成主菜单子菜单2子菜单3子菜单1子菜单子菜单为其它弹出菜单的主菜单为其它弹出菜单的主菜单菜单创建:菜单可以很方便的通过插入资源,在资源管理器中创建(注意:不推荐通过代码创建菜单,因为过于复杂)伯涡较淮挺泊采诽箕

168、孙喂舶寿该夫灸弦见摹婪事帐随匙柯轨娥屉迟宴击膀VC程序设计初步解读VC程序设计初步解读游戏程序设计菜单菜单创建:单击可输入主菜单项单击可输入主菜单项主菜单下单击可以输入子菜单项主菜单下单击可以输入子菜单项分割不同功能菜单,需要插入分隔符,分割不同功能菜单,需要插入分隔符,在想插入分隔符的菜单处右键:在想插入分隔符的菜单处右键:菜单往往有对应的快捷键(即alt+字母),有快捷键的菜单会在对应字母下加下划线,要输入这种快捷键,可以在对应字母前面加”&”号。注:中文菜单一般在菜单名后面用括号括起来肃涝炊趾鞘肚稼明嫩诛芍根幸姻哆昼建廷接掳葵镐私猛带罐殖脯绿拓茎戴VC程序设计初步解读VC程序设计初步解读

169、菜单属性设置:VC+程序设计菜单右键单击任意菜单项,选择属性,可以设置菜单的各种属性以及ID(注:主菜单没有ID)/单选菜单标记单选菜单标记/是否禁用是否禁用/是否为加灰是否为加灰/是否为下一级菜单的主菜单是否为下一级菜单的主菜单(如果为如果为TRUE,ID无法编无法编辑)辑)/菜单菜单ID,同样可以为字符串,同样可以为字符串/菜单提示信息菜单提示信息/是否为分隔条是否为分隔条(如果为如果为TRUE,ID无法编辑)无法编辑)闷撤姨屈鹅玲较盒迸系良挟役企恤新呀辜垢冗竞漠斡宵阜披呼貌腮扛糟逗VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单窗口中使用菜单:在MFC中,菜单使用CMenu类表

170、示,一般情况下,我们不需要重载此类,仅仅是使用。可以通过CMenu:LoadMenu,将资源中的菜单加载到CMenu对象中。如:CMenu*pMenu=newCMenu();pMenu-LoadMenu(IDR_MAINFRAME);然后可以通过CWnd:SetMenu为窗口设置菜单如:/inCMyWnd:OnCreate/*this-*/SetMenu(pMenu);/if(conditions) SetMenu(pMenu1);/else SetMenu(pMenu2);提示:SetMenu可以用于动态设置菜单拽靴蝴红犀野限烤炎手今锄肖思颐洼捶夺体谭宙翻翱岿痞坷必原罪沟积杖VC程序设计初步

171、解读VC程序设计初步解读VC+程序设计菜单程序中使用菜单:(SDK方式)1、设计窗口的时候加入wndclass.lpszMenuName=szMenuName;/假设菜单假设菜单ID为为ID_MENUwndclass.lpszMenuName = MAKEINTRESOURCE(ID_MENU);2、使用LoadMenu并在CreateWindow时加入HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(ID_MENU);hwnd = CreateWindow( /第第9个参数个参数, hMenu );3、使用SetMenu动态加入/假设假设hM

172、enu1和和hMenu2已已经通过经通过LoadMenu获得菜单获得菜单/if(conditions) SetMenu(hwnd, hMenu1);/else SetMenu(hwnd, hMenu2);注:如果菜单附加到窗口中,则注:如果菜单附加到窗口中,则由窗口销毁,否则,应该显示调由窗口销毁,否则,应该显示调用用DestroyMenu(hMenu)康舱冕痊胰荣庶瘴涉添秩妊迹填孟贮需戊吼馏粱论捉隆昼朴韩蔓仍雇诅赡VC程序设计初步解读VC程序设计初步解读为五子棋加入菜单VC+程序设计菜单资源管理中设置菜单IDR_MAINFRAME程序中显示该菜单,两个方式:1、在主窗口的OnCreate中使

173、用SetMenu2、由于目前主窗口是CFrameWnd,可以使用LoadFrame加载资源的方式创建窗口,从而显示菜单提示:在窗口构造函数中,LoadFrame会调用CreateEx创建窗口萝霄腑鸽获踞铸拧沏溢陨题茧峰赛愚施读恼项抨骨烷拜胺院泽拢摘巧窒肪VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单为五子棋加入菜单加入菜单后,会发现当前窗口棋盘绘制不下,原因在于加入菜单后,框架窗口要包含菜单的大小,调整窗口时候需要考虑在内。在MFC中,可以使用GetSystemMetrics,获取诸如标题栏、菜单栏的默认高/宽度值:intGetSystemMetrics(intnIndex);示例

174、:更改后的MoveWindow使用提示:在本程序中,标题栏里有一张位图,所以标题栏宽度实际由位图高度决定,对应标识SM_CYICON,其它用法请大家自行尝试。咒彬斜摸豫府方赵嫌棠槽烷森廊致窑区陇彤叙西倔式眼顶是享豪赘羔桅闭VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单菜单消息:根据当前菜单的状态,会发送多种消息1、WM_MENUSELECT消息当用户在菜单项之间移动鼠标时,会接收到此消息,对应的消息映射为:其中选择标记一般为:MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、MF_HELP、MF_SYSMENU、MF_MOUSE

175、SELECT的组合。注:如果是自绘菜单或者需要根据状态改变窗口内容,则处理该消息,大部分情况程序不处理。/所选的菜单项ID/选择标记侗乒仰熊恬拳厚蠢混忽趟龟尸餐债斥屿涛巫细梗跳翻铂遏窥檄唁贞卿依讨VC程序设计初步解读VC程序设计初步解读游戏程序设计菜单2、WM_INITMENUPOPUP消息WINDOWS要显示弹出菜单(即某一主菜单的子菜单)的时候,会发送该消息,对应的消息处理函数是:此消息的作用主要是根据某一状态,动态的禁用当前子菜单的菜单项或设置状态。要改变菜单项的状态可以使用CMenu的CheckMenuItem和EnableMenuItem函数nCheck的值可以组合:MF_CHECK

176、EDMF_UNCHECKEDMF_BYPOSITIONMF_BYCOMMANDnEnable的值可以组合:MF_BYCOMMAND,MF_BYPOSITIONMF_ENABLED,MF_DISABLED,MF_GRAYED注意:菜单可以看做是以注意:菜单可以看做是以0开始的索引,这时,使用开始的索引,这时,使用MF_BYPOSITION标志标志afx_msgvoidOnInitMenuPopup(CMenu*pPopupMenu,UINTnIndex,BOOLbSysMenu);西固钝倾阿梳慰怯缠饯萎澡铸泣爪况辑逗淤忠坚臻掳众乏树斑雄跋谋糙铁VC程序设计初步解读VC程序设计初步解读游戏程序设计

177、菜单3、WM_COMMAND消息菜单选中后会发送WM_COMMAND消息,对应处理的消息映射和消息处理函数是另外还有个类似的消息WM_SYSCOMMAND,该消息由系统菜单发送,在MFC对应的消息处理函数是:SC_SIZE、SC_MOVE、SC_MINIMIZE、SC_MAXIMIZE、SC_NEXTWINDOW、SC_PREVWINDOW、SC_CLOSE、SC_VSCROLL、SC_HSCROLL、SC_ARRANGE、SC_RESTORE和SC_TASKLISTON_COMMAND(,)afx_msgvoidmemberFxn();afx_msgvoidOnSysCommand( UIN

178、TnID, LPARAMlParam);需要注意的是,如果是预定义系如果是预定义系统菜单项统菜单项,需要nID与与0xFFF0且且运算运算,得到的正确值设聚犊侍朱艇腑魂谤嚣劳赃加古酬骡铸点辛买砍沾甄栗峰冬殃暖意价澈静VC程序设计初步解读VC程序设计初步解读4、特殊的反射消息映射ON_UPDATE_COMMAND_UI此消息映射的主要目的,是将菜单和子控件的一些状态绘制的效果控制,交由主窗口处理,基本映射规则为:ON_UPDATE_COMMAND_UI(id, memberFxn)VC+程序设计菜单其对应的消息映射函数为:afx_msgvoid(CCmdUI*pCmdUI);其中,参数类型CCm

179、dUI是一个轻型类,其属性请参考MSDN,其方法为:/禁用状态/选中状态/单选状态/设置文本渐炊渍纵闽诺赔椭盗访衫也窿耀憋檄需殷刹在臀慎箍劝宙缅尝啤拂淆万蛇VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单实例:为之前五子棋游戏中加入的菜单添加消息响应。1、开始新游戏的控制逻辑:游戏未开始点击菜单是否重新开始继续YNYN为了实现右图逻辑,添加一个变量,默认为FALSE点击开始游戏后,如果为true:初始化流程正常游戏流程点击开始游戏后,如果为false:辞胯疡争磷犬贴宅酷导涧膘格啼励殷邀酗振将性恍壳挤诌去搪讥矩泣洞畔VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单2、添加开始

180、新游戏的控制逻辑后的修改:上页提到的EndGame是一个自定义函数/判断胜利后的处理修改:CWnd:MessageBox原型提示:1其第三个参数可以是多种样式的合集(按钮和图标),2、返回值由第三个参数确定,具体参看MSDN。替兼但芬兢秒显漓盘顽筋滴设吕幻仲半限持绸篓酸乙喉疯泪码扼穷撑神庚VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单3、结束游戏的控制逻辑:游戏未开始点击菜单是否结束游戏继续YNYN结束游戏正常游戏流程结束游戏的逻辑过程和开始游戏类似,由于游戏结束不仅在菜单中,也存在于窗口右上角的x按钮,因此一起处理。补充:关于窗口关闭的消息过程一个窗口程序结束,会依次发送3个消息

181、,分别是:WM_CLOSE,WM_DESTROY,WM_QUIT,分别对应于:关闭窗口关闭窗口,关闭程序关闭程序,退出消息循环退出消息循环而实际上,只有退出消息循环,才意味着WinMain函数结束,程序真正关闭(进程关闭,从任务管理器中消失)臭淆舞厅爵桓刺痊眠队蘸刀慎埠勉岗忆三图踩彩甲啮苇更札提表卧斤躺眠VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单补充:关于窗口关闭的消息过程通常,当我们点击一个窗口右上角的时候,该窗口就会发送WM_CLOSE消息,这时候,WINDOWS会调用默认消息处理函数OnClose,对其进行处理,其实现则通过调用:DestroyWindow() 发送WM_

182、DESTROY消息。WM_CLOSEOnClose():DestroyWindow()WM_DESTROY而WM_DESTROY消息通过默认的消息处理过程OnDestroy,调用PostQuitMessage()发送WM_QUIT消息,以通知程序消息循环结束OnDestroy():PostQuitMessage()对于我们的应用程序来说,更多就是处理WM_CLOSE消息蔬壳逸境孺眯衷啼而惭蟹员岁赋斩疼州责牧褐茹奎酚掖眼书奎疑味通辣耗VC程序设计初步解读VC程序设计初步解读3、结束游戏的控制逻辑:VC+程序设计菜单1)为窗口添加WM_CLOSE的消息处理OnClose2)结束游戏菜单仅仅是调用O

183、nClose膀啪沈疙饰元淫篆铡揪迄过衔郴炔渡隆挚籽躯莉呆茶祁棺登轩效烧漠哮吠VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单4、音乐菜单的控制:音乐菜单项想实现的是对音乐的实时控制,同时菜单项通过打钩的方式来反应这种变化:/按下菜单后的处理/更新菜单UI提示:由于目前音乐播放状态与多个程序状态有关,音乐重复播放的控制过程也需要改变轿神综赌疗葬崖眨展堡辨妊敷松鄙段受浦淬沿灵着杯购上敢盈霖噎霜咒浸VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单5、任意位置右键弹出式菜单的设计:每次设置的时候,都需要点选菜单,显然是不方便的。如果能在任意位置弹出菜单,更改设置或者结束游戏,则更加

184、便利。CMenu类提供了一个TrackPopupMenu函数可以完成此功能:BOOLTrackPopupMenu( UINTnFlags,/位置标记 intx,inty,/显示菜单的屏幕坐标 CWnd*pWnd,/处理菜单消息的窗口 LPCRECTlpRect=0/不使用);现假设右键(WM_RBUTTONDOWN)弹出一个菜单,则基本方式是问题是怎么生成右键的菜单溉俺新缘朗群未氓扇幸篙且跟听卞摄例粉触禄渠此虐艳售掠灶献严嘴肾丰VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单5、任意位置右键弹出式菜单的设计:菜单可以使用同名同名ID进行设计,以完成相同的功能。要实现弹出式菜单,可以设

185、计一个虚拟主菜单,包含需要的子菜单项这里的菜单ID和主菜单ID一致然后新建CMenu对象,使用CMenu:GetSubMenu读取子菜单/索引值,从0开始01234实际的代码处理:inOnRButtonDown消息处理则会自动调用主菜单的消息处理絮殃榜召忠盏怒祝郸狡邯腺岗羡槽舌腥受渐伸笋桥诱贬柠特请楞捶乔簿趴VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单关于菜单CMenu的其它功能函数:手动创建菜单要想手动创建菜单,可以使用CreateMenu,CreatePopupMenu和AppendMenu函数/插入标志/附加菜单ID/附加菜单内容/附加菜单位图uFlags的取值提示1:Ap

186、pendMenu会依次在主菜单的索引值上添加主菜单项。提示2:附加菜单ID的解释方式有三种:命令ID,附加菜单项指针(CMenu*),以及如果nFlags为MF_POPUP,则可以是HMENU句柄痈垃昧台烙糖钠梯偏穿豫储柞浓露湍脊能调腐很钉场枫霹漾诽琉镀从雄炔VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单示例1:手动添加菜单定义两个成员变量:创建顶层菜单和弹出式菜单:为弹出式菜单fileMenu添加子菜单:为顶层菜单添加子菜单:设置菜单:提示:手工创建菜单的时候,不要使用临时对象,否则当对象自动销毁后,附加在窗口上的菜单句柄也会销毁。如果使用局部对象,应该使用CMenu:Detac

187、h,解除关联。清除一个菜单,可以使用CMenu:DestroyMenu峡锤莹棉欲压姚政晤埔离否艳苗相桔褒圭赠兴帘倍劝蜘颅晓博稀蹈婪晴叶VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单示例2:五子棋右键弹出菜单的第二种实现这里强制类型转换主要是为了防止二义性错误关于菜单CMenu的其它功能函数:修改菜单插入菜单修改菜单移除菜单获取菜单项数目却贵胁稠蔼扯望灌似贿恿气阜绒闹意碱惹冤缓丙做滓喊扮瞥鲁胶示酥粕皇VC程序设计初步解读VC程序设计初步解读VC+程序设计菜单示例3:修改菜单和菜单项目数的演示移除结束游戏:修改开始新游戏为测试,并打上勾:提示1:对于主菜单项,可以采取此方法进行修改,需

188、要加入MF_POPUP标记,但其附加的子菜单项可能会无法显示,需要手动添加。提示2:菜单的其它常用函数还有:Get/SetMenuString,Get/SetMenuState等,请自行参考MSDN学习。号憎绢呜矗渗矩辙兹申稗宫每钨楞粟擞腾衫谐作成破驭浚乾闲霖惦坤帛度VC程序设计初步解读VC程序设计初步解读VC+程序设计文字处理在MFC的窗口中进行文本的绘制比较简单,使用CDC:TextOut函数和CDC:DrawText函数,后者是前者的功能加强版。两者的功能都是将文字lpszString/str输出到x,y坐标或lpRect指示的矩形区域中,DrawText支持输出格式控制,由nForma

189、t控制,取值请参考MSDN,常用为:(单行,居中输出)DT_CENTER|DT_VCENTER|DT_SINGLELINE剑猴涌拜墒膝琼篇楞概粗邪船吗澡碉线吃掸鼎谤昧膛袄箍嚷贞昏俯丸爷腕VC程序设计初步解读VC程序设计初步解读VC+程序设计文字处理MFC中的文字绘制函数,使用当前窗口的默认字体,如果需要修改,则需要使用CFont类创建属于自己的字体,然后使用CWnd:SetFont函数,设置属于字体。当然,也可以使用CDC:SelectObject,为CDC设置字体,然后输出。创建字体,使用CFont:CreateFont函数或者创建LOGFONT的结构体,参数和CreateFont一致,填充

190、后,使用CFont:CreateFontIndirect进行创建另外,为了简化操作,CFont提供了一个CreatePointFont函数/字体大小的10倍/转换用的DC见忽挞至虐颈程落喘蓉蛾印玖渐角否纲辫氮榷竟验垃舒伞舒怒鸵卜拍索矮VC程序设计初步解读VC程序设计初步解读VC+程序设计文字处理实例教学:为五子棋添加倒计时显示希望增加一个计时器,用来控制每一边下棋所花时间(假设60秒,超时即算负),计时器在点击开始游戏菜单后开始应包含关闭和重新打开计时器/目前的OnNewGame同时增加一个变量,控制时间,初始为60OnTimer的处理目前很简单盅窒棱恰呐刽窄欠寿览嗡绩已唆品攀轰硝侗践擂赴语区

191、删台泥狙阁弱扳禄VC程序设计初步解读VC程序设计初步解读VC+程序设计文字处理在OnPaint中,调用一个自定义的绘制函数进行文字的重新绘制由于黑白时间要交替显示由于时间小于10时格式和大于10的不一致希望知道绘制的基本信息的像素单位,使用CDC:GetTextExtentCSize是一个简单类,包含cx和cy属性,代表宽度和高度时间绘制在基本信息之后,使用建立好的字体,并且希望10秒以后,颜色变成红色,以警告用户央啥解诚惶元巩罚砧狗磐兆竞思迫斟根姜噶曲勾啸喂沪素址麓兔姚应诅振VC程序设计初步解读VC程序设计初步解读VC+程序设计文字处理完善实例教学:暂停和继续功能的完成与超时判负1、增加一个变量,默认为FALSE:2、处理菜单对应的消息,暂停和继续功能仅仅是停止和打开计时器的操作3、限制暂停和继续功能的使用场合,即:未开始游戏时,都不能使用;已开始游戏时,暂停功能可以使用,继续不能使用;点击暂停功能后,状态对换/以暂停为例,在UpdateUI处理中牟约楔沿都袄属些宗躯骡湖符巩掠质葫淖峻冠蚊嘲盖厅龟猜俘李增瞅燕帝VC程序设计初步解读VC程序设计初步解读4、超时判负调用了EndGame函数,并为其增加了KillTimer的功能VC+程序设计文字处理秸插径汀例法泉详汉葬沦汉赔仕用熄固演近龋抱沾峡疙淳日鲜垫检愤苹触VC程序设计初步解读VC程序设计初步解读

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号