2017-02-13 6 views
2

Ich mache ein Programm mit Ncurses, die den Bildschirm in zwei Fenster teilt. Der obere Bildschirm kann Eingaben annehmen, und durch Drücken von '#' wird der gesamte Text in das untere Fenster verschoben und das obere Fenster gelöscht. In meinem Code versuche ich copywin() zu verwenden, um das untere Fenster zu ersetzen, aber es wird die Formulierung nicht in das zweite Fenster einfügen. Das ist, was ich habe ...Überschreiben eines Fensters

#include <ncurses.h> 

int main(int argc, char *argv[]) 
{ 
// Declare variables for windows and sizes 
WINDOW *top_win, *bottom_win; 
int maxx, maxy, halfy, flag = 0, ch; 

// Start curses 
initscr(); 
noecho(); 
refresh(); 

// get the max x's and y's 
getmaxyx(stdscr, maxy, maxx); 
halfy = maxy >> 1; 

// Start color 
start_color(); 
init_pair(1, COLOR_BLACK, COLOR_WHITE); 
init_pair(2, COLOR_WHITE, COLOR_CYAN); 
init_pair(3, COLOR_RED, COLOR_WHITE); 

// Make windows 
top_win = newwin(halfy, maxx, 0, 0); 
wbkgd(top_win, COLOR_PAIR(1)); 
wrefresh(top_win); 

bottom_win = newwin(halfy, maxx, halfy, 0); 
wbkgd(bottom_win, COLOR_PAIR(2)); 
wrefresh(bottom_win); 

// Allow functions keys 
keypad(top_win, TRUE); 
keypad(bottom_win, TRUE); 

// while loop to get input 
while((ch = getch()) != '`') 
    { 
     if(ch == '@') 
      { 
       if(flag == 1) 
        { 
         flag = 0; 
        } 
       else 
        { 
         flag = 1; 
        } 
      } 
     else if(ch == '#') 
      { 
       //waddstr(bottom_win, "testing"); 
       copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE); 
       //overwrite(top_win, bottom_win); 
       //werase(top_win); 
      } 
     else if(flag != 1) 
      { 
       waddch(top_win, ch | COLOR_PAIR(1)); 
      } 
     else if(flag == 1) 
      { 
       waddch(top_win, ch | COLOR_PAIR(3)); 
      } 
     wrefresh(top_win); 
     wrefresh(bottom_win); 
    } 

// end curses 
delwin(top_win); 
delwin(bottom_win); 
endwin(); 
return 0; 
} 

Ich weiß, dass ich zum Fenster drucken kann das Zeichen ‚#‘ wegen meiner kommentierte heraus, Test-Anweisung. Ich habe auch gerade mit override() versucht, aber das hat auch nicht funktioniert. Bekomme ich einfach die Argumente durcheinander oder ist es etwas anderes? Irgendwelche Ideen? Vielen Dank im Voraus!

Antwort

1

Ich habe keine gute Erklärung hat, warum es funktioniert, aber solange xoff und yoff sind mindestens 1 in dem folgenden Code, die Daten aus dem oberen Fenster wird in dem unteren Fenster OK kopiert (und gelöscht von das obere Fenster). Die Farbe wird nicht kopiert. Wenn der Offset 0 ist, werden die Daten nicht kopiert. Die Zeichenfolge testing wird oben links im unteren Fenster hinzugefügt - sie kann weggelassen werden und das kopierte Material ist noch in Ordnung.

#include <ncurses.h> 

