在 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%dn", size.X, size.Y);
OutputDebugString(strBuf);
}
i++;
}
} while (inputLeft > 0);
GetConsoleScreenBufferInfo(screenBufferHandle, &info);
}
}
这将在调整缓冲区大小时报告 (调试(。这是当这成为一个问题的时候:如果出现以下情况,则不会调整缓冲区的大小:
缓冲区已经比窗口高(出现垂直滚动条(和
调整大小事件仅影响 Y 轴
在这种情况下,不会调整缓冲区的大小,窗口会缩小,滚动条上的控点也会缩小。但是,我希望窗口报告此事件,因为:
我想保持缓冲区与窗口完全相同的大小,以隐藏滚动条。
我遇到了同样的挑战,所以我写了这个函数来处理它。从程序中的正确位置调用,窗口调整大小事件可以在事件本身的几毫秒内捕获。 向所有人致以最良好的祝愿。
#include <视窗>视窗>
/*------------------------------------------------------------------------------------
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.
*--------------------------------------------------------------------------------**/
国际check_console_window_resize_event(无效({
/* 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;
}