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

时间:2018-07-20 00:33:52

标签: c++ windows winapi console cursor

当字体很小时,将鼠标屏幕坐标转换为控制台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时,它就会变得混乱。

我可以更准确吗?还是应该使用其他方法?

2 个答案:

答案 0 :(得分:1)

我测试了此程序,对于小于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;
}

答案 1 :(得分:1)

比计算鼠标位置要好得多。使用ReadConsoleInput

使用ReadConsoleInput会比得到INPUT_RECORDMOUSE_EVENT_RECORD多得多。它还包含鼠标位置。

See sample code in the MSDN