让 Windows 控制台 API 报告窗口调整大小

问题描述 投票:0回答:1

在 Windows 控制台 API 中,您可以收集 BUFFER 大小调整时的输入(通过窗口大小调整),但无法收集 WINDOW 大小调整时的输入。为了说明这个问题,这里有一个小程序:

#include <Windows.h>
#include <stdio.h>

#define STR_BUF_SIZE 128
#define ENABLE_WINDOW_INPUT

int main() {
    HANDLE screenBufferHandle = CreateConsoleScreenBuffer(
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        CONSOLE_TEXTMODE_BUFFER,
        NULL
    );
    SetConsoleActiveScreenBuffer(screenBufferHandle);
    HANDLE in = GetStdHandle(STD_INPUT_HANDLE);

    CONSOLE_SCREEN_BUFFER_INFO info;
    INPUT_RECORD recordBuffer[32];

    char strBuf[STR_BUF_SIZE];

    while (1) {

        // Collect the input
        int inputLeft, inputToProcess;
        do {
            GetNumberOfConsoleInputEvents(in, &inputLeft);
            if (!inputLeft) {
                break;
            }
            inputLeft -= 32;
            ReadConsoleInput(
                in,
                recordBuffer,
                32,
                &inputToProcess
            );
            int i = 0;
            while (i < inputToProcess) {
                if (recordBuffer[i].EventType == WINDOW_BUFFER_SIZE_EVENT) {
                    COORD size = recordBuffer[i].Event.WindowBufferSizeEvent.dwSize;
                    sprintf_s(strBuf, STR_BUF_SIZE, "Event recorded, %dx%d\n", size.X, size.Y);
                    OutputDebugString(strBuf);
                }
                i++;
            }
        } while (inputLeft > 0);

        GetConsoleScreenBufferInfo(screenBufferHandle, &info);
    }

}

当缓冲区大小调整时,这将报告(调试)。这是当这成为问题时:缓冲区未调整大小if

  • 缓冲区已经比窗口高(出现垂直滚动条)AND

  • 调整大小事件仅影响Y轴

在这种情况下,缓冲区的大小不会调整,窗口会缩小,滚动条上的手柄也会缩小。但是,我希望 Windows 报告此事件因为

我想保持缓冲区与窗口大小完全相同,以隐藏滚动条。

c windows console
1个回答
0
投票

我遇到了同样的挑战,所以我编写了这个函数来处理它。 从程序中的正确位置调用窗口调整大小事件可以 在事件本身的几毫秒内被捕获。 祝大家一切顺利。

#include <windows.h>

/*------------------------------------------------------------------------------------
 
    check_console_window_resize_event()

    2022.10.05 - Created by Greg Spears and placed in the public domain.
               - Tested -- use at your own risk.

    Params: none
    Returns: TRUE if the console window has changed size.  FALSE if not.

    USAGE: Best practice is to call the function repeatedly from your main application 
    loop.   Preferably a place where the function can be called several times per second 
    throughout the program's run time.
 *--------------------------------------------------------------------------------**/

int check_console_window_resize_event(void)
{

    /* variables declared static hold their value between function calls.*/
    static int old_screen_w=0, old_screen_h=0;
    static HANDLE hConOut=NULL;
    int current_screen_w, current_screen_h;
    int window_resized = FALSE;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    SECURITY_ATTRIBUTES sa;

    if(!hConOut)
    {
        /* First call -- get the window handle one time and save it*/
        sa.nLength = sizeof(sa);
        sa.lpSecurityDescriptor = NULL;
        sa.bInheritHandle = TRUE;
        /* Using CreateFile we get the true console handle, avoiding any redirection.*/
        hConOut = CreateFile( TEXT("CONOUT$"),
             GENERIC_READ | GENERIC_WRITE,
             FILE_SHARE_READ | FILE_SHARE_WRITE,
             &sa, OPEN_EXISTING, (DWORD)0, (HANDLE)0 );
    }
    if(!hConOut) /* actually, this is a bad error, let your app handle the error as needed*/
        return FALSE;

    GetConsoleScreenBufferInfo( hConOut, &csbi );
    current_screen_w  = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    current_screen_h  = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;

    if(!old_screen_w && !old_screen_h)
    {
        /* Execution comes here if this is first time this function is called.  
        ** Initialize the static variables and bail...*/
        old_screen_w = current_screen_w;
        old_screen_h = current_screen_h;
        return FALSE;
    }

    /* At last the real work of this function can be realized...*/
    if(current_screen_w != old_screen_w || current_screen_h != old_screen_h)
    {
        old_screen_w = current_screen_w;
        old_screen_h = current_screen_h;
        window_resized = TRUE;
    }
    return window_resized;
}
© www.soinside.com 2019 - 2024. All rights reserved.