PDA

View Full Version : ایجاد منو(menu) گرافیکی در سی



Arash m
یک شنبه 02 تیر 1387, 21:06 عصر
سلام.
چند وقتی بود که توی محیط داس زبان سی میخواستم یه منو طراحی بکنم تا از دست پیغام ها و ... راحت بشم.برای همین یه تابع برای ایجاد منو نوشتم که کاملا مستقل هست و به هیچ چیزه دیگه ای احتیاج نداره. کد او این هست :

#include<conio.h>
#include<dos.h>
#include<string.h>

int get_menu(char *str,char *title,int cho_def,int effect_time,int text_color,int title_color,int border_color,int choice_color){
if(*str=='\0')
return 0;
int j,rtn=1,val_line=0,x_start,y_start,x_size,y_size,y _lines[100];
char ch_key;
struct text_info screen_info;

choice_color+=128;

gettextinfo(&screen_info);

x_start=screen_info.curx;
y_start=screen_info.cury;

x_size=screen_info.curx;
y_size=screen_info.cury;

_setcursortype(_NOCURSOR);

//print text of menu:
textcolor(text_color);
if(*title)
cprintf("\n\n\n");
else
cprintf("\n");
while(*str){
delay(effect_time);
if(val_line==0){
gotoxy(x_start+4,wherey());
val_line++;
y_lines[val_line-1]=wherey();

}
if((*str==',')){
if(*(str+1)==','){
cprintf(",");
str+=2;
}
else{
gotoxy(x_start+4,wherey()+2);
val_line++;
y_lines[val_line-1]=wherey();
str++;
}
}
else{
putch(*str);
str++;
}
x_size=wherex()>x_size ? wherex() : x_size;
}
y_size=wherey()>y_size ? wherey() : y_size;
x_size-=x_start;
y_size-=y_start;
y_size++;
textcolor(title_color);
if(*title){
x_size=strlen(title)+5>x_size ? strlen(title)+5 : x_size;
gotoxy(((x_size+2)-strlen(title)+1)/2,y_start+1);
cprintf("%s",title);
}

//Draw border:
textcolor(border_color);
gotoxy(x_start,y_start);
putch(201);
gotoxy(x_start+x_size,y_start);
putch(187);
for(j=y_start+1;j<y_start+y_size;j++){
delay(effect_time);
if((j==y_start+2)&&(*title!='\0')){
gotoxy(x_start,j);
putch(199);
gotoxy(x_start+x_size,j);
putch(182);
}
else{
gotoxy(x_start,j);
putch(186);
gotoxy(x_start+x_size,j);
putch(186);
}
}
gotoxy(x_start,y_start+y_size);
putch(200);
gotoxy(x_start+x_size,y_start+y_size);
putch(188);
for(j=x_start+1;j<x_start+x_size;j++){
delay(effect_time);
gotoxy(j,y_start);
putch(205);
if(*title!='\0'){
gotoxy(j,y_start+2);
putch(196);
}
gotoxy(j,y_start+y_size);
putch(205);
}
textcolor(choice_color);
if(cho_def>val_line)
rtn=val_line;
else if(cho_def<1)
rtn=1;
else
rtn=cho_def;
do{
gotoxy(x_start+2,y_lines[rtn-1]);
putch(16);
ch_key=getch();
if(ch_key==0)
ch_key=getch();
if((ch_key==72)&&(rtn>1)){
gotoxy(x_start+2,y_lines[rtn-1]);
putch(' ');
rtn--;
gotoxy(x_start+2,y_lines[rtn-1]);
putch(16);
}
else if((ch_key==80)&&(rtn<val_line)){
gotoxy(x_start+2,y_lines[rtn-1]);
putch(' ');
rtn++;
gotoxy(x_start+2,y_lines[rtn-1]);
putch(16);
}

}while(ch_key!=13);
textcolor(choice_color-128);
gotoxy(x_start+2,y_lines[rtn-1]);
putch(4);

gotoxy(x_start,y_start+y_size+1);
normvideo();
_setcursortype(_NORMALCURSOR);
return rtn;

}


این تابع چند تا ورودی داره و یک خروجی که پایین همشو براتون مینویسم.

الگوی فراخوانی تابع به صورت زیر است.


return get_menu(text menu,menu title,choice default,time of show,text color,title color,border color,choice color);


توضیحات:

return :
این مقدار که از نوع int است مقدار برگشی تابع است که شماره گزینه انتخابی توسط کاربر رو نمایش میده.مثلا شما یک منو ایجاد کردین وقتی کاربر گزینه دوم رو انتخاب کرد مقدار برگشتی این تابه 2 خواهد بود.

text menu :

این مقدار که از نوع رشته است که یکی از ورودی های تابع است.در درون این رشته گزینه ها رو مینویسیم و گزینه ها رو با کاراکتر (,) از هم جدا میکنیم.مثلا اگه بخواهم سه گزینه ی : yes و no و cancel رو ایجاد کنیم باید در این ورودی این مقدار رو وارد کنیم :

