当前位置: 首页 > article >正文

C++ 获取鼠标点击位置

C++ 获取鼠标点击位置

1.检测鼠标点击事件

GetAsyncKeyState函数可以检测按键点击事件
这里是它的函数原型:

SHORT_stdcall GetAsyncKeyState(int vKey);

我们首先要根据这个函数定义一个宏KEY_DOWN,这样可以方便以后的调用

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)

对于他的取值,请看下表

常量名				   对应按键						取值
—————————————————————————————————————————————————————————
VK_LBUTTON             鼠标左键                      0x01
VK_RBUTTON             鼠标右键                      0x02
VK_CANCEL              Ctrl + Break                  0x03
VK_MBUTTON             鼠标中键                      0x04
VK_BACK                Backspace 键       		     0x08
VK_TAB                 Tab 键                        0x09
VK_RETURN              回车键                        0x0D
VK_SHIFT               Shift 键                      0x10
VK_CONTROL             Ctrl 键                       0x11
VK_MENU                Alt 键                        0x12
VK_PAUSE               Pause 键                      0x13
VK_CAPITAL             Caps Lock 键                  0x14
VK_ESCAPE              Esc 键                        0x1B
VK_SPACE               空格键         				 0x20
VK_PRIOR               Page Up 键                    0x21
VK_NEXT                Page Down 键                  0x22
VK_END                 End 键                        0x23
VK_HOME                Home 键                       0x24
VK_LEFT                左箭头键                      0x25
VK_UP                  上箭头键                      0x26
VK_RIGHT               右箭头键                      0x27
VK_DOWN                下箭头键                      0x28
VK_SNAPSHOT            Print Screen 键               0x2C
VK_Insert              Insert 键                     0x2D
VK_Delete              Delete 键                     0x2E
'0''9'              数字 0 - 9             0x30 - 0x39
'A''Z'              字母 A - Z             0x41 - 0x5A
VK_LWIN                左WinKey(104键盘才有)         0x5B
VK_RWIN                右WinKey(104键盘才有)         0x5C
VK_APPS                AppsKey(104键盘才有)          0x5D
VK_NUMPAD0            小键盘 00x60
VK_NUMPAD1            小键盘 10x61
VK_NUMPAD2            小键盘 20x62
VK_NUMPAD3            小键盘 30x63
VK_NUMPAD4            小键盘 40x64
VK_NUMPAD5            小键盘 50x65
VK_NUMPAD6            小键盘 60x66
VK_NUMPAD7            小键盘 70x67
VK_NUMPAD8            小键盘 80x68
VK_NUMPAD9            小键盘 90x69
VK_F1 - VK_F24        功能键F1 – F24          0x70 - 0x87
VK_NUMLOCK            Num Lock 键                   0x90
VK_SCROLL             Scroll Lock 键                0x91

这个函数可以用来检测鼠标左键的按下,我们就需要这个,先来测试一下效果

#include <windows.h>                			//GetAsyncKeyState所需头文件
#include <iostream>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)  //用来检测按键的点击事件int main() {//----------移除快速编辑模式(对于win10用户)----------HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);DWORD mode;GetConsoleMode(hStdin, &mode);mode &= ~ENABLE_QUICK_EDIT_MODE;SetConsoleMode(hStdin, mode);//----------循环检测----------while(1) {                      			//循环检测if(KEY_DOWN(VK_LBUTTON)) {  			//鼠标左键按下printf("key down!\n");}Sleep(20);                  			//等待20毫秒,减少CPU占用}return 0;
}

可以看到,每次我们点击鼠标左键都会输出key down!这就说明我们的程序成功了。当然,如果你对其他的按键检测感兴趣,你也可以试试其他的。

那么接下来接下来就是获取鼠标点击时的位置了。

2.获取鼠标位置

那么如何获取鼠标的位置呢?C++为我们提供了GetCursorPos这个函数,它可以用来获取鼠标在屏幕上的位置。这个函数需要提供一个POINT类型的地址,像下面这样:

POINT p;
GetCursorPos(&p);

POINT类型包含int xint y两个变量,通过GetCursorPos函数就可以获取鼠标的位置,代码很简单,先来看一下效果:

#include <windows.h>                			//所需头文件
#include <iostream>
POINT p;
int main() {//----------循环检测----------while(1) {GetCursorPos(&p);                       //获取鼠标在屏幕上的位置printf("(%d,%d)\n",p.x,p.y);Sleep(20);                  			//等待20毫秒,减少CPU占用}return 0;
}

现在我们已经完成了已经完成了第二步,然后我们就要获取鼠标点击位置了。

3.获取鼠标点击位置

这个也是分简单,我们只需要把刚才的两段代码合起来就行了。

#include <windows.h>                			//GetAsyncKeyState所需头文件
#include <iostream>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)  //用来检测按键的点击事件POINT p;int main() {//----------移除快速编辑模式(对于win10用户)----------HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);DWORD mode;GetConsoleMode(hStdin, &mode);mode &= ~ENABLE_QUICK_EDIT_MODE;SetConsoleMode(hStdin, mode);//----------循环检测----------while(1) {                      			//循环检测if(KEY_DOWN(VK_LBUTTON)) {  			//鼠标左键按下GetCursorPos(&p);                   //获取鼠标在屏幕上的位置printf("key down (%d,%d)\n",p.x,p.y);}Sleep(100);                  			//等待100毫秒,减少CPU占用}return 0;
}

现在的程序已经基本上完成了 ,但是聪明的你可能会发现,这些坐标都是整个屏幕上的,如果我只想获取鼠标在该窗口上的位置呢?
这其实很简单,C++也为我们提供了这样一个函数ScreenToClient,它用来获取鼠标在指定窗口上的位置,其使用方法与之前的差不多:

POINT p;
GetCursorPos(&p);
ScreenToClient(h,&p);

在使用该函数之前,我们要先获取一下控制台窗口的句柄,用它来指定窗口;

HWND h=GetForegroundWindow();

其中,GetForegroundWindow函数用来获取最顶层窗口的句柄,这很适合我们的程序。
那么就先上代码吧!

#include <windows.h>                			//GetAsyncKeyState所需头文件
#include <iostream>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)  //用来检测按键的点击事件POINT p;
HWND h=GetForegroundWindow();int main() {//----------移除快速编辑模式(对于win10用户)----------HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);DWORD mode;GetConsoleMode(hStdin, &mode);mode &= ~ENABLE_QUICK_EDIT_MODE;SetConsoleMode(hStdin, mode);//----------循环检测----------while(1) {                      			//循环检测if(KEY_DOWN(VK_LBUTTON)) {  			//鼠标左键按下POINT p;GetCursorPos(&p);ScreenToClient(h,&p);               //获取鼠标在窗口上的位置printf("key down (%d,%d)\n",p.x,p.y);}Sleep(100);                  			//等待100毫秒,减少CPU占用}return 0;
}

现在输出的就是鼠标在控制台窗口上的位置了,但是如果需要像获取光标位置一样得到鼠标位置对应的控制台窗口上输出的坐标该怎样办呢?

首先我们要获取控制台字体的高和宽,像下面这样:

HANDLE hOutput;
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_FONT_INFO consoleCurrentFont;
GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont);

GetStdHandle(STD_OUTPUT_HANDLE)用来获取窗口的输出句柄,将它储存到hOutput内,consoleCurrentFont用来储存字体的信息,用GetCurrentConsoleFont函数可以获取当前控制台的字体信息。获取字体的高和宽就像下面这样:

consoleCurrentFont.dwFontSize.X			//宽
consoleCurrentFont.dwFontSize.Y			//高

然后用鼠标的位置除以这两个之就行了,话不多说,先上代码。

#include <windows.h>                			//GetAsyncKeyState所需头文件
#include <iostream>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)  //用来检测按键的点击事件POINT p;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
HWND h=GetForegroundWindow();
CONSOLE_FONT_INFO consoleCurrentFont;int main() {//----------移除快速编辑模式(对于win10用户)----------HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);DWORD mode;GetConsoleMode(hStdin, &mode);mode &= ~ENABLE_QUICK_EDIT_MODE;SetConsoleMode(hStdin, mode);//----------循环检测----------while(1) {                      			//循环检测if(KEY_DOWN(VK_LBUTTON)) {  			//鼠标左键按下POINT p;GetCursorPos(&p);ScreenToClient(h,&p);               //获取鼠标在窗口上的位置GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息int x=p.x/=consoleCurrentFont.dwFontSize.X;int y=p.y/=consoleCurrentFont.dwFontSize.Y;printf("key down (%d,%d)\n",x,y);}Sleep(100);                  			//等待100毫秒,减少CPU占用}return 0;
}
4.彩蛋

