System: Windows; Version c++23
Want to create an interactive button in a console application.
For this to work, I need to get where a user clicked 1) relative to console window 2) NOT IN PIXELS, but in CONSOLE CELL UNITS.
Things I tried:
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);
}
}
In fullscreen ALWAYS outputs 0 -4
Second try:
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);
}
}
Although 2nd try is better (but still not perfect)
Why the 2nd try is not perfect(Picture)
When you click on the red crosses
you select the slot leftside to it (not the slot itself)
Button 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 << " ";
}
}
}
};
>Solution :
You can use the function ReadConsoleInput to read several types of input events, such as mouse events.
When reading a mouse event, you will get a MOUSE_EVENT_RECORD structure. The dwMousePosition member of this structure is in character-cell coordinates, not pixels.