ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:26.84KB ,
资源ID:4279669      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4279669.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(windows程序设计第一章讲义.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

windows程序设计第一章讲义.docx

1、windows程序设计第一章讲义第一章这节课我们主要讲解WINDOWS的内部运行原理 ,要了解VISUAL C+程序 的开发过程 ,先要理解WINDOWS应用程序的运行机制,因为VISUAL C+是WINDOWS开发语言,我们要明白在WINDOWS环境下编程和在其他环境下一些根本的差别,全面讨论WINDOWS工作原理需要一本书的内容,我们没了解那么细,但还是要了解一些根本的概念原理。一Windows应用程序,操作系统,计算机硬件之间的相互关系 Windows程序设计是完全不同于传统的 DOS系统的设计方法,它采取事件驱动的机制的程序设计模式,主要是基于消息的 。当用户要实现某种功能时 ,会调用

2、操作系统的某种支持,然后操作系统将用户的需要包装成消息,并投递到消息队列中,最后应用程序从消息队列中取走消息并进行响应。向下的箭头表示操作系统能够操作输出设备以执行特定的功能,如让声卡发出声音,显卡画出图形等。向上的箭头表示操作系统能够感知输出设备状态的变化,如鼠标移动,键盘按下,并能够知道鼠标移动的位置,键盘按下的哪个键,这就是操作系统和计算机硬件的交互关系。应用程序开发者通常不需要知道其具体的实现细节,我们关心的是应用程序与操作系统的交互关系。向下的箭头表示应用程序可以通知操作系统执行某个具体的动作,如操作系统能够控制声卡发出声音,但它并不知道应该何时发出何种声音,需要应用程序告诉操作系统

3、该发出什么样的声音。这个关系好比有个机器人能够完成行走的功能,但是,如果人们不告诉它往哪个方向上走,机器人是不会主动行走的。这里的机器人就是操作系统,人们就是应用程序那么,应用程序是如何通知操作系统执行某个功能的呢?有过编程经验的读者都应该知道,在应用程序中要完成某个功能,都是以函数调用的形式实现的,同样,应用程序也是以函数调用的方式来通知操作系统执行相应的功能的。操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,也就是说,操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接

4、口(Application Programming Interface),简称Windows API。如CreateWindow就是一个API函数,应用程序中调用这个函数,操作系统就会按照该函数提供的参数信息产生一个相应的窗口。 在这里注意:我们不要把API与JAVA或其他的API混淆。API是一个已经被广泛使用的专业术语,如果说某个系统某个设备提供给应用程序对其进行编程操作的函数,类,组件等的集合。如做呼叫购买语音卡,提供一个开发包,开发包的函数集合称为语音卡的API。向上的箭头表示操作系统能够将输入设备的变化上传给应用程序。如用户在某个程序活动时按了一下键盘,操作系统马上能够感知到这一事件

5、,并且能够知道用户按下的是哪一个键,操作系统并不决定对这一事件如何作出反应,而是将这一事件转交给应用程序,由应用程序决定如何对这一事件作出反应。好比有个蚊子叮了我们一口,我们的神经末梢(相当于操作系统)马上感知到这一事件,并传递给了我们的大脑(相当于应用程序),我们的大脑最终决定如何对这一事件作出反应,如将蚊子赶走,或是将蚊子拍死。对事件作出反应的过程就是消息响应。 2.关于消息及消息队列 操作系统是怎样将感知到的事件传递给应用程序的呢?这是通过消息机制(Message)来实现的。操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,参看MSDN。MSG结构定义如下: type

6、def struct tagMSG HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; MSG; 解释:(MSDN是微软提供的程序开发的在线帮助系统,这个系统包括了微软的所有开发语言开发工具的帮助文件,信息很全每年发布4次,一个季度一次。)参数1 HWND hwnd; 解释:handle to window 新的数据类型,指示窗口的句柄,何谓窗口?屏幕上的一块矩形区域叫窗口,我们通常的开发的应用程序叫窗口程序,如VISUAL C+由许多窗口构成,每个窗口又要起标识,当你去定义一个变量来存储这些

7、标识时,你需要有存储定义这些标识的类型来定义变量,像定义整形变量存放整型数据,定义浮点类型变量存放浮点型数据,要存放窗口标识,需要有窗口句柄来定义这样的变量。句柄句柄(HANDLE),资源的标识。操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。句柄类似指针,也需要占据一块内存,那么对于资源占据一块内存,我们要所引这块内存,索引资源,就是通过句柄找到的 。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。 参数2 UIN

8、T message 无符号整型,消息就是具体一个消息,比如,按下鼠标左键,左键作为参数传递过来,整数表示方式。数值不好记忆,微软定义很多宏,以WM开头,window message,如鼠标左键按下LBUTTONDOWN,键盘按键,KEYDOWN参数3WPARAM wParam; 消息的附加信息 LPARAM lParam; 都是整型。 关于消息的附加信息。如按下A键,WM_CHAR消息,收到消息,我们并不知道那个字母,要想知道,把字母的ASCII码放到附加参数里,这样我们收到消息通过附加参数知道键盘上字母的ASII码。MSDN查看WM_CHAR消息 既然WPARAM LPARAM 都是整型,为

9、什么要再产生两个新的数据类型?我们看别人写的程序:int x,y;x=30; y=30; /x和y既可以用来表示坐标点,也可以用来表示宽度和高度,还可以用来表示身高和体重。typedef int WIDTHtypedef int HEIGHTWIDTH x;HEIGHT y;/好处:我们从变量的类型上就可以知道x和y是用来表示宽度和高度。这就是为什么在WINDOWS中微软为我们定义出这么多新的数据类型,虽然都是整型,参数5 DWORD 32位整数,指示消息传递出的时间。参数6 POINT 点结构体,x,y坐标,当消息被传递时光标在屏幕的位置。拷贝,查看MSDN由上看出消息结构体包含很多信息,它

10、包含消息与哪个窗口相关,消息的具体内容是什么,消息的附加参数,消息投递时间和光标位置。消息队列: 操作系统为每个应用程序都建立一个消息队列,是一个先进先出的缓冲区,通常是某种变量类型的数组,队列中的每个元素都是一个消息,操作系统将生成的每个消息按先后顺序存放到消息队列,应用程序总是取走队列中的第一个消息,消息取走后,第2条成为第1条,后面的依次前提,应用程序取得消息后就知道用户的操作和程序的变化,例如取得WM_CHAR消息,那么一定是用户输入了 字符,并且知道是哪个字符。应用程序得到消息后就要处理消息,这就是消息响应。消息响应通过编码来实现,这就是WINDOWS程序的主要代码区,需要编写一些编

11、码,这个过程叫消息响应。在实现过程可以调用API函数,以便完成特定的功能,例如,我们收到关闭窗口的消息,那么可以调用销毁窗口的函数来关闭窗口,或者用弹出消息框的形式询问用户是否真的关闭窗口。通过以上分析,我们知道要想开发WINDOWS应用程序,除了要具备良好的C+基础,还需要掌握两方面的东西:一消息本身,知道不同的消息不同的消息代表的用户操作和程序状态本,。二。对于不同消息我们要让操作系统执行特定的功能去响应响应 WINMAIN函数二,Windows程序的结构1 Windows程序的入口函数int WINAPI WinMain( HINSTANCE hInstance, / handle to

12、 current instance HINSTANCE hPrevInstance, / handle to previous instance LPSTR lpCmdLine, / command line int nCmdShow / show state);查看MSDN说明: 参数1 HINSTANCE hInstance:应用程序实例句柄,何谓运行程序实例句柄,即运行中的程序,叫实例,再次运行,有两个实例。这两个实例需要有个标识,同样需要有一种数据类型来定义变量来存放表示,这个类型就是HINSTANCE参数2 HINSTANCE hPrevInstance:先前实例句柄,对第2个实例,

13、前一个实例就是这个参数。兄弟实例注意:基于w32的应用程序该参数为空如98,NT下开发不需要此参数,为空。参数3 LPSTR lpCmdLine 类型是长指针,指向字符串首地址的指针。命令行参数,在DOS下MAIN函数可以有两个参数,argv,argc,argv指针数组,存放命令行参数, argc主要接受存放命令行参数个。同样在WINDOWS程序中也可以接受命令行参数运行 “notepad 1.txt” 1.txt就是命令行参数我们的程序中也可以接收命令行参数,project/settings/debug选项卡下program arguments输入“weixin.txt”,在程序中int W

14、INAPI WinMain开始位置设置断点,然后调试运行。参数4int nCmdShow 显示状态,程序运行时是最大化,最小化或隐藏显示。注意:WinMain函数是入口点函数,由操作系统调用。当操作系统启动我们的程序,它会给运行中的程序分配一个实例号,通过参数就传递进来,如果说启动时命令行参数,操作系统会将参数放在第3个参数中,参数都是由操作系统赋值。2 创建一个完整的窗口需要经过下面四个操作步骤:设计一个窗口类; 注册窗口类;创建窗口;显示及更新窗口。设计窗口WINDOWS已经做好框架,我们只需要填写一部分,如同做填空题一样,这就需要数据结构,结构体设计一个窗口类;原因:程序运行时窗口的样式

15、风格可以不一样,如光标在窗口是箭头还是十字,窗口的标题,背景等等,需要我们在设计窗口时就要确定的产生一个窗口和设计汽车是一样,生产汽车前,我们都需要在图纸上画出汽车的图,雏形,然后起个名字,比如奔腾600,有了图纸照着生产汽车。类似产生一个窗口也要设计窗口的特征,没有汽车复杂,windows已经给我们设计了窗口应该有的基本属性,我们要做的就跟做填空题一样,把它填写完整。(查看MSDN)typedef struct _WNDCLASS UINT style; 窗口类的类型,很多。结合程序看含义-,水平重画和垂直重画,就跟汽车喷漆一样。 WNDPROC lpfnWndProc; 指针指向窗口过程,

16、也称回调函数 int cbClsExtra; 类额外数据,操作系统为系统中每个窗口类管理类结构,当程序注册窗口类,可让系统为追加额外内存空间,我们称为类的附加内存,由属于这种窗口类的所有窗口共享,cbClsExtra,通常为0 int cbWndExtra; 操作系统为系统中每个窗口管理类结构,当程序注册窗口,可让系统为追加额外内存空间,我们称为窗口的附加内存 HANDLE hInstance; 实例号,设计窗口类,要知道属于哪个 HICON hIcon; 图标句柄,通过LoadIcon加载图标 HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lp

17、szMenuName; LPCTSTR lpszClassName; 新类的名字 WNDCLASS; UINT style参数1 UINT style; 窗口类的类型,很多。结合程序看含义-,水平重画和垂直重画,就跟汽车喷漆一样。在我们的程序中经常要用到一类变量,这个变量里的每一位(bit)都对应某一种特性。当该变量的某位为1时,表示有该位对应的那种特性,当该位为0时,即没有该位所对应的特性。当变量中的某几位同时为1时,就表示同时具有几种特性的组合。一个变量中的哪一位代表哪种意义,不容易记忆,所以我们经常根据特征的英文拼写的大写去定义一些宏,该宏所对应的数值中仅有与该特征相对应的那一位(bit

18、)为1,其余的bit都为0。我们使用goto definition就能发现CS_VREDRAW=0x0001,CS_HREDRAW=0x0002,CS_DBLCLKS =0x0008,CS_NOCLOSE=0x0200。他们的共同点就是只有一位为1,其余位都为0。如果我们希望某一变量的数值既有CS_VREDRAW特性,又有CS_HREDRAW特性,我们只需使用二进制OR(|)操作符将他们进行或运算相组合,如style=CS_VREDRAW | CS_HREDRAW | CS_NOCLOSE。如果我们希望在某一变量原有的几个特征上去掉其中一个特征,用取反()之后再进行与(&)运算,就能够实现,如

19、在刚才的style的基础上去掉CS_NOCLOSE特征,可以用style & CS_NOCLOSE实现。 参数2 WNDPROC lpfnWndProc; 指针指向窗口过程,也称回调函数回调函数的原理是这样的,当应用程序收到给某一窗口的消息时(还记得前面讲过的消息通常与窗口相关的吗?),就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统到底调用应用程序中的哪个函数(回调函数)来处理呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗

20、口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。 举例:汽车厂家生产汽车好比应用程序创建窗口,用户使用汽车好比操作系统管理窗口,某种汽车在销售前就指定好了修理站(类似回调函数),当用户的汽车出现故障后(类似窗口收到消息),汽车用户(类似操作系统)自己直接找到修理站去修理,不用厂家(类似应用程序)亲自将车送到修理站去修理,但修理站还得由厂家事先建造好。 参数3 int cbClsExtra; 类额外数据,操作系统为系统中每个窗口类管理类结构,当程序注册窗口类,可让系统为追加额外内存空间,我们称为类的附加内存,由属于这种窗口类的所有窗口共享,cbClsExtra,通常为0

21、,赋为0不是说内存为0,而是我们不需要这个参数。 参数4 int cbWndExtra; 操作系统为系统中每个窗口管理类结构,当程序注册窗口,可让系统为追加额外内存空间,我们称为窗口的附加内存参数5 HANDLE hInstance; 实例号,设计窗口类,要知道属于哪个应用程序实例,因此,当我们对实例赋值时,从winmain中的这个参数,传递过来。 参数6 HICON hIcon; 图标句柄,通过LoadIcon加载图标,那图标句柄如何赋值?查看MSDN:HICON LoadIcon( HINSTANCE hInstance, / handle to application instance

22、LPCTSTR lpIconName / name string or resource identifier);当取标准图标时,null。在windows编程中,当需要某些功能的函数时,可以凭感觉根据语义组合一些名称,如果,createwindow,destroywindow等。当然符合不符合需要还得去看看含义。时间长就记住了。 参数7 HCURSOR hCursor; 光标句柄,用LoadCursor与LoadIcon接近,查MSDNHCURSOR LoadCursor( HINSTANCE hInstance, / handle to application instance LPCTS

23、TR lpCursorName / name or resource identifier); 参数8 HBRUSH 画刷句柄hbrBackground=GetStockObject()查MSDN: HGDIOBJ GetStockObject( int fnObject / stock object type);可以修改例子中的参数,改为白色背景。就跟装修房子刷墙一样,刷什么颜色,墙就是什么颜色。要有强制类型转换。参数9 LPCTSTR lpszMenuName; 指向常量字符串的指针,指向菜单的名字参数10 LPCTSTR lpszClassName; 新类的名字,注册窗口类设计完窗口类后

24、,要向操作系统注册,RegisterClass(&类名)就如设计完汽车并不能直接生产,要上报进行注册。查MSDN ATOM RegisterClass( CONST WNDCLASS *lpWndClass / class data 窗体类结构体的指针); 创建窗口首先要定义一个句柄,因为创建窗口和生产汽车一样,生产多少汽车应该有数,同样创建窗口之后,哪个窗口的标识应该保存下来,有哪些窗口。函数:CreateWindow(“类名”),查msdnCreateWindow( /创建具体窗口句柄参数1LPCTSTR lpClassName /窗口类名,必须与注册时的名字相同,”weixin”,如果换

25、一下,运行后看到,窗口没有产生,但是程序还是运行,从任务管理器可以看到winmain原因?参数2 LPCTSTR lpWindowName szTitle, /窗口名字,即标题栏内容参数3 DWORD dwStyle 窗口类型即/显示方式,实例中的该参数点右键到go to definition #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | 重叠窗口,有一个标题栏和边框 WS_CAPTION | 有标题栏 WS_SYSMENU | WS_THICKFRAME | 创建具有可调边框的 WS_MINIMIZEBOX | WS_MAXIMIZEBOX)这就是

26、以前说的二进制位表示特征,想要某位时置为1,否则置为假,我们可以看看上面这些宏,都是只有1位为1.演示去掉最大化按钮参数4 int x,CW_USEDEFAULT, /初始的X位置参数5 int y,CW_USEDEFAULT, /初始的Y位置参数6 int nWidth CW_USEDEFAULT, /窗口的宽度参数7 int nHeight, /窗口的高度参数8 HWND NULL, /父窗口句柄,必须与注册时的名字相同参数9 HMENU NULL,/ /窗口菜单句柄,必须与注册时的名字相同参数10 HINCTANCE hInstance, /实例句柄,必须与程序使用的名字相同参数11 L

27、PVOID lpParam NULL /窗口创建时作为WM CREATE消息 的lpParam 附加消息通过结构体传入窗口的数据的指针 当窗口创建好后,就好像汽车造好,要开新闻发布会推出去一样,也需要显示出来。显示调用函数ShowWindow(hWnd,nCmdShow); 其中第1个参数是窗口句柄,第2个参数是窗口初始显示的形式, nCmdShow参数说明是最大化显示还是最小化显示,应用程序窗口是活动的窗口还是图标,它可置为以“SW_”开始的任何常量,这些常量在windows.h中定义,在WinMain 函数中,也是 nCmdShow 常量决定如何显示主窗口。 在用nCmdShow作为参数调

28、用函数ShowWindow之后,WinMain还要调用UpdateWindow函数。更新窗口。不影响窗口更新,可有可无。3 消息循环MSG msg;/消息 MSG msg; while(GetMessage(&msg,NULL,0,0) TranslateMessage(&msg); 转化翻译消息,它的作用是对取到的消息对进行转换,什么样的消息对?当我们在键盘上按下某个按键时,系统会发出WM_KEYDOWN和WM_KEYUP的消息,并且参数中提供的键盘上刚才按键的扫描码,但有时候用户按下的某个键,我们想得到的是表示用户输入的字符的消息,也就是键盘上的某个字母,在消息的补充参数,就是附加参数中提

29、供字母按键的ASCII码。TranslateMessage能够将WM_KEYDOWN和WM_KEYUP这样的消息对转换为一个WM_CHAR消息,并且将转化后的新消息投递到消息队列中,这个转换过程不会影响原来的消息,只能增加一个消息。 DispatchMessage(&msg); 是将我们收到的消息传给回调函数去处理。我们可以理解为将这个消息路由给操作系统,操作系统去调用窗口过程函数,即回调函数进行处理。 ; BOOL GetMessage( LPMSG lpMsg, / message information,指向消息结构体的指针,out标识表明在传参时不需要给结构体内部数据成员进行初始化,我

30、们只需要定义结构体的变量,将它的地址放在这就可以了。那么通过函数调用会自动填充消息结构体内部的成员变量。当 HWND hWnd, / handle to window 获取哪个窗口消息,NULL,可以获取所有消息 UINT wMsgFilterMin, / first message消息队列中有很多消息,有的我们感兴趣,有的不,也可以指定消息范围,指定消息最小值。WM_KEYFIRST指定键盘第一个消息,WM_MOUSEFIRST来指示第一个鼠标消息。 UINT wMsgFilterMax / last message消息最大值, 如果这两个值都设为0,就没有范围过滤了,所有消息都感兴趣。);

31、 这个消息返回值是BOOL,当取出一个消息时返回真,队列中只要有消息,返回值就是真,就构成循环。回顾消息循环我们再看一下窗口过程函数。MSDN查看WNDCLASS LRESULT CALLBACK WindowProc( HWND hwnd, / handle to window UINT uMsg, / message identifier WPARAM wParam, / first message parameter LPARAM lParam / second message parameter);注意::这是C+程序开发时规定的格式,不能改的,函数名可以变,但是参数类型不能变,名字可以随便取。LRESULT 是LONG型的,长整型。这4个参数和消息结构体的前4个参数比较类似,实际上是一样的,当DispatchMessage(&msg)执行时,把消息的前4个参数传递过来,消息的后2个参数没有用到,消息投递的时间和坐标在屏幕上的位置。 每当有消息产生时,都要调用窗口过程函数,因此要判断是哪个消息。RESULT CALLBACK WinSunProc( HWND hwnd, / handle to window UINT uMsg,

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1