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

接:Windows --- 常用消息以及消息附加参数_小雪菜本菜的博客-CSDN博客_windows 常用消息

如果处理了,一般情况下返回值要返回 0,如果 return 0;都将会交给系统,最终系统还会给你处理一遍(不管你是怎么处理的)

你处理的它会给你显示,你处理完之后,系统内部可能还有一些其他情况要处理

一般处理完后必须 return 0;系统还会给你处理

如果 return1;告诉系统你已经处理了,系统不会给你再处理

直接 return 0;也会调用系统的默认处理:关闭的过程中,没有调用 DestroyWindow 发出 WM_DESTROY 信息,系统会帮你自动调用

PostQuitMessage(0);发出一个退出消息 WM_QUIT→  传入 0 正常退出

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);
            //最终系统都会给你处理一遍
            return 0;
        }
        else  
        {   //如果不执行break
            break;
        }
        break;
    //窗口销毁消息
    case WM_DESTROY:
        //发出一个退出消息 WM_QUIT-> 传入0正常退出
        PostQuitMessage(0);
        break;
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

没有发出 WM_QUIT 消息,窗口销毁了,但是程序进程没有退出

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);
            //最终系统都会给你处理一遍
            return 0;
        }
        else  
        {   //如果不执行break
            break;
        }
        break;
    //窗口销毁消息
    case WM_DESTROY:
        //我已经处理了,不需要你再处理了 导致下面没有发出 WM_QUIT 消息
        return 1;
        //发出一个退出消息 WM_QUIT-> 传入0正常退出 要让程序退出必须调用 PostQuitMessage(0)
        PostQuitMessage(0);
        break;
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

鼠标点击消息

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //鼠标左键按下
    case WM_LBUTTONDOWN:
    {
        SetWindowText(hWnd,L"鼠标左键按下了");    
        break;
    }
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //鼠标左键按下
    case WM_LBUTTONDOWN:
    {
        //字符串
        wchar_t szText[100] = {0};
        //注意不能用等号的方式:应该用& 由于按下的时候,可能同时按下几个键:按ctrl、shift键...
        //鼠标左键按下 + Ctrl键
        if(wParam & MK_CONTROL)
        {
            //窄字符:strcat
            //宽字符:wcscat
            wcscat(szText,L"鼠标左键+Ctrl键按下");
        }
        //SetWindowText(hWnd,szText);    

        //鼠标左键按下 + Shift键
        if(wParam & MK_SHIFT)
        {
            wcscat(szText,L"鼠标左键+Shift键按下");
        }
        //鼠标左键按下
        if(wParam & MK_LBUTTON)
        {
            wcscat(szText,L"鼠标左键按下");
        }
        //鼠标右键按下
        if(wParam & MK_RBUTTON)
        {
            wcscat(szText,L"鼠标右键按下");
        }
        //鼠标中键按下
        if(wParam & MK_MBUTTON)
        {
            wcscat(szText,L"鼠标中键按下");
        }
        SetWindowText(hWnd,szText);    
        break;
    }
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

如果 Ctrl 键和 Shift 键都按下,那么两个都有

注意:左键按下只有一瞬间,应该先按下右键 / 中间键,再按下左键,否则出不来

 

按下和抬起是一个连续的过程,有按下就有一个抬起(除非你不抬起)

wParam:按键的状态值

  lParam:鼠标的坐标值

注意:需要包含头文件 <Windowsx.h>

#include <Windowsx.h>

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //鼠标左键按下
    case WM_LBUTTONDOWN:
    {
        int x = GET_X_LPARAM(Iparam);
        int y = GET_Y_LPARAM(Iparam);
        //字符串
        wchar_t szText[100] = {0};
        //格式化
        wsprintf(szText,"当前鼠标坐标:(%d,%d)",x,y);
        break;
    }
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

鼠标的坐标系是一个客户区坐标系

当然,除此之外还有一个宏不用包含头文件 <Windowsx.h>:低位字 LOWORD,高位字 HIWORD

int x = LOWORD(Iparam);
int y = HIWORD(Iparam);

#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))
#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))

高位和低位的实质是移位操作

低位字代表 x 坐标、高位字代表 y 坐标

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

鼠标左键抬起:WM_LBUTTONUP

鼠标右键按下:WM_RBUTTONDOWN

鼠标右键抬起:WM_RBUTTONUP

和鼠标左键按下基本是一样的,这里不再演示

鼠标移动消息

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //鼠标移动消息
    case WM_MOUSEMOVE:
    {
        //使用方式与鼠标左键按下基本是一样的,这里不再演示
        break;
    }
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

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

键盘消息

wParam:虚拟键值