"yes,no,cancel"یک سوال حال اگر بخواهم خود کاراکتر (, ) رو چاپ کنم چه می کنم : این کاراکتر رو دوبار پشت سر هم مینویسم مثل:


"yes,no,,cancel"menu title:
این ورودی که از نوع رشته است عنوان منو رو نمایش میده که در بالاترین قسمت منو نمایش داده میشه.

choice default :

این ورودی که از نوع int است گزینه پیش فرض انتخابی را معین میکند.مثلا اگه شما میخوایید به طور پیشفرض انتخاب رو گزینه دوم باشه این ورودی باید 2 باشه.

time of show :

این ورودی زمان نمایش منو رو مشخص میکنه یعنی هر چقدر این زمان بیشتر باشه منو با سرعت کمتری نمایش داده میشه.این ورودی به میلی ثانیه است.


text color :

این ورودی که از نوع int است رنگ گزینه ها رو مشخص میکند.کد رنگ ها رو پایین نوشتم :


BLACK │ 0
BLUE │ 1
GREEN │ 2
CYAN │ 3
RED │ 4
MAGENTA │ 5
BROWN │ 6
LIGHTGRAY │ 7
DARKGRAY │ 8
LIGHTBLUE │ 9
LIGHTGREEN │ 10
LIGHTCYAN │ 11
LIGHTRED │ 12
LIGHTMAGENTA │ 13
YELLOW │ 14
WHITE │ 15


title color :
این ورودی که از نوع int است رنگ عنوان منو رو مشخص میکنه.کد رنگ ها رو قبلا گفتم.

border color :
این ورودی که از نوع هدف است رنگ کادر منو رو مشخص میکنه.کد رنگ ها رو قبلا گفتم.

choice color :
این ورودی که از نوع int است رنگ اشاره گر منو رو مشخص میکنه.کد رنگ ها رو قبلا گفتم.


البته با نوشتن دستور زیر قبل از main و میتونین از همه ی این ورودی ها که بعضی هاشون غیر ضروری هستن صرف نظر کنید:


int get_menu(char*,char[]="",int=1,int=15,int=11,int=12,int=1,int=14);برای اینکه راحت باشین فایل برنامه رو به صورت آماده و بدون خطا تو فایل ضمیمه گزاشتم.
درضمن یه نمونه کار تابع رو به صورت عکس تو ضمیمه گزاشتم.
چون این تابع رو تازه نوشتم اگه خطایی داشت حتما به من بگین.

مرسی.

Dadai ahmad
چهارشنبه 05 تیر 1387, 19:48 عصر
آقا آرش اجازه میدهید که از منویی که نوشتید در پروژه ام استفاده کنم؟
اگر اجازه می دهید میشه توضیح کامل الگوریتم رو برام بذارید تا بتوانم در دفاعیه پروژه ام به استاد طرز کار و الگوریتم منو رو را به استاد توضیح دهم؟
ممنونم از لطفتون

Arash m
یک شنبه 16 تیر 1387, 00:02 صبح
خواهش میکنم.
دوست عزیز خودت یه نگاهی بهش بنداز و هر کجا رو که متوجه نشدی کدش رو به من بگو تا برات مفصل توضیح بدم.

amir1366
پنج شنبه 30 آبان 1387, 22:49 عصر
سلام دوست عزیز برنامه خوبی نوشتی ولی عکس برنامه با خود برنامه تفاوت داره...برنامه فقط درخوست خروج داره و بلی و خیر داره همین ...ولی توی عکس ضمیمه چیزهای دیگه ای هم هست.....اگر ممکنه یه توضیحی بدین چون برنامه اگه مثل عکس ضمیمه باشه خیلی جالب میشه

saeid99
دوشنبه 04 آذر 1387, 18:31 عصر
سلام دوست گرامي
ميشه در مورد الگوريتمش توضيح بديد؟

amin1softco
جمعه 09 بهمن 1388, 22:06 عصر
سلام راستش خودم می دونم که این تاپیک تاریخ مصرفش گذشته ولی من از طرز نوشتن کد این منو خیلی خوشم اومد چون من فکر می کردم با توابع گرافیکی سی نوشته شده ولی متوجه شدم که با سر فایل conio.h بیشتر قسمت هاش نوشته شده و یک مشکلم که وجود داره نمیشه از این منو در ویژوال سی پلاس پلاس استفاده کرد برای همین من خودم یک منو نوشتم و برای ویژوال هم بهینش کردم


http://up.iranblog.com/7/1264780262.jpg

کد برای ویژوال سی پلاس پلاس شش



#include <windows.h>
#include "conio.h"
#include <stdlib.h>

typedef enum
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
MAGENTA,
BROWN,
LIGHTGRAY,
DARKGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,
LIGHTRED,
LIGHTMAGENTA,
YELLOW,
WHITE
} COLORS;
static int __BACKGROUND = BLACK;
static int __FOREGROUND = LIGHTGRAY;

void textbackground (int color){
__BACKGROUND = color;
SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE),
__FOREGROUND + (color << 4));
}

int wherex (){
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT _HANDLE), &info);
return info.dwCursorPosition.X + 1;
}

