ba_wang_mao 发表于 2006-11-21 17:26

800X600图形模式 窗口的保存及恢复屏幕窗口

<P> 版主:<BR>    图形模式800X600下我想实现,当窗口弹出前保存窗口内容到XMS,而当窗口消失后恢复原先屏幕的内容。以下是程序,为什么实现不了呢?<BR><BR>char buf[800];//全局数组变量,每次取一行800个像素<BR>unsigned short xms_handle;//XMS句柄<BR>/**********************************************************/<BR>/* 保存窗口内容到XMS<BR>/**********************************************************/<BR>void  Save_Window_XMS(int x1,int y1,int x2,int y2)<BR>{<BR>    int i,j;<BR>    unsigned short size,len;<BR>    unsigned long offset = 0;<BR>    char *pp;</P>
<P>    size = (x2-x1+1)*(y2-y1+1)/1024 +1;<BR>    if (XMS_Size() &lt; size)<BR>        puts("not enough XMS");<BR>    if ((xms_handle = XMS_Alloc(size)) == 0)//XMS申请空间成功<BR>        puts("XMS handle Error...\n");<BR>    for (i= y1; i&lt;=y2;i++)<BR>    {<BR>        pp=buf;<BR>        for (j= x1; j&lt;=x2;j++)<BR>            *pp++ = getpixel(j,i);//在屏幕上获取像素点<BR>        len = x2-x1+1;<BR>        Write_To_XMS(buf,len,xms_handle,offset);//缓冲区buf中存储的像素送至XMS<BR>        offset += len;<BR>    }</P>
<P>}</P>
<P>/**********************************************************/<BR>/* 恢复XMS中的内容到屏幕<BR>/**********************************************************/<BR>void _Cdecl Restore_Window_XMS(int x1,int y1,int x2,int y2)<BR>{<BR>    int i,j;<BR>    unsigned short len;<BR>    unsigned long offset = 0;<BR>    char *pp;<BR>    <BR>    len = (x2-x1+1)<BR>    for (i= y1; i&lt;=y2;i++)<BR>    {<BR>        Read_From_XMS(buf,len,xms_handle,offset);<BR>        offset += len;<BR>        pp=buf;<BR>        for (j= x1; j&lt;=x2;j++)<BR>            putpixel(j,i,*pp++);<BR>    }<BR>    XMS_Free(xms_handle);<BR>}</P>

ba_wang_mao 发表于 2006-11-21 20:24

错了,更正为:<BR>版主:<BR>    图形模式800X600下我想实现,当窗口弹出前保存屏幕内容到XMS,而当窗口消失后恢复屏幕的内容从XMS到显示器上。<BR>

ba_wang_mao 发表于 2006-11-22 09:25

请问:是否保存屏幕就是把屏幕上的像素点存储在缓冲区中,<BR>char buffer[800];<BR>char *p;<BR>   p=buffer;<BR>   for (i=x1,j=0;i&lt;x2;i++)<BR>       *p++= getpixel(i,j);<BR><BR>而恢复屏幕就是把存储在缓冲区中的像素重新画在屏幕上<BR>char *p;<BR>   p=buffer;<BR>   for (i=x1,j=0;i&lt;x2;i++)<BR>       putpixel(i,j,*p++);<BR>

一笔苍穹 发表于 2006-11-22 10:19

对,是的,你可以写个程序验证一下。<BR>我在上班,没时间给你多看,提醒你如果能排除从屏幕上读像素部分的代码没问题的话,那你就要查查读写XMS的那几个函数了。

ba_wang_mao 发表于 2006-11-22 11:07

<P>谢谢一笔苍穹,我的XMS程序没有问题,<BR>我的程序运行的结果是:执行完屏幕恢复子程序后,被窗口遮盖的部分显示“一个黑色的矩形”,我程序中的背景色为黑色。<BR>char getpixel(int x, int y)<BR>{<BR>    long addr;<BR>    int  page;<BR>    char far *videoptr = (char far *)0xa0000000L;</P>
<P>    addr = (long)y * 800 + x;<BR>    page = (int)(addr &gt;&gt; 16);<BR>    set_vbe_page(page);<BR>    return *(videoptr + (unsigned)(addr &amp; 0xffff));<BR>}</P>
<P><BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>//画点函数<BR>/////////////////////////////////////////////////////////////////////////////////////////////////<BR>void putpixel(int x,int y,int color)<BR>{<BR>    long addr;<BR>    int page;<BR>    char far *videoptr = (char far *)0xa0000000L;</P>
<P>    addr = (long)y * 800 + x;<BR>    page = (int)(addr &gt;&gt; 16);<BR>    set_vbe_page(page);<BR>    setcolor(color);<BR>    *(videoptr+(unsigned int)(addr&amp;0xffff))= color;<BR>}<BR><BR>//-----------------------------------------------------------<BR>//英文输出函数<BR>//-----------------------------------------------------------<BR>void puthz(int x,int y,char *p,int color,int d)<BR>{<BR>    unsigned char far *ROM_ASCII;<BR>    unsigned int i,j;<BR>    unsigned char ch;<BR>    char buf[32];</P>
<P>    while((ch=*p++)!=0)<BR>    {<BR>          ROM_ASCII = cur_asc_rom(S8X16);//取16X8点阵字模<BR>           for(i=0;i&lt;16;i++)<BR>            {<BR>                buf[i*2]=*(ROM_ASCII+(ch)*16+i);<BR>                buf[i*2+1]=0;        /*字模右边8位补0*/</P>
<P>            }<BR>            for(j=0;j&lt;16;j++)<BR>                for(i=0;i&lt;8;i++)<BR>                    if ((0x80&gt;&gt;i%8)&amp;buf[2*j+i/8])<BR>                       putpixel(i+x,y+j,color);//用color色打点<BR>                    else<BR>                       putpixel(i+x,y+j,BLACK);//用黑色背景色打点<BR>            x+=8+d;<BR>        }<BR>    }<BR>}<BR><BR>1、由于我显示的数字要改变,如果不增加:putpixel(i+x,y+j,BLACK);,则如果原先显示123,现在显示454,则屏幕上就会一团糟,看不清,请问有什么好的办法,<BR>2、为什么,执行完屏幕恢复子程序后,被窗口遮盖的部分显示“一个黑色的矩形”?</P>

