Write a Class Windows menu with C under UNIX
When developing programs, the program's interface, openness is two very important aspects. Currently, the interface of programs running under UNIX systems is relatively dead, and it is not very convenient when performing functional expansion. So, can you design a program that can adjust the interface according to the user asking for the user asking for the user? The answer is yes. Through practice, the author has designed a menu program that allows users to make adjustments to menu positions, width, length, and border or the like by operating the menu parameter file by operating the menu parameter file; When the user needs to be expanded, there is no need to change the source program, and the new feature can be listed on the menu with the parameter file. A parameter file indicates that this program needs to be implemented by two parameter files by ribs: (1), the file (menu.def) of each parameter in the menu, its format is as follows:! The menu code! Sublide serial number! Menu item name! Explea program name! The lower-level menu code! Description: 1. If the menu is "0", it means that this item belongs to the main menu; 2, as the plug-in program name "0", the process corresponding to this menu item is inside or corresponds to a submenu; 3. If the following-level menu is coded as "0", it means that this menu item does not lower the submenu; 4, the item sequence number can be used as a menu hot button. If there is a line in the file menu.def:! 0! 3! Format disk! Format / dev / rfd0135ds18! 0! It represents the third item of the main menu is formatted, and its corresponding execution process is Format / DEV / RFD0135DS18, this item has no submenu. If the user wants to make the inquiry query function program XXX on the main menu of this Program, you can add the following line in Menu.def:! 0! 4! Inquire! XXX! 0! (2), the menu parameters will be described (Menu.conf), and its format is as follows:! Menu code! The last menu code! Border marker! Menu width! Number of menus! Menu column! Start abscissa! Start and leaving! Description: 1, the border sign is "0" means no frame, "1" means a border; 2, the upper-level menu is "-1", indicating that there is no upper-level menu; menu. When the user is not satisfied with the menu display style, you can design a personalized interface by adjusting this file.
Second programming implementation This program file is menu.c, part of the code as follows: #include #define esc 27 #define Ent 13 #define refresh 12 #define max_m 10 / * menu maximum number * / void initial (), NomlastPos (), Revcurpos (), Dispprevline (); Void DispnextLine (), DOMENU (), getMenuConf (), keycont (); void getItem (), get_m_conf (), get_m_item (), clearwin (), execprog (); / * Identify the structure of each menu item * / struct menu {short menu_code; / * The belonging menu code * / short item_order; / * 号 号 号 号 * / Char Item [20]; / * menu item name * / char prog [ 80]; / * This menu execute program * / short submenu_code; / * Next menu number * / struct menu * next; / * Refers to the first pointer * / struct menu * prev; / * points the next item Pointer * /} m_item, * head, * this, * new, * Last, * Scrpos, * lastscripos, * begin, * lastbegin, * lastscr [max_m]; / * Identify each menu content Structure * / Struct MenuConf {Short Menu_code; / * Menu code * / short last_code; / * Previous menu code * / short bord_flag; / * Border flag 0 - Border 1 - Border ** / short m_wight; / * menu display width * / Short m_lengh; / * Each line number * / short m_col; / * Menu column number * / short m_bx; / * menu start absorbent * / short m_by; / * menu initial handings * /} m_conf; WINDOW * MENUW IN, * Boxwin, * Curw, * Lastw [MAX_M], * WORKWIN; Long Curpos, LastCurpos, Lastscrcurpos, LastMenucur [MAX_M]; Short Menu_no = 0, WNO = 0; / * Primer * / Main () {Initial ); GetMenuConf (0); / * Take the No. 0 menu parameter * / / * Create the main window * / menuwin = newwin (m_conf.m_lengh, m_conf.m_wight, m_conf.m_bx 1, m_conf.m_by 1); CURW = menuwin; lastw [wno] = menuwin; getItem (); / * Take the current menu * / DOMENU (Head, 0); endwin ();} / * Take the menu of each parameter function * / void getItem () {File * fp; char buff [0x100]; / * Building a border window * / Boxwin = newwin (m_conf.m_lengh 2, m_conf.m_bx, m_conf.m_by); keypad (curw, true); IF (m_conf.bord_flag == 1) {Box (Boxwin, 0, 0); Wrefresh (Boxwin);} head =
NULL; if ((fp = fopen ("./ menu.def", "r")) == NULL) {fprintf (stderr, "/ n cannot open menu definition file / n"); return;} while (fgets (buff, 0x100, fp)! = null) {GET_M_ITEM (BUF); if (m_item.menu_code! = menu_no) Continue; new = (struct menu *) Malloc (Struct Menu); if (Head == Null ) {Last = head;} else {this-> next = new; las = this;} this = new; this-> menu_code = m_item.Menu_code; this-> item_order = m_item.item_order; strcpy (this -> Item, m_item.item; strcpy (this-> prog, m_item.prog); this-> SubMenu_code = m_item.submenu_code; this-> next = null; this-> prev = last;} fclose (fp); } / * Menu processing function * / void Domenu (CURSCRP, CURP) STRUCT MENU * CURSCRP; INT CURP; {INT I, X, Y; Struct Menu * MPOS; this = head; disponepage (this); curpos = curp; SCRPOS = CURSCRP; LastCurpos = Lastscrcurpos = 0; Revcurpos (); for (;;) {Switch (wgetch (curs) {copy ent: / * has the next menu * / if ((! strpos-> prog, "0")) && (SCRPOS-> SubMenu_code! = 0)) { lastbegin = begin-> next; getmenuconf (scrpos-> submenu_code); menu_no = scrpos-> submenu_code; wno ; lastmenucur [wno] = curpos; lastscr [wno] = scrpos; lastw [wno] = curw; workwin = newwin (m_conf .m_lengh, m_conf.m_wight, m_conf.m_bx 1, m_conf.m_by 1); CURW = Workwin; GetItem (); Domenu (Head, 0);} / * is an internal function * / / * is an external executable program * / Else {endwin (); execprog ();} Break; case esc: case 'q': case 'q': Case '0': / * No superior menu * / if (m_conf.last_code == -1) {Clearwin ();
Endwin (); exit (0);} / * has a higher-level menu * / else {menu_no = m_conf.last_code; clearwin (); getMenuConf (menu_no); GetItem (); touchwin (Lastw [WNO]); curw = lastw [ WNO]; curpos = lastmenucur [wno]; SCRPOS = lastscr [wno]; WNO ---; Wrefresh (CURW);} Break; Case 'R': Case 'R': Case Refresh: / * Removal screen * / Wrefresh (CURSCR); BREAK; Case key_right: / * right cursor key * / if (SCRPOS-> Next! = null) {LastCurpos = Curpos; Lastscripos = SCRPOS; SCRPOS = SCRPOS-> Next; GetYX (CURW, X, Y) ; If (x == m_conf.m_lengh-1) && (curpos% m_conf.m_col == m_conf.m_col-1)) {curpos - = (m_conf.m_col-1); LastCurpos = CURPOS - 1; / * Implementation Upset screen * / wmove (curw, 0, 0); wdeleteln (CURW); DispnextLine ("R");} else curpos ; if ((CURPOS% m_conf.m_col == 0) && (m_conf.m_lengh == 1 )) {REVCURPOS (); break;} else {nomlastpos (); revcurpos ();}} Break; Case Key_left: / * left cursor key * / if (SCRPOS-> prev! = Null) {LastCurpos = Curpos; Lastscripos = SCRPOS; SCRPOS = SCRPOS-> Prev; GetYX (CURW, X, Y); IF ((x == 0) && (curpos% m_conf.m_col == 0)) {curpos = m_conf.m_col-1; LastCurPos = CURPOS 1; / * Implement the downward screen * / Winsetln (CURW); DisppRevline ("L");} else curpos -; if ((curpos% m_conf.m_col == m_conf.m_col-1) && (m_conf.m_lengh == 1)) {REVCURPOS (); Break;} else {Nomlastpos Revcurpos ();}}}} Break; Case key_up: / * on the migratory key * / lastcurpos = curpos; Lastscripos = SCRPOS; MPOS = SCRPOS; for (i = 0; I / TD> IF (MPOS-> prev! = NULL) MPOS = MPOS-> Prev; Else Break;
}} (I == m_conf.m_col) {getYX (CURW, X, Y); if (x == 0) {LastCurpos = m_conf.m_col; / * Implement the downward screen * / winsetln (CURW); DisppRevline ("U");} else {curpos- = m_conf.m_col;} SCRPOS = MPOS; if (m_conf.m_lengh! = 1) nomlastpos (); revCurpos ();} Break; case key_down: / * Short timber button * / Lastcurpos = curpos; mpos = scrPos; for (i = 0; I / TD> IF) MPOS = MPOS-> Next; else break;} if (i == m_conf .m_col) {getYX (CURW, X, Y); if (x == m_conf.m_lengh-1) {LastCurpos - = m_conf.m_col; / * Implement an upward scroll * / wmove (CURW, 0, 0); Wdeleteln (CURW); DispNextLine ("D");} else curpos = m_conf.m_col; scrpos = mpos; if (m_conf.m_lengh! = 1) nomlastpos (); revcurpos ();} Break; default: beep (); break; ;}}} / * Reverse current item function * / void revcurpos () {WattRset (curw, a_standout); Wmove (CURW, CURPOS / M_CONF.M_COL, (CURPOS% M_Conf.m_col) * m_conf.m_wight / m_conf.m_col m_conf.m_col); WPrintW (CURW, "% s", SCRPOS-> ITEM); WattRset (CURW, A_NORMAL); WREFRESH (Boxwin);} / * Normal display Previous function * / void NomlastPos () {Wmove (curw, lastcurpos / m_conf.m_col, (LastCurpos% m_conf.m_col) * m_conf.m_wight / m_conf.m_col m_conf.m_col); WPrintW (CURW, "% S", LastsCrPos-> item);} / * Display a page function * / void disponepage (first) struct menu * first; {Short Col, row; begin = first; / * begin is this page head pointer * / for (row = 0; row / td> for (col = 0; col / td> / * m_conf.m_wight / m_col) for each menu item * / Wmove (CURW, ROW, COL * m_conf.m_wight / m_conf.m_col m_conf.m_col); WPrintW (CURW, "% S", first-> item);
Wrefresh (CURW); Last = first; first = first-> next; if (first == null) {Break;}}}} / * Display the previous row function * / void dispprevline (flag) Char flag [2]; / * L-left cursor causes U-gums to cause * / {struct menu * TMPOS; int TmpCurpos; tmpcurpos = curpos; TMPPOS = SCRPOS; if (Flag [0] == 'u') {while (tmpcurpos% m_conf.m_col ! = 0) {TMPPOS = TMPPOS-> prev; TmpCurpos -;} tmpos = tmpos-> prev;} for (tmpcurpos = m_conf.m_col-1; tmpcurpos> = 0; tmpcurpos -) {Wmove (CURW, 0 (tmpcurpos% m_conf.m_col) * m_conf.m_wight / m_conf.m_col m_conf.m_col); Wprintw (CURW, "% s", tmpos-> item); begin = tmpos; / * begin is this page first pointer * / Last = tmpos; tmpos = tmpos-> prev; if (tmpos == null) Break;} Wrefresh (CURW);} / * Show next line function * / void dispnextLine (FLAG) Char flag [2]; / * r - The right cursor causes D- down cursor caused * / {struct menu * TMPPOS; int TmpCurpos; tmpcurpos = curpos; tmpos = scrPos; if (Flag [0] == 'd') {while (tmpcurpos% m_conf.m_col! = m_conf.m_col-1) {TMPOS = TMPOS -> Next; TmpCurpos ;} tmpos = tmpos-> next;} for (tmpcurpos = 0; tmpcurpos
R ")) == NULL) {fprintf (stderr," can not open menu config file); return;} while (fgets (menu_buff, 0x100, fp)! = null) {GET_M_CONF (MENU_BUFF); if (m_conf. Menu_code == menu_code) Break;} return;} / * Take the specified menu parameter processing function * / void get_m_conf (menu_conf) char * menu_conf; {Register i, j, k; char buff [20]; j = k = 0; For (i = 0; i