按字母查成语词典:A|B|C|D|E F G|H|J|K|L|M|N|O|P|Q|R|S|T|W|X|Y|Z
在线新华字典:按偏旁部首查询汉字 | 按汉字拼音查询汉字 | 五笔字根查询
工商管理论文 | 工学工业论文 | 社会艺术论文 | 理学医学论文 | 语言教育论文 | 计算机论文
图形窗口的滚动
在设计应用程序,常会遇到图形屏幕滚动问题。文本方式下,可直接调用BIOS中断功能6和7,但在图形方式下,使用该方法,图形有跳动现象,还不容易控制随意某个区域的移动。这里介绍一种直接操作屏幕缓冲区以实现图形方式下任一窗口滚动的方法。
以常用的图形显示卡EGA/VGA为例说明该方法,屏幕显示内容是屏幕缓冲区(VRAM)的直接映射,要使屏幕某一区域滚动只要对其对应的VRAM进行操作,搬动VRAM的值就可达到目的。
EGA/VGA在非CGA兼容方式下(方式DH以上),屏幕对应内存VRAM是线性的,即VRAM从(A000H:0000H)开始对应屏幕以点(0,0)开始的从左到右的每一行,要使屏幕上移一行,只须把第i+1行对应的内存数据搬到第i行对应的内存里(i重新0到屏幕最大行数)即可实现。如要实现下滚,方法与上类似,只须改变搬移方向即可。这一方法的好处在于能实现任一窗口(x1, y1,x2, y2)内的图形滚动,而窗口外的部分则不动。在实现窗口滚动时,我们应完成三步,(1) 计算该窗口第一个点对应的内存地址。(2) 计算窗口每一行有多少个字节,决定每次移动的字节数。(3) 计算窗口一共有多少行,决定移动的次数。
下面以工作在方式EH(640*200)下来说明,方式DH下,屏幕共有200行,每行共占80个字节,每个字节表示8个像素。窗口(x1,x2,y1,y2)对应的内存段首地址为A000H,偏移量为ofs=y1*80+(x1 div 8)。共有(y2-y1+1)行。每行占字节数为[(x2-x1+1) div 8]。在选取窗口时应注意列座标的选取,因为内存是以字节为单位安排数据的,所以窗口内一行的像素应为8的倍数,窗口首位点的列座标x1也应为8的倍数。
应当说明的是EGA的视屏缓冲区的结构。它的VRAM被分为并行的4页,每页64kb,称为4个页面,分别表示红,蓝,绿,加亮。共用一个地址(A000H:0000H),所以屏幕上一个点其实是由VRAM的四个页面的相同地址处四个字节的某一位共同决定的。屏幕上8个点对应内存有4个字节。我们在进行内存数据搬家时,应对四个页面同时操作。可以提供EGA口地址的选取来指定访问所需的位平面。由EGA图形控制寄存器组(地址为3ceH)的4号寄存器确定哪个页面允许读,由顺序寄存器组(地址为3c4H)的2号寄存器确定适配器中哪个页面被开放(细节见EGA/VEA资料)。
后面附的程序是由Turbo Pascal写成。程序通过Turbo Pascal预定义的MEM数组访问内存,PORT数组访问寄存器端口。具体实现部分见过程movewin。它实现了窗口(x1,y1,x2,y2)上滚一行。可根据需要改写为下滚或水平滚动,直接在读者自己的程式中引用。
program nfm;
uses crt, graph;
const seg=$a000; ofs=$0000;
var m,n: integer;
{movewin 实现指定窗口 (x1,y1,x2,y2)的上滚}
procedure movewin (x1,y1,x2,y2: integer);
var j,addr, k, ofsl,bnum, time: integer;
buff:array [0..79] of byte;
begin
addr:=$00;
k:=$01;
ofs1:=ofs+yl*80+(x1 div 8);
time:=y2-y1+1;
bnum:=(x2-x1+1) div 8;
repeat
port[$3ce]:=4;
port[$3cf]:=addr;
addr:=addr+1;
port[$3c4]:=2;
port[$3c5]:=k;
k:=k*2;
move(mem[seg:ofs1+(time-1)*80], buff,bnum);
move(mem[seg:ofs1], mem[seg:ofs1+(time-1)*80], bnum);
for j:=1 to time do
move(mem[seg:ofs1+j*80], mem[seg: ofs1+(j-1)*80], bnum);
delay(100);
until addr=$04;
end;
begin
m:=ega;
n:=egalo;
initgraph(m,n,'');
setcolor(4);
setbkcolor(2);
bar3d (40,100,400,150,50,true);
repeat
movewin (72,60,319,139);
until keypressed;
closegraph;
end.
本文摘录自互联网络,在此刊登仅为传递更多信息,版权归作者所有.

