Windows --- 常用消息以及消息附加参数

Win32:Windows 窗口的原理,既可以编 32 位也可以编 64 位

WM:Windows Message

Windows --- 常用消息以及消息附加参数_第1张图片

创建窗口的窗口类型名要写第一步、第二步注册窗口的类型名,否则会导致创建窗口失败

下面来解析 Windows 中常用的消息:

窗口处理函数会处理很多消息,会处理哪些消息呢?下面来监测一下这些消息是什么

Windows --- 常用消息以及消息附加参数_第2张图片

//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    //定义一个字符串
    wchar_t szMsg[100];
    //多字节用 sprintf
    //格式化-> 宽字符用 wsprintf
    //把格式化的字符串存储到szMsg中,格式化窗口句柄hWnd 用十六进制显示 #会自动加前缀
    wsprintf(szMsg,L"hWnd:%#x\tuMsg:%#x\twParm:%#x\tlParam:%#x\n",hWnd,uMsg,wParam,lParam);
    //用于输出调试信息
    OutputDebugString(szMsg);

    switch(uMsg)
    { 
    //窗口客户区创建消息,出来的比较早的一个消息,此时主窗口已经创建好了,只不过没有显示出来
    case WM_CREATE:
        //父窗口为hWnd:当前创建的窗口
        //CreateWindow 函数的调用或者CreateWindowEx 函数的调用会发出 WM_CREATE 消息
        MessageBox(hWnd,"这是WM_CREATE消息",L"提示",MB_OK);
        //设置窗口的标题 要设置的窗口 要设置的标题
        SetWindowText(hWnd,L"windows编程");
        break;
   }
}

WINBASEAPI
VOID
WINAPI
OutputDebugStringW(
    _In_opt_ LPCWSTR lpOutputString
    );

#ifdef UNICODE
#define OutputDebugString  OutputDebugStringW

窗口出来之前会有消息, 会调用  WindowProc 函数很多次,会打印调试信息很多次

调试导致以下问题,直接去掉即可,就不会输出下面的信息:

Windows --- 常用消息以及消息附加参数_第3张图片

窗口句柄:都是相同的,是同一个窗口

Windows --- 常用消息以及消息附加参数_第4张图片

Windows --- 常用消息以及消息附加参数_第5张图片

当窗口大小发生改变的时候,会发出这个消息,应用程序将使用这个消息,去改变默认的大小值和位置

WM_GETMINMAXINFO 消息 (Winuser.h) - Win32 apps | Microsoft Docs

Windows --- 常用消息以及消息附加参数_第6张图片

NC:非客户区

  C:客户区

 非客户区的创建

 非客户区自动计算大小

 

 窗口创建消息:客户区的创建

 

消息分为入队列消息和不入队列消息

进队列的消息

不进队列的消息:不需要 GetMessage 去取消息,例如 WM_CREATE

GetMessage:从消息队列去取消息

WPARAM wParam,LPARAM lParam 为附加信息

会把创建窗口信息的值传到 lParam 中

正向缩进 tab,反向缩进 shift + tab

Windows --- 常用消息以及消息附加参数_第7张图片

LPARAM 指向结构体 CREATESTRUCT 的指针

typedef struct tagCREATESTRUCTW {
    LPVOID      lpCreateParams;
    HINSTANCE   hInstance;        //应用程序实例句柄
    HMENU       hMenu;            //菜单句柄
    HWND        hwndParent;       //父窗口句柄
    int         cy;               //窗口的高度
    int         cx;               //窗口的宽度
    int         y;                //窗口左上角纵坐标
    int         x;                //窗口左上角横坐标
    LONG        style;            //风格
    LPCWSTR     lpszName;         //窗口名
    LPCWSTR     lpszClass;        //窗口类型名
    DWORD       dwExStyle;        //窗口的拓展风格
} CREATESTRUCTW, *LPCREATESTRUCTW;
#ifdef UNICODE
typedef CREATESTRUCTW CREATESTRUCT;
//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    wchar_t szMsg[100];
    wsprintf(szMsg,L"hWnd:%#x\tuMsg:%#x\twParm:%#x\tlParam:%#x\n",hWnd,uMsg,wParam,lParam);
    OutputDebugString(szMsg);

    switch(uMsg)
    { 
    case WM_CREATE:
        //指向结构体的指针-> 强制类型转换为 LPCREATESTRUCT 任何指针都是指向四个字节
        LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;     
   }
}

在 case 中定义变量一定要加 { },表示是一个语句块, 不加 { } 会出现问题 

开始调试的同时,打开监视窗口

Windows --- 常用消息以及消息附加参数_第8张图片

选中变量,拖动到监视窗口中

Windows --- 常用消息以及消息附加参数_第9张图片

 Windows --- 常用消息以及消息附加参数_第10张图片

或者直接输入

按 F10 单步调试后

IPCreateParams 创建窗口时需要传递的信息 NULL:没有要传递的,如果传入某个值,那个值就被传到 IPCreateParams,注意传的是指针

 Windows --- 常用消息以及消息附加参数_第11张图片

检查窗口类型名,注意每一个应用程序都有一个窗口类型名

为什么要有窗口类型名?

任何一个窗口都有一个窗口类型名→ 检查窗口类型名

spy++:一个是 32位,一个是 64位

 Windows --- 常用消息以及消息附加参数_第12张图片

Windows --- 常用消息以及消息附加参数_第13张图片

点击查找窗口,按住鼠标移动到想要检查的窗口即可

Windows --- 常用消息以及消息附加参数_第14张图片

CreateWindow 中最后一个参数 lParam,int 类型强制转换为指针类型

HWND hWnd = CreateWindow(
    szAppClassName,                                                   //注册窗口的类型名
    szWindowName,                                                     //窗口的标题
    WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINMIZEBOX,         //窗口的风格 标题栏|系统菜单
    200,                                                              //窗口距离屏幕左上角横坐标
    200,                                                              //窗口距离屏幕左上角纵坐标
    800,                                                              //窗口的宽度
    600,                                                              //窗口的高度
    NULL,                                                             //父窗口句柄
    NULL,                                                             //菜单句柄
    hInstance,                                                        //应用程序实例句柄
    (LPVOID)10                                                        //创建窗口时需要传递的信息 NULL:没有要传递的 
);

typedef void far            *LPVOID;
#define far

Windows --- 常用消息以及消息附加参数_第15张图片

 Windows --- 常用消息以及消息附加参数_第16张图片

很多需要初始化的东西都可以放在 WM_CREATE 中

 else  
        { 
            break;  

        }

//如果不想自己处理、处理不了. . . 调用这个函数就交给操作系统处理
无论是否点了退出,最终都会执行这条语句:return DefWindowProc(hWnd,uMsg,wParam,lParam);

点击是

Windows --- 常用消息以及消息附加参数_第17张图片

 Windows --- 常用消息以及消息附加参数_第18张图片

 Windows --- 常用消息以及消息附加参数_第19张图片

点击否,窗口也被关闭

Windows --- 常用消息以及消息附加参数_第20张图片

Windows --- 常用消息以及消息附加参数_第21张图片

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //窗口关闭消息
    case WM_CLOSE:
        if(IDYES == MessageBox(NULL,L"您确定要退出吗?",L"提示",MB_YESNO))
        {
            //销毁当前处理的窗口句柄-> 发出 WM_DESTROY 信息
            DestroyWindow(hWnd);
        }
        else  
        {   //如果不执行break
            break;
        }
        break;
    //窗口销毁消息
    case WM_DESTROY:
        //发出一个退出消息 WM_QUIT-> 传入0正常退出
        PostQuitMessage(0);
        break;
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

能不能让它不处理,不想让它调用 DefWindowProc?

WM_CLOSE消息 (Winuser.h) - Win32 apps | Microsoft Docs

在关闭窗口时,不需要传递任何值

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //窗口关闭消息
    case WM_CLOSE:
        if(IDYES == MessageBox(NULL,L"您确定要退出吗?",L"提示",MB_YESNO))
        {
            //销毁当前处理的窗口句柄-> 发出 WM_DESTROY 信息
            DestroyWindow(hWnd);
        }
        else  
        {
            //点击否 最小化
            ShowWindow(hWnd,SW_MINIMIZE);
            //点击否 隐藏运行|托盘
            ShowWindow(hWnd,SW_HIDE);
            return 1;                 //我已经处理了,不需要你再处理了
            //return 0;               //我没有处理,你再处理,但是我没有交给操作系统默认处理函数处理
        }
        break;
    //窗口销毁消息
    case WM_DESTROY: 
        //主要做一些清理工作、保存数据-> 凡是程序走到这个地方程序不能还原 不能再显示窗口
        ShowWindow(hWnd,SW_MINIMIZE);
        return 1;
        //发出一个退出消息 WM_QUIT-> 传入 0 正常退出
        PostQuitMessage(0);
        break;
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

Windows --- 常用消息以及消息附加参数_第22张图片

Windows --- 常用消息以及消息附加参数_第23张图片

你可能感兴趣的