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

news2024/9/23 21:26:05

前言

各位师傅大家好,我是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参数中,该参数标识了按下或释放的键

获取键盘消息

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

位移状态

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

获取键盘消息

    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()获取键盘消息

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

我们也可以通过按下其他按键来向窗口模拟对应内容,比如说 我们想要通过按下F2,对应F1的按键内容
在这里插入图片描述

    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消息

 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()函数 讲解

FindWindowW(
    _In_opt_ LPCWSTR lpClassName,//窗口类名
    _In_opt_ LPCWSTR lpWindowName);//窗口标题
  • 用于在系统中查找具有指定类名和窗口名的顶级窗口
    在这里插入图片描述
    在这里插入图片描述
    通过 FindWindow()函数来获取句柄,触发消息
        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代表鼠标左键

代码案例

通过鼠标 画线段

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 按住鼠标左键 自由绘制图形

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

画图演示:
在这里插入图片描述
通过鼠标左键按住滑动 绘制图形

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】string讲解

一、string的理解 我们可以把string看作一个更高级用类实现的char* 。或者直接叫他字符串类型&#xff0c;一听就是定义字符串的。 二、string的使用 用法就和int、char 类型一样&#xff0c;而且功能比他们强大很多。 三、string的功能 只列举常用功能 1、通过“[]”访问…

日撸Java三百行(day26:栈实现二叉树深度遍历之前后序遍历)

目录 一、栈实现前序遍历 二、栈实现后序遍历 三、完整的程序代码 总结 一、栈实现前序遍历 先来看看我们之前写的用递归实现前序遍历的程序代码&#xff1a; /************************ Pre-order visit.**********************/public void preOrderVisit() {System.out…

Simple RPC - 06 从零开始设计一个服务端(上)_注册中心的实现

文章目录 Pre核心内容服务端结构概述注册中心的实现1. 注册中心的架构2. 面向接口编程的设计3. 注册中心的接口设计4. SPI机制的应用 5. 小结 Pre Simple RPC - 01 框架原理及总体架构初探 Simple RPC - 02 通用高性能序列化和反序列化设计与实现 Simple RPC - 03 借助Netty…

【与C++的邂逅】--- 类和对象(上)

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 与C的邂逅 本篇博客将讲解C中的类和对象&#xff0c;C是面向对象的语言&#xff0c;面向对象三大特性是封装,继承,多态。学习类和对象&#xff0c;我们可…

Adobe Dimension DN v4.0.2 解锁版下载和安装教程 (专业的三维3D建模工具)

前言 Adobe Dimension&#xff08;简称DN&#xff09;是一款3D设计软件&#xff0c;三维合成和渲染工具&#xff0c;2D平面的二维转为3D立体的三维合成工具&#xff0c;用于3Dmax\C4D\MAYA等三维软件生成的效果图&#xff0c;在3D场景中排列对象、图形和光照。3D应用程序使用的…

Nginx实验

编译安装 Nginx 准备rhel9环境 下载安装包nginx-1.24.0&#xff08;xftp&#xff09;/复制下载链接 &#xff08;nginx.org——>download&#xff09; 解压 [rootnginx nginx-1.24.0]# tar zxf nginx-1.24.0.tar.gz [rootnginx nginx-1.24.0]#tar zxf nginx-1.24.0.tar.…

yolov8安装教程

一、资源下载 1.下载YOLOv8代码 github:YOLOv8-github gitee:YOLOv8-gitee&#xff08;推荐使用国内的gitee&#xff09; 2.conda、cuda 如果没有安装conda&#xff0c;按照流程安装好conda&#xff0c;还要下载好符合自己电脑版本的CUDA 后续会用。 二、创建conda虚拟环…

C语言典型例题43

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题3.3 有一个函数&#xff1a;y{x,x<1;2x-1,1≤x≤10;3x-11,x≥10。写程序&#xff0c;输入x&#xff0c;输出y。 代码&#xff1a; //《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 //习题3.3…

OD C卷 - 传递悄悄话

传递悄悄话 &#xff08;100&#xff09; 给定一个二叉树&#xff0c;节点采用顺序存储&#xff0c;如 i0 表示根节点&#xff0c;2i 1 表示左子树根&#xff0c;2i 2 表示右子树根;每个节点站一个人&#xff0c;节点数值表示由父节点到该节点传递消息需要的时间&#xff1b…