学习了本次的内容,我们就来做一个简单的实例,真的很简单

4.1 实例:鼠标控制绘图

在写这个程序之前,我们先来了解一下几个函数:

void gotoxy(int x, int y) {COORD pos = {x,y};HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}

这个函数用来移动光标来输出。

void HideTheCursor() {CONSOLE_CURSOR_INFO cciCursor;HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {cciCursor.bVisible = FALSE;SetConsoleCursorInfo(hStdOut, &cciCursor);}
}

这个函数用来隐藏光标,这能使绘图效果更佳。

现在我们就来编写程序吧:

#include <windows.h>                			//GetAsyncKeyState所需头文件
#include <iostream>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)  //用来检测按键的点击事件POINT p;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
HWND h=GetForegroundWindow();
CONSOLE_FONT_INFO consoleCurrentFont;//----------移动光标----------
void gotoxy(int x, int y) {COORD pos = {x,y};HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}//----------隐藏光标----------
void HideTheCursor() {CONSOLE_CURSOR_INFO cciCursor;HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {cciCursor.bVisible = FALSE;SetConsoleCursorInfo(hStdOut, &cciCursor);}
}int main() {HideTheCursor();                            //隐藏光标//----------移除快速编辑模式(对于win10用户)----------HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);DWORD mode;GetConsoleMode(hStdin, &mode);mode &= ~ENABLE_QUICK_EDIT_MODE;SetConsoleMode(hStdin, mode);//----------循环检测----------while(1) {                      			//循环检测if(KEY_DOWN(VK_LBUTTON)) {  			//鼠标左键按下POINT p;GetCursorPos(&p);ScreenToClient(h,&p);               //获取鼠标在窗口上的位置GetCurrentConsoleFont(hOutput, FALSE, &consoleCurrentFont); //获取字体信息int x=p.x/=consoleCurrentFont.dwFontSize.X;int y=p.y/=consoleCurrentFont.dwFontSize.Y;gotoxy(x,y);                        //移动光标置鼠标位置printf("@");                        //在鼠标位置输出}Sleep(10);                  			//延时}return 0;
}

在这里插入图片描述
本次的教程就完成了,喜欢就关注一下吧。

4.2 下一篇文章:超大地图多人在线扫雷

在这里插入图片描述

http://www.lryc.cn/news/2419617.html

相关文章:

  • 开源评论系统 Isso 全攻略
  • (SDL2)SDL在ubuntu下的测试代码(雷霄骅)
  • 负数求补码
  • short 下 32768的二进制
  • winRAR 破解注册码
  • 文件加密系统的设计与实现(源码+开题报告)
  • contest11 CF510E div2 ooxxx oooox oooox
  • Spider爬虫框架之Spiders模块
  • JS-变量提升与暂时性死区概念
  • 什么是WordPress?
  • jq-jquery根据内容设置select和input radio选中
  • 高数 | 工具及必备方法 | 【一元函数积分学】常用积分公式表
  • default-gateway和default-router的区别
  • Apche部署https详解
  • 采样定理的证明与推导
  • XSLT知识总结
  • 传说中的“摸奶节”!随便你怎么摸!
  • 社会网络分析与人脉网络:如何建立有效的人脉资源
  • Toybox、toolbox、busybox 软件协议
  • HTTP代理和SOCKS代理
  • 内存术语详解
  • 探索听诊器效应:了解声音在耳朵中的传播方式
  • StringTokenizer类的详解
  • 超音速启动 2020 年版发布
  • AMR音频格式分析
  • CrashRpt
  • 【音视频知识】MP4文件格式解析-详解
  • 日本的feature phone版twitter的follow链接
  • Android——bindService()方法启动服务
  • 汇编实验1——利用8255实现LED的流水点亮实验