1
#include <iostream>
#include <curses.h>
#include "SourceFiles/generalFunc.h"

int main()
{

    initscr();
    int x = resize_term(51, 79);
    sleepMilli(5000); //sleep for 5 seconds
    endwin();
    std::cout << x << " " << int(ERR) << " " << int(OK);

}

この場合、私のコンピューターの画面はサイズ変更されませんが、x戻ってきます0(サイズ変更が成功したことを示します)。元の端末ウィンドウと同じサイズのままです。ただし、79 を 80 に増やすか、51 を 50 に減らすと、通常どおり画面のサイズが変更されます。私の画面は、これらのサイズに 1 マイルも対応するのに十分な大きさです。特定のアスペクト比を下回るのが好きではないようです。

これらの数値が画面に保持できる限界に近くない場合でも、サイズ変更に制限があるように見える理由について、これ以上の情報はありますか? これは 64 ビット Windows の pdcurses です。

4

1 に答える 1

3

resize_termncurses 関数です。

関数は端末のサイズをresize_term変更しません。ncurses が想定するサイズを変更します。

curses によって何も表示されないため、(マニュアル ページの注を参照)、あなたの例は nogetchを実行し、curses によって変更として表示されるものは何もありません。

興味深いことに、PDCurses は同じ名前の関数を実装しました (ncurses に触発されました: これらのいくつかがあります) が異なる方法で記述されています。のコメントから引用pdcurses/initscr.c

    resize_term() is effectively two functions: When called with  
    nonzero values for nlines and ncols, it attempts to resize the  
    screen to the given size. When called with (0, 0), it merely  
    adjusts the internal structures to match the current size after  
    the screen is resized by the user. On the currently supported  
    platforms, this functionality is mutually exclusive: X11 allows  
    user resizing, while DOS, OS/2 and Win32 allow programmatic  
    resizing. If you want to support user resizing, you should check  
    for getch() returning KEY_RESIZE, and/or call is_termresized()  
    at appropriate times; if either condition occurs, call  
    resize_term(0, 0). Then, with either user or programmatic  
    resizing, you'll have to resize any windows you've created, as  
    appropriate; resize_term() only handles stdscr and curscr. 

関数は次のように始まります。

int resize_term(int nlines, int ncols)
{   
    PDC_LOG(("resize_term() - called: nlines %d\n", nlines));

    if (!stdscr || PDC_resize_screen(nlines, ncols) == ERR)
        return ERR;

    SP->lines = PDC_get_rows();
    LINES = SP->lines - SP->linesrippedoff - SP->slklines;
    SP->cols = COLS = PDC_get_columns();

次に、Windows コンソールに対してこれを呼び出します。

int PDC_resize_screen(int nlines, int ncols)
{
    SMALL_RECT rect;
    COORD size, max;

    if (nlines < 2 || ncols < 2)
        return ERR;

    max = GetLargestConsoleWindowSize(pdc_con_out);

    rect.Left = rect.Top = 0;
    rect.Right = ncols - 1;

    if (rect.Right > max.X)
        rect.Right = max.X;

    rect.Bottom = nlines - 1;

    if (rect.Bottom > max.Y)
        rect.Bottom = max.Y;

    size.X = rect.Right + 1;
    size.Y = rect.Bottom + 1;

    _fit_console_window(pdc_con_out, &rect);
    SetConsoleScreenBufferSize(pdc_con_out, size);
    _fit_console_window(pdc_con_out, &rect);
    SetConsoleScreenBufferSize(pdc_con_out, size);
    SetConsoleActiveScreenBuffer(pdc_con_out);

    return OK;
}

結果が互換性のない関数であることを確認できます。(同様のSDLへのポートがあります)。PDCurses の動作に関連するいくつかの質問があります。

ただし、PDCurses は通常<xcurses.h>、curses (または ncurses) との違いを示すためにヘッダー ファイルをインストールします。質問は ncurses に関するもので、問題はライブラリ関数が何をするかについての混乱だと思いました:

PDCurses に戻ると、同じ 2 つの呼び出しが2 回行われるのは奇妙です。PDCurses 関数は、指定された値が収まるかどうかにかかわらず、いくつかの試行を行います。

 /* Calls SetConsoleWindowInfo with the given parameters, but fits them  
    if a scoll bar shrinks the maximum possible value. The rectangle  
    must at least fit in a half-sized window. */

static BOOL _fit_console_window(HANDLE con_out, CONST SMALL_RECT *rect)
{   
    SMALL_RECT run;
    SHORT mx, my;

    if (SetConsoleWindowInfo(con_out, TRUE, rect))
        return TRUE;

    run = *rect;
    run.Right /= 2;
    run.Bottom /= 2;

    mx = run.Right;
    my = run.Bottom;

    if (!SetConsoleWindowInfo(con_out, TRUE, &run))
        return FALSE;

    for (run.Right = rect->Right; run.Right >= mx; run.Right--)
        if (SetConsoleWindowInfo(con_out, TRUE, &run))
            break;

    if (run.Right < mx)
        return FALSE;

    for (run.Bottom = rect->Bottom; run.Bottom >= my; run.Bottom--)
        if (SetConsoleWindowInfo(con_out, TRUE, &run))
            return TRUE;

    return FALSE;
}

同じことを 2 回行う以外に、コードは奇妙に見えます。SetConsoleWindowInfoの MSDN の説明を参照すると、四角形パラメーターはinパラメーターです (変更されていません)。パラメータに従って、要求されたサイズを取得し、連続して試行しています

  1. 要求されたサイズを設定する、または
  2. 列を初期サイズの半分に縮小しながら、要求された行を設定する、または
  3. 行を初期サイズの半分に縮小しながら、要求された列を設定します。

おそらく、これが 2 回行われる理由は、コンソール API に不確定な動作があるためです。コード内のコメントは役に立ちません。

于 2016-10-27T08:47:24.570 に答える