[英]c++ get users cursor position in console "cells"
系统:Windows; 版本 c++23 想要在控制台应用程序中创建一个交互式按钮。 为此,我需要获取用户单击的位置 1) 相对于控制台 window 2) 不是在像素中,而是在控制台单元中。 我尝试过的事情:
using namespace std;
void GetMouseCursorPos(POINT *mC) {
*mC = POINT{0,0};
ScreenToClient(GetConsoleWindow(),mC);
mC->x = mC->x / font.dwFontSize.X;
mC->y = mC->y / font.dwFontSize.Y;
system("cls");
cout << mC->x << " " << mC->y;
}
int main (){
POINT mCoord;
while (true){
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_MOUSE_INPUT |
ENABLE_EXTENDED_FLAGS);
GetMouseCursorPos(&mCoord);
}
}
在全屏中总是输出 0 -4
第二次尝试:
using namespace std;
void GetMouseCursorPos(POINT *mC) {
*mC = POINT{0,0};
ScreenToClient(GetConsoleWindow(),mC);
mC->x = mC->x / font.dwFontSize.X;
mC->y = LONG(mC->y - 22.5) / font.dwFontSize.Y;
system("cls");
cout << mC->x << " " << mC->y;
}
int main (){
POINT mCoord;
while (true){
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_MOUSE_INPUT |
ENABLE_EXTENDED_FLAGS);
GetMouseCursorPos(&mCoord);
}
}
虽然第二次尝试更好(但仍然不完美)为什么第二次尝试不完美(图)
当你点击红色十字时,你 select 插槽左侧(不是插槽本身)
按钮 class:
using namespace std;
class Button {
public:
int x;
int y;
int height;
int width;
string text;
string text1;
string text2;
int color = 7;
int itemColor = 7;
string getText() { return text; };
void setText(string text) { this->text = text; };
bool isPressed(int mX, int mY) {
if (mX >= this->x && mX <= this->x + width && mY >= this->y && mY <= this->y + height) {
return true;
}
return false;
};
void print() {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {static_cast<SHORT>(x + 1), static_cast<SHORT>(y)});
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
for (int i = 0; i < width - 1; i++) {
cout << "-";
}
for (int i = 0; i < (height - 2); i++) {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
{static_cast<SHORT>(x), static_cast<SHORT>(y + i + 1)});
cout << "|";
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
{static_cast<SHORT>(x + width), static_cast<SHORT>(y + i + 1)});
cout << "|";
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
{static_cast<SHORT>(x + 1), static_cast<SHORT>(y + height -
1)});
for (int i = 0; i < width - 1; i++) {
cout << "-";
}
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
{static_cast<SHORT>(x + 1),
static_cast<SHORT>(y + height / 2)});
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
for (int i = 0; i < width / 2 - text.length() / 2 - 1; i++) {
cout << " ";
}
cout << text;
for (int i = 0; i < width / 2 - text.length() / 2 - 1; i++) {
cout << " ";
}
if (!text1.empty()) {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
{static_cast<SHORT>(x + 1),
static_cast<SHORT>(y + height / 2 + 1)});
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
for (int i = 0; i < width / 2 - text1.length() / 2 - 1; i++) {
cout << " ";
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), itemColor);
cout << text1[0];
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
cout << text1.substr(1);
for (int i = 0; i < width / 2 - text1.length() / 2 - 1; i++) {
cout << " ";
}
}
if (!text2.empty()) {
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),
{static_cast<SHORT>(x + 1),
static_cast<SHORT>(y + height / 2 - 1)});
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
for (int i = 0; i < width / 2 - text2.length() / 2 - 1; i++) {
cout << " ";
}
cout << text2;
for (int i = 0; i < width / 2 - text2.length() / 2 - 1; i++) {
cout << " ";
}
}
}
};
通过使用参数ENABLE_MOUSE_INPUT
SetConsoleMode
您可以将控制台设置为报告鼠标事件。 然后可以使用 function ReadConsoleInput
读取这些事件。
当读取一个鼠标事件时,你会得到一个MOUSE_EVENT_RECORD
结构。 此结构的dwMousePosition
成员位于字符单元格坐标中,而不是像素中。
这是一个示例程序:
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD ir;
DWORD dwRead;
//set console to report mouse input events (but nothing else, including keyboard events)
if ( !SetConsoleMode( hInput, ENABLE_MOUSE_INPUT ) )
{
fprintf( stderr, "Error setting console mode!\n" );
exit( EXIT_FAILURE );
}
while ( ReadConsoleInput( hInput, &ir, 1, &dwRead ) && dwRead == 1 )
{
//ignore all non-mouse events, except for the key "q", which is a request to end the program
if ( ir.EventType != MOUSE_EVENT )
{
if (
ir.EventType == KEY_EVENT &&
ir.Event.KeyEvent.bKeyDown &&
ir.Event.KeyEvent.uChar.AsciiChar == 'q'
)
{
return 0;
}
continue;
}
//ignore all mouse events which don't involve mouse button presses
if ( ir.Event.MouseEvent.dwEventFlags != 0 && ir.Event.MouseEvent.dwEventFlags != DOUBLE_CLICK )
continue;
//determine whether mouse button was clicked or released
if ( ir.Event.MouseEvent.dwButtonState != 0 )
printf( "Mouse button clicked" );
else
printf( "Mouse button released" );
//print coordinates of mouse click/release
printf(
" at the following cell coordinates: [%u,%u]\n",
ir.Event.MouseEvent.dwMousePosition.X,
ir.Event.MouseEvent.dwMousePosition.Y
);
fflush( stdout );
}
fprintf( stderr, "Input error!\n" );
}
该程序具有以下 output:
Mouse button clicked at the following cell coordinates: [24,9]
Mouse button released at the following cell coordinates: [24,9]
Mouse button clicked at the following cell coordinates: [46,10]
Mouse button released at the following cell coordinates: [60,12]
Mouse button clicked at the following cell coordinates: [45,17]
Mouse button released at the following cell coordinates: [31,10]
要退出程序,您必须按Q键。
请注意,此程序仅用于演示目的,并未针对性能进行优化。 在性能可能成为问题的适当程序中,使用ReadConsoleInput
一次读取多个事件可能会更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.