Win32学习材料(本人整理)_第1页
Win32学习材料(本人整理)_第2页
Win32学习材料(本人整理)_第3页
Win32学习材料(本人整理)_第4页
Win32学习材料(本人整理)_第5页
已阅读5页,还剩228页未读, 继续免费阅读

下载本文档

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

文档简介

1、Tar na,C/C+教学课程,Points,3,Windows编程基础,Windows应用程序的类型 控制台程序 Console DOS程序,本身没有窗口,通过Windows DOS窗口执行 窗口程序 拥有自己的窗口,可以与用户交互 库程序 存放代码、数据的程序,执行文件可以从中取出代码执行和获取数据 静态库程序 扩展名LIB,在执行文件执行时从中获取代码 动态库程序 扩展名DLL,在编译链接程序时,将函数地址放入到执行文件中,Windows编程基础,三种应用程序的对比 入口函数 控制台程序 - main 窗口程序 - WinMain 动态库程序 - DllMain 静态库程序 - 无入口函

2、数 文件存在方式 控制台程序、窗口程序 - EXE文件 动态库程序 - DLL文件 静态库程序 - LIB文件 执行方式 控制台程序 - 在DOS窗口内执行。 窗口程序 - 拥有自己的窗口在自己的窗口内执行. 动态库程序 - 本身无法执行,由可执行程序或其他的DLL调用 静态库程序 - 执行不存在,代码会嵌入到可执行文件或DLL等中,Windows开发环境,Windows开发工具和库 开发工具 Visual Studio C+ VC1.5 - VC6.0 VC2005-VC2010( 10.0 ) WIN31-WIN32-WIN95-WIN98-2000-XP- VC的编译工具 编译器CL.E

