Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ncurses: Beim verkleiner des Fensters keine neue Rückgabe von getmaxyx



CommanderSchmer
22-11-2005, 09:08
Moin!

Ich bin gerade dabei, mich in ncurses einzuarbeiten.

Jetzt ist allerdings ein Problem aufgetaucht, für das ich einfach keine Lösung finde..


Mein Programm ruft via getmaxyx() die Grösse des Terminalfensters ab und erstellt mit diesen Koordinaten ein Menü. Wenn die Fenstergrösse des Terminals geändert wird, soll sich das Menü natürlich entsprechend anpassen.

Momentan habe ich es so realisiert, dass, wenn ich F3 drücke, ein Zähler ausgegeben wird (zum testen), dann das Menü und meine Nachrichten via werase() gelöscht wird. Danach wird die Oberfläche wieder neu erstellt.

Wenn ich das Terminalfenster vergrössere, funktioniert alles wunderbar.
Wenn ich das Fenster jedoch verkleinere, wird der Zähler zwar hochgesetzt und angezeigt, aber die "aktualisierte" Ausgabe der Oberfläche wird nicht gemacht.
Ich lasse mir auch die von getmaxyx() zurückgegebenen X- und Y-Werte ausgeben - an diesen ändert sich auch nichts.


Ich habe schon das Netz und mehrere Foren durchsucht, allerdings bin ich nirgendwo auf dieses Problem gestossen.
Ich habe es mit dem Gnome Terminal und xterm ausprobiert, bei beiden tritt dieses Verhalten auf.


Hier ist mein Quellcode


#include <curses.h>
#include <stdlib.h>
#include <unistd.h>

#define ENTER 10
#define ESCAPE 27

int y, x, i;
WINDOW *menue,*nachrichten;

void haupt();
void oberflaeche();


void fenster_aendern()
{
printw(" %i", i);
i++;
refresh();
sleep(1);
werase(menue);
werase(nachrichten);
refresh();

oberflaeche();
}


void init_curses()
{
initscr();
start_color();
init_pair(1, COLOR_WHITE, COLOR_BLUE);
init_pair(2, COLOR_BLACK, COLOR_GREEN);
init_pair(3, COLOR_RED, COLOR_GREEN);
curs_set(0);
noecho();
keypad(stdscr, TRUE);
}


void mach_menue(WINDOW *menubar)
{
wbkgd(menue, COLOR_PAIR(2));
waddstr(menue, "Datenbank (");
wattron(menue, COLOR_PAIR(3));
waddstr(menue, "F2");
wattroff(menue, COLOR_PAIR(3));
waddstr(menue, ") |");

wmove(menue, 0, 17);
waddstr(menue, "Log (");
wattron(menue, COLOR_PAIR(3));
waddstr(menue, "F3");
wattroff(menue, COLOR_PAIR(3));
waddstr(menue, ") |");

wmove(menue, 0, 28);
waddstr(menue, "DK40 beenden (");
wattron(menue, COLOR_PAIR(3));
waddstr(menue, "F4");
wattroff(menue, COLOR_PAIR(3));
waddstr(menue, ") |");

wmove(menue, 0, x-22);
waddstr(menue, "Programm beenden ");
wattron(menue, COLOR_PAIR(3));
waddstr(menue, "(ESC)");
wattroff(menue, COLOR_PAIR(3));
}


void oberflaeche()
{
getmaxyx(stdscr, y, x);

bkgd(COLOR_PAIR(1));
menue = subwin(stdscr,1,x,0,0);
nachrichten = subwin(stdscr,1,x-1,y-1,1);
mach_menue(menue);

move(2,1);
printw("Bitte eine Funktionstaste druecken. x: %i, y: %i", x, y);
move(3,1);
printw("ESC beendet das Programm");
refresh();
}


void hauptschleife()
{
int key;

do
{
key = getch();
refresh();
werase(nachrichten);
wrefresh(nachrichten);
if (key == KEY_F(2))
{
touchwin(stdscr);
refresh();
} else
if (key == KEY_F(3))
{
fenster_aendern();
} else
if (key == KEY_F(4))
{
touchwin(stdscr);
refresh();
} /*else
if (key == KEY_RESIZE)
{
fenster_aendern();
}*/
} while (key != ESCAPE);
}


int main()
{
init_curses();

oberflaeche();
hauptschleife();

delwin(menue);
delwin(nachrichten);
endwin();

return 0;
}


Ich bedanke jetzt schon für alle hilfreichen Beiträge :)

Lord Kefir
24-11-2005, 21:02
Habe den Quelltext mal kurz überflogen... eigentlich würde ich das ja ganz anders machen :)

Erst einmal solltest Du 'nen Signalhandler einrichten, damit Du erfährst, wann sich die Maße des Fensters verändern.



#include <signal.h>

int breite, hoehe;

void zeichne_menue (void) {
...
}

void signal_handler (int sig) {
switch (sig) {
case SIGWINCH:
endwin ();
initscr ();
getmaxyx (stdscr, breite, hoehe);
zeichne_menue ();
break;
}
}

int main (int argc, char *argv[]) {
...
signal (SIGWINCH, signal_handler);
...
}


So in etwa sollte es funktionieren. Du musst bei der Größenveränderung ncurses beenden und neustarten...

Mfg, Lord Kefir


ps: Schau Dir mal cdk an - damit kannst Du ziemlich einfach Menüs etc. zusammenbasteln: http://www.vexus.ca/products/CDK/

CommanderSchmer
25-11-2005, 07:42
Erst einmal solltest Du 'nen Signalhandler einrichten, damit Du erfährst, wann sich die Maße des Fensters verändern.

Genau das hatte ich auch vor, allerdings hab ich das zum testen erst einmal rausgelassen, aber trotzdem danke. :)



So in etwa sollte es funktionieren. Du musst bei der Größenveränderung ncurses beenden und neustarten...

So funktioniert es leider auch nicht, es ist immer noch der selbe Fehler: Beim vergrössern des Fensters funktioniert alles, beim verkleinern sieht es so aus, als ob getmaxyx() gar keine neuen Werte zurückgibt..



ps: Schau Dir mal cdk an - damit kannst Du ziemlich einfach Menüs etc. zusammenbasteln: http://www.vexus.ca/products/CDK/
[/edit]

Danke für den Tipp, ich will aber alles, vor allem zu Lernzwecken, selber basteln. :)

Lord Kefir
25-11-2005, 17:04
Also ich hatte mal dasselbe Problem, weil ich getmaxy () vor meinem refresh () ausgeführt habe... könnte vielleicht daran liegen :)

Mfg, Lord Kefir

CommanderSchmer
28-11-2005, 14:15
:rolleyes:

Ich habe jetzt die neue Version von Ubuntu draufgemacht und benutze ausserdem nun E17 und hier funktioniert auch das verkleinern wunderbar... mysteriös... :confused:


Naja... trotzdem vielen Dank!:)