在 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 报告此事件因为:
我想保持缓冲区与窗口大小完全相同,以隐藏滚动条。
我遇到了同样的挑战,所以我编写了这个函数来处理它。 从程序中的正确位置调用窗口调整大小事件可以 在事件本身的几毫秒内被捕获。 祝大家一切顺利。
#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;
}