屏幕控制(2)

3 篇文章 0 订阅

2.键盘



一般来讲,键盘输入数据后,遇见换行符号才会把输入的数据送入系统,这种处理方式被称为预处理模式。
    1.键盘模式
    int echo();回显
    int noecho;关闭回显
    int cbreak();使用立刻返回的模式
    int cbreak();关闭立刻返回的模式
    int noraw();关闭特殊字符,这样用信号关闭程序就会被忽略。
    
    2.键盘输入
    读取键盘的输入使用以下几个函数
    int getch();
    int getstr(char* str);
    int getnstr(char* string, int number_of_char);
    int scanw(char* format,……)
    上面的函数与普通的gets,getchar(),scanf类似

实验:输入密码,与已经存在的密码对比。

程序会关闭回显,每次读取一个字符,立刻送入程序,不等待回车,然后输出一个*

输入结束后,重新输出刚刚输入的密码

#include<stdio.h>
#include<string.h>
#include<curses.h>
#include<unistd.h>

#define PW_LEN 256
#define NAME_LEN 256
int main()
{
        char name[NAME_LEN];
        char passwd[PW_LEN];
        char real_password[] = "123456";
        //输出提示字符
        int i = 0;
        initscr();
        move(5,10);
        printw("please login");
        move(7,10);
        printw("User name:");
        getstr(name);
        move(8,10);
        printw("Password:");
        refresh();

        //输入密码
        cbreak();
        noecho();//关闭回显
        memset(passwd,'\0',sizeof(passwd));
        while(i < PW_LEN)
        {
                passwd[i] = getch();
                if(passwd[i] == '\n') break;
                move(8,20+i);
                addch('*');
                refresh();
                i++;
        }
        //重新启动键盘回显,对比输入密码
        echo();
        nocbreak();
        move(11,10);
        if(strncmp(real_password, passwd, strlen(real_password)) == 0)
                printw("%s","Correct");
        else printw("Wrong");
        printf("%s",passwd);
        refresh();
        sleep(10);
        endwin();
        return 0;
}

3.窗口



    1.WINDOW结构
    之前的处理,都是基于标准窗口,这个标准窗口和标注输出一样,只是一种特殊的形态,接下来要接受的是各种普遍的窗口
    WINDOW* newwin(int num_of_lines, int num_of_cols, int start_y, int start_x);
    int delwin(WINDOW* win);
    newwin是创建一个新的窗口,delwin是删除一个创建的窗口
    
    2.通用函数
    在之前的函数前面加一个w就是对窗口的操作
    加上mv就是对光标的移动
    wmv是在窗口中移动光标
    比如:添加一个字符的函数
    int addch(const chtype char) 在窗口光标处添加一个字符
    int waddch(WINDOW* winptr, const chtype char) 在winptr窗口的光标处添加一个字符
    int wmv(WINDOW* win, int y, int x, const chtype char) 在win窗口,坐标(y,x)处添加一个字符

实验:

#include<stdio.h>
#include<string.h>
#include<curses.h>
#include<unistd.h>
int main()
{
        initscr();
        WINDOW* wptr = newwin(20,20,1,1);
        if(wptr == NULL)
        {
                fprintf(stderr,"新屏幕创建失败\n");
                return 0;
        }
        wprintw(wptr,"hello new curses\n");
        wrefresh(wptr);
        sleep(10);
        delwin(wptr);
        endwin();
        return 0;
}

    这里创建一个新的屏幕,起点在标准屏幕坐标的(1,1),长宽分别为20,20
    然后在新的屏幕上输出hello new curses
    和之前一样,每次更新屏幕的输出,都要刷新一次,调用对用的刷新函数即可


    3.移动窗口和更新窗口


    下面这些函数是用来移动窗口和重新绘制窗口的。
    int mvwin(WINDOW* window_to_move, int new_y, int new_x);
    int wrefresh(WINDOW* winptr);
    int wclear(WINDOW* window_ptr)
    int werase(WINDOW* window_ptr)
    int touchwin(WINDOW* );//为窗口发送信号,通知窗口已经需要做出改变了。因为wrefresh不一定会主动刷新窗口,他会比较窗口前后的变化,做出改变。
    int scrollok(WINDOW* window_ptr, bool scroll_flag);控制窗口卷屏,如果bool值取得true则表示允许卷屏
    int scroll(WINDOW* window_ptr);屏幕只卷一行
    
    实验:管理多窗口