ba_wang_mao 发表于 2006-11-27 13:03

难道无人知道?

一笔苍穹 发表于 2006-11-28 09:48

程序我是实在没时间,这几天忙着给公司网站改版。<BR>1、由于我显示的数字要改变,如果不增加:putpixel(i+x,y+j,BLACK);,则如果原先显示123,现在显示454,则屏幕上就会一团糟,看不清,请问有什么好的办法<BR>显示完了用底色覆盖再显示新的是很自然的做法,要不你试试XOR?<BR><BR>2、为什么,执行完屏幕恢复子程序后,被窗口遮盖的部分显示“一个黑色的矩形”?<BR>你不是说你的背景色是黑的吗?你之前保存的是背景色吧?

ba_wang_mao 发表于 2006-11-30 08:40

<P>谢谢一笔苍穹,屏幕内容保存到XMS以及恢复屏幕内容从XMS已经解决。<BR>注:POPUP_x1,POPUP_x2,POPUP_y1,POPUP_y2为窗口坐标<BR><BR>typedef unsigned int XMS_HANDLE;<BR>XMS_HANDLE xms_handle;                // 伪指针<BR>XMS_HANDLE xms_save_restore_handle;                // 伪指针<BR><BR>/*-----------------------------------------------------------<BR>//从常规内存缓冲区buf装载到扩充内存<BR>-----------------------------------------------------------*/<BR>void _Cdecl Write_To_XMS(char *buf,unsigned int size,XMS_HANDLE handle,unsigned long offset)<BR>{<BR>    xms.length = size;<BR>    xms.source_handle = 0;<BR>    xms.source_offset  = FP_SEG((void far *)buf);<BR>    xms.source_offset &lt;&lt;= 16;<BR>    xms.source_offset += FP_OFF((void far *)buf);<BR>    xms.dest_handle = handle;<BR>    xms.dest_offset = offset;<BR>    XMS_Move(&amp;xms);<BR>}</P>
<P><BR>/*-----------------------------------------------------------<BR>//从扩充内存中读取信息到常规内存缓冲区buf<BR>-----------------------------------------------------------*/<BR>void _Cdecl Read_From_XMS(char *buf,unsigned int size,XMS_HANDLE handle,unsigned long offset)<BR>{<BR>    xms.length = size;<BR>    xms.source_handle = handle;<BR>    xms.source_offset = offset;<BR>    xms.dest_handle = 0;<BR>    xms.dest_offset = FP_SEG((void far *)buf);<BR>    xms.dest_offset &lt;&lt;= 16;<BR>    xms.dest_offset  += FP_OFF((void far *)buf);<BR>    XMS_Move(&amp;xms);<BR>}</P>
<P><BR>char sssbuf[500];<BR>void _Cdecl Save_Image_XMS(void)<BR>{<BR>    int i,j;<BR>    unsigned short size;<BR>    unsigned long offset = 0;<BR>    char *pp;</P>
<P>    size = (POPUP_x2-POPUP_x1+1)*(POPUP_y2-POPUP_y1+1)/1024+1;<BR>    if (XMS_Size() &lt; size)<BR>        puts("not enough XMS");<BR>    if ((xms_save_restore_handle = XMS_Alloc(size)) == 0)<BR>        puts("XMS handle Error...\n");<BR>    for (i= POPUP_y1; i&lt;=POPUP_y2;i++)<BR>    {<BR>        size = POPUP_x2-POPUP_x1;<BR>        pp = sssbuf;<BR>        for (j= POPUP_x1; j&lt;=POPUP_x2;j++)<BR>            *pp++ = getpixel(j,i);<BR>        Write_To_XMS(sssbuf,size,xms_save_restore_handle,offset);<BR>        offset += size;<BR>    }<BR>}</P>

<P>void _Cdecl Restore_Image_XMS(void)<BR>{<BR>    int i,j;<BR>    unsigned short size;<BR>    unsigned long offset = 0;<BR>    char *pp;</P>
<P>    size = POPUP_x2-POPUP_x1;<BR>    for (i= POPUP_y1; i&lt;=POPUP_y2;i++)<BR>    {<BR>        Read_From_XMS(sssbuf,size,xms_save_restore_handle,offset);<BR>        offset += size;<BR>        pp = sssbuf;<BR>        for (j= POPUP_x1; j&lt;=POPUP_x2;j++)<BR>            putpixel(j,i,*pp++);//sssbuf[j-POPUP_x1]);<BR>    }<BR>    XMS_Free(xms_save_restore_handle);<BR>}</P>

一笔苍穹 发表于 2006-11-30 10:37

呵呵,恭喜~~

页: [1]

编程论坛