now, ether the menu->toprow or the menu->curitem is not match with what we see in the subwin.
After reading the sources, I find that, ether the function [set_current_item] or [set_top_row] can do what I wanted, so I change the source below:
Is there other method can do what I wanted? or is it a bug? Looking forward to your reply, thanks!
1 #include <curses.h>
2 #include <menu.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <locale.h>
6
7 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
8 #define CTRLD 4
9
10 char *choices[] = {
11 "Choice 1",
12 "Choice 2",
13 "Choice 3",
14 "Choice 4",
15 "Choice 5",
16 "Choice 6",
17 "Choice 7",
18 "Choice 8",
19 "Choice 9",
20 "Choice 10",
21 "Exit",
22 (char *)NULL,
23 };
24
25 void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
26
27 int main()
28 {
29 ITEM **my_items;
30 int c;
31 MENU *my_menu;
32 WINDOW *my_menu_win;
33 int n_choices, i;
34 /* Added by address@hidden [2014-03-03 18:31:25] */
35 int ret, cur_idx, count;
36
37 setlocale(LC_ALL, "");
38
39 /* Initialize curses */
40 initscr();
41 start_color();
42 cbreak();
43 noecho();
44 keypad(stdscr, TRUE);
45 init_pair(1, COLOR_RED, COLOR_BLACK);
46 init_pair(2, COLOR_CYAN, COLOR_BLACK);
47
48 /* Create items */
49 n_choices = ARRAY_SIZE(choices);
50 my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
51 for(i = 0; i < n_choices; ++i)
52 my_items[i] = new_item(choices[i], choices[i]);
53
54 /* Crate menu */
55 my_menu = new_menu((ITEM **)my_items);
56
57 /* Create the window to be associated with the menu */
58 my_menu_win = newwin(10, 40, 4, 4);
59 keypad(my_menu_win, TRUE);
60
61 /* Set main window and sub window */
62 set_menu_win(my_menu, my_menu_win);
63 set_menu_sub(my_menu, derwin(my_menu_win, 6, 38, 3, 1));
64 set_menu_format(my_menu, 5, 1);
65
66 /* Set menu mark to the string " * " */
67 set_menu_mark(my_menu, " * ");
68
69 /* Print a border around the main window and print a title */
70 box(my_menu_win, 0, 0);
71 print_in_middle(my_menu_win, 1, 0, 40, "My Menu", COLOR_PAIR(1));
72 mvwaddch(my_menu_win, 2, 0, ACS_LTEE);
73 mvwhline(my_menu_win, 2, 1, ACS_HLINE, 38);
74 mvwaddch(my_menu_win, 2, 39, ACS_RTEE);
75
76 /* Added by address@hidden [2014-03-03 18:31:12] */
77 ret = set_current_item(my_menu, my_items[8]);
78 cur_idx = item_index(current_item(my_menu));
79 count = item_count(my_menu);
80 if (cur_idx >= count - my_menu->arows) {
81 /* It's ugly that we use the menu's internal member [menu->toprow],
82 * because ether 'set_current_item' or 'set_top_row' will modify
83 * both of the member [menu->toprow] and [menu->curitem], and the
84 * logic between the two member is what we wanted */
85 my_menu->toprow = count - my_menu->arows;
86 }
87
88 /* Post the menu */
89 post_menu(my_menu);
90 wrefresh(my_menu_win);
91 attron(COLOR_PAIR(2));
92 mvprintw(LINES - 2, 0, "Use PageUp and PageDown to scoll down or up a page of items");
93 mvprintw(LINES - 1, 0, "Arrow Keys to navigate (F1 to Exit)");
94 attroff(COLOR_PAIR(2));
95
96 /* Added by address@hidden [2014-03-03 18:31:17] */
97 mvprintw(LINES - 4, 0, "ret: %d, top: %d, cur_idx: %d, cur->name: %s",
98 ret, top_row(my_menu), item_index(current_item(my_menu)), item_name(current_item(my_menu)));
99
100 refresh();
101 while((c = wgetch(my_menu_win)) != KEY_F(1))
102 {
103 switch(c)
104 {
105 case KEY_DOWN:
106 menu_driver(my_menu, REQ_DOWN_ITEM);
107 break;
108 case KEY_UP:
109 menu_driver(my_menu, REQ_UP_ITEM);
110 break;
111 case KEY_NPAGE:
112 menu_driver(my_menu, REQ_SCR_DPAGE);
113 break;
114 case KEY_PPAGE:
115 menu_driver(my_menu, REQ_SCR_UPAGE);
116 break;
117 }
118 wrefresh(my_menu_win);
119 }
120
121 /* Unpost and free all the memory taken up */
122 unpost_menu(my_menu);
123 free_menu(my_menu);
124 for(i = 0; i < n_choices; ++i)
125 free_item(my_items[i]);
126 endwin();
127 }
128 void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
129 {
130 int length, x, y;
131 float temp;
132
133 if(win == NULL)
134 win = stdscr;
135 getyx(win, y, x);
136 if(startx != 0)
137 x = startx;
138 if(starty != 0)
139 y = starty;
140 if(width == 0)
141 width = 80;
142 length = strlen(string);
143 temp = (width - length) / 2;
144 x = startx + (int)temp;
145 wattron(win, color);
146 mvwprintw(win, y, x, "%s", string);
147 wattroff(win, color);
148 refresh();
149 }