问题
I have been attempting to create a dynamic menu in ncurses for some time now and finally had some success. However I was concerned that the manner in which I am achieving this is risky. Below is my code:
void ListBox::CreateMenu()
{
my_items = (ITEM **) calloc(2,sizeof(ITEM *));
char * choices[] = {"Search Results", (char *) NULL};
my_items[0] = new_item(choices[0], (char *) NULL);
my_items[1] = new_item((char *) NULL, (char *) NULL);
my_menu = new_menu((ITEM**) my_items);
set_menu_win(my_menu, list_window);
der_window = derwin(list_window, h-2,w-2, 1, 1);
//set_menu_sub(my_menu, derwin(list_window, h-2,w-2, 1, 1));
set_menu_sub(my_menu, der_window);
set_menu_format(my_menu, h-2, 1);
set_menu_mark(my_menu, " > ");
post_menu(my_menu);
n_choices = 2;
}
void ListBox::UpdateRange(std::string search, int after_colon)
{
int start = 0;
int end = 0;
if(search_map.count(search.substr(after_colon)))
{
start = search_map[search.substr(after_colon)][0];
end = search_map[search.substr(after_colon)][1];
}
unpost_menu(my_menu);
for(int i = 0; i < n_choices; i++){free_item(my_items[i]);}
if(start == 0 && end == 0)
{
NoResults();
return;
}
my_items = (ITEM **) calloc(int((end-start)+ 1),sizeof(ITEM *));
int count = 0;
for(int i = start; i < end; i++)
{
my_items[count] = new_item(vec[i].c_str(), (char *) NULL);
count++;
}
my_items[int(vec.size())] = new_item((char *) NULL, (char *) NULL);
set_menu_items(my_menu, my_items);
post_menu(my_menu);
wrefresh(list_window);
n_choices = int(end-start) +1 ;
}
void ListBox::NoResults()
{
my_items = (ITEM **) calloc(2,sizeof(ITEM *));
char * choices[] = {"NO RESULTS", (char *) NULL};
my_items[0] = new_item(choices[0], (char *) NULL);
my_items[1] = new_item((char *) NULL, (char *) NULL);
set_menu_items(my_menu, my_items);
post_menu(my_menu);
wrefresh(list_window);
n_choices = 2;
}
The reason I am concerned about the above code is because when I looked at the ncurses method for unpost_menu and post_menu in m_post.c I became concerned and a little confused as to how my current code is working. In the code for unpost_menu.c, from ncurses, it looks like so,
unpost_menu(MENU * menu)
{
WINDOW *win;
T((T_CALLED("unpost_menu(%p)"), (void *)menu));
if (!menu)
RETURN(E_BAD_ARGUMENT);
if (menu->status & _IN_DRIVER)
RETURN(E_BAD_STATE);
if (!(menu->status & _POSTED))
RETURN(E_NOT_POSTED);
Call_Hook(menu, itemterm);
Call_Hook(menu, menuterm);
win = Get_Menu_Window(menu);
werase(win);
wsyncup(win);
assert(menu->sub);
delwin(menu->sub);
menu->sub = (WINDOW *)0;
assert(menu->win);
delwin(menu->win);
menu->win = (WINDOW *)0;
ClrStatus(menu, _POSTED);
RETURN(E_OK);
}
I notice that in unpost_menu there is a call to delwin; however my code works just fine and if there are no results it correctly displays no results and if there are results it correctly displays the results. I am wondering if anybody has any insight as what might actually be going on.
A basic description of my program is as follows. The CreateMenu() function is only called once, and that is when the ListBox constructor is called. My program then waits for the user to input a search query, if there are results it returns the results. If there are no results it returns no results. Everything appears to run correctly, but I am confused as to how it is running given the call to delwin in the unpost_menu method. Any insight would be great thanks.
Pictures of Program
来源:https://stackoverflow.com/questions/31974444/creating-a-dynamic-menu-in-ncurses