int wherey (){
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT _HANDLE), &info);
return info.dwCursorPosition.Y + 1;
}
void gotoxy(int x, int y){
COORD c;
c.X = x - 1;
c.Y = y - 1;
SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void _setcursortype (int type){
CONSOLE_CURSOR_INFO Info;
Info.dwSize = type;
SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE),&Info);
}
void textcolor (int color){
__FOREGROUND = color;
SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE),
color + (__BACKGROUND << 4));
}
void clrscr (){
system("cls");
/* or withot stdlib
DWORD written;
FillConsoleOutputAttribute (GetStdHandle (STD_OUTPUT_HANDLE),__FOREGROUND + (__BACKGROUND << 4), 2000, (){0, 0},&written);
FillConsoleOutputCharacter (GetStdHandle (STD_OUTPUT_HANDLE), ' ',2000, {0, 0}, &written);
gotoxy (1, 1);*/
}



int menu(char* title,char * itemstr,int ci=0){
_setcursortype(1);
char item[20][60],key;
int i,j=0,numi=0;
for(i=0;;i++){
key=itemstr[i];
if(key==0){break;}else if((itemstr[i-1]==',')&&(key==',')){}else if((key==',') && (itemstr[i+1]!=',')){item[numi][j]='0';numi++;j=0;}else{item[numi][j++]=key;}
}
textcolor(15);
gotoxy(4,2);
cprintf("%s",title);
if(ci>numi)ci=numi;else ci--;
do{
if(key==72){
if(ci>0) ci--; else ci=(numi-1);
}else if(key==80){
if(ci<(numi-1))ci++; else ci=0;
}
gotoxy(1,3);
for(i=0;i<numi;i++){
gotoxy(2,wherey()+1);
if(i==ci){
textcolor(15);
textbackground(5);
}else{
textcolor(7);
textbackground(0);
}
for(j=0;;j++){
if(item[i][j]=='0')break;
cprintf("%c",item[i][j]);
}}
textcolor(7);
textbackground(0);
gotoxy(1,wherey()+2);
cprintf("UP & Down for change item & enter to select");
gotoxy(1,wherey()+1);
cprintf("item = %d",ci+1);
key=getch();

}while(key!=13);
_setcursortype(1);
clrscr();
return (ci+1);
}
void main(){
clrscr();
cprintf("you select : %d \npress any key to continue...",menu("title of your request can any thing","1- item example ,2- Deafult value selected,3- item with,,must space betwen,, ,4- programming with Am,5- email: am,",2));
getch();
}



کدبرای استفاده در سی یا توربو سی یا بورلند سی


#include "conio.h"

int menu(char* title,char * itemstr,int ci=0){
_setcursortype(1);
char item[20][60],key;
int i,j=0,numi=0;
for(i=0;;i++){
key=itemstr[i];
if(key==0){break;}else if((itemstr[i-1]==',')&&(key==',')){}else if((key==',') && (itemstr[i+1]!=',')){item[numi][j]='0';numi++;j=0;}else{item[numi][j++]=key;}
}
textcolor(15);
gotoxy(4,2);
cprintf("%s",title);
if(ci>numi)ci=numi;else ci--;
do{
if(key==72){
if(ci>0) ci--; else ci=(numi-1);
}else if(key==80){
if(ci<(numi-1))ci++; else ci=0;
}
gotoxy(1,3);
for(i=0;i<numi;i++){
gotoxy(2,wherey()+1);
if(i==ci){
textcolor(15);
textbackground(5);
}else{
textcolor(7);
textbackground(0);
}
for(j=0;;j++){
if(item[i][j]=='0')break;
cprintf("%c",item[i][j]);
}}
textcolor(7);
textbackground(0);
gotoxy(1,wherey()+2);
cprintf("UP & Down for change item & enter to select");
gotoxy(1,wherey()+1);
cprintf("item = %d",ci+1);
key=getch();

}while(key!=13);
_setcursortype(1);
clrscr();
return (ci+1);
}
void main(){
clrscr();
cprintf("you select : %d \npress any key to continue...",menu("title of your request can any thing","1- item example ,2- Deafult value selected,3- item with,,must space betwen,, ,4- programming with Amin Rajabzadeh,5- email: amin1softco@gmail.com,",2));
getch();
}

روش استفاده هم مثل منوی قبلی هست که با تابع

menu("titre menu","1-gozine aval , 2- gozine dovom,3-gozine sevom,",4)

اول تیتر منو ها را می نویسید بعد ایتم ها را که بوسیله , از هم جدا می شوند برای آخری هم باید یک کاما بزارید وگرنه چاپ نمیشه مثل مثال و بعد هم گزینه انتخاب شده به طور پیش فرض هست که از نوع عدد هست مقدار بازگشتی تابع فوق منو انتخابی هست که از 1 شروع میشه
فایل های ضمیمه را هم ببینید نمونه کامپایل شده که در ویندوز سون هم کار میده:لبخندساده:
امید وارم که مفید واقع بشه

ashkan_d13
سه شنبه 05 مرداد 1389, 16:54 عصر
اینم یه منو مثل همین بالایی ها که از موس هم استفاده می کنه