0
已解决
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追加了内容
复制代码:
Xgugugu在2021-11-06 09:30:49追加了内容
注:
baidu上许多教程都有获取鼠标位置的教程
但是关于DPI的部分是我自己摸索出来的
在此感谢微软的知识库(真香)
Xgugugu在2021-11-06 11:30:48追加了内容
注2:
DPI模式在win10下才会对控制台生效
请先检测是否为win10系 统