[转]Win32 关键点总结系列

本文详细介绍了Windows编程中的关键概念,包括窗口类、消息处理、窗口过程、创建窗口、消息循环、显示窗口、窗口过程处理消息、窗口类结构、消息传递机制、控件如按钮、复选框、滚动条和编辑框的使用等。通过这些内容,读者可以深入理解Windows应用程序的基础架构和交互逻辑。
摘要由CSDN通过智能技术生成

窗口和消息

1 前缀

 

前缀

全称

释义

CS

class style

类风格选项

CW

create windows

创建窗口选项

DT

draw text

绘制文本选项

IDI

Icon ID

图标ID

IDC

Cursor ID

光标ID

MB

Message Box

消息框选项

SND

Sound

声音选项

WM

Windows Message

窗口消息

WS

Windows Style

窗口风格

 

 

2 WPARAMLPARAM的意义

   Windows是一种16位系统时,WndProc的第三个参数被定义为WORD,是一个16位的无符号整数,而第四个参数被定义为一个LONG,是一个32位有符号整数,所以导致对单词PARAM(参数)加前缀WL

但在32Windows中,WPARAM被定义为一个UINT,而LPARAM被定义为一个LONG,因此窗口过程的这两个参数都是32位的值。

 

3 新的函数类型

WndProc函数返回一个类型为LRESULT的值,该值是一个LONG型,32位有符号。

    

WndProc函数被指定为CALLBACK类型,WinMain函数被指定为WINAPI类型。这些类型指在Windows本身和用户的应用程序之间发生的函数调用的特殊调用序列。

 

4 窗口类结构WNDCLASS

10个域。分别是:

style:类风格,用于在什么时候发出窗口变化消息

cbClsExtra:在类结构保存的窗口结构中预留一些额外空间

       cbWndExtra:在Windows内部保存的窗口结构中预留一些额外空间

       hbrBackground:指定基于这个类创建的窗口背景颜色

       hCursor:读取光标

       hIcon:读取图标

       hInstance:程序的实例句柄

       lpfnWndProc:指定处理基于这个窗口类创建的所有窗口的窗口过程

       lpszClassName:指定类名

       lpszMenuName:指定窗口类菜单

 

5 注册窗口类RegisterClass

一般在Windows XP及以后都可以很顺利的注册成功。

所以可以只写RegisterClass(&wndclass);

 

6 创建窗口CreateWindow

    窗口类定义了窗口的一般特征,调用CreateWindow可以指定有关窗口的更详细的信息。

hwnd = CreateWindow (szAppName,          // 指定一个窗口类,基于该窗口类创建窗口

                   TEXT ("Hello Win"),    // 这个字符串会出现在标题栏中

                   WS_OVERLAPPEDWINDOW, // 本窗口风格

                   CW_USEDEFAULT,         //窗口左上角的X坐标

                   CW_USEDEFAULT,         //窗口左上角的Y坐标

                   CW_USEDEFAULT,         //窗口的宽度

                   CW_USEDEFAULT,         //窗口的高度

                   NULL,                    //窗口对象的父窗口句柄

                   NULL,                    //窗口对象的菜单句柄或者子窗口编号

                   hInstance,                  //当前进程的实例句柄

                   NULL) ;                   //窗口对象的参数指针句柄

 

创建窗口返回的是窗口句柄。

 

7 显示窗口

窗口创建成功后,系统将在内存中为其分配一块内存,但是此时窗口并未显示在显示器上,所以需要使用两个调用。

ShowWindow(窗口句柄,iCmdShow)

其中的第二个参数用于确定如何儿子屏幕上显示窗口,是最小化还是常规还是最大化。

 

UpdateWindow(窗口句柄)

调用上句将导致客户区被绘制。它通过给窗口过程发送一个WM_PAINT消息来做到这一点。

 

8 消息循环

调用UpdateWindow之后,窗口就出现在显示器上。

Windows为当前运行的每个Windows程序维护一个“消息队列”。在发生事件的时候,Windows将事件转换为一个“消息”,并将消息放入程序的消息队列中。

 

程序通过执行一个叫做“消息循环”的代码从消息队列中取出消息。

 

while (GetMessage(&msg, NULL, 0, 0))

           {

                  TranslateMessage(&msg);

                  DispatchMessage(&msg);

           }

   

其中msg是一个类型为MSG的结构,MSG结构在WINUSER.H中定义如下:

typedef struct tagMSG {

    HWND       hwnd;

    UINT         message;

    WPARAM     wParam;

    LPARAM      lParam;

    DWORD      time;

    POINT        pt;

} MSG, *PMSG

 