lParam:包含了一个 32 位的按键的其他信息(按下还是抬起. . .

0 ~ 15位:响应当前重复的次数、你按了几次

16 ~23位:键盘的扫描码,由键盘的产商决定,生产商给你设定的一个值,不需要考虑

24位:拓展键:ALT 键、CTRL 键,如果按下拓展键,值为 1,如果没按拓展键,值为 0

25 ~ 28位:保留,没有使用

29位:上下文代号,经常用于判断是否按下 Alt 键,如果按下,值就是 1,没有按下,值就是 0

30位:当前按键的状态值,如果在按下这个键之前,再次被发送了这个消息,这个值就是 1,否则就是 0

31位:表示状态的变化,在原来没有按下之前,如果正在按下,这个值就是 0,如果没有按下,这个值就是 1

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //键盘按下
    case WM_KEYDOWN:
    {
        switch(wParam)
        {
        //回车
        case VK_RETURN:
                MessageBox(hWnd,"按下了回车符",L"提示",MB_OK);
                break;
        //空格
        case VK_SPACE:
                SetWindowText(hWnd,L"按下了空格键");
                break;
        //按下ESC键
        case VK_ESCAPE:
                SetWindowText(hWnd,L"按下了ESC键");
                break;
        //按下SHIFT键
        case VK_SHIFT:
                SetWindowText(hWnd,L"按下了Shift键");
                break;
        //按下F1键
        case VK_F1:
                SetWindowText(hWnd,L"按下了F1键");
                break;
        //注意按下字母键的区别
        //按下A键
        case 0x41:
                SetWindowText(hWnd,L"按下了A键");
                break;
        //数字分为字母上边的数字和小键盘的数字
   
        //按下数字0 字母上边的数字
        case 0x30:
                SetWindowText(hWnd,L"按下了字母上边数字0键");
                break;
        //按下数字0 小键盘的数字
        case VK_NUMPAD0:
                SetWindowText(hWnd,L"按下了小键盘数字0键");
                break;
        }
        break;
    }
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

下面给出虚拟键码:

虚拟键码 (Winuser.h) - Win32 apps | Microsoft Docs

WM_KEYDOWN 只能截获你当前按下的一个按键

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
     //键盘按下
    case WM_KEYDOWN:
    {
        switch(wParam)
        {
        	if (wParam == VK_F3)
		{
			SetWindowText(hWnd, L"按了F3");
		}
		if (((lParam >> 24) & 1) == 1)
		{
			SetWindowText(hWnd, L"按了Ctrl");
		}
        break;   
    }
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

WM_SYSKEYDOWN 系统按键:都是截获同一瞬间、同一时刻的按键,按哪个键就发出哪个键,不能出现组合键,和 WM_KEYDOWN 一样

WM_KEYUP:键盘按键抬起(和按键按下是一样的,什么按键按下,什么按键抬起)

字符消息

TranslateMessage(&msg) 将按下和抬起组合形成 WM_CHAR,如果把这段代码去掉就不会形成 WM_CHAR

大写字母、小写字母、数字. . .

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
     //字符消息
    case WM_CHAR:
    {
        //想知道它按下什么键
        //需要格式化
        wchar_t szText[50];
        wsprintf(szText,L"字符:%c",(char)wParam);
        SetWindowText(hWnd, szText);
        break;  
    }      
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

MSG msg;
//不断从消息队列中获取消息,把获取到的消息保存到 GetMessage
//消息编号是一个编号 0,1,2,3...一般所有消息都要获取
while(GetMessage(&msg,NULL,0,0))
{
    //将虚拟键消息转为字符消息
    //当在键盘上按下某个字符,比如按下A,产生按下消息和抬起消息,把这两个消息转为字母 A 需要通过以下函数
    TranslateMessage(&msg);
    //将虚拟键消息分发给窗口处理函数
    DispatchMessage(&msg);
}

绘图消息

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    { 
    //绘图消息
    case WM_PAINT:
	{	
        //绘图结构体
		PAINTSTRUCT ps;
        //开启绘图 要画哪个窗口把窗口句柄拿过来
		HDC hDC = BeginPaint(hWnd, &ps);

		//绘图的过程
		//绘制矩形和正方形
        //Rectangle(hDC, 20, 20, 100, 60);//80 * 40
		Rectangle(hDC, 20, 20, 100, 100); //80 * 80

		//绘制圆和椭圆 矩形的内切圆
        //Ellipse(hDC, 20, 20, 100, 60);
		Ellipse(hDC, 20, 20, 100, 100);

		//输出文字
		wchar_t szText[100]=L"你好,Baby"; 
        //位置 第5个参数是字符的长度
		TextOut(hDC, 200, 100, szText, wcslen(szText));
        //结束绘图 释放ps
		EndPaint(hWnd, &ps);
		break;
	}
    }
    //调用操作系统默认窗口处理函数
    //如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值