如何检测控制台中当前是否启用了Windows 10缓冲区包装模式

时间:2015-12-10 19:31:39

标签: windows winapi console-application

有没有办法检测控制台应用是否在启用Windows 10的新功能的情况下运行?

This MSDN page表明HKEY_CURRENT_USER\Console\ForceV2HKEY_CURRENT_USER\Console\LineWrapHKEY_CURRENT_USER\Console\{name}\LineWrap控制它,但除了解析不太健壮之外,它可能不正确。如果用户切换到传统模式或从传统模式切换,则在控制台重新启动之前更改将不会生效。

如果我开发应用程序,我可以在启动时进行检查。但是可能存在竞争条件,这使得注册表检查对于任何实际使用都没用。我很好奇第三方控制台窗口的解决方案是什么。

1 个答案:

答案 0 :(得分:2)

似乎没有这方面的API,虽然我希望在以后的SDK中出现一个(可能是GetConsoleMode中的其他超扩展标志)。

同时,以下是一个快速入侵,它试图根据检查GetMinMaxInfo返回的ptMaxTrackSize.X值来检测新控制台的调整大小更广泛的功能。

传统控制台不允许将窗口大小调整为大于屏幕缓冲区宽度,而新控制台的宽度大于屏幕缓冲区宽度。假设(a)控制台以完全缓冲区宽度运行,即没有水平滚动条,(b)它尚未拉伸到完整/最大屏幕宽度,检查窗口是否允许自身调整大小是相当简单的更宽(新控制台)或不(传统控制台)。应该注意的是,假设(a)在技术上可以通过手动将缓冲区宽度从字符转换为像素来避免,而不是依赖于GetWindowRect,但假设(b)几乎是不可避免的。

这是代码(免责声明:快速而肮脏的概念证明,无错误检查等)。

int main()
{
    // largest possible console size for given font and desktop
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD cd = GetLargestConsoleWindowSize(hOut);
    SHORT nScrMaxXch = cd.X, 
        nScrMaxYch = cd.Y;

    // current and max console sizes for given screen buffer
    CONSOLE_SCREEN_BUFFER_INFOEX csbix = { sizeof(csbix) };
    GetConsoleScreenBufferInfoEx(hOut, &csbix);
    SHORT nWndXch = csbix.srWindow.Right - csbix.srWindow.Left + 1,
        nWndYch = csbix.srWindow.Bottom - csbix.srWindow.Top + 1;
    SHORT nWndMaxXch = csbix.dwMaximumWindowSize.X,
        nWndMaxYch = csbix.dwMaximumWindowSize.Y;

    wprintf(L"chars:   wnd-size %d %d, max-wnd-size %d %d, largest-size %d %d\n",
        nWndXch, nWndYch, nWndMaxXch, nWndMaxYch, nScrMaxXch, nScrMaxYch);

    // current window size
    HWND hWnd = GetConsoleWindow();
    RECT rc; GetWindowRect(hWnd, &rc);
    LONG nWndXpx = rc.right - rc.left,
        nWndYpx = rc.bottom - rc.top;

    // max window tracking size
    MINMAXINFO mmi = { 0 };
    SendMessage(hWnd, WM_GETMINMAXINFO, 0, (LPARAM)&mmi);
    LONG nWndMaxXpx = mmi.ptMaxTrackSize.x,
        nWndMaxYpx = mmi.ptMaxTrackSize.y;

    wprintf(L"pixels:  wnd-size %lu %lu, max-tracking-size %lu %lu\n",
        nWndXpx, nWndYpx, nWndMaxXpx, nWndMaxYpx);

    if (nWndXch == nWndMaxXch   // full buffer width, no h-scrollbar 
    && nWndXch < nScrMaxXch     // not already stretched to full screen width
    && nWndMaxXpx > nWndXpx)    // allowed to resized wider
        wprintf(L"\n...most likely a Win10 console with ForceV2 enabled\n");

    return 0;
}

这是在传统控制台中运行时的输出。

chars:   wnd-size 80 25, max-wnd-size 80 71, largest-size 240 71
pixels:  wnd-size 677 443, max-tracking-size 677 1179

这是在新控制台中运行时的输出。

chars:   wnd-size 80 25, max-wnd-size 80 71, largest-size 239 71
pixels:  wnd-size 677 443, max-tracking-size 1936 1186

...most likely a Win10 console with ForceV2 enabled