#include<stdio.h>
#include<string.h>
#include<curses.h>
#include<unistd.h>
int main()
{
	WINDOW* new_window_ptr = NULL;
	WINDOW* popup_window_ptr = NULL;
	int x_loop, y_loop;
	char a_letter = 'a';
	initscr();
	
	/*在主窗口输出a-z*/
	move(5,5);
	printw("%s\n","Testing multiple window");
	refresh();
	
	for(y_loop = 0; y_loop < LINES - 1; y_loop++)
		for(x_loop = 0; x_loop < COLS -1; x_loop++)
		{
			mvwaddch(stdscr, y_loop, x_loop, a_letter);
			a_letter++;
			if(a_letter > 'Z')
				a_letter = 'a';
		}
	refresh();
	sleep(2);

	/*创建一个新的窗口*/
	new_window_ptr = newwin(10,10,5,5);
	mvwprintw(new_window_ptr,2,2,"%s","hello world");
	mvwprintw(new_window_ptr,5,2,"%s","Notice how long lines wrap inside the window");
	wrefresh(new_window_ptr);
	sleep(2);
	/*对主窗口输出内容重新设置,输出0-9*/
	a_letter = '0';
	for(y_loop = 0; y_loop < LINES - 1; y_loop++)
		for(x_loop = 0; x_loop < COLS -1; x_loop++)
		{
			mvwaddch(stdscr, y_loop, x_loop, a_letter);
			a_letter++;
			if(a_letter > '9')
				a_letter = '0';
		}
	
	refresh();
	sleep(2);	
	
	char select = ' ';
	while(1)
	{
		do{
		select = getchar();
		}while(select == '\n');

	switch(select)
	{
		case '1'://刷新new窗口
			/*对新创建的窗口进行输出,什么也不会发生*/
			wrefresh(new_window_ptr);
			sleep(2);
			break;
		case '2'://强制刷新new窗口
			/*再刷新一次,这次发送一个信号,就会有变化*/
			touchwin(new_window_ptr);
			wrefresh(new_window_ptr);
			sleep(2);
			break;
		case '3'://创建一个带边框的窗口
			/*增加一个新的窗口,带边框*/
			popup_window_ptr = newwin(10,20,8,8);
			box(popup_window_ptr,'|','-');
			mvwprintw(popup_window_ptr,5,2,"%s","pop up window");
			wrefresh(popup_window_ptr);
			sleep(2);
			break;
		case '4'://刷新子窗口
			/*轮流刷新*/
			touchwin(new_window_ptr);//给子窗口发送信号	
			wrefresh(new_window_ptr);
			sleep(2);break;
		case '5'://清空new_window_ptr
			wclear(new_window_ptr);//清空窗口
			wrefresh(new_window_ptr);
			sleep(2);break;
		case '6'://删除new窗口
			delwin(new_window_ptr);//删除子窗口
			touchwin(popup_window_ptr);//给popup窗口发送信息
			wrefresh(popup_window_ptr);//刷新
			sleep(2);break;
		case '7'://
			delwin(popup_window_ptr);//删除popup窗口
			touchwin(stdscr);//给标准窗口发送信息
			refresh();sleep(2);break;
		default:break;	
		
	}
		if(select == '0')
			break;
	}
	endwin();
	return 0;
}

依次输入123456780,对照注释观察变化。

4.keypad模式
处理功能按键。比如上下左右的键盘
int keypad(WINDOW* window_ptr, bool keypad_on);

#include<stdio.h>
#include<string.h>
#include<curses.h>
#include<unistd.h>

#define LOCAL_ESCAPE_KEY 27
int main()
{
        int key;
        initscr();
        crmode();
        keypad(stdscr,TRUE);

        noecho();
        mvprintw(5,5, "keypad,press q exit");
        move(7, 5);
        refresh();
        key = getch();

        while(key != ERR && key != 'q')
        {
                move(7,5);
                clrtoeol();//关闭行模式

                if((key >= 'A' && key <= 'z') || (key >= 'a' && key <= 'z'))
                        printw("key was %c\n",(char)key);
                else{
                        switch(key){
                                case LOCAL_ESCAPE_KEY : printw("Escape key\n");break;
                                case KEY_END: printw("end key\n"); break;
                                case KEY_BEG: printw("begining key\n");break;
                                case KEY_RIGHT: printw("right key\n");break;
                                case KEY_LEFT: rpintw("left key\n");break;
                                case KEY_UP: printw("up key\n");break;
                                case KEY_DOWN:printw("down key\n"); break;
                                default: printw("unmatched -%d\n",key); break;
                        }
                        refresh();
                        key = getch();
                }
        }

        endwin();
        return 0;
}

5:彩色显示
    curses对颜色的支持有些不同,必须同时定义一个字符的前景色和背景色。
    (1)先检查是否支持颜色,然后对函数库初始化
    bool has_colors();成功返回true
    bool start_color();成功返回OK
    支持的颜色种类为COLOR_PAIRS,一般是最大的64,变量COLORS表示颜色数目的最大值,一般只有8种
    (2)对使用的颜色初始化,访问颜色
    int init_pair(short pair_number, short foreground,short backgound);对准备使用的颜色组合进行初始化
    int COLOR_PAIR(int pair_number);设置对颜色的访问
    int pair_content(short pair_number,short* foreground, short *backgound);获取定义的颜色组合信息
    颜色都是用COLOR_ + 颜色名字
    比如红色:COLOR_RED,绿色COLOR_GREEN
    颜色就和普通的属性一样,可以使用设置函数来显示attrset

#include<stdio.h>
#include<string.h>
#include<curses.h>
#include<unistd.h>

int main()
{
        initscr();
        if(has_colors() == false)
        {
                fprintf(stderr,"Don't suppose color\n");
                return 0;
        }
        if(start_color() != OK)
        {
                fprintf(stderr,"start color fail\n");
                return 0;
        }
        //设置红色和绿色
        if(init_pair(1, COLOR_RED, COLOR_GREEN) < 0)
        {
                fprintf(stderr,"init color fail\n");
                return 0;
        }
        //输出颜色
        attrset(COLOR_PAIR(1));
        printw("hello world");
        refresh();
        sleep(10);

        endwin();
        return 0;
}

    (4).pad
    使用WINDOW结构只能基于物理屏幕,超出屏幕范围就无效,而使用pad结构体,能够创建逻辑上的屏幕
    所有的写操作的curses对于pad都是通用的,但是pad有自己的创建函数和刷新函数
    创建一个pad
    (1)WINDOW* newpad(int num_of_lines, int num_of_cols);
    删除一个pad也是用delwin
    (2)刷新pad,pad是一个逻辑屏幕,因此需要指定刷新范围
    int prefresh(WINDOW* pad_ptr, int pad_row, int pad_column,
                        int screen_row_min, int screen_column_min,
                        int screen_raw_max, int screen_column_max);
    起点(int pad_row, int pad_column),指定的屏幕大小为(int screen_row_min, int screen_column_min,int screen_raw_max, int screen_column_max))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值