int main(void) 
{ 
    // Declare variables for windows and sizes 
    WINDOW *top_win, *bottom_win; 
    int maxx, maxy, halfy, flag = 0, ch; 

    // Start curses 
    initscr(); 
    noecho(); 
    refresh(); 

    // get the max x's and y's 
    getmaxyx(stdscr, maxy, maxx); 
    halfy = maxy >> 1; 

    // Start color 
    start_color(); 
    init_pair(1, COLOR_BLACK, COLOR_WHITE); 
    init_pair(2, COLOR_WHITE, COLOR_CYAN); 
    init_pair(3, COLOR_RED, COLOR_WHITE); 

    // Make windows 
    top_win = newwin(halfy, maxx, 0, 0); 
    wbkgd(top_win, COLOR_PAIR(1)); 
    wrefresh(top_win); 

    bottom_win = newwin(halfy, maxx, halfy, 0); 
    wbkgd(bottom_win, COLOR_PAIR(2)); 
    wrefresh(bottom_win); 

    // Allow functions keys 
    // keypad(top_win, TRUE); 
    // keypad(bottom_win, TRUE); 

    // while loop to get input 
    int xoff = 1; 
    int yoff = 1; 
    while ((ch = getch()) != '`') 
    { 
     if (ch == '@') 
     { 
      if (flag == 1) 
      { 
       flag = 0; 
      } 
      else 
      { 
       flag = 1; 
      } 
     } 
     else if (ch == '#') 
     { 
      waddstr(bottom_win, "testing"); 
      // copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE); 
      copywin(top_win, bottom_win, 0, 0, yoff, xoff, halfy-yoff, maxx-xoff, TRUE); 
      // overwrite(top_win, bottom_win); 
      werase(top_win); 
     } 
     else if (flag != 1) 
     { 
      waddch(top_win, ch | COLOR_PAIR(1)); 
     } 
     else if (flag == 1) 
     { 
      waddch(top_win, ch | COLOR_PAIR(3)); 
     } 
     wrefresh(top_win); 
     wrefresh(bottom_win); 
    } 

    // end curses 
    delwin(top_win); 
    delwin(bottom_win); 
    endwin(); 
    return 0; 
} 

Testing auf Mac macOS Sierra 10.12.3 mit GCC 6.3.0 ausgeführt wird, die lokale -lncurses Bibliothek.

+0

das wirklich seltsam .. Ich denke, weil es hat ein Problem mit dem Kopieren von allem und den Grenzen. Es funktioniert aber und vielen Dank, dass Sie es herausgefunden haben! Ich werde mehr auf die Argumente von copywin() eingehen müssen. –

+0

Ja - Ich vermute, dass es etwas mit Grenzen zu tun hat, aber die "Testing" -String erscheint dort, wo man erwarten würde, dass das kopierte Material erscheint. Wie gesagt, ich habe keine gute Erklärung für das, was vor sich geht. Ich begann mit Offsets von (10, 10) und bekam Material. Dies führte zur Minimierung (Offsets 2, 1, 0 nach 10). Wenn Sie eine gute Erklärung haben, lassen Sie es mich wissen (zum Beispiel einen Kommentar). –

3

copywin überprüft die angegebenen Zeilen/Spalten und decides that your destination rectangle doesn't lie completely within the destination window. Hier ist eine schnelle Lösung für Ihr Programm:

--- foo.c.orig 2017-02-13 16:13:12.000000000 -0500 
+++ foo.c  2017-02-13 16:30:18.037987489 -0500 
@@ -51,7 +51,7 @@ 
     else if(ch == '#') 
      { 
       //waddstr(bottom_win, "testing"); 
-    copywin(top_win, bottom_win, 0, 0, halfy, 0, halfy, maxx, TRUE); 
+    copywin(top_win, bottom_win, 0, 0, 0, 0, halfy - 1, maxx - 1, TRUE); 
       //overwrite(top_win, bottom_win); 
       //werase(top_win); 
      } 
@@ -73,4 +73,3 @@ 
endwin(); 
return 0; 
} 

Zeilen und Spalten sind nummeriert von Null bis zur letzten Zeile/Spalte (das ist eine weniger als die Fenstergröße), so dass ich subtrahiert man von der dmaxrow und dmaxcol Parameter. Der fünfte Parameter dminrow war über den unteren Rand des Fensters.

ncurses überprüft die Parameter. In Bezug auf Kompatibilität und Übertragbarkeit wird das gleiche Programm mit Solaris-Curses (das "ncurses.h" in "curses.h" ändert) ausgeführt.

Die manuelle Seite verbessert werden könnte, aber es ist klar genug in Bezug auf colors:

nur Text, wo die beiden Fenster überlappen kopiert