2015-10-24 135 views
2

我为curses表单对象构建了一个通用包装器,以便与我正在处理的大型 模拟项目一起使用。在ncurses中清除字段缓冲区

基本上,我实例化一个generic_form对象,添加一些字段和它们的 描述,然后给它一个焦点,并获得用户输入一个fill_form()例程。因为每个对象都可以多次使用,也就是说,fill_form()可能会在每个实例化中被调用多次,所以我需要在fill_form()例程的开头清除字段缓冲区。目前,我使用这个在程序的开始:

//clear the field buffers in case there's junk in them 
    for (std::vector<FIELD*>::iterator clear_iter = fields.begin(); 
      clear_iter != fields.end(); clear_iter++) 
    { 
     if (*clear_iter != nullptr) 
     { 
      set_field_buffer(*clear_iter, 0, " "); 
     } 
    } 

然而,它抛出在set_field_buffer行上调用fill_form()例程的浮点异常。此外,set_field_buffer行似乎没有做任何事情,至少不清除缓冲区,因为在例程结束时不调用free_field,而是在对象析构函数中,字段缓冲区在每个后续调用中保持不变。

下面是简洁的(丑陋的,在发展)fill_form()函数的全部:

void generic_form::fill_form() 
{ 
    //fields.push_back(NULL); 
    if (fields.size() == 1) 
    { 
     fields.push_back(NULL); 
     form = new_form(static_cast<FIELD**>(fields.data())); 
     fields.erase((fields.end() - 1)); 
     assert(fields.size() == 1); 
    } 
    else 
    { 
     form = new_form(static_cast<FIELD**>(fields.data())); 
    } 
    WINDOW* form_win = derwin(screen, fields.size() + 1, largest_desc + 6, ypos, 
      xpos); 
    set_form_win(form, form_win); 
    set_form_sub(form, form_win); 
    //clear the field buffers in case there's junk in them 
    for (std::vector<FIELD*>::iterator clear_iter = fields.begin(); 
      clear_iter != fields.end(); clear_iter++) 
    { 
     if (*clear_iter != nullptr) 
     { 
      set_field_buffer(*clear_iter, 0, " "); 
     } 
    } 
    post_form(form); 
    for (int x = 0; x < descriptions.size(); x++) 
    { 
     mvwprintw(form_win, x, 0, descriptions.at(x).c_str()); 
    } 
    wmove(form_win, 0, largest_desc + 1); 
    touchwin(screen); 
    wrefresh(form_win); 
    /* Loop through to get user requests */ 
    int ch; 
    while((ch = getch()) != '\n')//KEY_F(1)) 
    { switch(ch) 
      {  
      case KEY_DOWN: 
        /* Go to next field */ 
        form_driver(form, REQ_NEXT_FIELD); 
        /* Go to the end of the present buffer */ 
        /* Leaves nicely at the last character */ 
        form_driver(form, REQ_END_LINE); 
        break; 
      case KEY_UP: 
        /* Go to previous field */ 
        form_driver(form, REQ_PREV_FIELD); 
        form_driver(form, REQ_END_LINE); 
        break; 
      case KEY_LEFT: 
        form_driver(form, REQ_PREV_CHAR); 
        break; 
      case KEY_RIGHT: 
        form_driver(form, REQ_NEXT_CHAR); 
        break; 

      // Delete the char before cursor 
      case KEY_BACKSPACE: 
      case 127: 
        form_driver(form, REQ_DEL_PREV); 
           break; 

      // Delete the char under the cursor 
      case KEY_DC: 
        form_driver(form, REQ_DEL_CHAR); 
        break; 
      default: 
        /* If this is a normal character, it gets */ 
        /* Printed    */  
        form_driver(form, ch); 
        break; 
      } 
    } 
    form_driver(form, REQ_VALIDATION); 
    for (int x = 0; x < fields.size() && first_run; x++) 
    { 
     //store the int_inputs from the forms 
     if ((fields.at(x) != nullptr) && (field_type(fields.at(x)) == 
       TYPE_INTEGER)) 
     { 
      int_inputs.push_back(std::atoi(field_buffer((fields.at(x)), 0))); 
     } 
     if ((fields.at(x) != nullptr) && (field_type(fields.at(x)) == 
       TYPE_ALPHA)) 
     { 
      str_inputs.push_back(field_buffer((fields.at(x)), 0)); 
     } 
    } 
    first_run = false; 
    /* Un post form and free the memory */ 
    unpost_form(form); 
    free_form(form); 
    for (int x = 0; x < fields.size(); x++) 
    { 
     free_field(fields.at(x)); 
    } 
    delwin(form_win); 
} 

长话短说/ TLDR: 如何我清楚或ncurses的重置场缓冲器,不删除并重新添加?

回答

1

可以使用form_driver()

摘录man form_driver

REQ_CLR_EOL 
    Clear to end of line from cursor. 

REQ_CLR_EOF 
    Clear to end of field from cursor. 

REQ_CLR_FIELD 
    Clear the entire field. 

为了阐述这个多一点:-),我使用类似于下面的清算领域代码清理现场缓冲区:

#include <stdio.h> 
#include <stdlib.h> 
#include <form.h> 

enum f_name_l 
{ 
    f_name, f_surname, f_last 
}; 

int main (void) 
{ 
    int ch = 0, i = 0; 
    FIELD *field[3], *save_field; 
    FORM *my_form; 

    initscr(); 
    start_color(); 
    noecho(); 
    raw(); 
    keypad (stdscr, TRUE); 
    refresh(); 

    field[f_name] = new_field (1, 10, 0, 25, 0, 0); 
    field[f_surname] = new_field (1, 10, 2, 25, 0, 0); 
    field[f_last] = NULL; 

    set_field_back (field[f_name], A_UNDERLINE); 
    set_field_back (field[f_surname], A_UNDERLINE); 

    my_form = new_form (field); 
    post_form (my_form); 

    // Form labels 
    mvprintw (0, 1, "Name: "); 
    mvprintw (2, 1, "Surname: "); 
    mvprintw (4, 1, "F5 to clear active field. F6 to clear form."); 

    pos_form_cursor (my_form); 

    refresh(); 

    // ^q to exit 
    while ((ch = getch()) != 17) 
    { 
    switch (ch) 
    { 
     case KEY_UP: 
     form_driver (my_form, REQ_PREV_FIELD); 
     break; 
     case KEY_DOWN: 
     form_driver (my_form, REQ_NEXT_FIELD); 
     break; 
     case KEY_F(5): 
     form_driver (my_form, REQ_CLR_FIELD); 
     break; 
     case KEY_F(6): 
     save_field = current_field (my_form); 

     for (i = 0; i < f_last; i++) 
     { 
      set_current_field (my_form, field[i]); 
      form_driver (my_form, REQ_CLR_FIELD); 
     } 

     set_current_field (my_form, save_field); 
     break; 
     default: 
     form_driver (my_form, ch); 
     break; 
    } 

    form_driver (my_form, REQ_VALIDATION); 
    } 

    endwin(); 

    return EXIT_SUCCESS; 
} 

但看到帖子从Thomas Dickey我开始觉得我的生活是一个谎言:-)。

+0

你能详细解答吗? :-) –

+0

这些将清除关联的窗口,但不清除字段缓冲区。 –