其中,hwnd 是消息发向的窗口句柄。

      message 是消息标识符,以WM_开头。

      wParam 一个32位的消息参数。

      lParam 一个32位的消息参数。

      time 消息放入消息队列的时间。

      pt 消息放入消息队列时鼠标的坐标。

 

消息循环以GetMessage调用开始,它从消息队列中取出一个消息,GetMessage(&msg, NULL, 0, 0)这一调用传给Windows一个指向名为msgMSG结构的指针。其余三个参数设置为NULL0,表示程序接收自己创建的所有窗口的所有消息。

 

只要从消息队列中取出的消息的message域不为WM_QUITGetMessage就返回一个非0值,while循环就可以继续。

TranslateMessage(&msg);msg结构传给Windows,进行一些键盘转换。

DispatchMessage(&msg);msg结构传给Windows,然后Windows将里面的消息发给相应的窗口过程进行处理。处理后,WndProc返回到WindowsWindows返回到程序,程序继续下一个while循环。

 

9 窗口过程WndProc

实际的动作发生在窗口过程中。窗口过程确定了在窗口的客户区显示什么,以及怎么处理用户输入。

窗口过程是命名为WndProc的函数。(也可以其他不冲突的名字)

一个Windows程序可以包含多个窗口过程。

一个窗口过程总是与调用RegisterClass注册的特定窗口类相关联。

CreateWindow函数根据特定的窗口类创建一个窗口,返回该窗口的句柄。

但是基于一个窗口类可以创建多个窗口。

 

1程序     包括   n个窗口过程

1窗口过程 关联   1窗口类

1窗口类   创建   n个窗口

CreateWindows根据窗口类创建一个窗口。

 

窗口过程总是声明成如下形式:

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)

4个参数跟MSG结构的前4个域是相同的。

第一个参数:接收消息的窗口句柄。

第二个参数:消息类型,标识消息的数字

最后两个参数:32位的消息参数。

 

程序通常不直接调用窗口过程,而是由Windows调用窗口过程。

 

10 窗口过程处理消息

窗口过程接收的每个消息均是用一个数值来标识的,也就是传给窗口过程的message参数。

窗口过程处理消息时,必须返回0.窗口过程不予处理的所有消息应该被传给名为DefWindowsProcWindows函数。

switch语句来处理不同消息,消息以WM_开头。

 

11 WM_CREATE消息

Windows在处理CreateWindow函数时,窗口过程就会接收到WM_CREATE消息。

通常,窗口过程在WM_CREATE处理期间进行一次窗口初始化。

 

12 WM_PAINT消息

当窗口客户区域的一部分或全部变成“无效”时,必须进行刷新,WM_PAINT将通知程序。

在最初创建窗口的时候,整个客户区都是无效的,因为程序还没有在窗口上画任何东西。在调用UpdateWindow时,通常会触发第一个WM_PAINT消息,指示窗口过程在客户区域上画一些东西。

 

在改变程序窗口大小后,客户区也会变得无效,至于怎么变得无效由CS_引导的类风格选项确定。

 

WM_PAINT的处理几乎总是从一个BeginPaint调用开始,以一个EndPaint结束。

hdc = BeginPaint(hwnd, &pt);

do something;(如GetClientRect(hwnd, &rect);)

EndPaint(hwnd, &pt);

 

hwnd是要刷新的窗口的窗口句柄。

pt是指向类型为PAINTSTRUCT的结构指针。

 

BeginPaint调用中,如果客户区域的背景还未被擦除,就由Windows来擦除。然后使用注册窗口类的WNDCLASS结构中的hbrBackground域中第一的刷子来删除背景。

BeginPaint调用使整个客户区有效,并返回一个“设备描述表句柄”。设备描述表是指物理输出设备及其驱动程序。可以利用该“设备描述表句柄”在客户区域显示文本和图形。

EndPaint调用释放设备描述表句柄。

 

GetClientRect(hwnd, &rect)

第一个参数:程序的窗口句柄;

第二个参数:指向RECT类型的rectangle结构。该结构有4LONG域,标识客户区域的尺寸。

当改变窗口大小时,WndProc通过调用GetClientRect来获取变化后的窗口大小,重新绘制客户区。

 

13 WM_DESTROY消息

    当用户点击关闭按钮时发生。

程序可以通过调用PostQuitMessage以标准方式响应WM_DESTROY消息;

PostQuitMessage(0);

该函数在程序的消息队列插入一个WM_QUIT消息。

GetMessage对于除了WM_QUIT消息之外的从消息队列中取出的所有消息都返回非0值。而当GetMessage取到一个WM_QUIT消息时,返回0.

 

14 关闭程序时的消息传递

用户点击关闭按钮

产生WM_SYSCOMMAND消息;

产生WM_CLOSE消息响应WM_SYSCOMMAND

