WIN32编程梳理总结——窗口和消息

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.wParam 和 lParam意义

在Windows是一种16位系统时,WndProc的第三个参数被定义为WORD,是一个16位的无符号整数,而第四个参数被定义为一个LONG,是一个32位有符号整数,所以导致对单词PARAM(参数)加前缀W和L。
但在32位Windows中,WPARAM被定义为一个UINT,而LPARAM被定义为一个LONG,因此窗口过程的这两个参数都是32位的值。

3.注册窗口类RegisterClass

窗口类结构WNDCLASS(WNDCLASSEX):

WNDCLASS wc;

  ① wc.style:类风格,用于在什么时候发出窗口变化消息
  ② wc.cbClsExtra:在类结构保存的窗口结构中预留一些额外空间
  ③ wc.cbWndExtra:在Windows内部保存的窗口结构中预留一些额外空间
  ④ wc.hbrBackground:指定基于这个类创建的窗口背景颜色
  ⑤ wc.hCursor:读取光标
  ⑥ wc.hIcon:读取图标
  ⑦ wc.hInstance:程序的实例句柄
  ⑧ wc.lpfnWndProc:指定处理基于这个窗口类创建的所有窗口的消息处理函数(WndProc)
  ⑨ wc.lpszClassName:指定类名
  ⑩ wc.lpszMenuName:指定窗口类菜单

4.创建窗口CreateClass

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

hwnd = CreateWindow (szAppName,     // 窗口类名,基于该窗口类创建窗口
         TEXT ("Hello Win"),        // 这个字符串会出现在标题栏中
         WS_OVERLAPPEDWINDOW,       // 本窗口风格
         CW_USEDEFAULT,             //窗口左上角的X坐标
         CW_USEDEFAULT,             //窗口左上角的Y坐标
         CW_USEDEFAULT,             //窗口的宽度
         CW_USEDEFAULT,             //窗口的高度
         NULL,                      //窗口对象的父窗口或所有者窗口句柄
         NULL,                      //菜单句柄
         hInstance,                 //当前进程的实例句柄
         NULL) ;                    //传递给窗口WM_CREATE消息的指针

返回一个窗口句柄。

5.显示窗口

窗口创建成功后,系统将在内存中为其分配一块内存,但是此时窗口并未显示在显示器上,所以需要使用两个调用。
① ShowWindow(窗口句柄,iCmdShow);
其中的第二个参数用于确定如何儿子屏幕上显示窗口,是最小化还是常规还是最大化。
② UpdateWindow(窗口句柄)
调用上句将导致客户区被绘制。它通过给窗口过程发送一个WM_PAINT消息来做到这一点。

6.消息循环

调用UpdateWindow之后,窗口就出现在显示器上。
Windows为当前运行的每个Windows程序维护一个“消息队列”。在发生事件的时候,Windows将事件转换为一个“消息”,并将消息放入程序的消息队列中。
程序通过执行一个叫做“消息循环”的代码从消息队列中取出消息。(注意GetMessage(阻塞,若没有消息则不返还控制权)和PeekMessage(非阻塞,若没有消息也会返回)的区别)

7.消息处理函数(回调函数)WndProc

实际的动作发生在消息处理函数中。消息处理函数确定了在窗口的客户区显示什么,以及怎么处理用户输入。
  (1)消息处理函数是命名为WndProc的函数。(也可以其他不冲突的名字)
  (2)一个Windows程序可以包含多个消息处理函数。
  (3)一个消息处理函数总是与调用RegisterClass注册的特定窗口类相关联。
  (4)CreateWindow函数根据特定的窗口类创建一个窗口,返回该窗口的句柄。
  (5)但是基于一个窗口类可以创建多个窗口。

    1程序 —— 包括 ——n个回调函数
    1回调函数 —— 关联 —— 1窗口类
    1窗口类 —— 创建 —— n个窗口

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

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
   }
    return 0;
}

8.WM_CREATE消息

当Windows在处理CreateWindow函数时,回调函数就会接收到WM_CREATE消息。

9.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结构。该结构有4个LONG域,标识客户区域的尺寸。
当改变窗口大小时,WndProc通过调用GetClientRect来获取变化后的窗口大小,重新绘制客户区。

10.WM_DESTROY消息

当用户点击关闭按钮时发生。程序可以通过调用PostQuitMessage以标准方式响应WM_DESTROY消息;
PostQuitMessage(0);  // 该函数在程序的消息队列插入一个WM_QUIT消息。

>>关闭程序时的消息响应:

 ① 用户点击关闭按钮
 ② 产生WM_SYSCOMMAND消息
 ③ 产生WM_CLOSE消息响应WM_SYSCOMMAND
 ④ 产生WM_DESTROY消息响应WM_CLOSE
 ⑤ 产生WM_QUIT消息响应WM_DESTROY

11.队列消息和非队列消息

队列消息是由Windows放入程序消息队列中的。在程序的消息循环中,重新返回并分配给回调函数。
非队列消息在Windows调用窗口时直接发送给回调函数。

(队列消息基本上是用户输入的结果,还包括时钟消息、刷新消息、退出消息。
   非队列消息基本上是来自调用特定的Windows函数。)

猜你喜欢

转载自blog.csdn.net/LOG_IN_ME/article/details/82216784