Windows编程
本文是介绍Windows编程的一篇博客
窗口是Windows应用程序的基本单位
山窗初曙,透纸黎光。 ——张岱
WINDOWS编程
控制台程序 Console
DOS程序,本身没有窗口,通过Windows DOS窗口执行
窗口程序
拥有自己的窗口,可以与用户交互
库程序
存放代码,数据的程序,执行文件可以从中取出代码执行和获取数据
静态库:扩展名LIB,在编译链接程序时,将代码放入执行文件中
动态库:扩展名DLL,在执行文件执行时从中获取代码
开发工具和库
编译工具
编译器 CL.EXE 将源代码编译成目标代码
链接器 LINK.EXE 将目标代码,库链接生成最终文件
资源编译器RC.EXE 将资源编译,最终通过链接器存入最终文件
C:\Program Files(x86)\Microsoft Visual Studio 10.0\VC\bin
库和头文件
Windows库
kernel32.dll 提供了核心的API,例如进程,线程,内存管理等
user32.dll 提供了窗口,消息等API
gdi32.dll 绘图相关的API
路径 C:\Windows\System32
头文件
windows.h 所有windows头文件的集合
windef.h windows数据类型
winbase.h kernel32的API
wingdi.h gdi32的API
winuser.h user32的API
winnt.h UNICODE字符集支持
相关函数
WinMain函数
窗口创建过程
定义WInMain函数
定义窗口处理函数(自定义,处理消息)
注册窗口类(向操作系统写入一些数据)
创建窗口(内存中创建窗口)
显示窗口(绘制窗口的图像)
消息循环(获取/翻译/派发消息)
消息处理
字符编码
ASC
7位128个
ASCII
8位256个
DBCS
单双字节混合编码
UNICODE
几乎所有国家的字符
Ubuntu一般使用UTF-8,Windows使用的UTF-16
宽字节字符
wchar_t 每个字符占两个字节,不是基本的数据类型,实际上是unsigned short类型
定义时,需要加"L"
通知编译器按照双字节编译字符串
wchar_t* pwszText=L"Hello World";
TCHAR
定义Unicode宏的情况下是wchar_t
否则是char
系统调用函数的参数类型
注册窗口类
窗口类的概念
窗口类就是包含了窗口各种参数信息的数据结构
每个窗口都具有窗口类,基于窗口类创建窗口
每个窗口类都有一个名称,使用前必须注册到系统
窗口类是操作系统内核的一堆数据
窗口类的分类
系统窗口类
系统已经定义好的窗口类,所有应用程序都可以直接使用
应用程序全局窗口类
由用户自己定义,当前应用程序所有模块都可以使用
应用程序局部窗口类
由用户自己定义,当前应用程序中本模块都可以使用
注册窗口类
style的几个参数:
CS_DBCLKS 允许窗口接收鼠标双击
CS_NOCLOSE 窗口没有关闭按钮
全局和局部窗口类
style窗口类风格
应用程序全局窗口类注册,需要在窗口类的风格中增加CS_GLOBALCLASS。
例如:
WNDCLASS wce={0};
wce.style=....|CS_GLOBALCLASS
不增加CS_GLOBALCLASS就是局部窗口类
不建议用全局窗口类,全局窗口类能完成的局部窗口类也能完成
创建窗口
注册窗口类的两个重要成员
wc.hInstance=Ins;
wc.lpszClassName="Main";
CreateWindowEx
进入这个函数就进入内核态
CreateWindowEx(.."Main",...hIns..)
消息的概念和作用
系统根据传入窗口类名称,在应用程序局部窗口类中查找,如果找到执行2,如果未找到执行3
比较局部窗口类和创建窗口传入的HINSTANCE变量。如果发现相等,创建和注册的窗口类在同一模块(进程),创建窗口返回。如果不相等,继续执行3
在应用程序全局窗口类,如果找到,执行4,如果没有找到执行5
使用找到的窗口类的信息,创建窗口返回
在系统窗口类中查找,如果找到创建窗口返回,否则创建窗口失败
创建子窗口
创建时要设置父窗口句柄
创建风格要增加WS_CHILD|WS_VISIBLE
消息基础
消息的概念和作用
消息组成
窗口句柄
消息ID
消息的两个参数(两个附带信息)
消息的产生时间
消息产生时的鼠标位置
消息的作用
当系统通知窗口工作时,就采用消息的方式派发给窗口
每个窗口都必须有窗口处理函数
当系统通知窗口时,会调用窗口处理函数,同时将消息ID和消息参数传递给窗口处理函数。在窗口处理函数中,不处理消息,使用缺省窗口处理函数。例如:DefWindowProc
可以给各种消息做默认处理
三个消息处理函数
lpMsg 当获取到消息后,将消息的参数存放到MSG结构中
hWnd 获取到hWnd所指定窗口的消息
TranslateMessage将按键消息翻译成字符消息
检查消息是否是按键消息,如果不是按键消息,不做处理,继续执行
将消息派发到该消息所属窗口的窗口处理函数上
常见消息
一个消息需要掌握的三个方面
产生时间
附带的两个信息告诉我们什么
消息的一般用法(能拿来做什么)
常见的消息
WM_DESTROY
产生时间:窗口被销毁时的消息
附带信息:wParam 为0
lParam 为0
一般用法:常用于窗口被销毁之前,做相应的善后处理,例如资源,内存等
WM_SYSCOMMAND
产生时间:当点击窗口的最大化,最小化,关闭等
附带信息:wParam 具体点击的位置,例如关闭SC_CLOSE等
lParam 鼠标光标的位置
LOWORD(lParam)//水平位置
HIWORD(lParam)//垂直位置
一般用法:常用在窗口关闭时,提示用户处理
WM_CREATE
产生时间:在窗口创建成功但还未显示时
附带信息:wParam 为0
lParam 为CREATESTRUCT类型的指针
通过这个指针可知获取CreateWindowEx中的全部12个参数的信息
一般用法:常用于初始化窗口的参数,资源等等,包括创建子窗口
WM_SIZE
产生时间:在窗口大小发生变化后
附带信息:wParam 窗口大小变化的原因
lParam 窗口变化后的大小
LOWORD(lParam)//变化后的宽度
HIWORD(lParam)//变化后的高度
一般用法:常用于窗口大小变化后,调整窗口内各个部分的布局
消息循环原理
GetMessage从系统获取信息,将消息从系统中移除,阻塞函数。当系统无消息时,会阻塞等候下一条消息。
PeekMessage 以查看的方式从系统中获取消息,可以不将消息从系统中移除,非阻塞函数。当系统无消息时,返回False,继续执行后续代码
发送消息
SendMessage 发送消息,会等候消息处理结果
PostMessage 投递消息,消息发出之后立刻返回,不等候消息执行结果
消息分类
系统消息-ID范围 0-0x03FF
由系统定义好的消息,可以在程序中直接使用
用户自定义消息 ID范围 0x0400-0x7FFF
由用户自己定义,满足用户自己的需求,由用户自己发出消息,并响应处理
自定义消息宏:WM_USER
消息队列
用来存放消息的队列
消息在队列中先入先出
所有窗口程序都具有消息队列
程序可以从队列中获取信息
消息队列的分类
系统消息队列-由系统维护消息队列,存放系统产生的消息,例如鼠标,键盘
程序消息队列-属于每一个应用程序的消息队列,由应用程序维护
消息和消息队列的关系
1.当鼠标,键盘产生消息时,会将消息存放到系统消息队列
2.系统会根据存放的消息,找到对应程序的消息队列
3.将消息投递到程序的消息队列
根据消息和消息队列的关系,将消息分为两类:
队列消息
非队列消息
常见的队列消息:键盘,鼠标,定时器,WM_PAINT
键盘消息
WM_KEYDOWN 按键被按下时产生
WM_KEYUP 按键被放开时产生
WM_SYSKEYDOWN 系统键按下时产生,比如ALT,F10
WM_SYSKEYDOWN 系统键放开时产生
附带信息
WPARAM 按键的Virtual Key
LPARAM 按键的参数,按下次数
鼠标消息
鼠标消息分类
基本鼠标消息
WM_LBUTTONDOWN 鼠标左键按下
WM_LBUTTONUP 鼠标左键抬起
WM_RBUTTONDOWN 鼠标右键按下
WM_RBUTTONUP 鼠标右键抬起
WM_MOUSEMOVE 鼠标移动消息
双击消息
WM_LBUTTONDBLOCK 鼠标左键双击
WM_RBUTTONDBLOCK 鼠标右键双击
滚轮消息
WM_MOUSEWHELL 鼠标滚轮消息
附带信息:
wPARAM 其他按键的状态,例如Ctrl/Shift等
lPARAM 鼠标的位置,窗口客户区坐标系
一般情况鼠标按下/抬起成对出现,在鼠标移动过程中,会根据移动速度产生一系列WM_MOUSEMOVE消息
定时器消息
定时器消息的介绍
在程序中创建定时器,当到达时间间隔时,定时器想程序发送一个WM_TIMER消息,定时器的精度是毫秒,但是准确度很低,例如设置时间间隔为1000ms,但是会在非1000ms到达消息
附带信息:wPARAM 定时器ID
lPARAM 定时器处理函数的指针
菜单资源
菜单分类
窗口的顶层菜单
弹出式菜单
系统菜单
菜单资源的使用
添加菜单资源
加载菜单资源
注册窗口类时设置菜单
创建窗口传参设置菜单
在主窗口WM_CREATE消息中利用SetMenu函数设置菜单
未完待续
- 点赞
- 收藏
- 关注作者
评论(0)