简体   繁体   English

有 Windows 控制台 API 报告 Window 调整大小

[英]Have Windows Console API Report Window Resize

In the windows console API, you can collect input for when the BUFFER is resized (Via window resize), but you cannot collect input for when the WINDOW is resized.在 windows 控制台 API 中,您可以收集 BUFFER 调整大小时的输入(通过 window resize),但是您不能收集 WINDOW 调整大小时的输入。 To illustrate this issue, here is a small program:为了说明这个问题,这里有一个小程序:

#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);
    }

}

This will report (To debug) when the buffer is resized.这将在调整缓冲区大小时报告 (To debug)。 Here is when this becomes a problem: The buffer is not resized if :这就是这成为问题的时候:如果出现以下情况,则不会调整缓冲区的大小:

  • The buffer is already taller than the window (Vertical scrollbars appear) AND缓冲区已经高于 window(出现垂直滚动条)并且

  • The resize event only affects the Y axis resize事件只影响Y轴

In this case, the buffer is not resized, the window shrinks, and the handle on the scrollbar does too.在这种情况下,缓冲区不会调整大小,window 会缩小,滚动条上的句柄也会缩小。 However, I want windows to report this event because :但是,我希望 windows 报告此事件,因为

I would like to keep the buffer exactly the same size as the window, to hide the scrollbars.我想让缓冲区与 window 的大小完全相同,以隐藏滚动条。

I had the same challenge, and so I wrote this function to deal with it.我遇到了同样的挑战,所以我写了这个 function 来处理它。 Called from the right place in your program, the window resize event can be captured within millisecs of the event itself.从程序中的正确位置调用 window 调整大小事件可以在事件本身的几毫秒内捕获。 Best wishes to all.向所有人致以最良好的祝愿。

#include <windows.h> #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) { 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;

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM