问题标题: C++实现鼠标点击获取

0
1
已解决
Xgugugu
Xgugugu
新手守护
新手守护

我 是 薛 乘 志 的 小 号 !!!

番外:关于我是如何被禁言1周

前段时间,问答代码分享莫名消失了

于是,我发了个问题“草,没有代码分享了吗?”

然后...就因为“侮辱、诽谤他人被禁言了”...

 

正片:(以后可能会提供可复制的地方)

关于在windows下获取鼠标点击,我们首先要知道的是:

win7+提供了快速编辑模式,点击就会选择文本并暂停程序

这严重影响了我们的鼠标点击获取

所以,需要在程序开始前,禁用快速编辑模式(仅对此程序有效)

不解释了,代码如下:

HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
mode &= ~ENABLE_QUICK_EDIT_MODE;
mode &= ~ENABLE_INSERT_MODE;
mode &= ~ENABLE_MOUSE_INPUT;
SetConsoleMode(hStdin, mode);

在windows.h中,提供了GetAsyncKeyState()这一接口

我们可以直接这样使用:

bool KeyDown(int key) { //是否按下某键
    //key取值:
	//VK_LBUTTON 左键
	//VK_RBUTTON 右键
	//VK_MBUTTON 中键
	return GetAsyncKeyState(key) & 0x8000;
}

这样,可以使用一个大循环获取点击:

while(1){
    if(KeyDown(VK_LBUTTON)){
        cout<<"左键按下了\n";
    }
    Sleep(100); //直接无延时循环会占用大量cpu资源
}

对于获取鼠标坐标,windows.h提供了GetCursorPos()函数使用

POINT p;
GetCursorPos(&p);

这样可以获取全局的鼠标位置

但是这样的坐标没有任何作用,因为这不是对于我们写的窗口的坐标

我们可以提供这样的函数来获取相对于我们程序窗口的坐标:

HWND hwnd = GetForegroundWindow(); //在程序一开始使用
...
ScreenToClient(hwnd, &p);

可将全局坐标改为局部坐标

但是这样的坐标仍然不是窗口的行列坐标,而是鼠标所在像素的坐标

我们需要使用该坐标除以每个字体的大小获取窗口的坐标

CONSOLE_FONT_INFO font;
GetCurrentConsoleFont(handle, FALSE, &font);
p.x /= font.dwFontSize.X;
p.y /= font.dwFontSize.Y;

这样就可以获取到所在行列的坐标了

使用:

void gotoxy(short x, short y) { //移动光标函数
	COORD coord = {x, y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
	return;
}
...
//获取坐标后:
gotoxy(p.x,p.y);

可以将光标移动到该位置

但是,还没完!

在新电脑中,一般使用2k或4k的分辨率,在这种情况下,**显示的字体会变得非常小,所以需要开缩放

但是我们获取到的字体大小是未缩放的,所以需要进行以下处理

	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); 
	CONSOLE_FONT_INFO font;
	GetCurrentConsoleFont(handle, FALSE, &font);
	int DPI = GetDeviceCaps(GetDC(NULL), LOGPIXELSX); //获取**DPI
	double Zoom = DPI * 1.0 / 24 * 25.0 / 100.0; //将DPI转化为百分比
	p.x /= font.dwFontSize.X * Zoom; //乘以百分比
	p.y /= font.dwFontSize.Y * Zoom;

这就是全部的代码了

Xgugugu在2021-11-06 09:27:07追加了内容

复制代码:

Ubuntu Pastebin

Xgugugu在2021-11-06 09:30:49追加了内容

注:

baidu上许多教程都有获取鼠标位置的教程

但是关于DPI的部分是我自己摸索出来的

在此感谢微软的知识库(真香)

Xgugugu在2021-11-06 11:30:48追加了内容

注2:

DPI模式在win10下才会对控制台生效

请先检测是否为win10系 统


0
0
0
沙宸安
沙宸安
高级启示者
高级启示者

①我本人是静音党,除了上完课外,我的电脑音箱常年静音,所以Beep函数还是省了吧

②不过,之前那个XACRAFT行走的bug,我已经修复了。

我要回答