2017-01-13 11 views
0

Cで基本的なメニューを実行しようとしていますが、これはncursesのlibで行います。私はこのチュートリアルで働いていた: 1)メニューは、それは、メニュー項目を選択するだけながら明らかにし、適切に印刷されません。 Video On YouTube基本的なNcursesメニュー

しかし、私のバージョンはいくつかの問題があります。その後、ハイライトは消えません 2)メニューのオプションは上部に印刷されません

私を助けてくれますか?そのメニューのアイデアは良いですか、私は他のチュートリアル(任意のヘルプ?)を探す必要がありますか?

#include <stdio.h> 
#include <ncurses.h> 
#include <string.h> 
#include <menu.h> 
int main(int argc, char **argv) 
{ 
    int i, c; 
    char powitanie[]="SLOWNIK UNIWERSALNY"; 
    int szer, dlug; //wartosci dlugosci i szerokosci terminalu 
    initscr(); //Inizjalizacja całości ncurses, kolory itp 
    raw(); 
    noecho(); 
    keypad(stdscr, TRUE); 
    start_color(); 
    //init_pair(1, COLOR_BLUE, COLOR_BLACK); //wybór kolorów 
    getmaxyx(stdscr, szer, dlug); //pobranie rozmiarów terminalu 
    move(szer/2, (dlug-strlen(powitanie))/2); //przesuwamy kursor na środek (tak aby się ładnie wydrukowało) 
    //attron(COLOR_PAIR(1)); //Aktywujemy wybrane kolory 
    printw(powitanie); //Drukujemy powitanie 
    //attroff(COLOR_PAIR(1));//Dezaktywujemy kolory 
    refresh();//Odswiezamy (inaczej się nie wyswietli) 
    WINDOW * menuwin=newwin(6, dlug-12, szer-8, 6); //Definiujemy i tworzymy 'okno' 
    box(menuwin, 0, 0); 
    refresh();//ponownie odświeżamy aby okno się pojawiło 
    wrefresh(menuwin);//odświeżamy samo okno 
    keypad(menuwin, TRUE);//umozliwiamy dzialanie klawiatury w oknie 
    char *opcje[] = { 
         "Tlumacz z Polskiego na Angielski", 
         "Tlumacz z Angielskiego na Polski", 
         "Edystuj slownik", 
         "Wybierz slownik", 
         "Wyjdz", 
        }; 
    int wybor; 
    int zaznacz=0; 
    while(1)//cala ta petla sluzy ciaglemu tworzeniu menu z podswietleniem wybranego elementu 
    { 
     for(i=0; i<5; i++) 
     { 
      if(i==zaznacz) 
      { 
       wattron(menuwin, A_REVERSE); 
       mvwprintw(menuwin, i+1, 1, opcje[i]); 
       wattroff(menuwin, A_REVERSE); 
      } 
      wybor = wgetch(menuwin); 
      switch(wybor) 
      { 
       case KEY_UP: 
       zaznacz--; 
       if(zaznacz==-1) zaznacz=0;//zabezpieczenie przed wyjsciem "poza" menu 
       break; 
       case KEY_DOWN: 
       zaznacz++; 
       if(zaznacz==5) zaznacz=4; 
       break; 
       default: 
       break; 
      } 
      if(wybor==10) break; 
     } 
     printw("Wybrano:%s", opcje[zaznacz]); 
    } 
    return(0); 
} 

PS:コードのコメントは英語ではありませんが、私はかなりの数の問題がここにあります

答えて

1

必要ではないことを願っています。私は動作するコードの修正版を含んでおり、変更点を記述しようとします。

そこにはいくつかの未使用の変数、すなわちargcargv、およびcはなかったので、私は、コンパイラの警告を黙らせるためにvoidにこれらをキャスト。必要に応じてcを削除してint main(void)に変更して、これらの変数を完全に削除することができます。

#includestdlib.hヘッダーファイルを追加しました。exit()機能です。これは、コードに追加した新しいエラー関数fail()で使用されます。 C言語でプログラミングするときに呼び出す関数の戻り値を常にチェックする必要があります。まず、端末がhas_colors()関数で色をサポートしているかどうか、次にstart_color()への呼び出しが成功したかどうかを確認することが特に重要です。これらのいずれかが失敗すると、エラーメッセージとともにfail()関数が呼び出され、プログラムはEXIT_FAILUREの値で終了します。 has_colors()boolを返し、start_color()関数はint(成功した場合はOK、それ以外の場合はERR)を返します。

色が初期化されたので、メニュー選択ウィンドウの下端がメニューテキストによって上書きされていることがわかりました。この問題を解決するために、私はそれが1行背の高い作り、あなたのウィンドウのサイズを変更:

WINDOW * menuwin=newwin(7, dlug-12, szer-9, 6); 

あなたが報告された不適切な印刷の基本的な問題は、メニューの印刷を制御するforループであるため紛失ブレースでしたアイテム。ループを少し再編成する機会を得ました。今すぐmvwprintw()への呼び出しが1つしかありません。 A_REVERSE属性は、現在の項目が選択項目でもある場合は印刷前に設定され、印刷後に再び設定解除されます。

また、switch文の制限テストを等価から不等式に変更しました。このような場合には、if (zaznacz == -1)の代わりに、たとえばif (zaznacz < 0)を使用する方が良い方法です。 最後のprintw()の書式文字列の先頭に改行文字を追加しました。選択の一部が長すぎてタイトル末尾のウィンドウに収まらないためです。この出力は、好きな場所に移動できます。

は最後に、私はプログラムを終了する前にをENTER ヒットするユーザーを待つために、最終的なprintw()文の後refresh()を追加し、getch()。NCursesプログラムを終了する前にendwin()に電話をかけてクリーンアップすることは非常に重要です。この関数は、プログラムの実行中にNCursesによって端末に加えられた変更を元に戻します。これを行わないと、端末の不具合が発生する可能性があります。

#include <stdio.h> 
#include <ncurses.h> 
#include <string.h> 
#include <menu.h> 
#include <stdlib.h>   // added for exit() function 

void fail(char *msg) { 
    endwin(); 
    puts(msg); 
    exit(EXIT_FAILURE); 
} 

int main(int argc, char **argv) 
{ 
    /* Commandline argument currently unused */ 
    (void) argc; 
    (void) argv; 

    int i, c; 
    (void) c;      // c is currently unused 
    char powitanie[]="SLOWNIK UNIWERSALNY"; 
    int szer, dlug; //wartosci dlugosci i szerokosci terminalu 

    initscr(); //Inizjalizacja całości ncurses, kolory itp 
    raw(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    /* Test to see if terminal has colors */ 
    if (has_colors() == false) { 
     fail("Colors unavailable\n"); 
    } 

    if (start_color() != OK) { 
     fail("Unable to start colors\n"); 
    } 

    //init_pair(1, COLOR_BLUE, COLOR_BLACK); //wybór kolorów 

    getmaxyx(stdscr, szer, dlug); //pobranie rozmiarów terminalu 
    move(szer/2, (dlug-strlen(powitanie))/2); //przesuwamy kursor na środek (tak aby się ładnie wydrukowało) 
    //attron(COLOR_PAIR(1)); //Aktywujemy wybrane kolory 
    printw(powitanie); //Drukujemy powitanie 
    //attroff(COLOR_PAIR(1));//Dezaktywujemy kolory 
    refresh();//Odswiezamy (inaczej się nie wyswietli) 
    WINDOW * menuwin=newwin(7, dlug-12, szer-9, 6); //Definiujemy i tworzymy 'okno' 
    box(menuwin, 0, 0); 
    refresh();//ponownie odświeżamy aby okno się pojawiło 
    wrefresh(menuwin);//odświeżamy samo okno 
    keypad(menuwin, TRUE);//umozliwiamy dzialanie klawiatury w oknie 

    char *opcje[] = { 
     "Tlumacz z Polskiego na Angielski", 
     "Tlumacz z Angielskiego na Polski", 
     "Edystuj slownik", 
     "Wybierz slownik", 
     "Wyjdz", 
    }; 
    int wybor; 
    int zaznacz=0; 

    while(1)//cala ta petla sluzy ciaglemu tworzeniu menu z podswietleniem wybranego elementu 
    { 
     for(i = 0; i < 5; i++) { 
      if(i == zaznacz) 
       wattron(menuwin, A_REVERSE); 
      mvwprintw(menuwin, i+1, 1, opcje[i]); 
      if (i == zaznacz) 
       wattroff(menuwin, A_REVERSE); 
     } 

     wybor = wgetch(menuwin); 
     switch(wybor) 
     { 
     case KEY_UP: 
      zaznacz--; 
      if(zaznacz < 0) zaznacz = 0;//zabezpieczenie przed wyjsciem "poza" menu 
      break; 
     case KEY_DOWN: 
      zaznacz++; 
      if(zaznacz > 4) zaznacz = 4; 
      break; 
     default: 
      break; 
     } 

     if(wybor==10) break; 
    } 

    printw("\nWybrano:%s", opcje[zaznacz]); 
    refresh(); 

    /* Wait for user to press enter to exit */ 
    getch(); 

    /* Need to cleanup before exit */ 
    endwin(); 

    return 0; 
} 
+1

この例では、menu.hヘッダーは使用されていません。 –