Windows SDK(四)鼠标和键盘消息处理
鼠标基础知识
鼠标一般分为三种状态,三个按钮
三种状态:单击,双击,拖动
三个按钮:左键(LBUTTON),右键(RBUTTON),中键(MBUTTON)
左键具有的消息
WM_LBUTTONDOWM 点击鼠标
WM_LBUTTONUP 抬起鼠标
WM_LBUTTONDBLCLK 双击鼠标,有时窗的不支持
右键具有的消息
WM_RBUTTONDOWM
WM_RBUTTONUP
WM_RBUTTONDBLCLK(双击,有时窗口不支持)
中键具有的消息
WM_MBUTTONDOWM
WM_MBUTTONUP
WM_MBUTTONDBLCLK(双击,有时窗口不支持)
直接通过messsage进行分发的消息一般是WM开头,也叫顶层消息,如上消息都是顶层消息
lParam,32位大小,低16位存储x坐标,高16位存储y坐标,用于存储鼠标目前的坐标信息
wParam,32位大小,用于存储系统键盘或鼠标输入的消息
键盘基础知识
顶级窗口:存在多个窗口时,在最上面的窗口
焦点:鼠标点击窗口后,只有该窗口可以被执行各种操作,如键盘发送的消息只会发送到有焦点的
窗口,鼠标点击处叫做焦点
键盘消息的发送:点击键盘时,系统将对应的硬件扫描码格式化成消息,发送到操作系统的消息队
列中,由操作系统进行消息的初步存储,当应用完成上一次消息的处理后,系统将会从消息队列中
抽取消息分发到应用程序进行翻译处理
我们可以自行操作的键盘消息有四种,可以分为以下两种类型:
非系统按键:
WM_KEYDOWN:按键按下去的消息
WM_KEYUP:按键抬起来的消息
当按键按下去不放时,系统认为有很多个按下去的消息发送给操作系统,但此时抬起来时,只会有
一次抬起来的消息发送给操作系统
GetMessageTime:获取上次消息时间
系统按键:
WM_SYSKEYDOWN
WM_SYSKEYUP
如ALT+TAB:页面切换,ALT+F4:关闭窗口,诸如此类ALT按键+,都属于系统按键
如果使用系统按键,应用程序会跳过安全消息,直接把该消息交给默认处理程序:
DefWindowProc进行转发,由Windows进行默认处理,应用程序不对该消息进行处理
每个按键都有相应的虚拟键码对应,用于表示按键动作
wParam 可以与鼠标或键盘的输入的状态作为参数结合,用于判断是否同时多种行为同时进行,这
些参数如下显示,都是以MK_ 前缀:
MK_LBUTTON : 左键按下
MK_MBUTTON : 中键按下
MK_RBUTTON: 右键按下
MK_SHIFT : Shift键按下
MK_CONTROL : Ctrl键按下
应用如下:在点击鼠标左键时
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_LBUTTONDOWN 用于接收系统鼠标消息,此处左键按下
{
if(wParam & MK_SHIFT) 指在左键点击的前提下,shift键按下
{
MessageBox(NULL, L"MK_SHIFT + LBUTTON", L"Msg", MB_OK);
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
获取窗口句柄的两种方式:
方式一,用类名寻找窗口:
HWND hMyHWnd = FindWindow(L"rkvir", NULL); 参数依次 窗口类名 标题名,
返回值是窗口句柄
方式二,用标题名寻找窗口:
HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");
鼠标点击画点
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下
{
int nPosX = LOWORD(lParam);
int nPosY = HIWORD(lParam); 获取鼠标点击处的xy坐标
HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");访问一个外部的窗口
HDC hDC = GetDC(hMyHWnd); 获取窗口句柄
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(hMyHWnd, hDC); 释放设备上下文
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
鼠标点击划线
鼠标点击某处,再移动到其他处,松开鼠标,出现一条线
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下
{
Pos[0].x = LOWORD(lParam);
Pos[0].y = HIWORD(lParam); 保存第一个点xy坐标
break;
}
case WM_LBUTTONUP: 鼠标抬起时绘制
{
Pos[1].x = LOWORD(lParam);
Pos[1].y = HIWORD(lParam); 保存第二个点
HWND hMyHWnd = FindWindow(NULL, L"GrkDemo"); 此处是在一起其他的窗口处
HDC hDC = GetDC(hMyHWnd);
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); 画笔移至结束位置
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
鼠标点击画矩形
鼠标点击某处,再移动到其他点,松开鼠标,出现一个矩形
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下
{
Pos[0].x = LOWORD(lParam);
Pos[0].y = HIWORD(lParam); 保存第一个点xy坐标
break;
}
case WM_LBUTTONUP: 鼠标抬起时绘制
{
Pos[1].x = LOWORD(lParam);
Pos[1].y = HIWORD(lParam); 保存第二个点
HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");
HDC hDC = GetDC(hMyHWnd);
HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0));
SelectObject(hDC, hPen);
Rectangle(hDC, Pos[0].x, Pos[0].y, Pos[1].x, Pos[1].y);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
鼠标点击画圆
鼠标点击某处,再移动到其他点,松开鼠标,出现一个圆
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下
{
Pos[0].x = LOWORD(lParam);
Pos[0].y = HIWORD(lParam); 保存第一个点xy坐标
break;
}
case WM_LBUTTONUP: 鼠标抬起时绘制
{
Pos[1].x = LOWORD(lParam);
Pos[1].y = HIWORD(lParam); 保存第二个点
HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");
HDC hDC = GetDC(hMyHWnd);
HPEN hPen = CreatePen(PS_SOLID, 8, RGB(255, 0, 0));
SelectObject(hDC, hPen);
Arc(hDC, Pos[0].x, Pos[0].y, Pos[1].x, Pos[1].y, 350, 350, 350, 350);
ReleaseDC(hMyHWnd, hDC);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
鼠标点击移动画圆
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_LBUTTONDOWN: 用于接收系统鼠标消息,此处左键按下
{
Pos[0].x = LOWORD(lParam);
Pos[0].y = HIWORD(lParam); 保存第一个点xy坐标
break;
}
case WM_MOUSEMOVE: 鼠标滑动
{
if (wParam & WM_LBUTTONDOWN) 滑动的同时按住左键
{
int nPosX = LOWORD(lParam);
int nPosY = HIWORD(lParam);
HWND hMyHWnd = FindWindow(NULL, L"GrkDemo");
HDC hDC = GetDC(hMyHWnd);
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(hMyHWnd, hDC);
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
键盘的应用
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_KEYDOWN 用于接收系统键盘消息
{
switch (wParam) 传入按键信息
{组合键
case VK_F1: 按下按键F1
{
SHORT bFlag = (getKeyState(VK_SHIFT) & 0x8000); 判断是否同时按下shift键,此处加上&0x8000,可以屏蔽其他无关状态
if(bFlag < 0) 如果获取短整数小于0,说明shift键被按到
{
MessageBox(NULL, L"F1 + SHIFT", L"Msg", MB_OK); 生成一个窗口
}
else
{
MessageBox(NULL, L"F1", L"Msg", MB_OK); 生成一个窗口
}
break;
}
case VK_F2: 按下F2,如果想要触发按下F1的消息:
{
SendMessage(hWnd, WM_KEYDOWN, VK_F1, NULL); 发送消息到某窗口 参数依次 要发
送到的窗口的句柄 发送的消息 两个附加消息,如主消息的内部各种选择,一般写NULL。该函数不
仅可以发送给自己的窗口,也可以是别的窗口,此处是发送给别的窗口。此时窗口按下F2,会触
发按下F1的指令
SendMessage(hWnd, 0x12138, 9999, NULL); 按下F2,触发0x12138的指令
break;
}
case 'B':
case 'b': 该方式可以设置按到两种不同按键时,都可以同一种操作
{
MessageBox(NULL, L"B/b", L"Msg", MB_OK); 生成一个窗口
break;
}
case 0x12138: 接收一个自定义消息
{
switch (wParam)
{
case 9999:
{
MessageBox(NULL, L"MyMsg", L"Msg", MB_OK);
break;
}
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
按钮绘制
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps; 创建一个包含窗口信息的结构体
HDC hdc = BeginPaint(hWnd, &ps);
HFONT hFont = CreateFont(20, 10, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, L"宋体"); 创建一个字体
SelectObject(hdc, hFont); 选择应用该字体
SetBkMode(hdc, TRANSPARENT); 设置背景色
RECT rect; 获取位置
SetRect(&rect, 30, 50, 400, 200);设置x30y50位置
SetTextColor(hdc, RGB(0, 0, 255)); 设置字体颜色
DrawText(hdc, L"蓝色", -1, &rect, DT_NOCLIP); 输出字体
SetRect(&rect, 30, 100, 400, 200);
SetTextColor(hdc, RGB(255, 0, 0));
DrawText(hdc, L"红色", -1, &rect, DT_NOCLIP);
HBRUSH hSolidBrushBlue = CreateSolidBrush(RGB(0, 0, 255));创建实心画刷
SelectObject(hdc, hSolidBrushBlue); 选择画刷
Rectangle(hdc, 90, 50, 120, 80); 绘制矩形
HBRUSH hSolidBrushRed = CreateSolidBrush(RGB(255, 0, 0));
SelectObject(hdc, hSolidBrushRed);
Rectangle(hdc, 90, 100, 120, 130);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
相关文章:
Windows SDK(四)鼠标和键盘消息处理
鼠标基础知识 鼠标一般分为三种状态,三个按钮 三种状态:单击,双击,拖动 三个按钮:左键(LBUTTON),右键(RBUTTON),中键(MBUTTON&…...
LabVIEW汽车自燃监测预警系统
LabVIEW汽车自燃监测预警系统 随着汽车行业的飞速发展,汽车安全问题日益受到公众的关注。其中,汽车自燃现象因其突发性和破坏性,成为一个不可忽视的安全隐患。为了有效预防和减少自燃事故的发生,提出了LabVIEW的汽车自燃监测预警…...
数据图表方案,企业视频生产数据可视化
在信息爆炸的时代,如何将复杂的数据转化为直观、生动的视觉信息,是企业在数字化转型中面临的挑战。美摄科技凭借其独特的数据图表方案,为企业在数据可视化领域打开了一扇全新的大门。 一、数据图表方案的优势 1、高效便捷:利用数…...
【HarmonyOS应用开发】APP应用的通知(十五)
相关介绍 通知旨在让用户以合适的方式及时获得有用的新消息,帮助用户高效地处理任务。应用可以通过通知接口发送通知消息,用户可以通过通知栏查看通知内容,也可以点击通知来打开应用,通知主要有以下使用场景: 显示接收…...
开启一个服务,将服务器指定的文件读取,传播到网上其他终端
from flask import Flask, render_template_string app Flask(__name__)app.route(/get-data) def get_data():# 读取data.txt文件的内容with open(r./2024/2/4/data.txt, r) as file:data file.read()print(data)# 返回数据的HTML表示return render_template_string(<div…...
nii convert to 2D image【python】
可以自己精简,我的label是二分类 import SimpleITK as sitk import cv2 from PIL import Image import numpy as np import nibabel as nib # nii格式一般都会用到这个包 import imageio # 转换成图像 import osimport numpy as np from scipy.ndimage import ro…...
C语言指针学习 之 指针是什么
前言 指针是C语言中一个重要概念,也是C语言的一个重要特色,正确而灵活地运用指针可以使程序简洁、紧凑、高效。每一个学习和使用C语言的人都应当深入的学习和掌握指针,也可以说不掌握指针就没有掌握C语言的精华。 一、什么是指针 想弄清楚什…...
【文本到上下文 #10】探索地平线:GPT 和 NLP 中大型语言模型的未来
一、说明 欢迎阅读我们【文本到上下文 #10】:此为最后一章。以我们之前对 BERT 和迁移学习的讨论为基础,将重点转移到更广阔的视角,包括语言模型的演变和未来,特别是生成式预训练转换器 (GPT) 及其在 NLP 中…...
(四)elasticsearch 源码之索引流程分析
https://www.cnblogs.com/darcy-yuan/p/17024341.html 1.概览 前面我们讨论了es是如何启动,本文研究下es是如何索引文档的。 下面是启动流程图,我们按照流程图的顺序依次描述。 其中主要类的关系如下: 2. 索引流程 (primary) 我们用postman发送请求&…...
飞天使-k8s知识点16-kubernetes实操1-pod
文章目录 深入Pod 创建Pod:配置文件详解写个pod的yaml 文件深入Pod 探针:探针技术详解 深入Pod 创建Pod:配置文件详解 资源清单参考链接:https://juejin.cn/post/6844904078909128712写个pod的yaml 文件 apiVersion: v1 kind: P…...
【gcc】webrtc发送侧 基于丢包更新码率
参考大神的分析1 rtt 有问题:网络拥堵,直接下调码率 G:\CDN\rtcCli\m98\src\modules\congestion_controller\goog_cc\send_side_bandwidth_estimation.hRttBasedBackoff RttBasedBackoff rtt_backoff_;class RttBasedBackoff {public:explicit RttBasedBackoff(const WebRtcK…...
数字经济的未来:探索Web3的商业模式
随着技术的不断演进,Web3正逐渐成为数字经济发展的关键驱动力之一。在这个数字时代,我们目睹着Web3为商业模式带来翻天覆地的变革,探索着数字经济未来的可能性。 1. 去中心化的商业生态 Web3以去中心化为核心理念,打破了传统商业…...
Centos7部署MetaBase-v0.48.3
MetaBase_v0.48.3下载地址 : http://downloads.metabase.com/v0.48.3/metabase.jar JDK11 下载地址:https://repo.huaweicloud.com/java/jdk/11.0.113/jdk-11.0.1_linux-x64_bin.tar.gz 1.不修改源数据库的方式 官方提示此方式仅用于测试学习使用,如用生…...
【计算机网络】Socket的SO_TIMEOUT与连接超时时间
SO_TIMEOUT选项是Socket的一个选项,用于设置读取数据的超时时间。它指定了在读取数据时等待的最长时间,如果在指定的时间内没有数据可读取,将抛出SocketTimeoutException异常。 SO_TIMEOUT的设置 默认情况下,SO_TIMEOUT选项的值…...
解密 ARMS 持续剖析:如何用一个全新视角洞察应用的性能瓶颈?
作者:饶子昊、杨龙 应用复杂度提升,根因定位困难重重 随着软件技术发展迭代,很多企业软件系统也逐步从单体应用向云原生微服务架构演进,一方面让应用实现高并发、易扩展、开发敏捷度高等效果,但另外一方面也让软件应…...
【OJ比赛日历】春节快乐 #02.10-02.16 #9场
CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 2024-02-10(周六) #4场比赛2024-02-11…...
前端下载文件有哪些方式
前端下载文件有哪些方式 在前端,最常见和最常用的文件下载方式是: 使用 标签的 download 属性: 创建一个 标签,并设置其 href 属性为文件的 URL,然后使用 download 属性指定下载的文件名。 这种方式简单直接&…...
vscode预览github上的markdown效果
需要安装的插件有: Github Markdown Preview Markdown Checkboxes Markdown Emoji Markdown footnotes Markdown Preview Github Styling Markdown Preview Mermaid Support Markdown yaml Preamble ctrlshiftv结合双页功能...
使用PaddleNLP识别垃圾邮件:用BERT做中文邮件内容分类,验证集准确率高达99.6%以上(附公开数据集)
使用PaddleNLP识别垃圾邮件:用BERT做中文邮件内容分类,验证集准确率高达99.6%以上(附公开数据集)。 要使用PaddleNLP和BERT来识别垃圾邮件并做中文邮件内容分类,可以按照以下步骤进行操作: 安装PaddlePaddle和PaddleNLP:首先,确保在你的环境中已经安装了PaddlePaddle和…...
在bash或脚本中,如何并行执行命令或任务(命令行、parallel、make)
最近要批量解压归档文件和压缩包,所以就想能不能并行执行这些工作。因为tar自身不支持并行解压,但是像make却可以支持生成一些文件,所以我才有了这种想法。 方法有两种,第一种不用安装任何软件或工具,直接bash或其他 …...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
