Giáo trình C - Chương 2: Bàn phím và Cursor

Chúng ta đã thấy bàn phím tạo các mã thông th-ờng cho các chữ cái, các số và dấu

chấm câu. Các phím này đều tạo mã ASCII dài 1 byte. Tuy nhiên có nhều phím và tổ hợp

phím không đ-ợc biểu diễn bằng bộ kí tự dài một byte này ví dụ nh-các phím chức năng từ

F1 đến F10 hay các phím điều khiển cursor . Các phím này đ-ợc mô tả bằng một mã dài 2

byte. Byte đầu tiên có trị số là 0 và byte thứ hai là trị số mã của phím này .

1. Nhận biết các mã mở rộng : Một mã mở rộng phải có 2 byte và byte đầu tiên là 0 nên

ch-ơng trình cần phải đọc 2 byte này . Sau đây là đoạn ch-ơng trình nhận biết các mã mở

rộng Ch-ơng trình 2-1:

#include <string.h>

main()

{

char key,key1;

clrscr();

while ((key=getche())!='x')

if (key==0)

{

 key1=getch(); printf("%3d%3d",key,key1);

}

else

printf("%3d",key);

}

Ch-ơng trình này sẽ hiện thị các mã của các phím đ-ợc gõ cho dù chúng là mã một

byte hay 2 byte . Ta dùng hàm getch() để không hiển thị kí tự vừa gõ lên màn hình . Trong

biểu thức kiểm tra của while ch-ơng trình đọc mã đầu tiên . Nếu mã này là 0 , ch-ơng trình

biết đó là mã mở rộng và đọc tiếp phần thứ hai của mã bằng hàm getch() . Sau đó nó hiển thị

cả hai phần . Nếu phần đầu khác không ch-ơng trình sẽ cho rằng đây không phải là mã mở

rộng và hiện thị mã này .

pdf8 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1977 | Lượt tải: 0download
Tóm tắt nội dung Giáo trình C - Chương 2: Bàn phím và Cursor, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
ím mở rộng 
 Chúng ta đã thấy bàn phím tạo các mã thông th−ờng cho các chữ cái, các số và dấu 
chấm câu. Các phím này đều tạo mã ASCII dài 1 byte. Tuy nhiên có nhều phím và tổ hợp 
phím không đ−ợc biểu diễn bằng bộ kí tự dài một byte này ví dụ nh− các phím chức năng từ 
F1 đến F10 hay các phím điều khiển cursor . Các phím này đ−ợc mô tả bằng một mã dài 2 
byte. Byte đầu tiên có trị số là 0 và byte thứ hai là trị số mã của phím này . 
1. Nhận biết các mã mở rộng : Một mã mở rộng phải có 2 byte và byte đầu tiên là 0 nên 
ch−ơng trình cần phải đọc 2 byte này . Sau đây là đoạn ch−ơng trình nhận biết các mã mở 
rộng Ch−ơng trình 2-1: 
#include 
main() 
 { 
 char key,key1; 
 clrscr(); 
 while ((key=getche())!='x') 
 if (key==0) 
 { 
 key1=getch(); 
 printf("%3d%3d",key,key1); 
 } 
 else 
 printf("%3d",key); 
 } 
 Ch−ơng trình này sẽ hiện thị các mã của các phím đ−ợc gõ cho dù chúng là mã một 
byte hay 2 byte . Ta dùng hàm getch() để không hiển thị kí tự vừa gõ lên màn hình . Trong 
biểu thức kiểm tra của while ch−ơng trình đọc mã đầu tiên . Nếu mã này là 0 , ch−ơng trình 
biết đó là mã mở rộng và đọc tiếp phần thứ hai của mã bằng hàm getch() . Sau đó nó hiển thị 
cả hai phần . Nếu phần đầu khác không ch−ơng trình sẽ cho rằng đây không phải là mã mở 
rộng và hiện thị mã này . 
2. Đoán nhận mã mở rộng : Một cách đoán nhận mã mở rộng là dùng phát biểu switch nh− 
trong ch−ơng trình sau : 
Ch−ơng trình 2-2 : 
main() 
 { 
 int key,key1; 
 clrscr(); 
 while ((key=getche())!='X') 
 if (key==0) 
 { 
 key1=getch(); 
 switch (key1) 
 { 
 case 59 : printf("Phim F1 duoc nhan\n"); 
 break; 
 case 60 : printf("Phim F2 duoc nhan\n"); 
13
 break; 
 case 75 : printf("Phim left arrow duoc nhan\n"); 
 break; 
 default : printf("Phim mo rong khac duoc nhan\n"); 
 break; 
 } 
 } 
 else 
 printf("%3d",key); 
 getch(); 
 } 