周末休整

我写的东西&#xff0c;不爱看的人可以不看&#xff0c;我是给喜欢我的人写的&#xff0c;不喜欢我的人&#xff0c;我也讨厌她。 今天故意写点教人学坏的东西&#xff0c;因为以前写了很多正能量的东西&#xff0c;虽然阅读量还可以&#xff0c;但当见面聊天之后&#xff0c;…

【CSS】CSS新单位vmin和vmax

通过vmin单位可以自动取视口宽度和高度中较小的那个值&#xff0c;vmax同理。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1…

百度智能云通用文字识别(标准版)- java.lang.NoSuchFieldError: Companion

需求环境 ORC识别图片信息 参考百度示例 百度智能云API文档通用文字识别 官方示例 package baidu.com;import okhttp3.*; import org.json.JSONObject;import java.io.*;/*** 需要添加依赖* <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->…

8.16-ansible的应用

ansible ansible是基于模块工作的&#xff0c;本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块&#xff0c;ansible只是提供一种框架。 格式 ansible 主机ip|域名|组名|别名 -m ping|copy|... 参数 1.ping模块 m0 # 查看有没有安装epel ​ [rootm0 ~]#…

在vue3中配置scss

要在 Vue 3 中使用 SCSS&#xff08;Sass 的一个子集&#xff09;&#xff0c;你需要安装相应的依赖&#xff0c;并对项目进行一些配置。下面是详细的步骤&#xff1a; 步骤 1: 安装依赖 首先&#xff0c;你需要安装 sass 和 vue-loader&#xff08;如果你使用的是 Vue CLI&a…

vue 2.x + @vue/cli 4.x开发阶段使用Vite

项目用的是vue 2.x vue/cli 4.x(webpack 4.x)。冷启动项目时耗时较长&#xff0c;达到了2分钟以上。热更新时间也达到了10s以上。严重影响了开发体验和效率。 解决问题的过程中遵循2个原则&#xff1a; 不对会影响原构建流程的代码进行改动&#xff0c;向原Webpack构建兼容。…

加密创投周期进化论:未来或黯淡,但流动性是那道光

加密创投领域的风起云涌&#xff0c;而在2022年后&#xff0c;加密市场逐渐进入“行业阵痛期”&#xff0c;面对熊市的寒冬&#xff0c;整个行业的流动性急剧减少&#xff0c;市场的发展被迫寄希望于“板块轮动”的交替炒作。尽管如此&#xff0c;比特币生态和L2生态的兴起&…

树莓派开发笔记03-树莓派的GPIO口输入检测

github主页&#xff1a;https://github.com/snqx-lqh gitee主页&#xff1a;https://gitee.com/snqx-lqh 本项目github地址&#xff1a;https://github.com/snqx-lqh/RaspberryPiLearningNotes 本项目gitee地址&#xff1a;https://gitee.com/snqx-lqh/RaspberryPiLearningNote…

LLAMA 3.1 论文的见解

这有什么大不了的&#xff1f; LLAMA 3.1 的发布标志着 AI 开发的一个重要里程碑。开源模型首次接近领先的闭源模型的性能水平。这一转变预示着未来开源模型同样有效&#xff0c;任何人都可以灵活地修改和调整它们。马克扎克伯格将此与 Linux 的开源性质进行了比较&#xff0c;…

Mysql原理与调优-如何进行sql优化

1.绪论 本文主要讲解我们如何优化一个sql。优化的过程主要分为3个步骤&#xff0c;找到哪些sql需要被优化&#xff0c;这就需要用到慢sql日志。然后发现慢SQL为什么慢&#xff0c;即当前sql是如何执行的&#xff0c;这就需要用到执行计划。最后才是对sql进行优化&#xff0c;对…

作业帮 TiDB 7.5.x 使用经验

作者&#xff1a; 是我的海 原文来源&#xff1a; https://tidb.net/blog/5f9784d3 近期在使用 TiDB 时遇到的一些小问题的梳理总结&#xff0c;大部分版本都在6.5.6和7.5.2 1、limit 导致的扫描量过大的优化 研发定时任务每天需要扫描大量数据&#xff0c;到时机器网卡被…