我(在我之前,我已经做了很多搜索)尝试让我的控制台显示没有滚动条的缓冲区。我根据系统字体大小和请求的缓冲区大小调整了窗口大小,但即使在更改(和更新)控制台的样式标志后,我仍然留有水平和垂直滚动条所在的空白区域。
任何人都可以帮我解决这个问题吗?
#include <windows.h>
#include <iostream>
const bool adjustWindowSize( const unsigned int p_console_buffer_width,
const unsigned int p_console_buffer_height )
{
/// Get the handle to the active window
HWND l_window_handle( GetConsoleWindow() );
if( l_window_handle == NULL )
{
std::cout << "GetConsoleWindow() failed\n";
return false;
}
/// Get the dimensions of the active window
RECT l_window_rect;
if( !GetWindowRect( l_window_handle, &l_window_rect ) )
{
std::cout << "GetWindowRect() failed\n";
return false;
}
/// Remove unwanted WindowStyle flags
LONG l_style( GetWindowLong( l_window_handle, GWL_STYLE ) );
l_style &= ~( WS_VSCROLL | WS_HSCROLL | WS_MAXIMIZEBOX | WS_MINIMIZEBOX |
WS_SIZEBOX );
SetWindowLong( l_window_handle, GWL_STYLE, l_style );
/// Set new window size to update the style flags
if( !SetWindowPos( l_window_handle, HWND_TOP, l_window_rect.left,
l_window_rect.top, l_window_rect.right -
l_window_rect.left, l_window_rect.bottom -
l_window_rect.top, SWP_HIDEWINDOW ) )
{
std::cout << "SetWindowPos() failed\n";
return false;
}
/// Get the dimensions of the client area within the window's borders
RECT l_client_rect;
if( !GetClientRect( l_window_handle, &l_client_rect ) )
{
std::cout << "GetClientRect() failed\n";
return false;
}
/// Get handle to console
HANDLE l_console_handle( GetStdHandle( STD_OUTPUT_HANDLE ) );
if( l_console_handle == nullptr )
{
std::cout << "GetStdHandle() failed\n";
return false;
}
/// Get font information
CONSOLE_FONT_INFO l_font_info;
if( !GetCurrentConsoleFont( l_console_handle, false, &l_font_info ) )
{
std::cout << "GetCurrentConsoleFont() failed\n";
return false;
}
/// Prepare desired client area size
unsigned int l_target_width( l_font_info.dwFontSize.X *
p_console_buffer_width );
unsigned int l_target_height( l_font_info.dwFontSize.Y *
p_console_buffer_height );
POINT l_top_left;
l_top_left.x = l_client_rect.left;
l_top_left.y = l_client_rect.top;
ClientToScreen( l_window_handle, &l_top_left );
POINT l_bottom_right;
l_bottom_right.x = l_client_rect.right;
l_bottom_right.y = l_client_rect.bottom;
ClientToScreen( l_window_handle, &l_bottom_right );
unsigned int l_diff_x = l_window_rect.right - l_bottom_right.x +
l_top_left.x - l_window_rect.left;
unsigned int l_diff_y = l_window_rect.bottom - l_bottom_right.y +
l_top_left.y - l_window_rect.top;
/// Adjust window to fit exactly it's borders + the new client size
l_window_rect.right = l_target_width + l_diff_x;
l_window_rect.bottom = l_target_height + l_diff_y;
/// Set new window size
if( !SetWindowPos( l_window_handle, HWND_TOP, l_window_rect.left,
l_window_rect.top, l_window_rect.right,
l_window_rect.bottom, SWP_SHOWWINDOW ) )
{
std::cout << "SetWindowPos() failed\n";
return false;
}
/// Set new console buffer size
if( !SetConsoleScreenBufferSize( l_console_handle,
COORD( { (SHORT)p_console_buffer_width,
(SHORT)p_console_buffer_height } ) ) )
{
std::cout << "SetConsoleScreenBufferSize() failed\n";
return false;
}
return true;
}
int main()
{
SetConsoleTitle( (LPCSTR)"Console Test" );
unsigned int l_buffer_x( 100 );
unsigned int l_buffer_y( 40 );
if( !adjustWindowSize( l_buffer_x, l_buffer_y ) )
{
std::cout << "adjustWindowSize() failed\n";
return 1;
}
for( unsigned int i( 0 ); i < l_buffer_x * l_buffer_y; ++i )
{
std::cout << i % 10;
}
SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ),
COORD( { 0, 0 } ) );
return 0;
}
答案 0 :(得分:0)
正如我理解你的问题,你想创建没有滚动条的控制台窗口,可见区域正好是输出屏幕缓冲区的大小?这是你如何做到这一点:
#include <windows.h>
#include <iostream>
void SetConsoleWindow(HANDLE conout, SHORT cols, SHORT rows)
{
CONSOLE_SCREEN_BUFFER_INFOEX sbInfoEx;
sbInfoEx.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
GetConsoleScreenBufferInfoEx(conout, &sbInfoEx);
sbInfoEx.dwSize.X = cols;
sbInfoEx.dwSize.Y = rows;
sbInfoEx.srWindow = { 0, 0, cols, rows };
sbInfoEx.dwMaximumWindowSize = { cols, rows };
SetConsoleScreenBufferInfoEx(conout, &sbInfoEx);
DWORD mode;
GetConsoleMode(conout, &mode);
mode &= ~ENABLE_WRAP_AT_EOL_OUTPUT;
SetConsoleMode(conout, mode);
SetConsoleTitle(L"Console Test");
}
int main()
{
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
SHORT cols = 100, rows = 20;
SetConsoleWindow(out, cols, rows);
for (int y = 0; y < rows; ++y)
{
for (int x = 0; x < cols; ++x)
std::cout << y %10;
if (y < rows - 1)
std::cout << std::endl;
}
SetConsoleCursorPosition(out, { 0,0 });
return 0;
}
这需要一些解释。 CONSOLE_SCREEN_BUFFER_INFOEX
结构似乎包含实现这一目标所需的所有参数。如果检查控制台窗口的属性并将它们与结构成员进行比较
您发现dwSize
对应Screen Buffer Size
,srWindow.Right - srWindow.Left
和srWindow.Bottom - srWindow.Top
对应Window Size
。
如果未设置dwMaximumWindowSize
,则默认为桌面边界,如果窗口较大则添加滚动条。设置它也可以解决这个问题。
最后,需要从控制台选项中删除ENABLE_WRAP_AT_EOL_OUTPUT
以停止光标跳到行尾的下一行,从而使用最后打印的字符滚动缓冲区。我已经调整了打印循环以解决这个问题。