如何确定鼠标光标所在的控制台字符?

How to determine the Console Character over which the Mouse Cursor is on?

当字体非常小时,我无法将鼠标屏幕坐标转换为控制台 2D 缓冲区。我找到的唯一方法是这个:

COORD CursorToBuffer()
{
    POINT ptCursor;
    GetCursorPos(&ptCursor);
    ScreenToClient(GetConsoleWindow(), &ptCursor);
    /** Now ptCursor has the Mouse Position relative to the console client area. **/

    COORD dwBufferPosition;
    dwBufferPosition.X = ptCursor.x / dwFontWidth;
    dwBufferPosition.Y = ptCursor.y / dwFontHeight;

    return dwBufferPosition;
}

当字体在12x16左右时,是准确的。但是当字体大小低于 10x10 时,它开始变得混乱。

我可以使这个更准确吗,或者我应该使用其他方法吗?

我测试了这个程序,它似乎适用于小于 10x10 的字体大小,即使没有调用 LPtoDP 它也能正常工作,但我把它留在里面了。它调用 GetConsoleFontSize 来获取字体大小和它将它打印到输出中,以便您可以在缩小字体时检查值。希望对你有帮助。

#include <Windows.h>
#include <sstream>
#include <iostream>

CONSOLE_FONT_INFO fontInfo;
HANDLE hStdout;
HWND hwnd;
HDC hdc;

COORD CursorToBuffer()
{
    POINT ptCursor;
    GetCursorPos(&ptCursor);
    ScreenToClient(hwnd, &ptCursor);
    /** Now ptCursor has the Mouse Position relative to the console client area. **/
    COORD dwFontSize = GetConsoleFontSize(hStdout, fontInfo.nFont);

    POINT dpFontSize = { dwFontSize.X, dwFontSize.Y };
    LPtoDP(hdc, &dpFontSize, 0);
    COORD dwBufferPosition;
    dwBufferPosition.X = ptCursor.x / dpFontSize.x;
    dwBufferPosition.Y = ptCursor.y / dpFontSize.y;

    std::string fontSize = "fontSize: " + std::to_string(dpFontSize.x) + ' ' + std::to_string(dpFontSize.y) + "\n";
    OutputDebugStringA(fontSize.c_str());

    return dwBufferPosition;
}

void writeAt(int x, int y, std::string text)
{
    COORD position = { x, y };
    SetConsoleCursorPosition(hStdout, position);
    std::cout << text;
}

int main()
{
    hwnd = GetConsoleWindow();
    hdc = GetDC(hwnd);
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    GetCurrentConsoleFont(hStdout, FALSE, &fontInfo);

    while (1) {
        COORD cursor = CursorToBuffer();
        std::string txt = std::to_string(cursor.X) + " " + std::to_string(cursor.Y) + "   \n";
        writeAt(1, 1, txt);
    }

    return 0;
}

比计算鼠标位置更好的是获得它的真实值。使用 ReadConsoleInput

使用 ReadConsoleInput 而不是 INPUT_RECORDMOUSE_EVENT_RECORD。它还包含鼠标位置。

See sample code in the MSDN