[SDK]-键盘消息和鼠标消息

前言

各位师傅大家好,我是qmx_07,今天给大家讲解键盘消息和鼠标消息,下一节讲解控件的相关知识点

键盘消息

  • 应用程序从windows接收的关于键盘事件的消息分为击键字符两种
  • windows再发送击键消息的同时 还会发送字符消息
  • Shift、ctrl、alt、光标移动键盘,这些键值只会产生击键消息

系统按键与非系统按键

当键盘按下时,windows会将消息送到消息队列

  • SYS 代表系统,表示这个按键 对于应用程序来讲,更加重要
  • 比如说 ALT+F4 关闭应用程序,ALT+TAB 换页,程序通常忽略WM_SYSKEYUP和WM_SYSKEYDOWN消息,并将它们传送到DefWindowProc。
  • 由于Windows要处理所有Alt键的功能,所以不需要进行拦截消息
  • WM_KEYDOWN和WM_KEYUP消息通常是在按下或者释放不带Alt键的键时产生的

虚拟键码

  • 虚拟键码保存在WM_KEYDOWN,WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP消息的wParam参数中,该参数标识了按下或释放的键

获取键盘消息

c 复制代码
LRESULT CALLBACK WndProc(
HWND hWnd,//窗口句柄
UINT message,//消息ID
WPARAM wParam, //虚拟码
LPARAM lParam)//键盘发过来的原始数据,转换为虚拟码

位移状态

  • SHORT FLAG = GetKeyState (VK_SHIFT) & 0x8000; 如果按下了键盘按钮,则这个值为负,& 0x8000 会让系统更加稳定,减少出错

获取键盘消息

c 复制代码
    case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_F1:
        {
            SHORT Flag = (GetKeyState(VK_SHIFT) & 0x8000);//判断SHIFT是否按下
            if (Flag < 0)
            {
                MessageBox(NULL, L"SHIFT + F1", L"Msg", MB_OK);//SHIFT + F1同时按下
            }
            else
            {
                MessageBox(NULL, L"F1", L"Msg", MB_OK);//F1按下
            }

            break;
        }

        default:
            break;
        }
        break;
    }
  • 通过GetKeyState()函数的方式,捕获多个按键消息

通过SendMessage()获取键盘消息

c 复制代码
SendMessage(
    _In_ HWND hWnd,//窗口句柄
    _In_ UINT Msg,//消息 也就是到那个地方去处理
    _Pre_maybenull_ _Post_valid_ WPARAM wParam,//按下的按钮
    _Pre_maybenull_ _Post_valid_ LPARAM lParam);

我们也可以通过按下其他按键来向窗口模拟对应内容,比如说 我们想要通过按下F2,对应F1的按键内容

c 复制代码
    case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_F1:
        {
            SHORT Flag = (GetKeyState(VK_SHIFT) & 0x8000);
            if (Flag < 0)
            {
                MessageBox(NULL, L"SHIFT + F1", L"Msg", MB_OK);
            }
            else
            {
                MessageBox(NULL, L"F1", L"Msg", MB_OK);
            }

            break;
        }
        case VK_F2:
        {
            SendMessage(hWnd,WM_KEYDOWN, VK_F1, NULL);
            break;
        }
        default:
            break;
        }
        break;
    }
    

通过SendMessage()获取其他ID消息

c 复制代码
 case WM_KEYDOWN:
    {
        switch (wParam)
        {
        case VK_F1:
        {
            SHORT Flag = (GetKeyState(VK_SHIFT) & 0x8000);
            if (Flag < 0)
            {
                MessageBox(NULL, L"SHIFT + F1", L"Msg", MB_OK);
            }
            else
            {
                MessageBox(NULL, L"F1", L"Msg", MB_OK);
            }

            break;
        }
        case VK_F2:
        {
            SendMessage(hWnd,0x12138, 9999, NULL);
            break;
        }
        default:
            break;
        }
        break;
    }
    case 0x12138:
    {
        switch (wParam)
        {
        case 9999:
        {
            MessageBox(NULL, L"MyMsg", L"Msg", MB_OK);
            break;
        }
        default:
            break;

        }
    }
  • SendMessage函数,也可以向其他消息ID发送消息请求,来触发处理程序

FindWindow()函数 讲解