Đ2. Điều khiển cursor và ansi.sys 
1.Khái niệm chung :Tập tin ansi.sys cung cấp tập đã chuẩn hoá các mã điều khiển cursor . 
ANSI - America National Standards Institut. Để bảo đảm sự cài đặt của tập tin ansi.sys trong 
tập tin config.sys ta đặt dòng lệnh : 
 device = ansi.sys 
2. Điều khiển cursor bằng ansi.sys : ansi.sys dùng dãy escape để điều khiển con nháy . 
Chuỗi escape gồm nhiều kí tự đặc biệt . Ansi.sys tìm chuỗi escape này qua thành phần của 
chuỗi trong hàm prinft() và giải mã các lệnh theo sau nó . Chuỗi escape luôn luôn giống 
nhau , gồm kí tự không in đ−ợc “\x1B”(là mã của kí tự escape) sau đó là dấu [ . Sau chuỗi 
escape có thể có một hay nhiều kí tự . Nhờ chuỗi này con nháy có thể đi lên , xuóng , sang 
trái , phải hay định vị tại một vị trí nào đó . Ví dụ để di chuyển con nháy xuống d−ới ta dùng 
chuỗi “\x1B[B” 
Ch−ơng trình 2-3 : Viết ch−ơng trình in một chuỗi theo đ−ờng chéo : 
main() 
 { 
 clrscr(); 
 printf("Cho mot chuoi tan cung bang dau .:"); 
 while (getche()!='.') 
 printf("\x1B[B"); 
 getch(); 
 } 
3. Dùng #define và chuỗi escape : Chuỗi “\x1B[B” đ−ợc mã hoá và rất khó đọc . Khi dùng 
các ch−ơng trình phức tạp nên ghi chú rõ ràng bằng cách dùng dẫn h−ớng #define . 
Ch−ơng trình 2-4 : 
#define c_down "\x1B[B" 
main() 
 { 
 while (getche()!='.') 
 printf(c_down); 
 getch(); 
 } 
Tóm tắt các lệnh điều khiển con nháy 
Mã Công dụng 
14
“[2J” Xoá màn hình và đ−a con nháy về home 
“[K” Xoá đến cuối dòng 
“[A” Đ−a con nháy lên một dòng 
“[B” Đ−a con nháy xuống một dòng 
“[C” Đ−a con nháy sang phải một cột 
“[D” Đ−a con nháy sang trái một cột 
“[%d;%df Đ−a con nháy đến vị trí nào đó 
“[s” Cất giữ vị trí con nháy 
“[u” Khôi phục vị trí con nháy 
“[%dA” Đ−a con nháy lên một số dòng 
“[%dB” Đ−a con nháy xuống một số dòng 
“[%dC” Đ−a con nháy sang phải một số cột 
“[%dD” Đ−a con nháy sang trái một dòng và nhiều cột 
4. Điều khiển con nháy từ bàn phím : Sau đây là ch−ơng trình cho phép bạn vẽ các hình 
đơn giản trên màn hình 
Ch−ơng trình 2-5 : 
#define clear "\x1B[2J" 
#define c_left "\x1B[D" 
#define c_right "\x1B[C" 
#define c_up "\x1B[A" 
#define c_down "\x1B[B" 
#define l_arrow 75 
#define r_arrow 77 
#define u_arrow 72 
#define d_arrow 80 
#define across 205 
#define updown 186 
main() 
 { 
 int key; 
 printf(clear); 
 while ((key=getch())==0) 
 { 
 key=getche(); 
 switch (key) 
 { 
 case l_arrow : printf(c_left); 
 putch(across); 
 break; 
 case r_arrow : printf(c_right); 
 putch(across); 
 break; 
 case u_arrow : printf(c_up); 
 putch(updown); 
 break; 
 case d_arrow : printf(c_down); 
 putch(updown); 
 break; 
 } 
15
 printf(c_left); 
 } 
 getch(); 
 } 
5. Đ−a con nháy đến vị trí bất kì : Chuỗi escape dạng sau sẽ đ−a con nháy đến vị trí bất kì 
trên màn hình 
 Số hex 1B của kí tự escape 
 Số hiệu dòng 
 Số hiệu cột 
 Chữ cái f 
“ \ x 1 B [ 10 ; 40 f ” 
Sau đây là một ch−ơng trình ví dụ về cách dùng chuỗi đó 
Ch−ơng trình 2-6 : 
#define true 1 
#define clear "\x1B[2J" 
#define erase "\x1B[K" 
main() 
 { 
 int row=1,col=1; 
 printf(clear); 
 while(true) 
 { 
 printf("\x1B[23;1f"); 
 printf(erase); 
 printf("Nhap vao so dong va so cot dang(20,40)"); 
 scanf("%d%d",&row,&col); 
 printf("\x1B[%d;%df",row,col); 
 printf("*(%d,%d)",row,col); 
 } 
 } 
Đ6. Trình bày chỗ bất kì trên màn hình 
 Sau đây là ch−ơng trình dùng chuỗi định vị cursor .Ch−ơng trình cung cấp hai menu 
định vị dọc theo màn hình . 
Ch−ơng trình 2-7 : 
#define size1 5 
#define size2 4 
#define clear "\x1B[2J" 
main() 
 { 
 static char *menu1[]= 
 { 
 "Open", 
 "Close" 
 "Save" 
 "Print" 
 "Quit" 
16
 }; 
 static char *menu2[]= 
 { 
 "Cut", 
 "Copy", 
 "Paste", 
 "Reformat" 
 }; 
 void display(char *[],int ,int); 
 printf(clear); 
 display(menu1,size1,20); 
 display(menu2,size2,20); 
 getch(); 
 } 
void display(char *arr[],int size,int hpos) 
 { 
 int j; 
 for (j=0;j<size;j++) 
 { 
 printf("\x1B[%d",j+1,hpos); 
 printf("%s\n",*(arr+j)); 
 } 
 } 
 Các mục cho từng menu đ−ợc cất giữ trong mảng các con trỏ trỏ tới chuỗi . Sau đó 
ch−ơng trình dùng hàm để hiển thị menu . Hàm định vị con nháy nhờ dãy định vị ANSI.SYS 
, lấy số hiệu dòng từ số hiệu của mục trên menu và số hiệu cột đ−ợc ch−ơng trình chính 
truyền sang . 
Đ7. Các thuộc tính của kí tự 
 Mỗi kí tự hiển thị trên màn hình đ−ợc cất giữ trong hai byte bộ nhớ . Một byte là mã 
thông th−ờng của kí tự và byte kia là thuộc tính của nó . Byte thuộc tính ấn định diện mạo 
của kí tự nh− chớp nháy , đậm , gạch d−ới , đảo màu . Ta có thể dùng chuỗi escape của 
ANSI để ấn định thuộc tính của kí tự . Theo sau chuỗi kí tự escape và ngoặc vuông là con số 
và chữ m . Sau đây là danh sách các số tạo hiệu ứng trên màn hình : 
 2,3,6 màu tối 
 0 tắt thuộc tính , th−ờng là màu trắng trên nền đen 
 1 đậm 
 4 gạch d−ới 
 5 chớp nháy 
 7 đảo màu 
 8 không thấy đ−ợc 
Chuỗi escape có dạng nh− sau : 
 Số hex 1B của kí tự escape 
 Số cho biết kiểu thuộc tính 
17
“ \ x 1 B [ 10 m” 
Chuỗi này đ−ợc gởi trong tiến trình hiển thị . Mỗi khi bật một thuộc tính , tất cả các kí tự sẽ 
hiển thị theo thuộc tính mới cho đến khi nó tắt đi . Sau đây là ch−ơng trình biểu diễn các 
thuộc tính của kí tự 
Ch−ơng trình 2-8 : 
#define NORMAL "\x1B[Om" 
#define BOLD "\x1B[1m" 
#define UNDER "\x1B[4m" 
#define BLINK "\x1B[5m" 
#define REVERSE "\x1B[7m" 
main() 
 { 
 printf("normal%s blink %s normal \n\n",BLINK,NORMAL); 
 printf("normal%s bold %s normal \n\n",BOLD,NORMAL); 
 printf("normal%s underline %s normal \n\n",UNDER,NORMAL); 
 printf("normal%s reversed %s normal \n\n",REVERSE,NORMAL); 
 printf("%s%s reversed and blink %s \n\n",BLINK,REVERSE,NORMAL); 
 } 
Đ8. Menu 
 Ta xây dựng một ch−ơng trình gồm 5 mục menu là Open ,Close,Save,Print,Quit . Các 
phím mũi tên lên xuống sẽ di chuyển vệt sáng đến các mục cần chọn.Phím INS để chọn và 
thực hiện công việc t−ơng ứng . Mục Quit sẽ kết thúc ch−ơng trình . 
Ch−ơng trình 2-9 : 
#define true 1 
#define num 5 
#define clear "\x1B[2J" 
#define erase "\x1B[K" 
#define normal "\x1B[Om" 
#define reverse "\x1B[7m" 
#define home "\x1B[1;1f" 
#define bottom "\x1B[20:1f" 
#define u_arro 72 
#define color "\x1B[4m" 
/*#define l_arro 75 
#define r_arro 77*/ 
#define d_arro 80 
#define insert 83 
main() 
 { 
 static char *item[num]= 
 { 
 "Open", 
 "Close", 
 "Save", 
 "Print", 
 "Quit" 
 }; 
18
 int curpos; 
 int code; 
 void display(char *[],int,int); 
 int getcode(void); 
 void action(int); 
 printf(clear); 
 curpos=0; 
 while(true) 
 { 
 display(item,num,curpos); 
 code=getcode(); 
 switch (code) 
 { 
 case u_arro:if (curpos>0) 
 --curpos; 
 break; 
 case d_arro:if (curpos<num-1) 
 ++curpos; 
 break; 
 case insert:action(curpos); 
 break; 
 } 
 } 
 } 
void display(char *arr[],int size,int pos) 
 { 
 int j; 
 printf(home); 
 for (j=0;j<size;j++) 
 { 
 if (j==pos) 
 printf(reverse); 
 printf("%s\n",*(arr+1)); 
 printf("%s%5s",color,*(arr+j)); 
 printf(normal); 
 printf("%s"," "); 
 printf(home); 
 } 
 } 
int getcode() 
 { 
 int key; 
 while(getch()!=0) 
 ; 
 return (getch()); 
 } 
void action(int pos) 
19
 { 
 switch(pos) 
 { 
 case 0: printf("Open"); 
 break; 
 case 1: printf("Close"); 
 break; 
 case 2: printf("Save"); 
 break; 
 case 3: printf("Print"); 
 break; 
 case 4: exit(); 
 } 
 } 
Đ9. Gán phím chức năng bằng ansi.sys 
 Nhờ gán chuỗi vào phím chức năng ta có thể cấu hình lại bàn phím đamg dùng . 
Dạng thức của chuỗi gán phím chức năng nh− sau : 
 mã escape gồm 1xB[ 
 byte thứ nhất của mã mở rộng cho phím chức năng 
 dấu ; 
 byte thứ hai của mã mở rộng cho phím chức năng 
 dấu ; 
 chuỗi cần gán 
 dấu ; 
 xuống dòng 
 chữ p 
\ x 1 B [ 0 ; 68 ; “s” ; 13 p 
Ch−ơng trình 2-10: 
main() 
 { 
 char str[81]; 
 int key; 
 clrscr(); 
 printf("Nhap vao mot so cua phim chuc nang :"); 
 gets(str); 
 key=atoi(str); 
 printf("Nhap vao mot chuoi de gan phim nay : "); 
 gets(str); 
 printf("\x1B[0;%d;\"%s\";13p",key+58,str); 
 } 

File đính kèm:

  • pdfGiao_Trinh_C_Chuong2.pdf