C语言实现可视化人机界面的有效方法

来源:万方数据

点击:1335

A+ A-

所属频道:新闻中心

关键词:C语言 人机界面 图形函数库

    引言

        C语言中要实现可视化人机界面, 就必须要绘制图像, 而printf( )函数只能用来输出文本, 显然不能满足绘图的要求。但是, C语言标准函数库提供了一个较为强大的图形函数库,所有图形函数都在头文件graph程序包括了Graphics. h 头文件以后, 所有图形函数的使用都必须在图形模式下进行。而默认模式都是文本模式, 在这种模式下所有图形函数都是无法正常工作的。所以必须先使用一个图形模式初始化函数将计算机设置为图形模式。本文利用这些图形函数提出了实现可视化人机界面的有效方法。

    1 设置图形模式

        要使用C语言绘制图形通常首先要提供一个graphics. h 头文件, 它包含了大量的图形绘制函数。无法立即使用这些函数, 必须首先设置屏幕为图形模式。要将原来屏幕默认的文本模式(80列, 25 行字符模式) 设置为图形模式, 必须对显示卡进行操作。显示卡实际上就是显示适配器的通称, 不同的显示适配器有着不同的色彩种数和图形分辨率。因此, 在使用图形函数作图之前, 必须使用一个Graphics. h图形函数库提供的初始化图形模式的initgraph( )函数根据显示适配器种类设置成为某种确定的图形模式。

        另外, 尽管在程序最开始加了# include , 但如果在初始化图形语句中没有将驱动程序的路径写对, 会导致程序无法找到图形驱动文件, 从而无法在图形模式下进行工作。在屏幕上总是出现如下出错信息:

        BGI Error: Graphics not initialized( use initag raph)下面给出一个最简化的初始化图形模式的例程以清楚地说明问题:

        # include

        / * 声明标准图形函数头文件* /

        int main( )

        {

        int g driver , gmode; / * 定义图形驱动器变量* /

        gdriver= DETECT ; / * 设定图形驱动器为自动监测* /

        initgraph( & gdriver, & gmode,c: \ tc) ;

        / * 初始化图形模式* /

        line( 100, 100, 200, 200) ; / * 画线* /

        getch( ) ;

        clo seg raph( ) ; / * 关闭图形模式* /

        return 0;

        }

        程序的几点说明:

        (1) 对于gdriver, 是原本要求设置所希望的并且计算机提供的图形驱动器, 而gmode 则是对应于这种驱动器的使用模式。将gdriver 设置为DETECT, 让硬件自动监测图形驱动器和模式, 这将非常省力。

        (2) 如果发现bg i 文件在c: \ tc 目录下, 而当前目录在c: \ \ 下, path 可以使用绝对路径, 如: c: \ \ tc; 也可以使用相对路径, 如: \ \ tc。

        (3)一旦初始化了图形模式便可以作图了, 在程序中line ( 100, 100, 200, 200) 语句就是在图形模式下画一条从点( 100, 100) 到点( 200, 200) 的直线。(4) 使用closeg raph( ) 函数来退出图形状态回到默认的文本状态。

    2 在图形模式下写字

        在图形模式下, 仍然可以使用标准输出printf( ) ,put s( ) , putchar ( ) 将文本输出到屏幕。不过C 语言图形函数提供了一些专门用于在图形显示模式下的文本输出函数out tex txy ( ) 等。

        还可以利用setcolor( ) 函数设置输出文字的颜色。用户还可以对文本字符大小进行设置, 具体实现方法有如下两个函数:

        sett ex tsty le( ) / * 水平和垂直方向以相同倍数放大* /

        setusercharsize( ) / * 分别定义水平和垂直放大倍数* /

    3 独立图形程序的建立

        当在图形模式下写好程序, 然后放在别的用户的计算机中却发现对方根本无法使用。这是因为在设置图形模式的时候, 要求有对应的BGI 文件( 对于用init graph( ) 函数直接进行图形初始化程序, 在编译和连接时并没有将相应的驱动程序* . bgi 装入到执行程序) 。而将软件复制给用户的时候并没有将BGI 文件复制给用户, 于是用户根本无法进入图形模式( 当程序进行到initgraph( ) 语句时, 从该函数中第三个形式参数char* path 所规定的路径中去找相应的驱动程序, 若没有,将出现错误:

        BGI Eorro: Gra phics not initialize ( useinitgraph) )即便将所有* . bgi 文件复制给用户, 还是可能存在一个路径错误问题。

        因此只能将BGI 文件( 图形驱动程序) 也一起装到程序中, 这样问题就解决了。这里提供了建立一个不需要驱动程序就能独立运行的可执行图形程序的方法, 以下是具体步骤( 这里以VGA EGA 显示器为例) :

        (1) 在C 语言编译器目录下输入命令:

        BGIOBJ EGAVGA

        BGIOBJ 命令将驱动程序EGAVGA. BGI 转化成EGAVGA. OBJ 的目标文件。

        (2) 在C 语言编译器目录下输入命令:

        TLIBLIB\ GRAPHICS. LIB+ EGAVGATLIB 命令的意思是将EGABGA. OBJ 的目标模块装到GRAPHICS. LIB 库文件中。

        (3) 在程序中调用initgraph( ) 函数之前加上一句:

        registerbg idriver( EGAVGA_driver) ;

        该函数告诉连接程序在连接时把EGAVGA 的驱动程序装入到GRA PHICS. LIB 库文件中。

    4 实现动画思路

        为了达到动态显示由下位机传送过来的信息, 就必须使用动画技术。动画片的原理是将一幅一幅的图片排列起来, 至少以24 幅/ s 的速度连续播放, 这样以来骗过了人们迟钝的眼睛, 使人们误以为看到的一切在运动, 而忘记了这一切都只是静止图片组成的。

        这一思路对做电脑动画非常有帮助, 很容易让人联想到将屏幕作为一张图片, 每次对屏幕这样的图片进行重新绘制。具体思路如下:

        (1) 在屏幕上画一个将要运动的图像;

        (2) 停留一些时间( 事实上非常短, 很可能只有几十到几百毫秒) ;

        (3) 清除屏幕( 或者是屏幕的局部);

        (4) 在刚才被清除的地方相近处( 固定增量) 重新画一个图像;

        (5) 重复步骤(2) ~ (4) 。

    5 简单动画实现

        逻辑运算中的异或指A 与B 的非同B 与A 的非进行或操作的结果。异或逻辑运算有一个特点, 如果A 和B 是相同的, 那么结果一定为0( 1 异或1= 1* 0+0* 1= 0+ 0= 0) 。或者说, 自身异或等于没有进行任何操作。异或与图形绘制有一定的关系。

        如果在一个位置画了一条红色的线, 然后在这个位置再画一次结果是红线还在那里, 没有变化。可是如果在画第一条线之前就设置用异或方式画线, 那么当画第二条线的时候奇迹便发生了屏幕上的那条红线消失了。实现清单如下:

        # include

        # include < stdio.h>

        # include < stdlib.h>

        # include < conio.h>

        int main( void) {

        int gdriver= DETECT , gmode;

        initgraph( & gdriver, & gmode, ) ; / / 初始化图形模式

        setwritemode( XOR_PUT) ; / / 设置异或模式

        setcolor( RED) ; / / 设置前景颜色为红色

        line( 100, 200, 500, 200) ; / / 画红线

        getch( ) ;

        closeg raph( ) ; / / 关闭图形模式, 恢复到文本模式

        return 0;

        }

        在要进行异或操作之前, 使用了一个设置异或模式的函数setwritemode( ) 。异或可以帮助我们用最简单的方法二次完全重画方法擦除原先的图形。那么如何将它和动画联系起来呢?

        提出的异或思路如下:

        (1)设置异或模式, 然后在屏幕上画一个圆和一个正方形;

        (2)停留一些时间;

        (3)在刚才画圆的位置用同样的颜色再画一个圆(圆消失了) ;

        (4)在刚才画圆位置相近处( 固定增量) 再画一个圆;

        (5)重复步骤(2) ~ (4) 。

        以下是使用异或思路实现一个运动的圆和一个静止的正方形的例程。

      # include < graphics. h>

        # include < stdlib. h>

        # include < stdio. h>

        # include < conio . h>

        int main( void)

        { int gdriver= DETECT, gmode;

        void * ball;

        int x, y, maxx ;

        unsigned int size;

        initgraph( & g driver, & gmode,) ;

        maxx= get maxx ( ) ;

        x= 0; y= 200;

        rectangle( x , y+ 11, x+ 20, y+ 31) ; / / 绘制矩形

        circle( x+ 10, y, 10) ; / / 绘制圆

        size= imagesize( x , y- 10, x+ 20, y+ 10) ;

        / / 计算保存区域大小

        ball= mallo c( size) ; / / 申请保护区域内存

        getimage( x , y- 10, x+ 20, y+ 10, ball) ;

        / / 保存圆所在的位置图形到内存

        while( ! kbhit( ) ) {

        putimage( x, y- 10, ball, XOR_PUT) ;

        / / 用异或方式在新位置绘制圆, 圆消失

        x+ = 10; / / 计算圆移动增量

        if ( x> = max x ) {

        x= 0;

        putimage( x, y- 10, ball, XOR_PUT) ;

        / / 用异或方式在新位置绘制圆, 圆出现

        delay( 1000) ; / / 延迟一定时间

        } }

        free(ball) ;

        closegraph( ) ;

        return 0;

        }

        该程序的运行情况, 和前面的例程的效果差不多。但从实际画点开销角度来看, 3 个圆球运行的例程是不一样的。

        本例程使用XOR 异或方法重画, 每次画点开销为:

        10* 4 点(重画圆形清除) + 10* 4 点(重画圆形) = 80 点

        由此可见,异或在这里是最好的绘制动画的选择。


    (审核编辑: 智汇小新)