c 复制代码
FindWindowW(
    _In_opt_ LPCWSTR lpClassName,//窗口类名
    _In_opt_ LPCWSTR lpWindowName);//窗口标题
  • 用于在系统中查找具有指定类名和窗口名的顶级窗口


    通过 FindWindow()函数来获取句柄,触发消息
c 复制代码
        case VK_F2:
        {
            HWND class_hwnd = FindWindow(L"qmx_07", NULL);
            HWND title_hwnd = FindWindow(NULL,L"demo");
            SendMessage(class_hwnd, WM_KEYDOWN, VK_F1, NULL);
            SendMessage(title_hwnd, 0x12138, 9999, NULL);
            break;
        }

鼠标消息

概念

  • 三种状态:单击、双击、拖动
  • 三个按钮:左键(LBUTTON)、右键(RBUTTON)、中键(MBUTTON)

1Param的结构解析

  • 低16位存储X坐标:这部分数据表示鼠标光标的X轴位置。
  • 高16位存储Y坐标:这部分数据表示鼠标光标的Y轴位置

宏的使用

  • LOWORD宏提取X坐标
  • HIWORD宏提取Y坐标

通过1Param参数,可以实时获取鼠标位置

wParam的含义

  • 鼠标键状态标识:wParam用来标识鼠标键的状态,例如MK_LBUTTON代表鼠标左键

代码案例

通过鼠标 画线段

c 复制代码
POINT Pos[2] = { 0 };
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_LBUTTONDOWN://获取起点的坐标位置
    {

        Pos[0].x = LOWORD(lParam);
        Pos[0].y = HIWORD(lParam);
        break;
    }
    case WM_LBUTTONUP://获取终点的坐标位置画图
    {
        
        Pos[1].x = LOWORD(lParam);
        Pos[1].y = HIWORD(lParam);
        HDC hDC = GetDC(hWnd);
        HPEN hpen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0));
        SelectObject(hDC, hpen);
        POINT pi = { 0 };
        MoveToEx(hDC, Pos[0].x, Pos[0].y, &pi);
        LineTo(hDC, Pos[1].x, Pos[1].y);
        ReleaseDC(hWnd, hDC);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

画面演示:

  • 通过WM_LBUTTONDOWN 获取鼠标按下的位置,再通过WM_LBUTTONUP获取鼠标抬起的位置,就可以画出线段

通过 WM_MOUSEMOVE 按住鼠标左键 自由绘制图形

c 复制代码
    case WM_LBUTTONDOWN:
    {


        break;
    }
    case WM_LBUTTONUP:
    {
        
        break;
    }
    case WM_MOUSEMOVE:
    {
        if (wParam & WM_LBUTTONDOWN)
        {
            int nPosX = LOWORD(lParam);
            int nPosY = HIWORD(lParam);
            HDC hDC = GetDC(hWnd);
            HPEN hpen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0));
            SelectObject(hDC, hpen);
            POINT pi = { 0 };
            MoveToEx(hDC, nPosX, nPosY, &pi);
            LineTo(hDC, nPosX, nPosY);
            ReleaseDC(hWnd, hDC);
        }
        break;
    }

画图演示:

通过鼠标左键按住滑动 绘制图形

总结

学习了键盘消息和鼠标消息的原理和使用,下一章节我们学习控件的相关知识

相关推荐
C嘎嘎嵌入式开发2 小时前
(13)100天python从入门到拿捏《目录操作》
windows·python·microsoft
爱隐身的官人4 小时前
PWN环境配置
windows·pwn·ctf
非凡ghost1 天前
猫眼浏览器(Chrome内核增强版浏览器)官方便携版
前端·网络·chrome·windows·软件需求
熊文豪1 天前
Windows安装RabbitMQ保姆级教程
windows·分布式·rabbitmq·安装rabbitmq
搬砖的小码农_Sky1 天前
Windows操作系统上`ping`命令的用法详解
运维·网络·windows
Kiri霧1 天前
Rust模式匹配详解
开发语言·windows·rust
程序设计实验室2 天前
使用命令行删除 Windows 网络映射驱动器
windows
用户31187945592182 天前
Windows 电脑安装 XTerminal 1.25.1 x64 版(带安装包下载关键词)
windows
Logintern092 天前
windows如何设置mongodb的副本集
数据库·windows·mongodb
Chandler242 天前
一图掌握 操作系统 核心要点
linux·windows·后端·系统