3、XE 将源代码编译成目标代码 链接器LINK.EXE 将目标代码、库链接生成最终文件 资源编译器RC.EXE 将资源编译,最终通过链接器存入最终文件(.rc,Windows开发环境,Windows库和头文件 Windows库 kernel32.dll - 提供了核心的API,例如进程、线程、内存管理等。 user32.dll - 提供了窗口、消息等API gdi32.dll - 绘图相关的API 头文件 windows.h - 所有windows头文件的集合 windef.h - windows数据类型 winbase.h - kernel32的API wingdi.h - gdi32的API

4、 winuser.h - user32的API winnt.h - UNICODE字符集支持,HelloWorld程序的相关函数,int WINAPI WinMain( HINSTANCE hInstance,/当前程序的实例句柄,本进程的内存 HINSTANCE hPrevInstance, /当前程序前一个实例句柄 LPSTR lpCmdLine,/命令行参数字符串,char*类型 int nCmdShow /窗口的显示方式-最大化,最小化,原样显示 ); hPrevInstance - Win32下,一般为NULL int MessageBox( HWND hWnd,/父窗口句柄 LPC

5、TSTR lpText, /显示在提示框中的文字-char*类型 LPCTSTR lpCaption, /显示在标题栏中的文字-char*类型 UINT uType /提示框中的按钮、图标显示类型 );/ 返回点击的按钮ID,MessageBox返回值,按钮的IDIDABORT Abort button was selected.中止IDCANCEL Cancel button was selected. 取消按钮IDCONTINUE Continue button was selected. IDIGNORE Ignore button was selected. 忽略按钮IDNO No b

6、utton was selected. IDOK OK button was selected. IDRETRY Retry button was selected. 重试IDTRYAGAIN Try Again button was selected. IDYES Yes button was selected,编译、链接和执行,编译环境准备 VC98BINVCVARS32.BAT 编译程序 - CL CL.EXE -? 显示CL的帮助 /c 只编译不链接 /Tc 编译C文件 /Tp 编译C+文件 链接程序 - LINK LINK.EXE xxx.obj xxx.lib 执行,编写第一个窗口

7、程序(HelloWorld版,编写窗口程序的步骤: 1 定义WinMain函数 2 定义窗口处理函数 (处理消息) 3 注册窗口类(向操作系统中写入一些数据) 4 创建窗口 (在内存中将窗口创建出来) 5 显示窗口(根据内存中的数据将窗口绘制出来) 6 消息循环(提取/翻译/派发 消息) 7 消息处理,资源的使用,编写资源的文件 .rc资源脚本文件 编译rc文件 RC.EXE 将资源链接到程序中 LINK.EXE 硬盘上文件的图片是ICO,NMAKE 和 Makefile,NMAKE Makefile的一个解释执行的工具,根据 Makefile文件中的定义,编译和链接程序,最终生成文件. Ma

8、kefile(以.mak为后缀) 定义编译和链接等操作的脚本文件(把项目的处理命令写入),一般对整个项目进行处理,Makefile的语法,HELLO:依赖行 cl.exe hellownd.c /c/命令行 rc.exe hellownd.rc/命令行 link.exe hellownd.obj hellownd.res user32.lib /命令行 Makefile文件中可以有多个依赖行。Namke /f hello.mak CLEAN 执行方式 NMAKE首先找到第一个依赖行 检查依赖行的依赖项,如果发现依赖项,首先执行依赖项命令行 执行完所有依赖项命令后,再执行自己的命令行,HELLO

9、:CLEAN-以来行 CL.EXE /c hello.c 命令 RC.EXE hello.rc命令 LINK.EXE hello.obj hello.res命令 user32.libCLEAN: del *.obj del *.res del *.exe注意:CLEAN是依赖项,必须放在:后面,DBCS和UNICODE编码的区别,DBCS字符编码:单双字节混合编码(主流) A 我 是 程 序 员 01 0203 0405 0607 0809 0A0B 但是解析时,可能为: 01 02030405060708090A0B 0102 030405060708090A0B UNICODE编码:全部按

10、两个字节编码 A 我 是 程 序 员 0001 0203 0405 0607 0809 0A0B 不存在解析的问题,字符集的应用,宽字节字符 wchar_t 每个字符占2个字节 wcslen()可以用来求wchar_t的长度 char 每个字符占1个字节或2个字节DBCS编码 wchar_t 实际是 unsigned short 类型,定义时,需要增加“L”,通知编译器按照双字节编译字符串,采用UNICODE编码。 需要使用支持 wchar_t 函数操作宽字节字符串。例如: wchar_t * pwszText = L“Hello wchar”;双引号中的每个字符都占两个字节 wprintf(

11、 L%sn, pwszText,字符集的应用,TCHAR 以下内容在WINNT.H头文件中,被windows.h包含 #ifdef UNICODE / r_winnt typedef WCHAR TCHAR, *PTCHAR; #define _TEXT(quote) L#quote #else typedef char TCHAR, *PTCHAR; #define _TEXT(quote) quote #endif UNICODE字符打印 wprintf对UNICODE字符打印支持不完善。 在Windows下使用WriteConsole API打印UNICODE字符(UNICODE宏必须添

12、加在WINDOWS.H之前,BOOL WriteConsole( HANDLE hConsoleOutput, / 标准输出句柄 CONST VOID *lpBuffer, / 输出内容的buff DWORD nNumberOfCharsToWrite, /准备输出内容的长度 LPDWORD lpNumberOfCharsWritten, /返回实际输出的内容的长度 LPVOID lpReserved / 备用,为NULL);注意:标准输出,标准输入,标准出错,HANDLE GetStdHandle( DWORD nStdHandle / 标准输入输出出错的类型);该选项:STD_INPUT_

13、HANDLESTD_OUTPUT_HANDLESTD_ERROR_HANDLE该函数返回值是标准输入输出出错的句柄,窗口程序的创建,窗口程序的创建步骤: 1 定义WinMain入口函数 2 定义窗口处理函数 WindowProc(用来处理消息) 3 注册窗口类 RegisterClass 4 创建窗口 CreateWindow(在内存将窗口创建出来) 5 显示窗口 ShowWindow/UpdateWindow 6 消息循环 GetMessage TranslateMessage DisptachMessage 7 消息处理,窗口的注册,窗口类 窗口类包含了窗口的各种参数信息的数据结构。每个窗

14、口都具有窗口类,基于窗口类创建窗口。每个窗口类都具有一个名称,使用前必须注册到系统。 窗口类的分类 系统窗口类 系统已经定义好的窗口类,所有应用程序都可以直接使用 应用程序全局窗口类 由用户自己定义,当前应用程序所有子进程模块都可以使用。 应用程序局部窗口类 由用户自己定义,当前应用程序中本模块可以使用,系统窗口类的注册,不需要注册,直接使用窗口类即可。系统 已经定义好相应名称,例如: 按钮 - BUTTON 编辑框 - EDIT,应用程序全局窗口类的注册,RegisterClass/RegisterClassEx ATOM RegisterClass( CONST WNDCLASS *lpW

15、ndClass /窗口类的数据 ); 注册成功后,返回一个数字标识。 ATOM RegisterClassEx( CONST WNDCLASSEX *lpwcx /窗口类的数据 ); 功能一样,成功返回一个非零,失败返回-1,应用程序全局窗口类的注册,typedef struct _WNDCLASSEX UINT cbSize; /结构体的大小 sizeof()/平台不一样结构体大小不同 UINT style; /窗口类的风格 WNDPROC lpfnWndProc; /窗口处理函数 int cbClsExtra; /窗口类的附加数据buffer的大小 int cbWndExtra; /窗口的

16、附加数据buffer的大小 HINSTANCE hInstance; /当前模块的实例句柄 HICON hIcon; /窗口图标句柄 HCURSOR hCursor; /鼠标的句柄 HBRUSH hbrBackground; /绘制窗口背景的画刷句柄 LPCTSTR lpszMenuName; /窗口菜单的资源ID字符串 LPCTSTR lpszClassName; /窗口类的名称 HICON hIconSm; /窗口的小图标句柄 WNDCLASSEX, *PWNDCLASSEX,普通版本Typedef struct _WNDCLASS UINT style; WNDPROC lpfnWndP

17、roc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; WNDCLASS, *PWNDCLASS; 加强版typedef struct _WNDCLASSEX UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInst

18、ance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; WNDCLASSEX, *PWNDCLASSEX,应用程序全局窗口类的注册,应用程序全局窗口类的注册,需要在窗口类的风格中增加 CS_GLOBALCLASS,例如: WNDCLASSEX wce = 0; wce.style = CS_GLOBALCLASS|; 应用程序局部窗口类 在注册窗口类时,不添加CS_GLOBALCLASS风格,窗口类的风格,CS_GL

19、OBALCLASS - 应用程序全局窗口类 CS_BYTEALIGNCLIENT - 窗口客户区的水平位置8倍数对齐 CS_BYTEALIGNWINDOW - 窗口的水平位置8倍数对齐 CS_HREDRAW - 当窗口水平变化时,窗口重新绘制 CS_VREDRAW - 当窗口垂直变化时,窗口重新绘制 CS_CLASSDC - 该类型的窗口,都是有同一个绘图(DC)设备 CS_PARENTDC - 该类型的窗口,使用它的父窗口的绘图(DC)设备 CS_OWNDC - 该类型的窗口,每个窗口都使用自己的绘图(DC)设备 CS_SAVEBITS - 允许窗口保存成图(位图),提高窗口的绘图效率,但是

20、耗费内存资源 CS_DBLCLKS - 允许窗口接收鼠标双击 CS_NOCLOSE - 窗口没有关闭按钮,窗口类的查找过程,1 系统根据传入的窗口类名称,在应用程序局部窗口类中查找,如果找到执行2,如果未找到执行3。 2比较局部窗口类与创建窗口时传入的HINSTANCE变量。如果发现相等,创建和注册的窗口类在同一模块,创建窗口返回。如果不相等,继续执行3。 3 在应用程序全局窗口类,如果找到,执行4,如果未找到执行5。(匹配时,不用匹配HINSTANCE变量) 4 使用找到的窗口类的信息,创建窗口返回。 5 在系统窗口类中查找,如果找到创建窗口返回,否则创建窗口失败。 一旦匹配成功,就申请一块

21、内存,向这块内存放入数据,在内存中创建窗口,相关API,RegisterClass/RegisterClassEx 注册 GetClassInfo 获取信息 UnregisterClass 卸载,获得已经注册的类的信息 BOOL GetClassInfo( HINSTANCE hInstance, /应用程序实例句柄LPCTSTR lpClassName, / class name LPWNDCLASS lpWndClass / class data ); 卸载已经注册的类的信息 BOOL UnregisterClass( LPCTSTR lpClassName, / class name H

22、INSTANCE hInstance /应用程序实例句柄,窗口的创建,CreateWindow/CreateWindowEx HWND CreateWindowEx( DWORD dwExStyle, /窗口的扩展风格,多于CreateWindow的一个参数,支持往窗口中拖拽文件/文件夹 LPCTSTR lpClassName, /已经注册的窗口类名称 LPCTSTR lpWindowName, /窗口标题栏的名字 DWORD dwStyle, /窗口的基本风格 int x, /窗口左上角水平坐标位置 int y, /窗口左上角垂直坐标位置 int nWidth, /窗口的宽度 int nHe

23、ight,/窗口的高度 HWND hWndParent,/窗口的父窗口句柄,子窗口需要填写,没有父窗口填NULL HMENU hMenu,/窗口菜单句柄 HINSTANCE hInstance, /应用程序实例句柄,WinMain的参数 LPVOID lpParam /窗口创建时附加参数,可以附加指针、整数、NULL ); 创建成功返回窗口句柄,DWORD dwStyle的选项值:WS_BORDER-有边线WS_CAPTION-有标题栏WS_CHILD/WS_CHILDWINDOW-子窗口WS_CLIPSIBLINGS-可以裁剪的窗口WS_DISABLED-窗口不可用,点击每有任何反应WS_D

24、LGFRAME-对话框窗口的边框WS_GROUP-分组风格WS_HSCROLL-水平滚动条WS_VSCROLL-垂直滚动条WS_ICONIC/ WS_MINIMIZE -创建之初最小化状态WS_MAXIMIZE-创建之初最大化状态WS_MAXIMIZEBOX-有最大化按钮 WS_MINIMIZEBOX -有最小化按钮 WS_SIZEBOX/WS_THICKFRAME -可以改变窗口的大小 WS_SYSMENU -系统菜单窗口WS_TABSTOP-可以使用TAB键切换鼠标的焦点WS_VISIBLE-创建的窗口可见,子窗口的创建,创建时要设置父窗口句柄 创建风格要增加 WS_CHILD|WS_VI

25、SIBLE,BOOL MoveWindow( HWND hWnd, / 窗口句柄 int X, / int Y, / int nWidth, / int nHeight, / BOOL bRepaint / 是否重绘,窗口类和窗口的附加数据,作用 注册窗口时,可以设置这两个数据内存空间 的大小。 int cbClsExtra; /窗口类的附加数据BUFFER大小 int cbWndExtra; /窗口的附加数据BUFFER大小 可以提供窗口类和窗口存放自己的数据的空间,窗口类缓冲区,窗口类附加数据缓冲区的用法: 1、申请缓冲区 int cbClsExtra 一般赋4的倍数,因为下面的LONG是

26、长整型,4个字节,当类注册 成功时,该内存就开始存在 2、写入数据 DWORD SetClassLong( HWND hWnd;/窗口句柄 int nIndex;/字节索引号,表明从哪个字节开始存。当int cbClsExtra为200时,最大写196 LONG dwNewLong/存入的数据 ); 3、读取数据 DWORD GetClassLong( HWND hWnd;窗口句柄 int nindex /字节索引号(从哪个字节开始读) );/返回值获取读取的数据,窗口缓冲区,窗口附加数据缓冲区的用法: 1、申请缓冲区 int cbWndExtra 一般赋4的倍数,只有当窗口创建的时候,该内存

27、才存在 2、写入数据 LONG SetWindowLong( HWND hWnd;/窗口句柄 int nIndex;/字节索引号(从哪个字节开始存储) LONG dwNewLong/写入数据 ) 3、读取数据 LONG GetWindowLong( HWND hWnd;/窗口句柄 int nIndex/字节索引号(从哪个字节开始读) );/返回值获取读取的数据,窗口类和窗口附件数据缓冲区的区别,窗口类附加数据缓冲区:是所有基于该窗口类创建出来的所有窗口共享的缓冲区。 窗口附件数据缓冲区:是窗口自己私有的缓冲区,即便是基于同一个窗口类创建出来的窗口相互之间也不共享,内存中画窗口,ShowWind

28、ow(hWnd, SW_SHOW) hWnd 保存窗口数据的内存,根据内存中关于窗口的数据,在显示器中绘制窗口图像 UpdateWindow(hWnd)重画,Windows消息机制,程序执行机制 过程驱动 - 程序的执行过程是按照预定好的顺序执行。 事件驱动 - 程序的执行是无序,用户可以根据需要随机触发相应的事件。 Win32窗口程序就是采用 事件驱动 方式执行,也就是 消息机制,什么是消息,当系统通知窗口工作时,就采用消息的方式派发给窗口。 DispatchMessage()派发 消息组成(windows平台下): 窗口句柄 -说明是哪个窗口的消息 消息ID -通过ID可以知道是什么消息

29、消息的两个参数-附带信息 消息产生的时间 消息产生时的鼠标位置,typedef struct tagMSG HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; MSG, *PMSG,窗口处理函数和消息,每个窗口都必须具有窗口处理函数。 LRESULT CALLBACK WindowProc( HWND hwnd, /窗口句柄 UINT uMsg, /消息ID WPARAM wParam, /消息参数 LPARAM lParam /消息参数 ); 当系统通知窗口时,会调用窗口处理函数同时,将消息

30、ID和消息参数传递给窗口处理函数。 在窗口处理函数中,不处理的消息,使用缺省窗口处理函数,例如DefWindowProc,消息相关函数,1 GetMessage - 获取本进程消息。 BOOL GetMessage( LPMSG lpMsg, /存放获取到的消息BUFF HWND hWnd, /窗口句柄,为NULL则抓本进程的所有消息 UINT wMsgFilterMin,/获取消息的最小ID UINT wMsgFilterMax /获取消息的最大ID ); lpMsg - 当获取到消息后,将消息的参数存放到MSG结构中。 hWnd - 获取到hWnd所指定窗口的消息。 wMsgFilterM

31、in和wMsgFilterMax -只能获取到由它们指定的消息范围内的消息,如果都为0,表示没有范围,消息相关函数,2 TranslateMessage - 翻译消息。将按键消息,翻译成字符消息。 BOOL TranslateMessage( CONST MSG *lpMsg /要翻译的消息地址 );检查消息是否是按键的消息,如果不是按键消息,不做任何处理,继续执行。 3 DispatchMessage - 派发消息。将消息派发到该消息所属窗口的窗口处理函数上 LRESULT DispatchMessage( CONST MSG *lpmsg /要派发的消息,掌握一个消息的三方面:一、消息什么

32、时候产生二、消息的作用,用来干什么三、这个消息附带什么信息,Windows常用消息,WM_DESTROY - 窗口被销毁时的消息,无消息参数。常用于在窗口被销毁(保存窗口数据的那块内存被释放)之前,做相应的善后处理,例如资源、内存等。 WM_SYSCOMMAND - 系统命令消息,当点击窗口的最大化、最小化、关闭、标题栏、边框等命令时,收到这个消息。 常用在窗口关闭时,提示用户处理。 wParam - 具体点击的位置,例如关闭SC_CLOSE等. lParam - 鼠标位置(长整型,以下是两个宏) LOWORD 低字 - 水平位置 HIWORD 高字 - 垂直位置,取鼠标位置,取低字段的水平位

33、置 int x = LOWORD(IParam) 取高字段的锤子位置 int x = HIWORD(IParam,Windows常用消息,WM_CREATE - 在窗口创建成功还未显示之前,收到这个消息。 常用于初始化窗口的参数、资源等等,包括创建子窗口、控件等。 WPARAM - 不使用 LPARAM - 是CREATESTRUCT结构类型的指针,保存了CreatWindowEx中的12个参数。 WM_SIZE - 在窗口的大小发生变化后,会收到WM_SIZE。 常用于窗口大小变化后,调整窗口内各个部分控件的布局。 WPARAM - 窗口大小变化的原因。比如点击关闭,最大化,最小化 LPAR

34、AM - 变化窗口客户区的大小 LOWORD - 变化后的宽度 HIWORD- 变化后的高度,调试程序的手段:控制台窗口HANDLE g_hOutput = NULL;/标准输出句柄,全局变量AllocConsole();/给窗口程序添加一个附带的DOS窗口,主程序中g_hOutput=GetStdHandle(STD_OUTPUT_HANDLE);WriteConsole(g_hOutput, szText, strlen(szText), NULL, NULL);/标准输出句柄,输出字符串, 字符串长度, 实际输出字符串长度,未输出的窗口,BOOL MoveWindow( HWND hWn

35、d, / int X, / horizontal position int Y, / vertical position int nWidth, / width int nHeight, / height BOOL bRepaint / repaint option );移动窗口控件,Windows常用消息,WM_QUIT - 用于结束消息循环处理。 wParam - PostQuitMessage 函数传递的参数 lParam - 不使用 当GetMessage收到这个消息后,会返回FALSE,结束while处理,退出消息循环。 WM_PAINT - 绘图消息 键盘消息 鼠标消息 定时器消息

36、,消息的获取,GetMessage - 从系统获取消息,将消息从系统中移除,阻塞函数。当系统无消息时,GetMessage会等候下一条消息。 PeekMessage - 以查看的方式从系统获取消息,可以不将消息从系统移除,非阻塞函数。当系统无消息时,返回FALSE,继续执行后续代码。 BOOL PeekMessage( LPMSG lpMsg, / message information HWND hWnd, / handle to window UINT wMsgFilterMin, / first message UINT wMsgFilterMax, / last message UIN

37、T wRemoveMsg /移除标识,是否从操作系统提取消息,消息的发送,SendMessage - 发送消息,会等候消息处理的结果。 PostMessage - 投递消息,消息发出后立刻返回,不等候消息执行结果。 BOOL SendMessage/PostMessage( HWND hWnd,/消息发送的目的窗口 UINT Msg, /消息ID WPARAM wParam, /消息参数 LPARAM lParam /消息参数 );/消息的后两个参数由该函数内部自动填写,消息的分类,1 系统消息 - ID范围 0 - 0 x03FF 由系统定义好的消息,可以在程序中直接使用。 2 用户自定义消

38、息 - ID范围 0 x0400 - 0 x7FFF (31743) 由用户自己定义,满足用户自己的需求。由用户自己发出消息,并响应处理。 #define WM_MYMESSAGE WM_USER+n 自定义消息宏:WM_USER 3 应用程序消息 - ID范围 0 x8000 - 0 xBFFF 程序之间通讯时使用的消息。多用于底层驱动 应用程序消息宏:WM_APP 4 系统注册消息 - ID范围 0 xC000 - 0 xFFFF 在系统注册并生成相应消息,然后可以在各个程序中使用这个消息,消息队列,消息队列用于存放消息的一个队列,消息在队列中先入先出。所有窗口程序都具有消息队列。程序可以

39、从队列中获取消息。 消息队列的类型 系统消息队列-由系统维护的消息队列。存放系统产生的消息,例如鼠标、键盘等。 程序消息队列-属于每一个应用程序(线程)的消息队列。由应用程序(线程)维护。 消息队列的关系 1 当鼠标、键盘产生消息时,会将消息存放到系统消息队列 2 系统会根据存放的消息,找到对应窗口的消息队列。 3 将消息投递到程序的消息队列中,消息和消息队列,根据消息和消息队列之间使用关系,将消息分成两类: 队列消息 - 消息的发送和获取,都是通过消息队列完成。 非队列消息 - 消息的发送和获取,是直接调用消息的窗口处理完成。 队列消息-消息发送后,首先放入队列,然后通过消息循环,从队列当中

40、获取。 GetMessage 只能从消息队列中获取消息 PostMessage - 将消息投递到消息队列(系统消息对-进程消息队列) 常见队列消息:WM_PAINT、键盘、鼠标、定时器。 非队列消息消息发送时,首先查找消息接收窗口的窗口处理函数,直接调用处理函数,完成消息。 SendMessage - 直接将消息发送给窗口的处理函数,并等候处理结果。 常见消息:WM_CREATE、WM_SIZE等,消息的获取,消息循环 GetMessage /PeekMessage从程序的消息队列当中,获取到消息。 TranslateMessage 检查获取到的消息,如果发现是按键消息,产生一个字符消息WM_

41、CHAR,并放入程序的消息队列。 DispatchMessage 根据消息,找到窗口处理函数,调用窗口处理函数,完成消息的处理,GetMessage/PeekMessage次序,1 在程序(线程)消息队列查找消息,如果队列有消息,检查消息是否满足指定条件(HWND,ID范围),不满足条件就不会取出消息,否则从队列取出消息返回。 2 如果程序(线程)消息队列没有消息,向系统消息队列获取属于本程序的消息。如果系统队列的当前消息属于本程序,系统会将消息转发到程序的消息队列 3 如果系统消息队列也没有消息,检查当前窗口的需要重新绘制的区域,如果发现有需要绘制的区域,GetMessage产生WM_PAI

42、NT消息,取得消息返回处理。 4 如果没有重新绘制区域,检查定时器如果有到时的定时器,GetMessage产生WM_TIMER,返回处理执行。 5 如果没有到时的定时器,整理程序的资源、内存等等。 6 GetMessage会继续等候下一条消息。PeekMessage会返回FALSE,交出程序的控制权。 注意:GetMessage如果获取到是WM_QUIT,函数会返回FALSE,消息的发送,1 SendMessage 发送消息到指定的窗口,并等候对方将消息处理,然后消息执行结果,用于非队列消息的发送。 2 PostMessage 将消息放到消息队列中,立刻返回,用于队列消息的发送。 无法获知消息

43、是否被对方处理,绘图消息WM_PAINT,WM_PAINT 当窗口需要绘制的时候,会发送窗口处理函数。 当窗口重新显示和窗口变大时,就需要重画,被遮挡和小化不需要重画 窗口无效区域(被声明成需要重新绘制的区域) BOOL InvalidateRect( HWND hWnd, /窗口句柄 CONST RECT* lpRect, /区域的矩形坐标,为空则整个窗口都重画 BOOL bErase /重绘前是否先擦除 ); 在程序中,如果需要绘制窗口,调用函数声明窗口无效区域,绘图消息WM_PAINT,WM_PAINT参数 WPARAM - 不使用 LPARAM - 不使用 消息处理步骤 1 开始绘图处

44、理 HDC BeginPaint( HWND hwnd, /绘图窗口 LPPAINTSTRUCT lpPaint /绘图参数的BUFF ); 返回绘图设备句柄HDC 2 绘图 3 结束绘图处理 BOOL EndPaint( HWND hWnd, /绘图窗口 CONST PAINTSTRUCT *lpPaint /绘图参数的指针BeginPaint返回,键盘消息,1 键盘消息 WM_KEYDOWN - 按键被按下时产生 WM_KEYUP - 按键被放开时产生 注意:两个消息不一定一对一出现 WM_SYSKEYDOWN - 系统键按下时产生 比如ALT、F10 WM_SYSKEYUP - 系统键放

45、开时产生 WM_CHAR - 字符消息(TranslateMessage()函数发送) 2 消息参数 按键消息: WPARAM - 按键的Virtual Key(虚拟键码) LPARAM - 按键的参数,例如按下次数 WM_CHAR消息: WPARAM - 输入的字符(ASC编码) LPARAM - 按键的相关参数,键盘消息,消息的使用 1 KEYDOWN可以重复出现,KEYUP只能在按键松开时出现1次 2 TranslateMessage在转换WM_KEYDOWN消息时,对于可见字符可以产生WM_CHAR,不可见字符无此消息。 3 WM_KEYDOWN/UP的wParam是表示的按键 虚拟键

46、码,WM_CHAR是表示输入的字符的ASC字符编码,鼠标消息,鼠标消息 1 基本鼠标消息 WM_LBUTTONDOWN - 鼠标左键按下 WM_LBUTTONUP - 鼠标左键抬起 WM_RBUTTONDOWN - 鼠标右键按下 WM_RBUTTONUP - 鼠标右键抬起 WM_MOUSEMOVE - 鼠标移动消息 2 双击消息 WM_LBUTTONDBLCLK - 鼠标左键双击 WM_RBUTTONDBLCLK - 鼠标右键双击 3 滚轮消息 WM_MOUSEWHEEL - 鼠标滚轮消息,鼠标消息,基本鼠标消息 消息参数 WPARAM - 其他按键的状态,例如Ctrl/Shift等 LPAR

47、AM - 鼠标的位置,窗口客户区坐标系。 LOWORD X坐标位置 HIWORD Y坐标位置 鼠标消息使用 一般情况鼠标按下/抬起成对出现。在鼠标移动过程中,会根据移动速度产生一系列的WM_MOUSEMOVE消息,鼠标消息,双击鼠标消息 消息参数 WPARAM - 其他按键的状态,例如Ctrl/Shift等 LPARAM - 鼠标的位置,窗口客户区坐标系。 LOWORD X坐标位置 HIWORD Y坐标位置 使用时需要在注册窗口类的时候添加CS_DBLCLKS 风格。 消息产生顺序 以WM_LBUTTONDBLCLK为例: WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUT

48、TONDBLCLK WM_LBUTTONUP,鼠标消息,鼠标滚轮 WM_MOUSEWHEEL-头文件StdAfx.h中的#include 头文件之前定义#define _WIN32_WINNT 0X400 消息参数 WPARAM: LOWORD - 其他按键的状态 HIWORD - 滚轮的偏移量,是120的倍数,通过正负值表示表示滚动方向。 正:向前滚动 负:向后滚动 LPARAM:鼠标当前的位置,屏幕坐标系 LOWORD - X坐标 HIWORD - Y坐标 使用 通过偏移量,获取滚动的方向和倍数,定时器消息,1 定时器消息(此定时器多用于刷新界面) 可以在程序中设置定时器,当到达时间 间隔

49、时,定时器会向程序发送一个 WM_TIMER消息。 定时器的精度是毫秒,但是准确度很低。 例如设置时间间隔为1000ms,但是会在 非1000毫秒到达。 2 消息的参数 WPARAM - 定时器ID LPARAM - 定时器处理函数的指针,VOID CALLBACK TimerProc( HWND hwnd, / UINT uMsg, / UINT idEvent, / DWORD dwTime /当前定时器的时间,定时器消息,3 定时器使用 3.1 创建定时器 UINT SetTimer( HWND hWnd,/定时器窗口句柄,定时器触发了,并让该窗口的处理函数处理 UINT nIDEven

50、t, /定时器ID UINT uElapse,/时间间隔。毫秒为单位,1000毫秒=1秒 TIMERPROC lpTimerFunc /定时器处理函数指针,程序员自己定义,系统调用 );创建成功,返回非0。 使用窗口处理函数,做为定时器处理函数,lpTimerFunc为NULL 使用定时器处理函数处理定时器消息。 3.2 消息处理 WM_TIMER 3.3 关闭定时器 BOOL KillTimer( HWND hWnd,/定时器窗口句柄 UINT uIDEvent /定时器ID ); 附:GetClientRect 获取窗口客户区大小,练习,绘制圆的函数 BOOL Ellipse( HDC h

51、dc, / dc句柄(BeginPaint的返回值) int nLeftRect, / 左上角X坐标 int nTopRect, /左上角Y坐标 int nRightRect, /右下角X坐标 int nBottomRect /左右下角Y坐标 ); 获取窗口边界 BOOL GetClientRect( HWND hWnd, / 窗口句柄 LPRECT lpRect / 返回窗口边界的信息,菜单的使用,菜单的分类 1.1 窗口的顶层菜单 1.2 弹出式菜单 1.3 系统菜单 HMENU类型表示菜单,菜单每一项有相应的ID,菜单的使用,窗口的顶层菜单 创建菜单 HMENU CreateMenu(V

52、OID); /创建成功返回菜单句柄 增加菜单项(InsertMenu()随意追加) BOOL AppendMenu( HMENU hMenu, /菜单句柄 UINT uFlags, /菜单项风格 UINT uIDNewItem, /菜单项ID或下拉菜单的句柄 LPCTSTR lpNewItem /菜单项的名称 ); 设置到窗口 BOOL SetMenu( HWND hWnd, /窗口句柄 HMENU hMenu /菜单句柄,AppendMen()中的uFlags MF_POPUP-具有这种风格的菜单项,被点击后弹出下拉菜单uIDNewItem参数必须设置下拉菜单的句柄 MF_SEPARATOR

53、-具有这种风格的菜单项,为分隔线 MF_STRING-具有这种风格的菜单项,被点击后能够发出MF_COMMAND,菜单的使用,弹出式菜单 Popup 菜单的创建 HMENU CreatePopupMenu(VOID);/创建成功返回菜单句柄 加入顶层菜单 BOOL AppendMenu( HMENU hMenu, /菜单句柄 UINT uFlags, /菜单项增加选项,MF_POPUP UINT_PTR uIDNewItem, /弹出式菜单的句柄 LPCTSTR lpNewItem /菜单项的名称,void OnCreate(HWND hWnd)HMENU hMain=CreateMenu()

54、;HMENU hFile = CreatePopupMenu();AppendMenu(hFile, MF_STRING, 1003, “新建”);AppendMenu(hFile, MF_SEPARATOR, 0, “”);AppendMenu(hFile, MF_STRING, 1004, “退出”);HMENU hHelp = CreatePopupMenu();AppendMenu(hHelp, MF_STRING, 1005, “关于”);AppendMenu(hMain, MF_POPUP, (UINT)hFile, “文件”);AppendMenu(hMain, MF_POPUP

55、, (UINT)hHelp, “帮助”);SetMenu(hWnd, hMain);MF_MENUBARBREAK 是让菜单项换行,菜单的使用,菜单命令处理 具有MF_STRING 风格的菜单项被点击发出WM_COMMAND 消息 WPARAM: HIWORD - 对于菜单为0 LOWORD - 菜单项的ID LPARAM - 对于菜单为NULL 命令处理过程 获取WPARAM菜单ID,根据ID处理,菜单的使用,菜单项的状态 在增加菜单项可以设置菜单项的状态。 可以使用菜单API修改状态 CheckMenuItem EnableMenuItem 函数使用时,需要通过设置MF_BYPOSITIO

56、N或者MF_BYCOMMAND,确定使用菜单索引或者菜单ID。 WM_INITMENUPOPUP(在这个消息时可以设置菜单的初始状态) 在菜单被激活(点击)但是未显示,窗口会收到这个消息 WPARAM - 菜单句柄(被激活的菜单句柄) LPARAM - LOWORD 是菜单项索引(被点击的顶层菜单项索引(即将被显示的菜单的上层菜单)) HIWORD 是窗口菜单标识(即将显示菜单是否为窗口菜单) 顶层菜单/系统菜单 属于窗口菜单。但弹出式菜单不属于窗口菜单,如何让菜单的状态灵活改变,设置菜单项是否勾选 DWORD CheckMenuItem( HMENU hmenu, / 被修改的菜单的句柄 U

57、INT uIDCheckItem, /菜单中的那一项,菜单项的ID或位置(索引) UINT uCheck / 具体状态 ); 最后一个参数如果是MF_BYCOMMAND-uIDCheckItem必须填写菜单项ID(默认参数) 如果是MF_BYPOSITION-uIDCheckIte必须填写菜单的位置,在被修改的菜单中所占的位置 MF_CHECKED-菜单项勾选 MF_UNCHECKED-菜单项非勾选 用位或来连接,if (g_state = 0) CheckMenuItem(hFile, 1003, MF_BYCOMMAND|MF_UNCHECKED); else CheckMenuItem(

58、hFile, 0, MF_BYPOSITION|MF_CHECKED); g_state = !g_state,设置菜单是否可用和是否灰色 BOOL EnableMenuItem( HMENU hMenu, / 菜单句柄 UINT uIDEnableItem, /菜单中的那一项,菜单项的ID或位置(索引) UINT uEnable / 具体状态 ); 最后一个参数如果是MF_BYCOMMAND-uIDCheckItem必须填写菜单项ID 如果是MF_BYPOSITION-uIDCheckIte必须填写菜单的位置 MF_DISABLED-菜单项勾选 MF_ENABLED-菜单项非勾选 MF_GR

59、AYED-菜单项灰色 用位或来连接,系统菜单的使用,1 系统菜单的获取 HMENU GetSystemMenu( HWND hWnd,/窗口句柄 BOOL bRevert /重置选项 ); 返回获取到的系统菜单句柄 bRevert:TRUE - 删除旧菜单,恢复到默认的系统菜单 FALSE - 返回当前的系统菜单句柄。 2 系统菜单的修改 AppendMenu DeleteMenu 3 系统菜单命令响应 通过WM_SYSCOMMAND响应菜单命令。 WPARAM的LOWORD是命令ID,删除菜单项 BOOL DeleteMenu( HMENU hMenu, / 菜单句柄 UINT uPosition, / 菜单中的那一项,菜单项的ID或位置(索引) UINT uFlags / 具体状态 ); 最后一个参数如果是MF_BYCOMMAND-uIDCheckItem必须填写菜单项ID 如果是MF_BYPOSITION-uIDCheckIte必须填写菜单的位置 uFlags-TRUE或FALSE,右键菜单 Context Menu的使用,1 创建菜单 右键菜单是一个弹出式菜单,使用CreatePopupMenu创建。 2 显示菜单 BOOL TrackPopupMenu( HMENU hMenu, /菜单句柄,显示那个弹出式菜单 UINT uFlags, /显示方式 int x,/水平位

温馨提示

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

评论

0/150

提交评论