产生WM_DESTROY消息响应WM_CLOSE

产生WM_QUIT消息响应WM_DESTROY

 

15 进队消息和不进队消息

消息能够分为:进队消息和不进队消息。

进队消息是由Windows放入程序消息队列中的。在程序的消息循环中,重新返回并分配给窗口过程。

不进队消息在Windows调用窗口时直接发送给窗口过程。

 

也就是说,进队消息发送给消息队列,不进队消息发送给窗口过程。

在任何情况下,窗口过程都将获得窗口所有的消息。窗口过程是窗口的消息中心。

 

进队消息基本上是用户输入的结果,还包括时钟消息、刷新消息、退出消息。

不进队消息基本上是来自调用特定的Windows函数。

 

输出文本

16 有效矩形和无效矩形

窗口过程一旦接受到WM_PAINT消息之后,就准备更新整个客户区,但往往只需更新一个较小的区域。这个区域就称为“无效区域”。正是客户区内存在无效区域,才提示Windows将一个WM_PAINT消息放入消息队列。

 

Windows内部为每个窗口保存一个“绘图信息结构”,这个结构包含了包围无效区域的最小矩形的坐标以及其他信息,这个矩形就叫做“无效矩形”。

如果在窗口过程处理WM_PAINT消息之前,客户区又有一个区域变为无效,那么Windows计算出一个包围两个无效区域的新的无效矩形,并将这个变化后的信息放在绘制信息结构中。

一个消息队列在一个时刻只能有一个WM_PAINT消息在队列中。

 

窗口过程可以调用InvalidateRect使客户区变为无效。如果消息队列包含一个WM_PAINT消息,那么Windows将计算出新的无效矩形;否则,就在消息队列中添加一个WM_PAINT消息。

 

在处理WM_PAINT消息期间,窗口过程在调用了BeginPaint之后,整个客户区就会变得有效。

程序也可以显式调用ValidateRect函数使客户区内的任意矩形区域变得有效。如果这条调用使整个客户区都有效,那么将在当前消息队列中删除WM_PAINT消息。

 

17 设备描述表

要在窗口的客户区绘图,可以使用Windows的图形设备接口GDI函数。

设备描述表DCGDI内部保存的数据结构。

设备描述表与特定的显示设备有关。

设备描述表中的有些值是图形化的“属性”,如指出颜色、背景色、坐标映射方式等。

 

当程序要绘图时,必须先获取设备描述表句柄。在获取了该句柄之后,Windows用默认的属性值填充设备描述表结构的内部各域。

当程序在客户区绘图完毕后,必须释放设备描述表句柄。句柄被释放后不再有效,也不再使用。程序必须在处理单个消息期间获取和释放句柄。

 

18 获取设备描述表句柄的方法之一

在使用WM_PAINT消息时,使用这种方法。它涉及到BeginPaintEndPaint两个函数。

在处理WM_PAINT消息时,窗口过程首先调用BeginPaintBeginPaint函数一般在准备绘制时导致无效区域的背景被擦除。BeginPaint返回的值是设备描述表句柄,这一返回值通常被保持在叫做hdc的变量中。

HDC hdc

HDC数据类型定义为32位的无符号数。

然后,程序就可以使用需要设备描述表句柄的GDI函数了。

调用EndPaint即可释放设备描述表句柄。

 

一般地,处理WM_PAINT消息的形式如下:

case WM_PAINT

    hdc = BeginPaint(hwnd, &ps);

    使用GDI函数

    EndPaint(hwnd, &ps);

    return 0;

 

处理WM_PAINT消息时,必须成对地调用BeginPaintEndPaint

 

19 绘图信息结构

Windows为每一个窗口保存一个绘图信息结构。这就是PAINTSTRUCT,定义如下:

 

typedef struct tagPAINTSTRUCT {

    HDC         hdc;          

    BOOL        fErase;        

    RECT        rcPaint;

    BOOL        fRestore;

    BOOL        fIncUpdate;

    BYTE        rgbReserved[32];

} PAINTSTRUCT

 

在程序调用BeginPaint时,Windows填充该结构的各个字段。用户程序只需要使用前三个字段。

hdc是设备描述表句柄。

 

fErase通常被标识为FLASE,这意味着Windows已经擦除了无效矩形的背景。

如果程序通过调用Windows函数InvalidateRect使客户区中的矩形失效,那么该函数的最后一个参数会指定fErase的值。如果指定0,那么在稍后的PAINTSTRUCT里面的fErase会被设置为TRUE

 

rcPaintRECT结构,定义了无效矩形的边界。RECT结构中的lefttoprightbottom以像素点为单位。此时,Windows将绘图操作限制在此RECT结构定义的矩形范围内,如果要在无效矩形外绘图,应该在调用

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值