将窗口调节和选择菜单封装成类
这是我目前为止觉得自己写的最好的一段c++了,虽然还是挺烂的吧。
//转载请注明Author : liutianchen
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); const int width = 100, height = 30; const int marginleft = 3, margintop = 2; class window_set { private: char *title; int Lbg_color, Lfg_color; const int main_list_marginleft = 4 * marginleft; const int main_list_margintop = margintop * 2; const int main_list_width = width - 2 * main_list_marginleft - 4; const int main_list_height = height - 2 * main_list_margintop; void goto_xy(const int x, const int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(console_handle, coord); } void set_color(const int bg_color, const int fg_color) { SetConsoleTextAttribute(console_handle, bg_color * 16 + fg_color); } public: window_set(const char * title,const int bg_color,const int fg_color) { char window_info[50]; char window_color[50]; sprintf(window_info, "mode con cols=%d lines=%d", width, height); system(window_info); sprintf(window_color, "color %X%X", bg_color, fg_color); system(window_color); Lbg_color = bg_color; Lfg_color = fg_color; SetConsoleTitle(title); } COORD get_pos() { COORD pos = { (short)main_list_marginleft,(short)main_list_margintop }; return pos; } COORD get_size() { COORD size = { (short)main_list_width,(short)main_list_height }; return size; } COORD get_color() { COORD color = { (short)Lbg_color,(short)Lfg_color }; return color; } }; class _list { private: char **lplist; int Lbg_color = 0, Lfg_color = 7; COORD Lpos = { 0,0 }; COORD Lsize = { 100,30 }; int selected_toll_gate; void clear_line() { CONSOLE_SCREEN_BUFFER_INFO buffer_info; GetConsoleScreenBufferInfo(console_handle, &buffer_info); COORD cur_pos = buffer_info.dwCursorPosition; DWORD length; FillConsoleOutputAttribute(console_handle, Lbg_color * 16 + Lfg_color, Lsize.X, cur_pos, &length); FillConsoleOutputCharacter(console_handle, ' ', Lsize.X, cur_pos, &length); } void goto_xy(const int x, const int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(console_handle, coord); } void set_color(const int bg_color, const int fg_color) { SetConsoleTextAttribute(console_handle, bg_color * 16 + fg_color); } void highlight(const char **list, const int i, const int j, const int list_marginleft, const int list_margintop) { goto_xy(list_marginleft, list_margintop + j); set_color(7, 0); clear_line(); printf(list[i]); set_color(Lbg_color, Lfg_color); } void select_list(const char **list, const int height, const int list_marginleft, const int list_margintop, int *selected_toll_gate); void dual_outline_border(const int marginleft, const int margintop, const int border_width, const int border_height); void print_list(const char **list, const int start, const int selected, const int height, const int list_marginleft, const int list_margintop); public: void get_pos_size(COORD pos, COORD size) { Lpos = pos; Lsize = size; } void make_str(char ***list) { int i; *list = new char *[101]; for (i = 0;i < 100;i++) { (*list)[i] = new char[8]; sprintf((*list)[i], "关卡%03d", i + 1); } (*list)[100] = NULL; } int start_(COORD color) { Lbg_color = color.X; Lfg_color = color.Y; dual_outline_border(Lpos.X - 2, Lpos.Y - 1, Lsize.X / 2 + 1, Lsize.Y + 2); select_list((const char **)lplist, Lsize.Y, Lpos.X, Lpos.Y, &selected_toll_gate); return selected_toll_gate; } _list(char *** list) { make_str(&lplist); *list = lplist; } ~_list() { int i; for (i = 0;i < 100;i++) delete lplist[i]; delete[] lplist; } }; void _list::dual_outline_border(const int marginleft, const int margintop, const int border_width, const int border_height) { int i; goto_xy(marginleft, margintop); for (i = 0;i < border_width;i++) { goto_xy(marginleft + i * 2, margintop + border_height); cout << "═"; goto_xy(marginleft + i * 2, margintop); cout << "═"; } for (i = 0;i < border_height;i++) { goto_xy(marginleft, margintop + i); cout << "║"; goto_xy(marginleft + border_width * 2, margintop + i); cout << "║"; } goto_xy(marginleft, margintop); cout << "╔"; goto_xy(marginleft + border_width * 2, margintop); cout << "╗"; goto_xy(marginleft + border_width * 2, margintop + border_height); cout << "╝"; goto_xy(marginleft, margintop + border_height); cout << "╚"; goto_xy(marginleft, margintop + border_height + 3); } void _list::print_list(const char **list, const int start, const int selected, const int height, const int list_marginleft, const int list_margintop) { int i, j; for (i = start, j = 0;j <= height&&list[i] != NULL;i++, j++) { goto_xy(list_marginleft, list_margintop + j); if (j == selected) { set_color(7, 0); clear_line(); printf(list[i]); set_color(Lbg_color, Lfg_color); } else { clear_line(); printf(list[i]); } } } void _list::select_list(const char **list, const int height, const int list_marginleft, const int list_margintop, int *selected_toll_gate) { char t1, t2; int i = 0, j = 0; print_list(list, 0, 0, height, list_marginleft, list_margintop); if (i < height) while (1) { t1 = _getch(); if (t1 == -32) { t2 = _getch(); if (t2 == 72) { if (j > 0) { goto_xy(list_marginleft, list_margintop + j); set_color(Lbg_color, Lfg_color); clear_line(); printf(list[i]); j--; i--; highlight(list, i, j, list_marginleft, list_margintop); } else if (j == 0) if (i > 0) { i--; print_list(list, i - j, j, height, list_marginleft, list_margintop); } } else if (t2 == 80) { if (j < height) { goto_xy(list_marginleft, list_margintop + j); set_color(Lbg_color, Lfg_color); clear_line(); printf(list[i]); j++; i++; highlight(list, i, j, list_marginleft, list_margintop); } else if (j == height) if (list[i + 1] != NULL) { i++; print_list(list, i - j, j, height, list_marginleft, list_margintop); } } } else if (t1 == 13) { system("cls"); *selected_toll_gate = i; return; } } }
为什么为什么为什么少于150字》》凸
算上代码这都多少字了??
好吧我其实注意到了两个问题
第一个,传参如果和private成员重名了会是一件很麻烦的事情,所以我的private成全统统改名Lvalue
第二个,尽量让一个类完成一个功能,我一开始把两个合在一起写,乱的个我啊
第三个,Console Function其实没有那么难,一些数据类型都是正常向数据类型的封装(huangemingzi——)用的时候直接查msdn就行
但是要注意一下,很多自动转换的数据类型(比如LPSTR-》char*)在其他严格的编译器下是过不去的,所以稍稍谨慎一下
我到现在才知道COORD的x和y都是short
翻滚屏幕刷新闪屏严重的话有这么几个办法
第一个,把cout换成printf
第二个,把清屏换成FillConsoleOutputCharactor
写过的函数最好具有普适性
比如我写的clear_line()
从一开始我就没打算把现在的位置传参,而是直接读
就是因为我想让这个函数在哪里都能用而不是限定在这个地方
好了,够150了吗?