[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;
    }

画图演示:

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

总结

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

相关推荐
女程序猿!!!2 小时前
视频分辨率
windows
不讲废话的小白3 小时前
文件拖不进企微了怎么办
windows·企微
聪明努力的积极向上3 小时前
【.net framework】WINDOWS服务和控制台程序简单介绍
windows·.net
程序员霸哥哥7 小时前
snipaste免费版下载安装使用教程(附安装包)
windows·microsoft·snipaste
程序员霸哥哥8 小时前
Keil5下载教程及安装教程(附安装包)
windows·keil5·keil5下载教程·keil5安装教程
AI大模型学徒8 小时前
Chatbox 安装 for Windows
windows·语言模型·chatgpt
千里马学框架11 小时前
windows系统上aosp15上winscope离线html如何使用?
android·windows·html·framework·安卓窗口系统·winscope
2501_9389639611 小时前
Flutter 3.19 桌面应用开发:适配 Windows/macOS 端窗口大小与菜单栏自定义
windows·flutter·macos
G311354227311 小时前
云服务器系统 选择Windows和Linux的理由
linux·服务器·windows
龙须草AI笔记13 小时前
N8N系列:新手课程,本地 N8N 不安全?Windows 下 HTTPS 配置指南,新手也能看懂
windows·安全·https·入门教程·ai技术·ai工具·n8n