本程序必须在TC++ 3.0及心上版本编译
#include <bios.h>
#include <dos.h>
#include <string.h>
#ifdef __cplusplus
    #define __CPPARGS ...
#else
    #define __CPPARGS
#endif
#define ESC_KEY                    0x011B
#define DOUBLE_X                 205
#define DOUBLE_Y                 186
#define DOUBLE_LEFT_UP          201
#define DOUBLE_LEFT_DOWN          187
#define DOUBLE_RIGHT_UP          200
#define DOUBLE_RIGHT_DOWN          188
#define SHADOW_ATTR              0x07
#define WINDOW_ATTR              0x1E
#define DESKTOP_ATTR             0x71
#define DESKTOP_CHAR             0xB0
#define WINDOW_CHAR              0X20
#define WHITE_BLACK                0x70
#define WHITE_RED                0x74
#define WHITE_YELLOW            0x76
#define WHITE_BLUE                0x71
#define BLUE_WHITE                0x17
#define BLUE_WHITE_LIGHT        0x1F
#define BLUE_LIGHT_WHITE        0x97
#define BLUE_GRAY                0x18
#define BLUE_LIGHT_GRAY            0x98
#define BLUE_YELLOW                0x1E
#define BLUE_GREEN                0x12
#define BLUE_LIGHT_GREEN        0x1A
#define BLUE_RED                0x1D
#define MIN_DESKTOP_X            0x01
#define MAX_DESKTOP_X            0x17
#define MAX_WINDOW_X            0x17
#define MIN_WINDOW_X            0x01
#define MAX_DESKTOP_Y            0x4F
#define MIN_DESKTOP_Y            0x00
//保存光标
void CursorSave(void)
{
    union REGS regs;
    regs.h.ah = 0x03;
    regs.h.bh = 0x00;
    int86(0x10,®s,®s);
    xSave = regs.h.dh;
    ySave = regs.h.dl;
    regs.h.ah = 0x02;
    regs.h.bh = 0x00;
    regs.h.dh = 0x50;
    regs.h.dl = 0x50;
    int86(0x10,®s,®s);
}
//恢复光标
void CursorRestore(void)
{
    union REGS regs;
    regs.h.ah = 0x02;
    regs.h.bh = 0x00;
    regs.h.dh = xSave;
    regs.h.dl = ySave;
    int86(0x10,®s,®s);
}
//窗口区域上滚,背景颜色=attr
void WindowScrollUp(char x1,char y1,char x2,char y2,char attr)
{
    union REGS regs;
    regs.h.ah = 0x06;
    regs.h.al = 0x01;
    regs.h.bh = attr;
    regs.h.cl = y1;
    regs.h.ch = x1;
    regs.h.dl = y2;
    regs.h.dh = x2;
    int86(0x10,®s,®s);
}
//在(x,y)写字符,颜色=attr
void WriteChar(unsigned char x,unsigned char y,unsigned char c,unsigned char attr)
{
    char far *v = (char far *)0xb8000000;
    char far *t;
    t = v + x*0xA0+y*0x02;
    *t++ = c;
    *t++ = attr;
}
//在(x,y)写字符串,颜色=attr
void WriteString(const unsigned char x,const unsigned char y,char *String,const unsigned char attr)
{
    unsigned char j = y;
    char *ptr = String;
    while (*ptr)
        WriteChar(x,j++,*ptr++,attr);
}
//读(x,y)处的字符及颜色
unsigned int ReadCharAttr(const unsigned char x , const unsigned char y)
{
    unsigned char lo,hi;
    char far *v = (char far *)0xb8000000;
    char far *t;
    t = v + x*0xA0+y*0x02;
    lo = *t++;                                   // char
    hi = *t++;                                   // attr
    return int(hi*256+lo);
}
//保存窗口区域内容
void WindowSaveImage(void)
{
    unsigned char far *image_ptr = image;
    unsigned int num;
    for (char i = 0x00 ; i <= 0x18; i++)
        for (char j = 0x00 ; j <= 0x4F; j++)
        {
            num = ReadCharAttr(i,j);
            *image_ptr++ = num%256;
            *image_ptr++ = num/256;
        }
}
//恢复窗口区域内容
void WindowRestoreImage(void)
{
    unsigned char far *image_ptr = image;
    for (char i = 0x00; i <= 0x18; i++)
        for (char j = 0x00 ; j <= 0x4F ; j++)
        {
            unsigned char c = *image_ptr++;
            unsigned char attr = *image_ptr++;
            WriteChar(i,j,c,attr);
        }
}
//画窗口
void WindowBorder(const char x1,const char y1,const char x2,const char y2,unsigned char box_attr)
{
    for (char i=y1; i<y2; i++)
    {
        WriteChar(x1,i,DOUBLE_X,box_attr);
        WriteChar(x2,i,DOUBLE_X,box_attr);
    }
    for (i=x1; i<x2; i++)
    {
        WriteChar(i,y1,DOUBLE_Y,box_attr);
        WriteChar(i,y2,DOUBLE_Y,box_attr);
    }
    WriteChar(x1,y1,DOUBLE_LEFT_UP,box_attr);
    WriteChar(x1,y2,DOUBLE_LEFT_DOWN,box_attr);
    WriteChar(x2,y1,DOUBLE_RIGHT_UP,box_attr);
    WriteChar(x2,y2,DOUBLE_RIGHT_DOWN,box_attr);
}
//窗口初始化
void WindowInit(const int x1,const int y1,const int x2,const int y2,unsigned char box_attr,unsigned char window_attr,unsigned char title_attr,char *title)
{
    char i,j;
    for (i=x1; i<x2; i++)
        for (j=y1; j<y2; j++)
            WriteChar(i,j,WINDOW_CHAR,window_attr);
    for (i = x1+1;i<=x2+1;i++)
        WriteChar(i,y2+1,WINDOW_CHAR,SHADOW_ATTR);
    for (j=y1+2; j<=y2+1; j++)
        WriteChar(x2+1,j,WINDOW_CHAR,SHADOW_ATTR);
    for (i=x1+1; i<=x2+1; i++)
        WriteChar(i,y2+1,WINDOW_CHAR,SHADOW_ATTR);
    for (j=y1+2; j<=y2+1; j++)
        WriteChar(x2+1,j,WINDOW_CHAR,SHADOW_ATTR);
    WindowBorder(x1,y1,x2,y2,box_attr);
    WriteString(x1,y1+(y2-y1+1-strlen(title))/2,title,title_attr);
}
//桌面初始化
void DeskTopInit(char *title)
{
    for (unsigned char i = 0x00 ; i <= 0x4F;i++)
    {
        WriteChar(0x00,i,WINDOW_CHAR,WHITE_BLACK);
        WriteChar(0x18,i,WINDOW_CHAR,WHITE_BLACK);
    }
    for (i = MIN_DESKTOP_X; i<=MAX_DESKTOP_X; i++)
        for (unsigned char j = MIN_DESKTOP_Y; j<=MAX_DESKTOP_Y; j++)
            WriteChar(i,j,DESKTOP_CHAR,DESKTOP_ATTR);
    WriteString(0x00,(80-strlen(title))/2,title,WHITE_BLACK);
}
