Linux下c语言的图形编程(转) curses.h 函式库
时间:2023-05-06 01:07:00
http://tech.techweb.com.cn/viewthread.php?tid=181892
注明转载,然后自己写,呵呵。先看看哈哈。
以下是UNIX下c语言的图形编程
UNIX下c语言的图形编程--curses.h 函式库
作者:不详来源:supcode.com收集整理发布时间:2005-7-22 19:39:36
减小字体 增大字体
相信你一定在网上用过。tin,elm 等工具, 这些软件有一个共同的特点,
也就是说,他们可以使用上下左右等方向键来控制游标的位置.除此之外, 这些程式
画面也比较美. 对 Programming 感兴趣的朋友一定很好奇, 也 8j
b sJ5D5g
许他能在 PC 上用 Turbo C 类似的程式很容易写出来, 然而, 但当他将是一样的 tech.techweb.com.cnECU L(H#/U*Kh(g
当程式一字不变地移到工作站进行编译时, 然而,有一堆错误是抓不完的。. 程序开发、操作系统、服务器、源代码下载、Linux,Unix,BSD,PHP,Apach,asp,下载,源码
Iq&D0Y]*zi;g
其实, 原因很简单, 他使用的函式库可能在 UNIX 没有定义.有些
在 Turbo-C 一些被广泛使用的函式, 可能在 UNIX 它不被定义.
TechWeb技术社区(h9lRF||j
go2z"bJ
为了应对网络上的各种终端形式(terminal), UNIX 特别发展
一套函式库, 专门用于处理 UNIX 上游标准移动和屏幕显示.这就是本篇
文章要介绍给你 - curses.h 函式库.使用此函式库, 你也可以写 -f1f7^z0[?9x
像 elm 方向键移动光棒位置的程式. (CCCA 最近提供的在线选择
课程式, 程序服务界面, 也就是作者用的 curses 发展而成的 )
■ curses 历史与版本 ~lUhl-iXW
t/~,X8m8FGXlG
cureses 最早是柏克莱大学 Bill Joy 及 Ken Arnold 发展出来的. 程序开发、操作系统、服务器、源代码下载、Linux,Unix,BSD,PHP,Apach,asp,下载,源码
mh&CC)L
o/d
该函式库的发展主要是为了提高程式对不同终端的相容性
计的.因此, 利用 curses开发的程式将与您使用的终端无关.
也就是说, 你不用担心你的程序因为换了终端而不能使用.这对程 'T(v?l/|
Xya
对于风格设计师来说, 尤其是网路上程式的撰写, 是件相当重要的一件事. ~}E*^(E
curses之所以能工作上百种终端,这是因为它为所有终端提供资金
料, 存放在一个名字里 termcap 的资料库, ( 第二版 System V 系统中 程序开发、操作系统、服务器、源代码下载、Linux,Unix,BSD,PHP,Apach,asp,下载,源码O cU2H$O
, 新版的 curses 以 terminfo 取代原来的 termcap). 有了这些记录, 程 tech.techweb.com.cn
E4b9o(t?@`
公式可以知道遇到哪种终端, 移动游标的位置需要发送哪些字元,
送什麽字元才能清除整个萤幕清除. (* 注一)
8g$ifHw)f j~'lT
另外, 本文的介绍 以 System V 的 curses 版本为主. tech.techweb.com.cng"E m?|
?^[,z3f
hIXtech.techweb.com.cn■ 如何在您的程式使用 curses ? 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码5K'r8FT([{P
"nY0j
^GY0nd
在您的 C 程式的档头将
这个函式库後, 系统会自动将
来.另外, 在 System V 版本中,
include进来.
/jx.P/z@J&aqe|)i
#include
i
~`%CUBTpS c
main()
{ -j6f5@ z+zHj _r
: : 8^j['yV9f6w*g
: : 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码7b^Nk @6?I!r
}
当然, 您的系统内必须放有 curses.h 这个函式库. tech.techweb.com.cn�Nqh3wX*F_
_vo&`&gNZ+e5r P
■ 如何编译(compile)
当您编辑好您的程式, 在 UNIX 提示符号下键入: tech.techweb.com.cn-/ jD1VM/
% /usr/5bin/cc [file.c] -lcurses
^^^^^^^
引进 curses.h 这个 library
或 % /usr/5bin/cc [file.c] -lcurses -ltermlib TechWeb技术社区�V e[(tQi
TechWeb技术社区'EO$/_](Fq
(*注二)
pQ,a9|PD&C
ZQD8ELT~HO
■ 如何开始我的第一个 curses 程式?
在开始使用 curses 的一切命令之前, 您必须先利用 initscr()这个函式 gk,Kwr,Y[] e9lC
来开启 curses 模式.
相对的, 在结束 curses 模式前 ( 通常在您结束程式前 ) 也必须以 ]Q
hT8[ e+|^
endwin()来关闭 curses 模式. J/EU{`5J
#include
I}2j
main() e,?d(Sb+V0oo%{ l
{ E`$@'KEJ
initscr();
: :
: : TechWeb技术社区!hq!F{4?!x7_'n"w
: : &}Q.L!V|^4DY$@m
endwin(); tech.techweb.com.cn"M;G*P,`dN+~-K
}
这是一般 curses 程式标准的模式.
此外, 您可以就您程式所须, 而做不同的设定. 当然, 您可以不做设定,而
只是呼叫 initscr().
0VD#Y;X2c
您可以自己写一个函式来存放所有您所须要的设定. 平常使用时, 只要呼
叫这个函式即可启动 curses 并完成一切设定.
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码7t ])Nj1N
Y4Q
下面的例子, 即是笔者将平常较常用的一些设定放在一个叫 initial()的函 rn,I/TZ/RgV*E
式内.
TechWeb技术社区Z z}X gh2R(a
void initial()
{
initscr();
cbreak();
nonl();
noecho(); 7d
a.q)Y!J`Z8A0[
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE); .Sr/vl]_6@ Y9z
refresh(); tech.techweb.com.cn]4~a
Eq ~
}
各函式分别介绍如下:
F�Sl |+m"[-AQ3|.F
□ initscr()
initscr() 是一般 curses 程式必须先呼叫的函数, 一但这个函数
被呼叫之後, 系统将根据终端机的形态并启动 curses 模式.
Y
i]z-{5^;r}&r8Gx7@
,t7j {$F0qC;L[iT
□ endwin() 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码
G:v;W/h%d)L
z%rJ-/_
curses 通常以呼叫 endwin() 来结束程式. endwin() 可用来关闭
curses 模式, 或是暂时的跳离 curses 模式.如果您在程式中须要 f!/,{T;pMr!n
call shell ( 如呼叫 system() 函式 ) 或是需要做 system call,
就必须先以 endwin() 暂时跳离 curses 模式. 最後再以 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码M)[ C9S._m.z
wrefresh() doupdate() 来重返 curses 模式. TechWeb技术社区)j(K(fL0_M7u
`S{!?
tech.techweb.com.cnzx�m8A}uD(j
□ cbreak()
nocbreak()
当 cbreak 模式被开启後, 除了 DELETE 或 CTRL 等仍被视为特殊
控制字元外一切输入的字元将立刻被一一读取.当处於 nocbreak 模 TechWeb技术社区%O?M O:qe2t?m
式时, 从键盘输入的字元将被储存在 buffer 里直到输入 RETURN tech.techweb.com.cn^w1A(zc@(Ap |�S
或 NEWLINE.在较旧版的 curses 须呼叫 crmode(),nocrmode() 来 tech.techweb.com.cn5M'[�e#RU:w)Y E.Qh
取代 cbreak(),nocbreak()
TechWeb技术社区js(^e
c/lv
□ nl() #G/aHGl+xW1x3O8~
nonl() i2||Wc(y�dL:e
u'W0R/(d!T+L6t
用来决定当输入资料时, 按下 RETURN 键是否被对应为 NEWLINE 字
元 ( 如 /n ).
而输出资料时, NEWLINE 字元是否被对应为 RETURN 和 LINDFEED
系统预设是开启的.
9/-rI,l"CD8E
□ echo() tech.techweb.com.cnV2y/J${N
noecho()
此函式用来控制从键盘输入字元时是否将字元显示在终端机上.系统 B1R0{m*Z5e
预设是开启的. tech.techweb.com.cnz4Z#H
}oG+{'B4/
@6s,B6o*B5f[{,aX
□ intrflush(win,bf)
呼叫 intrflush 时须传入两个值: P
g"oeA
win 为一 WINDOW 型态指标, 通常传入标准输出入萤幕 stdscr @H%ic-Y!y-j,C
bf 为 TRUE 或 FALSE
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码:a4X9w$V7uT9X w
当 bf 为 true 时, 当输入中断字元 ( 如 break) 时, 中断的反应 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码0iEK B/M2V*W!lW
将较为快速.但可能会造成萤幕的错乱. tech.techweb.com.cnru5@"/)zq3amE
J3{;|9Kh7w:A
□ keypad(win,bf)
呼叫 keypad 时须传入两个值:
win 为一 WINDOW 型态指标, 通常传入标准输出入萤幕 stdscr tech.techweb.com.cn0A^GU4j(w_g
bf 为 TRUE 或 FALSE 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码~4a'K?,Y(B3@9[
tech.techweb.com.cn!ws qG&j
当开启 keypad 後, 可以使用键盘上的一些特殊字元, 如上下左右 ;B je6eb$Y
等方向键, curses 会将这些特殊字元转换成 curses.h 内定义的一 a4WfD.rJw
些特殊键. 这些定义的特殊键通常以 KEY_ 开头.
tech.techweb.com.cn:b^4k2H"ai
□ refresh() 0[:[ yb d4N@
tech.techweb.com.cn/s
rR�YEf y
refresh() 为 curses 最常呼叫的一个函式. tech.techweb.com.cn+Y+D SobwW8@q
curses 为了使萤幕输出入达最佳化, 当您呼叫萤幕输出函式企图改 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码HI.{9D#Mz
变萤幕上的画面时, curses 并不会立刻对萤幕做改变, 而是等到 tsmUCoY
refresh() 呼叫後, 才将刚才所做的变动一次完成. 其馀的资料将 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码!oK#{M6Rb[
维持不变. 以尽可能送最少的字元至萤幕上. 减少萤幕重绘的时间.
如果是 initscr() 後第一次呼叫 refresh(), curses 将做清除萤
幕的工作. ;{-M#O
[9UU#j
4nQ1V&HE
]%h.C rGg
■ 游标的控制 6R5gG8@7J"Q!eV
move(y,x) 将游标移动至 x,y 的位置
getyx(win,y,x) 得到目前游标的位置 tech.techweb.com.cn8vgB@
B QF&Ry
(请注意! 是 y,x 而不是 &y,&x ) I*YY
ILwgY]
■ 有关清除萤幕的函式
clear() %g~&d5_ h k?S
erase() 将整个萤幕清除 :sfN9rL-P?
(请注意配合refresh() 使用)
J"Z3HW6Ju*c3S(a
■ 如何在萤幕上显示字元 i3O3sDvs;E
tech.techweb.com.cntR_-FK%b+k
echochar(ch) 显示某个字元
MkX
whak4M;a!y g
addch(ch) 显示某个字元
mvaddch(y,x,ch) 在(x,y) 上显示某个字元 bC v
O�h
相当於呼叫 move(y,x);addch(ch);
u,VIc"MN@r!W0Q
addstr(str) 显示一串字串
mvaddstr(y,x,str) 在(x,y) 上显示一串字串 TechWeb技术社区$^L9v(Gz:yh
相当於呼叫 move(y,x);addstr(str);
printw(format,str) 类似 printf() , 以一定的格式输出至萤幕
mvprintw(y,x,format,str) 在(x,y) 位置上做 printw 的工作.
相当於呼叫 move(y,x);printw(format,str);
-sF@g!K
R.sl
z!T/jka LKm
■ 如何从键盘上读取字元
0I#VUa9f
getch() 从键盘读取一个字元 (注意! 传回的是
整数值)
getstr() 从键盘读取一串字元 TechWeb技术社区&Q,EUig
scanw(format,&arg1,&arg2...) 如同 scanf, 从键盘读取一串字元
TechWeb技术社区�oZ:`ii$r? v#H
□例: $[hDM@q-D.P
tech.techweb.com.cn*vW!H
wW:?h
int ch; d8x
v
M
{8AU
char string1[80]; /* 请注意! 不可宣告为 char *string1; */
char string2[80]; tech.techweb.com.cn2_mo}5HD4k
8f6HH9V)Hl.Y
echo(); /* 开启 echo 模式, 使输入立刻显示在萤幕上 */
ch=getch();
string1=getstr();
scanw("%s",string2);
mvprintw(10,10,"String1=%s",string1); 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码&t-B`$p0I'BG+e(d
mvprintw(11,10,"String2=%s",string2);
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码k?+U+XR3~
■ 如何利用方向键
O/_,o6^(it�F,]
curses 将一些如方向键等特殊控制字元, 以 KEY_ 为开头定义在 curses.h
这个档案里头, 如 KEY_UP 即代表方向键的 " ↑ ". 但, 如果您想使用 )[ Q5o#/o2H8joa
tech.techweb.com.cn$C2zN_Z`
curses.h 所为您定义的这些特殊键的话, 您就必须将 keypad 设定为
Qna1iD
TRUE. 否则, 您就必须自己为所有的特殊键定义了.
curses.h 为一些特殊键的定义如下:
KEY_UP 0403 ↑
KEY_DOWN 0402 ↓ tech.techweb.com.cn? b0pJ#J
KEY_LEFT 0404 ← 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码_)AoYAeE
KEY_RIGHT 0405 → TechWeb技术社区K/
^`
JN:@d+mz
KEY_HOME 0406 Home key (upward+left arrow) TechWeb技术社区;p6x
D_e7U X.QA
KEY_BACKSPACE 0407 backspace (unreliable)
KEY_F0 0410 Function keys.
KEY_F(n) (KEY_F0+(n)) formula for f . tech.techweb.com.cn-K S?p'jp4Z8]?
Vq0{
KEY_NPAGE 0522 Next page
KEY_PPAGE 0523 Previous page
以上仅列出笔者较常使用的一些控制键, 至於其他控制键的定义, 请自行参
;Q,S7C4Z0P2^s
w
阅 man curses (* 注三) ?
RSj
YxQf)Z
一并为您列出其他常用的一些特殊字元 ]d
G+l5^
f'lx&?
[TAB] /t
[ENTER] /r tech.techweb.com.cn!K0TM7O/J0U
[ESC] 27
[BACKSPACE] 127 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码/UkA.LO%n
■ 如何改变萤幕显示字元的属性 TechWeb技术社区0[�tLE"uO2[
为了使输出的萤幕画面更为生动美丽, 我们常须要在萤幕上做一些如反白, TechWeb技术社区1K$E+GwYQ5f6]2o ]
闪烁等变化. curses 定义了一些特殊的属性, 透过这些定义, 我们也可以 7~Pl5o!ID-J"`&Ew
emi+Zy+J
在 curses 程式□控制萤幕的输出变化. k,L8Kwo+fy7q!y"H
d;w/u2S_O#D J3?A
attron(mod) 开启属性 p4va+Tx_
PI
attroff(mod) 关闭属性
curses.h 里头定义了一些属性, 如:
A_UNDERLINE 加底线
A_REVERSE 反白
A_BLINK 闪烁
A_BOLD 高亮度 9FCM5D/mN5Z
A_NORMAL 标准模式 (只能配合 attrset() 使用)
vZ
vv
Q"RI^
!iY5b S']?
当使用 attron() 开启某一种特殊属性模式後, 接下来在萤幕的输出都会以 J8QEC9a+XG
该种属性出现. 直到您呼叫 attroff() 将此模式关闭.
tech.techweb.com.cn d9Y,S/,n{X
请注意, 当您欲 attron() 开启另一种属性时, 请记得利用 attroff()先关
TechWeb技术社区x1^ }2V+gncK"i a
闭原来的属性, 或直接以 attrset(A_NORMAL) 将所有特殊属性关闭.否则,
curses 会将两种属性做重叠处理.
TechWeb技术社区|2IZ{5k(Fy1y
□例: 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码7b sYhG]#Sfun
attrset(A_NORMAL); /* 先将属性设定为正常模式 */
attron(A_UNDERLINE); /* 加底线 */
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码;`;~/abbI8[Z
mvaddstr(9,10,"加底线"); /* 加底线输出一串字元 */ TechWeb技术社区8H{8CF0|5awt
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码Yw(a!k o@t^ g
attroff(A_UNDERLINE); /* 关闭加底线模式, 恢复正常模式 */ sh@W`t
&Q'p C"sz*Zmf
attron(A_REVERSE); /* 开启反白模式 */
mvaddstr(10,10,"反白"); /* 输出一串反白字元 */ tech.techweb.com.cnW!N(@GM,q
attroff(A_REVERSE); /* 关闭反白模式, 恢复正常模式 */ Y:A1x/s9hi/zK.}
tech.techweb.com.cnn2Zj#{j
i
i
attron(A_BLINK); /* 开启闪烁模式 */
q4w*usjXv!x/Y
zi6zSF
mvaddstr(11,10,"闪烁"); /* 输出一串闪烁字元 */ +Rhx2}sF Y1w
tech.techweb.com.cn4c@L4j
JY-a X
attroff(A_BLINK); /* 关闭闪烁模式, 恢复正常模式 */ TechWeb技术社区!SPA,_n{.Dc
attron(A_BOLD); /* 开启高亮度模式 */ TechWeb技术社区!s Abv["r]q
mvaddstr(12,10,"高亮度"); /* 输出一串高亮度字元 */
attroff(A_BOLD); /* 关闭高亮度模式, 恢复正常模式 */ uQOUr;BQ
tech.techweb.com.cng;_E7m}$s|
■ 其他常用的一些函式 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码6A4rf(s"jN G!sf_;q1NN
~r~Q
c"D+j:U
beep() 发出一声哔声
box(win,ch1,ch2) 自动画方框 ch1: 画方框时垂直方向所用字元
ch2: 画方框时水平方向所用字元
TechWeb技术社区t}2])B2D-T_ABU
example: box(stdscr,'|','-'); ga1_ g%N G5e3d"E
将以 | 及 - 围成一个方框
■ 应用完整□例
T9C^ct)i
下面所举的例子, 即完全利用刚刚所介绍的含式来完成.这个程式可将从键 zdh,W&/C7s
#TzM
kB W9Z@
盘上读取的字元显示在萤幕上, 并且可以上下左右方向键来控制游标的位置
tech.techweb.com.cnv~q
x Gc{�sF
, 当按下 [ESC] 後, 程式即结束. )m^_#j"H#u.E�iL
tech.techweb.com.cn S)oT)[8j
您有没有发现, 这不就是一个简单全萤幕编辑器的雏形吗?
`(kO.JJTU;HJ7pc
#include
stdio.h */ TechWeb技术社区'pN?
@M+}x
#define StartX 1 /* 决定游标初始位置 */
#define StartY 1 TechWeb技术社区)r?E
a"Ys
void initial();
main()
{
int x=StartX; /* 宣告 x,y 并设定其初值
*/
tech.techweb.com.cn%N7V eI8[gCT
int y=StartY; ke`&T v(R
int ch; /* 宣告 ch 为整数,配合 getch()
使用 */ 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码`Z)A z
UF$~w
tech.techweb.com.cn2[%/1C~g7EB9e C
TechWeb技术社区-KGH(^S~5{;H_b
initial(); /* 呼叫 initial(), 启动 curses 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码*}zQrt
模式, */ 3_I5d;A9D]I;?:o
B4`0`+j|'[
At
/* 并完成其它设定 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码k{E DWT
*/
box(stdscr,'|','-'); /* 画方框
*/ 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码,q8A{Il7}a2r
程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码$O*e)`
I&frp�S
attron(A_REVERSE); /* 开启反白模式
*/ tech.techweb.com.cn"c@VD+N`
mvaddstr(0,20,"Curses Program"); /* 在 (20,0) 处输出反白字元
*/ tech.techweb.com.cn
Ub
O^:Y
attroff(A_REVERSE); /* 关闭反白模式 Z7l8ezn4c/+{jQ O
*/ tech.techweb.com.cnXq8Ls7@
LU)X2^9GkT}
/ k8Gm6i,G
move(x,y); /* 将游标移至初始位置
*/
i*|Gi+r4L/%Mm*E'V
do { /* 以无限回圈不断等待输入
*/
ch=getch(); /* 等待自键盘输入字元
switch(ch) { /* 判断输入字元为何
*/
9i0y&wk(L
case KEY_UP: --y; /* 判断是否"↑"键被按下
*/ 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码#D)`'U
_0J!a,JZ3p
y4WB,gB
break; 程序开发,操作系统,服务器,源码下载,Linux,Unix,BSD,PHP,Apach,asp,下载,源码S+K8/a/b3?6h
case KEY_DOWN: ++y; /* 判断是否"↓"键被按下 TechWeb技术社区.t/EPd1J e#w
*/
*~3{%j+M1WE
break; QE+e.JSM-Y
a+{
case KEY_RIGHT: ++x; /* 判断是否"→"键被按下 TechWeb技术社区^}uRR y2SxU
*/