c++ SetConsoleWindowInfo函数一直返回false

k4ymrczo  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(219)

我试图使自己成为一个轻量级的控制台图形引擎,作为学习语言的一部分,我在尝试调整控制台窗口大小时遇到了这个错误。这是我的代码。

Sc_Buffer = new CHAR_INFO[Sc_Width * Sc_Height];

    _ConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);

    if (_ConsoleOut == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL, TEXT("Invalid Output Handle."), TEXT("Error"), MB_OK);
        return FALSE;
    }
    else if (!SetConsoleActiveScreenBuffer(_ConsoleOut))
    {
        MessageBox(NULL, TEXT("Unable to Initialize screen buffer."), TEXT("Error"), MB_OK);
        return FALSE;
    }
    else if (!SetConsoleWindowInfo(_ConsoleOut, TRUE, &Sc_Range))
    {
        MessageBox(NULL, TEXT("Unable to set screen resolution."), TEXT("Error"), MB_OK);
        return FALSE;
    }

调整控制台大小的最后一个“if”语句总是返回false,我似乎找不到原因。
请帮帮我先谢谢你了。
最好的问候!

aelbi1ox

aelbi1ox1#

1.)SetConsoleWindowInfo()存在问题。它只能成功地调整一个窗口矩形时,它的大小明显增加或减少。因此,一个40 x50的矩形增加到38 x70并不是这个API增加的明确事实,因为38的值小于40。您可能认为矩形的总面积可能是一个决定性因素,但奇怪的是,测试表明它不是。
解决方案是设置中间矩形COORD,这是API的明显增加/减少…然后执行对最终期望矩形值的第二次调用。我会给予你一个函数,我一起黑了这个。
2.)另一件要知道的事情是,当调整控制台窗口矩形的大小时,还必须注意控制台窗口缓冲区。就像听起来一样,缓冲区是控制台窗口数据的内存空间。它必须始终等于或大于目标窗口矩形。
因此,如果要增加窗口矩形,则必须首先通过调用SetConsoleScreenBufferSize()来增加控制台窗口缓冲区--假设当前缓冲区小于目标控制台窗口矩形。如果您尝试将控制台窗口矩形设置为大于当前控制台窗口缓冲区,SetConsoleWindowInfo()肯定会失败。但如果当前控制台窗口缓冲区已经足够大,可以容纳更大的目标窗口矩形,则不需要调用SetConsoleScreenBufferSize()。很简单,对吧?因此,在处理好控制台窗口缓冲区之后,可以调用SetConsoleWindowInfo()将控制台窗口矩形设置为目标大小。
如果您正在缩小控制台窗口矩形,那么当前缓冲区大小将永远不会成为问题--除了美观...例如:当缓冲区大于控制台窗口矩形时,滚动条出现在底部和侧面。要使这些滚动条消失,首先调用SetConsoleWindowInfo()将控制台窗口矩形设置得更小,然后调用SetConsoleScreenBufferSize()缩小控制台窗口缓冲区,使滚动条消失。注意,这是INCREASING方法的相反顺序。
这里是get_intermediate_coords()

/*------------------------------------------------------------------------

get_intermediate_coords()

SetConsoleWindowInfo() has issues.  It can only successfully resize a 
window rectangle when it's CLEARLY increasing or decreasing in size. Hence, 
a 40x50 rectangle that is increasing to 38x70 isn't really a CLEAR fact of
increase to this API because of the 38 value being smaller than 40.  You might
think that total area of the rectangle might be a determining factor, but 
testing has shown that it is not, oddly enough.

The solution is to set intermediate rectangle COORDs which are a clear 
increase/decrease to the API .. and then perform a 2nd call for the final desired 
rectangle value, like this:

Current: 40x50 
Interm:  37x48 <-- clearly smaller than Current.
Final:   38x70 <-- Clearly larger than Intermediate

PARAMS: 
    COORD cur -- current window wdth and hgt 
    COORD targ -- target window wdth and hgt
    BOOL shrink_ok -- it's OK to provide a lower intermediate value than current 
    and target COORDs.  Else larger COORDs than current and target will be given.

RETURNS:  COORD structure having intermediate wdth and hgt COORDs

*-------------------------------------------------------------------------------*/
COORD get_intermediate_coords(COORD cur, COORD targ, BOOL shrink_ok)
{
COORD interm;

if(shrink_ok)
{
    interm.X = min(cur.X, targ.X) - 1;
    interm.Y = min(cur.Y, targ.Y) - 1;
}
else
{
    interm.X = max(cur.X, targ.X) + 1;
    interm.Y = max(cur.Y, targ.Y) + 1;
}

return interm;
}

相关问题