C/C++分别实现画图软件

1.C语言版

#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <math.h>
#include <alloc.h>

/*定义常量*/
/*向上翻页移键*/
#define PAGEUP 0x4900
/*向下翻页移键*/
#define PAGEDOWN 0x5100
/*Escape键*/
#define ESC 0x011b 
/*左移键*/
#define LEFT 0x4b00
/*右移键*/
#define RIGHT 0x4d00 
/*下移键*/
#define DOWN 0x5000 
/*上移键*/
#define UP 0x4800
/*空格键*/
#define SPACE 0x3920

#define   NO_PRESSED    0
#define   LEFT_PRESSED  1
#define   RIGHT_PRESSED 2
#define   pi            3.1415926

/*定义全局变量*/
int Rx,Ry,R;
int TOPx,TOPy,BOTTOMx,BOTTOMy;
int Centx,Centy;
int lineStartx,lineStarty,lineEndx,lineEndy;
int linePoint_x[20],linePoint_y[20];


/*这里的字模数组均由“点阵字模工具”生成,你可以用你自己需要的点阵信息来
替换示例中的字模信息,注意字模大小要一致,否则显示会出问题。*/
char zhi16K[]={
/* 以下是 '直' 的 16点阵楷体_GB2312 字模,32 byte */
  0x01,0x00,0x01,0x00,0x01,0xF0,0x1E,0x00,
  0x02,0x00,0x07,0xC0,0x08,0x40,0x0F,0x40,
  0x08,0x40,0x0F,0x40,0x08,0x40,0x0F,0x40,
  0x08,0x40,0x0F,0xFC,0x70,0x00,0x00,0x00,
};

char xian16K[]={
/* 以下是 '线' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x80,0x00,0x90,0x08,0x88,0x10,0x80,
  0x24,0xF0,0x45,0x80,0x78,0xB0,0x11,0xC0,
  0x2C,0x88,0x70,0x50,0x04,0x60,0x18,0xA4,
  0x63,0x14,0x00,0x0C,0x00,0x04,0x00,0x00,
};

char ju16K[]={
/* 以下是 '矩' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x00,0x08,0x00,0x08,0x78,0x10,0x80,
  0x1E,0x80,0x28,0xF8,0x48,0x88,0x0E,0x88,
  0xF8,0xF0,0x08,0x80,0x14,0x80,0x12,0x9E,
  0x20,0xE0,0x40,0x00,0x00,0x00,0x00,0x00,
};

char xing16K[]={
/* 以下是 '形' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x00,0x07,0x88,0x3A,0x08,0x12,0x10,
  0x12,0x20,0x17,0x48,0xFA,0x10,0x12,0x20,
  0x12,0xC8,0x12,0x08,0x22,0x10,0x42,0x20,
  0x00,0x40,0x00,0x80,0x03,0x00,0x00,0x00,
};

char yuan16K[]={
/* 以下是 '圆' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0xF8,0x3F,0x08,0x23,0x88,0x24,0x88,
  0x27,0x08,0x21,0xC8,0x2E,0x48,0x29,0x48,
  0x29,0x48,0x22,0x88,0x24,0x48,0x28,0x08,
  0x3F,0xE8,0x00,0x10,0x00,0x00,0x00,0x00,
};

char qing16K[]={
/* 以下是 '清' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x80,0x00,0xE0,0x33,0x80,0x10,0xE0,
  0x03,0x80,0x40,0xFC,0x2F,0x00,0x01,0xE0,
  0x12,0x20,0x13,0xA0,0x22,0x20,0x63,0xA0,
  0x42,0x20,0x02,0x60,0x00,0x20,0x00,0x00,
};

char ping16K[]={
/* 以下是 '屏' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0xF0,0x0F,0x30,0x08,0x60,0x0F,0x80,
  0x0A,0x20,0x09,0x40,0x08,0xF8,0x17,0x20,
  0x11,0x3E,0x2F,0xE0,0x21,0x20,0x42,0x20,
  0x82,0x20,0x04,0x20,0x08,0x20,0x00,0x00,
};

char bao16K[]={
/* 以下是 '保' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x00,0x09,0xF0,0x0A,0x10,0x12,0x10,
  0x13,0xE0,0x30,0x80,0x50,0xFC,0x9F,0x80,
  0x11,0xC0,0x12,0xA0,0x14,0x98,0x18,0x8E,
  0x10,0x80,0x10,0x80,0x00,0x00,0x00,0x00,
};

char cun16K[]={
/* 以下是 '存' 的 16点阵楷体_GB2312 字模,32 byte */
  0x01,0x00,0x01,0x00,0x01,0xF0,0x1E,0x00,
  0x02,0x70,0x05,0x90,0x08,0x20,0x08,0x40,
  0x18,0x7E,0x2B,0xA0,0xC8,0x20,0x08,0x20,
  0x08,0x20,0x08,0xA0,0x00,0x40,0x00,0x00,
};

char jia16K[]={
/* 以下是 '加' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
  0x0F,0x00,0x79,0x3C,0x09,0x44,0x11,0x44,
  0x11,0x44,0x22,0x44,0x22,0x78,0x4A,0x00,
  0x84,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

char zai16K[]={
/* 以下是 '载' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x80,0x08,0xA0,0x08,0x90,0x0E,0x80,
  0x38,0xF0,0x0F,0x80,0x78,0x50,0x0E,0x50,
  0x34,0x20,0x1E,0x20,0x34,0x50,0x0E,0x92,
  0x75,0x0A,0x04,0x06,0x04,0x02,0x00,0x00,
};

char bang16K[]={
/* 以下是 '帮' 的 16点阵楷体_GB2312 字模,32 byte */
  0x04,0x00,0x07,0x38,0x1C,0x48,0x06,0x50,
  0x1C,0x50,0x07,0x48,0x78,0x58,0x11,0x40,
  0x21,0xF0,0x4F,0x10,0x09,0x10,0x09,0x50,
  0x09,0x20,0x01,0x00,0x01,0x00,0x00,0x00,
};


char zhu16K[]={
/* 以下是 '助' 的 16点阵楷体_GB2312 字模,32 byte */
  0x00,0x00,0x00,0x20,0x0C,0x20,0x34,0x20,
  0x24,0x20,0x34,0x38,0x25,0xC8,0x34,0x48,
  0x24,0x48,0x26,0x88,0x38,0x88,0xE1,0x28,
  0x02,0x10,0x04,0x00,0x00,0x00,0x00,0x00,
};

/*自定义函数*/
void outChinese(char *mat,int matsize,int x,int y,int color);
void fill(int startx,int starty,int endx,int endy,int color);
void showHelp();

void save();
void load();

int mouseStatus(int* x,int* y);
int setMousePos(int x, int y);
void DrawMouse(float x,float y);

void DrawLine();
void DrawRectangle();
void LineToCircle(int x0,int y0,int r);
void DrawCircle();
long factorial(int n);
float berFunction(int i,int n,double t);
void DrawBezier();


/*根据点阵信息显示中文函数*/
void outChinese(char *mat,int matsize,int x,int y,int color)
/*依次:字模指针、点阵大小、起始坐标(x,y)、颜色*/
{
  int i, j, k, n;
  n = (matsize - 1) / 8 + 1;
  for(j = 0; j < matsize; j++)
    for(i = 0; i < n; i++)
      for(k = 0;k < 8; k++)
        if(mat[j * n + i] & (0x80 >> k))
          /*测试为1的位则显示*/
          putpixel(x + i * 8 + k, y + j, color);
}

/*填充函数*/
void fill(int startx,int starty,int endx,int endy,int color)
{
    int i,j;
        for(i=startx;i<=endx;i++)
            for(j=starty;j<=endy;j++)
            /*在指定位置以指定颜色画一像素*/
            putpixel(i,j,color);

} 

/*显示用户帮助函数*/
void showHelp()
{
    setcolor(14);
    outtextxy(45,50,"Line:");
    setcolor(WHITE);
    outtextxy(45,50,"      1 Press left button to start until to line end.");
    outtextxy(45,65,"      2 Use UP,DOWN,LEFT,RIGHT keys to move it.");
    outtextxy(45,80,"      3 Use PAGEUP key to enlarge it, and PAGEDOWN key to shrink it.");
    outtextxy(45,95,"      4 Use SPACE key to rotate it.");

    setcolor(14);
    outtextxy(45,120,"Rectangle:");
    setcolor(WHITE);
    outtextxy(45,120,"           1 Press left button to start until to right corner.");
    outtextxy(45,135,"           2 Use UP,DOWN,LEFT,RIGHT keys to move it.");
    outtextxy(45,150,"           3 Use PAGEUP key to enlarge it, and PAGEDOWN key to shrink it.");


    setcolor(14);
    outtextxy(45,170,"Circle:");
    setcolor(WHITE);
    outtextxy(45,170,"        1 Press left button to start until to end.");
    outtextxy(45,185,"        2 Use PAGEUP key to enlarge it, and PAGEDOWN key to shrink it.");


    setcolor(14);
    outtextxy(45,205,"Bezier:");
    setcolor(WHITE);
    outtextxy(45,205,"        Press left button to start, and right button to end.");


    outtextxy(45,230,"Press ESC key to stop the operation function.");
    outtextxy(45,245,"Press right button to end the drawing works.");
    outtextxy(45,260,"Press any key to continue......");
    getch();
    fill(40,40,625,270,0);

}

/*保存函数*/
void save()
{
    int i,j; 
    FILE *fp;
    char fileName[20];

    fill(0,447,630,477,2);
    gotoxy(1,25);
    printf("\n\n\n\n  Input the file name[.dat]:");
    scanf("%s",fileName);
    fill(0,447,630,477,2);

    /*以读写的方式打开文件*/
    if((fp=fopen(fileName,"w+"))==NULL)
    {
        outtextxy(260,455,"Failed to open file!");
        exit(0); 
    } 
    outtextxy(280,455,"saving...");

    /*保存像素到文件*/
    for(i=5;i<630;i++)
        for(j=30;j<=445;j++)
            fputc(getpixel(i,j),fp);
    fclose(fp);

    fill(0,447,630,477,2);
    outtextxy(260,455,"save over!");
} 

/*打开函数*/
void load()
{ 
    int i,j; 
    char fileName[20];
    FILE *fp;

    fill(0,447,630,477,2);
    gotoxy(1,25); 
    printf("\n\n\n\n  Input the file name[.dat]:");
    scanf("%s",fileName);

    /*打开指定的文件*/
    if((fp=fopen(fileName,"r+"))!=NULL)
    { 
        fill(0,447,630,477,2);
        outtextxy(280,455,"loading...");

        /*从文件中读出像素*/
        for(i=5;i<630;i++)
            for(j=30;j<=445;j++)
                putpixel(i,j,fgetc(fp));
        fill(0,447,630,477,2);
        outtextxy(280,455,"loading over !");
    }
    /*打开失败*/
    else
    {
        fill(0,447,630,477,2);
        outtextxy(260,455,"Failed to open file!");

    }
    fclose(fp);
}

/*获取鼠标状态函数*/
int mouseStatus(int* x,int* y)
{
    /*定义两个寄存器变量,分别存储入口参数和出口参数*/
    union REGS inregs,outregs;
    int status;
    status=NO_PRESSED;

    /*入口参数AH=3,读取鼠标位置及其按钮状态*/
    inregs.x.ax=3;
    int86(0x33,&inregs,&outregs);
    /*CX表示水平位置,DX表示垂直位置*/
    *x=outregs.x.cx;
    *y=outregs.x.dx;

    /*BX表示按键状态*/
    if(outregs.x.bx&1)
        status=LEFT_PRESSED;
    else if(outregs.x.bx&2)
        status=RIGHT_PRESSED;
    return (status);
}

/*设置鼠标指针位置函数*/
int setMousePos(int x,int y)
{
    union REGS inregs,outregs;

    /*入口参数AH=4,设置鼠标指针位置*/
    inregs.x.ax=4;
    inregs.x.cx=x;
    inregs.x.dx=y;
    int86(0x33,&inregs,&outregs);
}

/*绘制鼠标函数*/
void DrawMouse(float x,float y)
{
    line(x,y,x+5,y+15);
    line(x,y,x+15,y+5);
    line(x+5,y+15,x+15,y+5);
    line(x+11,y+9,x+21,y+19);
    line(x+9,y+11,x+19,y+21);
    line(x+22,y+19,x+20,y+21);
}


/*绘制直线函数*/
void DrawLine()
{
   int x0,y0,x1,y1;
   int last_x=0,last_y=0;
   int endFlag=0;
   int key;
   int temStartx,temStarty,temEndx,temEndy;
   int increment_x,increment_y,angle;

   DrawMouse(last_x,last_y);
   while(1)
   {
        /*右键结束画直线*/
        while((mouseStatus(&x1,&y1)==RIGHT_PRESSED))
            endFlag=1;
        if(endFlag==1)
            break;
        /*鼠标移动,没有单击,仅仅画移动的鼠标*/
        while(mouseStatus(&x1,&y1) == NO_PRESSED)
        {
            if(last_x!=x1||last_y!=y1)
            {
                DrawMouse(last_x,last_y);
                DrawMouse(x1,y1);
                last_x=x1;
                last_y=y1;
            }
        }
        /*单击左键后,开始画直线*/
        if(mouseStatus(&x0,&y0)==LEFT_PRESSED)
        {
            DrawMouse(last_x,last_y);
            line(x0,y0,x1,y1);
            last_x=x1;
            last_y=y1;
            /*拉动过程中,画直线和鼠标*/
            while(mouseStatus(&x1, &y1)==LEFT_PRESSED)
            {
                if(last_x!=x1||last_y!=y1)
                {
                    line(x0,y0,last_x,last_y);
                    line(x0,y0,x1,y1);
                    last_x=x1;
                    last_y=y1;
                 }
            }
            /*松开左键后,画直线完成,记录直线的起始位置*/
            lineStartx=x0;
            lineStarty=y0;
            lineEndx=x1;
            lineEndy=y1;

            while(1)
            {
                /*从键盘获取键值,开始操作(移动、放大、缩小、旋转)直线*/
                key=bioskey(0);
                /*ESC键,退出操作*/
                if(key==ESC)
                    break;

                /*旋转*/
                if(key==SPACE)
                {   
                    /*计算旋转中心*/
                    /*如果直线示倾斜的*/
                    if((lineStarty!=lineEndy)&& (lineStartx!=lineEndx))
                    {
                        Centx=(lineEndx-lineStartx)/2+lineStartx;
                        Centy=(lineEndy-lineStarty)/2+lineStarty;
                    }
        
                    /*如果直线是竖直的*/
                    if(lineStarty==lineEndy)
                    {
                        Centx=(lineEndx-lineStartx)/2+lineStartx;
                        Centy=lineStarty;
                    }

                    /*如果直线是水平的*/
                    if(lineStartx==lineEndx)
                    {
                        Centx=lineStartx;
                        Centy=(lineEndy-lineStarty)/2+lineStarty;
                    }

                    temStartx=lineStartx;
                    temStarty=lineStarty;
                    temEndx=lineEndx;
                    temEndy=lineEndy;

                    /*旋转不能超过边界*/
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        /*清除原有的直线*/
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);

                        /*计算旋转30度后的起点坐标*/
                        lineStartx=(temStartx-Centx)*cos(pi/6)-(temStarty-Centy)*sin(pi/6)+Centx;
                        lineEndx=(temEndx-Centx)*cos(pi/6)-(temEndy-Centy)*sin(pi/6)+Centx;

                        /*计算旋转30度后的终点坐标*/
                        lineStarty=(temStartx-Centx)*sin(pi/6)+(temStarty-Centy)*cos(pi/6)+Centy;
                        lineEndy=(temEndx-Centx)*sin(pi/6)+(temEndy-Centy)*cos(pi/6)+Centy;
    
                        temStartx=lineStartx;
                        temStarty=lineStarty;
                        temEndx=lineEndx;
                        temEndy=lineEndy;

                        /*绘制旋转后的直线*/
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }   
                }
                /*左移直线*/
                if(key==LEFT)
                {
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                        /*起始的横坐标减小*/
                        lineStartx-=5;
                        lineEndx-=5;
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }
                }

                /*右移直线*/
                if(key==RIGHT)
                {
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                        /*起始的横坐标增加*/
                        lineStartx+=5;
                        lineEndx+=5;
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }
                }

                /*下移直线*/
                if(key==DOWN)
                {
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                        /*起始的纵坐标增加*/
                        lineStarty+=5;
                        lineEndy+=5;
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }
                }

                /*上移直线*/
                if(key==UP)
                {
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                        /*起始的纵坐标减小*/
                        lineStarty-=5;
                        lineEndy-=5;
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }
                }
                /*放大直线*/
                if(key==PAGEUP)
                {   
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);

                        /*如果直线是倾斜的*/
                        if((lineStarty!=lineEndy)&& (lineStartx!=lineEndx))
                        {
                            /*计算直线的倾角*/
                            angle=atan((fabs(lineEndy-lineStarty))/(fabs(lineEndx-lineStartx)));
                            /*计算水平增量*/
                            increment_x=cos(angle)*2;
                            /*计算垂直增量*/
                            increment_y=sin(angle)*2;

                            /*计算放大后的起始坐标*/
                            if(lineStartx<lineEndx)
                            {
                                lineStartx-=increment_x;
                                lineStarty-=increment_y;
                                lineEndx+=increment_x;
                                lineEndy+=increment_y;
                            }
                            if(lineStartx>lineEndx)
                            {
                                lineEndx-=increment_x;
                                lineEndy-=increment_y;
                                lineStartx+=increment_x;
                                lineStarty+=increment_y;
                            }

                        }

                        /*如果直线竖直的*/
                        if(lineStarty==lineEndy)
                        {
                            lineStartx-=5;
                            lineEndx+=5;
                        }

                        /*如果直线是水平的*/
                        if(lineStartx==lineEndx)
                        {
                            lineStarty-=5; 
                            lineEndy+=5;
                        }
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }
                }
                /*缩小直线*/
                if(key==PAGEDOWN)
                {
                    if(lineStartx>=10 && lineStarty>=40 && lineEndx <=620 && lineEndy <=445)
                    {
                        setwritemode(XOR_PUT);
                        line(lineStartx,lineStarty,lineEndx,lineEndy);

                        /*如果直线是倾斜的*/
                        if((lineStarty!=lineEndy)&& (lineStartx!=lineEndx))
                        {
                            /*计算直线的倾角*/
                            angle=atan((fabs(lineEndy-lineStarty))/(fabs(lineEndx-lineStartx)));
                            /*计算水平减少量*/
                            increment_x=cos(angle)*2;
                            /*计算垂直减少量*/
                            increment_y=sin(angle)*2;
                            /*计算缩小后的起始坐标*/
                            if(lineStartx<lineEndx)
                            {
                                lineStartx+=increment_x;
                                lineStarty+=increment_y;
                                lineEndx-=increment_x;
                                lineEndy-=increment_y;
                            }
                            if(lineStartx>lineEndx)
                            {
                                lineEndx+=increment_x;
                                lineEndy+=increment_y;
                                lineStartx-=increment_x;
                                lineStarty-=increment_y;
                            }
                        }

                        /*如果直线竖直的*/
                        if(lineStarty==lineEndy)
                        {
                            lineStartx+=5;
                            lineEndx-=5;
                        }

                        /*如果直线是水平的*/
                        if(lineStartx==lineEndx)
                        {
                            lineStarty+=5;
                            lineEndy-=5;
                        }
                        line(lineStartx,lineStarty,lineEndx,lineEndy);
                    }
                }
            }
            DrawMouse(x1,y1);
        }
    }
    DrawMouse(last_x,last_y);
}


/*绘制矩形函数*/
void DrawRectangle()
{
   int x0,y0,x1,y1;
   int last_x=0,last_y=0;
   int endFlag=0;
   int key;

   DrawMouse(last_x,last_y);
   while(1)
   {    
        /*单击右键,结束绘制矩形*/
        while((mouseStatus(&x1,&y1)==RIGHT_PRESSED))
            endFlag=1;
        if(endFlag==1)
            break;

        /*移动鼠标,仅仅绘制鼠标即可*/
        while(mouseStatus(&x1,&y1) == NO_PRESSED)
        {
            if(last_x!=x1||last_y!=y1)
            {
                DrawMouse(last_x,last_y);
                DrawMouse(x1,y1);
                last_x=x1;
                last_y=y1;
            }
        }

        /*单击左键开始绘制矩形*/
        if(mouseStatus(&x0,&y0)==LEFT_PRESSED)
        {
            DrawMouse(last_x,last_y);
            rectangle(x0,y0,x1,y1);
            last_x=x1;
            last_y=y1;

            /*按着鼠标左键不动,绘制矩形*/
            while(mouseStatus(&x1,&y1)==LEFT_PRESSED)
            {
                if(last_x!=x1||last_y!=y1)
                {
                    rectangle(x0,y0,last_x,last_y);
                    rectangle(x0,y0,x1,y1);
                    last_x=x1;
                    last_y=y1;
                }
            }

            /*绘制结束后,记录左上角和右下角的坐标*/
            TOPx=x0;
            TOPy=y0;
            BOTTOMx=x1;
            BOTTOMy=y1;

            while(1)
            {
                key=bioskey(0);
                if(key==ESC)
                    break;

                /*放大矩形*/
                if(key==PAGEUP)
                {
                    if(TOPx>=10 && TOPy>=40 && BOTTOMx <=620 &&BOTTOMy <=445)
                    {
                        /*清除原有的直线*/
                        setwritemode(XOR_PUT);
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                        /*左上角坐标减小*/
                        TOPx-=5;
                        TOPy-=5;
                        /*右下角坐标增加*/
                        BOTTOMx+=5;
                        BOTTOMy+=5;
                        /*绘制放大后的矩形*/
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                    }
                }

              /*缩小矩形*/
                if(key==PAGEDOWN)
                {
                    if(TOPx>=10 && TOPy>=40 && BOTTOMx <=620 &&BOTTOMy <=445)
                    {
                        setwritemode(XOR_PUT);
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                        /*左上角坐标增加*/
                        TOPx+=5;
                        TOPy+=5;
                        /*右下角坐标减小*/
                        BOTTOMx-=5;
                        BOTTOMy-=5;
                        /*绘制缩小后的矩形*/
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                    }
                }

                /*左移矩形*/
                if(key==LEFT)
                {
                    if(TOPx>=10 && TOPy>=40 && BOTTOMx <=620 &&BOTTOMy <=445)
                    {
                        setwritemode(XOR_PUT);
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                        /*横坐标减小*/
                        TOPx-=5;
                        BOTTOMx-=5;
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                    }
                }

                /*右移矩形*/
                if(key==RIGHT)
                {
                    if(TOPx>=10 && TOPy>=40 && BOTTOMx <=620 &&BOTTOMy <=445)
                    {
                        setwritemode(XOR_PUT);
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                        /*横坐标增加*/
                        TOPx+=5;
                        BOTTOMx+=5;
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                     }
                }

                /*下移矩形*/
               if(key==DOWN)
               {
                   if(TOPx>=10 && TOPy>=40 && BOTTOMx <=620 &&BOTTOMy <=445)
                   {
                        setwritemode(XOR_PUT);
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                        /*纵坐标增加*/
                        TOPy+=5;
                        BOTTOMy+=5;
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                   }
                }

                /*上移矩形*/
                if(key==UP)
                {
                     if(TOPx>=10 && TOPy>=40 && BOTTOMx <=620 &&BOTTOMy <=445)
                     {
                        setwritemode(XOR_PUT);
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                        /*纵坐标减小*/
                        TOPy-=5;
                        BOTTOMy-=5;
                        rectangle(TOPx,TOPy,BOTTOMx,BOTTOMy);
                     }
                }
            }
            DrawMouse(x1,y1);
        }
   }
   DrawMouse(last_x,last_y);
}

/*用直线法生成圆*/
void LineToCircle(int x0,int y0,int r)
{
   int angle;
   int x1,y1,x2,y2;

   angle=0;
   x1=r*cos(angle*pi/180);
   y1=r*sin(angle*pi/180);

   while(angle<45)
   {
      angle+=5;
      x2=r*cos(angle*pi/180);
      y2=r*sin(angle*pi/180);
      while(x2==x1)
        x2++;
      while(y2==y1)
        y2++;
      line(x0+x1,y0+y1,x0+x2,y0+y2);
      line(x0-x1,y0+y1,x0-x2,y0+y2);
      line(x0+x1,y0-y1,x0+x2,y0-y2);
      line(x0-x1,y0-y1,x0-x2,y0-y2);
      line(x0+y1,y0-x1,x0+y2,y0-x2);
      line(x0+y1,y0+x1,x0+y2,y0+x2);
      line(x0-y1,y0-x1,x0-y2,y0-x2);
      line(x0-y1,y0+x1,x0-y2,y0+x2);
      x1=x2+1;
      y1=y2+1;
    }
}

/*绘制圆函数*/
void DrawCircle()
{
   int x0,y0,x1,y1,r,oldr;
   int last_x,last_y;
   int endFlag;
   int key;

   last_x=0;
   last_y=0;
   endFlag=0;

   DrawMouse(last_x,last_y);
   while(1)
   {
        /*单击右键,绘制圆结束*/
        while((mouseStatus(&x1,& y1)==RIGHT_PRESSED))
        {
            endFlag=1;
        }
        if(endFlag==1)
            break;

        /*移动鼠标,仅绘制鼠标即可*/
        while(mouseStatus(&x1,&y1) == NO_PRESSED)
        {
            if(last_x!=x1||last_y!=y1)
            {
                DrawMouse(last_x,last_y);
                DrawMouse(x1,y1);
                last_x=x1;
                last_y=y1;
            }
        }

        /*单击左键,开始绘制圆*/
        if(mouseStatus(&x0,&y0)==LEFT_PRESSED)
        {
            /*计算半径*/
            r=sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
            DrawMouse(last_x,last_y);
            LineToCircle(x0,y0,r);
            last_x=x1;
            last_y=y1;
            oldr=r;

            /*按住鼠标左键不动,拖动鼠标绘制圆*/
            while(mouseStatus(&x1,&y1)==LEFT_PRESSED)
            { 
                if(last_x!=x1||last_y!=y1)
                {
                    r=sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
                    LineToCircle(x0,y0,oldr);
                    LineToCircle(x0,y0,r);
                    last_x=x1;
                    last_y=y1;
                    oldr=r;
                }          
            }
            /*绘制结束后,记录圆的圆心和半径*/
            Rx=x0;
            Ry=y0;
            R=r;

         while(1)
        {
            key=bioskey(0);
            if(key==ESC)
               break;
            /*放大圆*/
            if(key==PAGEUP)
                {
                    if(Rx-R>10 && Ry-R>40 && Rx+R<620 && Ry+R<445)
                    {
                        /*如果半径和初始状态一样大,则保留原来的圆*/
                        if(R==r)
                        {
                            setcolor(WHITE);
                            R+=10;
                            circle(Rx,Ry,R);
                        }
                        else
                        {
                            setcolor(BLACK);
                            /*用背景色画圆,覆盖原有的*/
                            circle(Rx,Ry,R);
                            /*增加半径*/
                            R+=10;
                            setcolor(WHITE);
                            /*绘制新圆*/
                            circle(Rx,Ry,R);
                        }
                     }
                }
            /*缩小圆*/
             if(key==PAGEDOWN)
                {
                    if(Rx-R>10 && Ry-R>40 && Rx+R<620 && Ry+R<445)
                    {
                        /*如果半径和初始状态一样大,则保留原来的圆*/
                        if(R==r)
                        {
                            setcolor(WHITE);
                            R-=10;
                            circle(Rx,Ry,R);

                        }
                        else
                        {
                            setcolor(BLACK);
                            /*用背景色画圆,覆盖原有的*/
                            circle(Rx,Ry,R);
                            setcolor(WHITE);
                            /*减小半径*/
                            R-=10;
                            circle(Rx,Ry,R);
                        }

                     }
                }

            }
            DrawMouse(x1,y1);
        }
   }
   DrawMouse(last_x,last_y);
}       

/*求阶乘函数*/
long factorial(int n)
{ 
    long s=1;
    if(n==0)
        return 1;

    while(n>0)
    {
        s*=n;
        n--;
    }
    return s;
}

/*伯恩斯坦基函数*/
float berFunction(int i,int n,double t)
{
    if(i==0&&t==0||t==1&&i==n)
        return  1;
    else if(t==0||t==1)
        return 0;
    return  factorial(n)/(factorial(i)*factorial(n-i))*pow(t,i)*pow(1-t,n-i);

}

/*绘制Bezier曲线函数*/
void DrawBezier()
{
    int x,y,x0,y0,x1,y1;
    float j,t,dt;
    int i,n;
    int endFlag=0;
    int last_x=0,last_y=0;
    n=0;

    DrawMouse(last_x,last_y);
    while(mouseStatus(&x1,&y1)==LEFT_PRESSED);
    while(1)
    {
            while((mouseStatus(&x1,&y1)==RIGHT_PRESSED))
                endFlag=1;
            if(endFlag==1)
                break;
            /*如果有两个以上的点,则将其连接,即画直线*/ 
            if(n>1)
               line(linePoint_x[n-1],linePoint_y[n-1],linePoint_x[n-2],linePoint_y[n-2]);

            /*移动鼠标*/
            while(mouseStatus(&x1,&y1) == NO_PRESSED)
            {
                if(last_x!=x1||last_y!=y1)
                {
                    DrawMouse(last_x,last_y);
                    DrawMouse(x1,y1);
                    last_x=x1;
                    last_y=y1;
                }
            }

            /*单击左键时,绘制点*/
            while(mouseStatus(&x0,&y0)==LEFT_PRESSED);
            putpixel(x0,y0,14);
            /*记录每次鼠标左键单击的点坐标*/
            linePoint_x[n]=x0;
            linePoint_y[n]=y0;
            n++;
      }
      DrawMouse(x1,y1);

      dt=1.0/10;
      setwritemode(0);
      for(j=0;j<=10;j+=0.5)
      {
        t=j*dt;
        x=0;
        y=0;
        i=0;
        while(i<n-1)
        {
            x+=berFunction(i,n-2,t)*linePoint_x[i];
            y+=berFunction(i,n-2,t)*linePoint_y[i];
            i++;
        }
        if(j==0)
           moveto(x,y);

        lineto(x,y);

      }
      setwritemode(1);
}

void main()
{
    int gdriver,gmode;
    int x0,y0,x1,y1;
    int last_x,last_y;
    int i;

    x0=250;
    y0=250;
    gdriver=DETECT;
    while( 1)
    {
        initgraph(&gdriver,&gmode,"");
        setbkcolor(0);
        setcolor(14);
        /*绘制画布*/
        rectangle(5,30,630,445);
        setfillstyle(1,2);
        /*填充画布以外的颜色,画布仍呈背景色*/
        floodfill(10,10,14);

        /*绘制按钮框*/
        for(i=0;i<=7;i++)
        {
            setcolor(RED);
            line(60*i+1,2,60*i+1,25);
            line(60*i+1,2,60*i+55,2);
            setcolor(RED);
            line(60*i+1,25,60*i+55,25);
            line(60*i+55,2,60*i+55,25);
        }

        setcolor(RED);
        line(0,446,639,446);
        line(0,478,639,478);

        setcolor(8);
        /*绘制退出按钮框*/
        rectangle(570,2,625,25);
        setfillstyle(1,RED);
        floodfill(620,5,8);
        setcolor(WHITE);
        outtextxy(585,10,"EXIT");

        /*显示“直线”*/
        outChinese(zhi16K, 16, 10,6, WHITE);
        outChinese(xian16K, 16, 28,6, WHITE);

        /*显示“矩形”*/
        outChinese(ju16K, 16, 70,6, WHITE);
        outChinese(xing16K, 16, 88,6, WHITE);

        /*显示“圆形”*/
        outChinese(yuan16K, 16, 130,6, WHITE);
        outChinese(xing16K, 16, 148,6, WHITE);

        outtextxy(185,10,"Bezier");

        /*显示“清屏”*/
        outChinese(qing16K, 16, 250,6, WHITE);
        outChinese(ping16K, 16, 268,6, WHITE);

        /*显示“保存”*/
        outChinese(bao16K, 16, 310,6, WHITE);
        outChinese(cun16K, 16, 328,6, WHITE);

        /*显示“加载”*/
        outChinese(jia16K, 16, 370,6, WHITE);
        outChinese(zai16K, 16, 388,6, WHITE);

        /*显示“帮助”*/
        outChinese(bang16K, 16, 430,6, WHITE);
        outChinese(zhu16K, 16, 448,6, WHITE);

        setMousePos(x0,y0);
        setwritemode(1);
        DrawMouse(x0,y0);

        last_x=x0;
        last_y=y0;
        while(!((mouseStatus(&x1,&y1)==NO_PRESSED) && x1>240 &&x1<295&&y1>1&&y1<25))
        {
            /*单击退出按钮*/
            if((mouseStatus(&x1,&y1)==NO_PRESSED) && x1>570 &&x1<625&&y1>1&&y1<25)
                exit(0);
            /*鼠标移动*/
            while(mouseStatus(&x1,&y1) == NO_PRESSED||y1>25)
            {
                if(last_x!=x1 && last_y!=y1)
                {
                    DrawMouse(last_x,last_y);
                    DrawMouse(x1,y1);
                    last_x=x1;
                    last_y=y1;
                }
            }

            DrawMouse(last_x,last_y);
            /*在按钮框中单击左键后*/
            while(mouseStatus(&x1,&y1)==LEFT_PRESSED);
            /*绘制直线*/
            if(x1>0 && x1<60 && y1>1 && y1<25)
            {
                setwritemode(0);
                setcolor(8);
                /*呈凹陷状态*/
                line(1,2,1,25);
                line(1,2,55,2);
                setcolor(15);
                line(1,25,55,25);
                line(55,2,55,25);
                setwritemode(1);

                DrawLine();

                setwritemode(0);
                setcolor(RED);
                /*还原成初始状态*/
                rectangle(1,2,55,25);
                setcolor(15);
                setwritemode(1);

                DrawMouse(last_x,last_y);
            }

            /*绘制矩形*/
            if(x1>60 && x1<115 && y1>1 && y1<25)
            {
                setwritemode(0);
                setcolor(8);
                line(61,2,61,25);
                line(61,2,115,2);
                setcolor(15);
                line(61,25,115,25);
                line(115,2,115,25);
                setwritemode(1);

                DrawRectangle();

                setwritemode(0);
                setcolor(RED);
                rectangle(61,2,115,25);
                setcolor(15);
                setwritemode(1);

                DrawMouse(last_x,last_y);
            }

            /*绘制圆形*/
            if(x1>120 && x1<175 && y1>1 && y1<25)
            {
                setwritemode(0);
                setcolor(8);
                line(121,2,121,25);
                line(121,2,175,2);
                setcolor(15);
                line(121,25,175,25);
                line(175,2,175,25);
                setwritemode(1);

                DrawCircle();

                setwritemode(0);
                setcolor(RED);
                rectangle(121,2,175,25);
                setcolor(15);
                setwritemode(1);

                DrawMouse(last_x,last_y);
            }

            /*绘制Bezier曲线*/
            if(x1>180 && x1<235 && y1>1 && y1<25)
            {
                setwritemode(0);
                setcolor(8);
                line(181,2,181,25);
                line(181,2,235,2);
                setcolor(15);
                line(181,25,235,25);
                line(235,2,235,25);
                setwritemode(1);

                DrawBezier();

                setwritemode(0);
                setcolor(RED);
                rectangle(181,2,235,25);
                setcolor(15);
                setwritemode(1);
                DrawMouse(last_x,last_y);
            }

            /*保存文件*/
            if(x1>300 && x1<355 && y1>1 && y1<25)
            {
                setwritemode(0);
                setcolor(8);
                line(301,2,301,25);
                line(301,2,355,2);
                setcolor(15);
                line(301,25,355,25);
                line(355,2,355,25);
                setwritemode(1);

                save();

                setwritemode(0);
                setcolor(RED);
                rectangle(301,2,355,25);
                setcolor(15);
                setwritemode(1);
                DrawMouse(last_x,last_y);
            }

            /*加载已有的文件*/
           if(x1>360 && x1<415 && y1>1 && y1<25)
           {
                setwritemode(0);
                setcolor(8);
                line(361,2,361,25);
                line(361,2,415,2);
                setcolor(15);
                line(361,25,415,25);
                line(415,2,415,25);
                setwritemode(1);

                load();

                setwritemode(0);
                setcolor(RED);
                rectangle(361,2,415,25);
                setcolor(15);
                setwritemode(1);
                DrawMouse(last_x,last_y);
            }

            /*显示用户帮助*/
            if(x1>420 && x1<475 && y1>1 && y1<25)
            {
                setwritemode(0);
                setcolor(8);
                line(421,2,421,25);
                line(421,2,475,2);
                setcolor(15);
                line(421,25,475,25);
                line(475,2,475,25);
                setwritemode(1);

                showHelp();

                setwritemode(0);
                setcolor(RED);
                rectangle(421,2,475,25);
                setcolor(15);
                setwritemode(1);
                DrawMouse(last_x,last_y);
            }

        }
        closegraph();
    }
}

2.基于MFC的C++版

CMainFrame.h

// MainFrm.h : CMainFrame 类的接口
//

#pragma once
#include<stack>
using namespace std;
class CMainFrame : public CFrameWnd
{
	
protected: // 仅从序列化创建
	CMainFrame();
	DECLARE_DYNCREATE(CMainFrame)

// 特性
public:
	int w_x;
	int w_y;
	stack<CBitmap *> sk;
// 操作
public:

// 重写
public:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// 实现
public:
	virtual ~CMainFrame();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // 控件条嵌入成员
	CToolBar          m_wndToolBar;
	/*CStatusBar        m_wndStatusBar;*/

// 生成的消息映射函数
protected:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void Quit();
	DECLARE_MESSAGE_MAP()

};

CMainFrame.cpp

// MainFrm.cpp : CMainFrame 类的实现
//

#include "stdafx.h"
#include "截屏.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
const int  iMaxUserToolbars = 10;
const UINT uiFirstUserToolBarId = AFX_IDW_CONTROLBAR_FIRST + 40;
const UINT uiLastUserToolBarId = uiFirstUserToolBarId + iMaxUserToolbars - 1;

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_COMMAND(ID_CONTEXT_HELP,&CMainFrame::Quit)
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // 状态行指示器
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};
void CMainFrame::Quit()
{
	this->PostMessage(WM_CLOSE);
}
// CMainFrame 构造/析构
CMainFrame::CMainFrame()
{
	// TODO: 在此添加成员初始化代码
	w_x=::GetSystemMetrics(SM_CXSCREEN);
	w_y=::GetSystemMetrics(SM_CXSCREEN);
	CWindowDC dc(GetDesktopWindow());
	CDC cdc;
	cdc.CreateCompatibleDC(&dc);
	//位图
	CBitmap *bitmap= new CBitmap ;
	bitmap->CreateCompatibleBitmap(&dc,w_x,w_y);
	sk.push(bitmap);
	cdc.SelectObject(bitmap);
	cdc.BitBlt(0,0,w_x,w_y,&dc,0,0,SRCCOPY);
	
}

CMainFrame::~CMainFrame()
{
	while(sk.empty()==false)
	{
		delete sk.top();
		sk.pop();
	}
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_BOTTOM| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_TOOLBAR1))
	{
		TRACE0("未能创建工具栏\n");
		return -1;      // 未能创建
	}

	//if (!m_wndStatusBar.Create(this))
	//{
	//	TRACE0("未能创建状态栏\n");
	//	return -1;      // 未能创建
	//}
	/*m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));*/

	// TODO: 如果不需要可停靠工具栏,则删除这三行
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);
	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式
	cs.style=WS_POPUP;
	return TRUE;
}

// CMainFrame 诊断

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}
#endif //_DEBUG


// CMainFrame 消息处理程序

mian.h

// 截屏.h : 截屏 应用程序的主头文件
//
#pragma once

#ifndef __AFXWIN_H__
	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif

#include "resource.h"       // 主符号

class C截屏App : public CWinAppEx
{
public:
	C截屏App();

// 重写
public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();
// 实现
	afx_msg void OnAppAbout();
	DECLARE_MESSAGE_MAP()
};
extern C截屏App theApp;

mian.cpp

// 截屏.cpp : 定义应用程序的类行为。
//

#include "stdafx.h"
#include "afxwinappex.h"
#include "afxdialogex.h"
#include "截屏.h"
#include "MainFrm.h"
#include "截屏Doc.h"
#include "截屏View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

BEGIN_MESSAGE_MAP(C截屏App, CWinAppEx)
	ON_COMMAND(ID_APP_ABOUT, &C截屏App::OnAppAbout)
	// 基于文件的标准文档命令
	ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
	// 标准打印设置命令
	ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)
END_MESSAGE_MAP()
// C截屏App 构造
C截屏App::C截屏App()
{
	// 支持重新启动管理器
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
#ifdef _MANAGED
	// 如果应用程序是利用公共语言运行时支持(/clr)构建的,则:
	//     1) 必须有此附加设置,“重新启动管理器”支持才能正常工作。
	//     2) 在您的项目中,您必须按照生成顺序向 System.Windows.Forms 添加引用。
	System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
#endif

	// TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式
	//为 CompanyName.ProductName.SubProduct.VersionInformation
	SetAppID(_T("截屏.AppID.NoVersion"));

	// TODO: 在此处添加构造代码,
	// 将所有重要的初始化放置在 InitInstance 中
}

// 唯一的一个 C截屏App 对象
C截屏App theApp;
// C截屏App 初始化

BOOL C截屏App::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);
	CWinAppEx::InitInstance();

	// 初始化 OLE 库
	if (!AfxOleInit())
	{
		AfxMessageBox(IDP_OLE_INIT_FAILED);
		return FALSE;
	}

	AfxEnableControlContainer();

	EnableTaskbarInteraction(FALSE);

	// 使用 RichEdit 控件需要  AfxInitRichEdit2()	
	// AfxInitRichEdit2();

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小,则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串,
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
	LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)

	// 注册应用程序的文档模板。文档模板
	// 将用作文档、框架窗口和视图之间的连接
	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(C截屏Doc),
		RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
		RUNTIME_CLASS(C截屏View));
	if (!pDocTemplate)
		return FALSE;
	AddDocTemplate(pDocTemplate);

	// 分析标准 shell 命令、DDE、打开文件操作的命令行
	CCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	// 调度在命令行中指定的命令。如果
	// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	// 唯一的一个窗口已初始化,因此显示它并对其进行更新
	m_pMainWnd->ShowWindow(SW_MAXIMIZE);
	m_pMainWnd->UpdateWindow();
	return TRUE;
}

int C截屏App::ExitInstance()
{
	//TODO: 处理可能已添加的附加资源
	AfxOleTerm(FALSE);

	return CWinAppEx::ExitInstance();
}

// C截屏App 消息处理程序


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

// 用于运行对话框的应用程序命令
void C截屏App::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

// C截屏App 消息处理程序


C截屏View.h

// 截屏View.h : C截屏View 类的接口
//

#pragma once


class C截屏View : public CView
{
protected: // 仅从序列化创建
	C截屏View();
	DECLARE_DYNCREATE(C截屏View)
// 特性
public:
	C截屏Doc* GetDocument() const;
	CPoint m_point;
	COLORREF  color;
	BOOL flag;
	int n_drawStyle;
// 操作
public:

// 重写
public:
	virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
	virtual ~C截屏View();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void Tool(UINT uid);
	afx_msg void Color();
	afx_msg void FIll();
};

#ifndef _DEBUG  // 截屏View.cpp 中的调试版本
inline C截屏Doc* C截屏View::GetDocument() const
   { return reinterpret_cast<C截屏Doc*>(m_pDocument); }
#endif

C截屏View.cpp

// 截屏View.cpp : C截屏View 类的实现
//

#include "stdafx.h"
#include"MainFrm.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "截屏.h"
#endif

#include "截屏Doc.h"
#include "截屏View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

enum{m_Line ,m_Rectangle ,m_Round ,m_Triangle,delta,Fill};
// C截屏View
IMPLEMENT_DYNCREATE(C截屏View, CView)

BEGIN_MESSAGE_MAP(C截屏View, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONUP()
	ON_COMMAND_RANGE(ID_Line,ID_Triangle,&C截屏View::Tool)
	ON_COMMAND(ID_COLOR,&C截屏View::Color)
	ON_COMMAND(ID_Fill,&C截屏View::FIll)
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

// C截屏View 构造/析构
void C截屏View::FIll()
{
	n_drawStyle=Fill;
}
void C截屏View::Color()
{
	CColorDialog dialog;
	if(dialog.DoModal()==IDOK)
	{
		color=dialog.GetColor();
	}
}
C截屏View::C截屏View()
{
	// TODO: 在此处添加构造代码
	n_drawStyle=m_Line;
	flag=false;
	color=RGB(0,0,255);
}

C截屏View::~C截屏View()
{
}

BOOL C截屏View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式
	
	return CView::PreCreateWindow(cs);
}

// C截屏View 绘制

void C截屏View::OnDraw(CDC* /*pDC*/)
{
	C截屏Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CMainFrame * frm=(CMainFrame *)AfxGetMainWnd();
	CClientDC dc(this);
	CDC cdc;
	cdc.CreateCompatibleDC(&dc);
	cdc.SelectObject(frm->sk.top());
	dc.BitBlt(0,0,frm->w_x,frm->w_y,&cdc,0,0,SRCCOPY);

}
// C截屏View 打印

BOOL C截屏View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void C截屏View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void C截屏View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// C截屏View 诊断

#ifdef _DEBUG
void C截屏View::AssertValid() const
{
	CView::AssertValid();
}

void C截屏View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

C截屏Doc* C截屏View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(C截屏Doc)));
	return (C截屏Doc*)m_pDocument;
}
#endif //_DEBUG


// C截屏View 消息处理程序


void C截屏View::OnLButtonDown(UINT nFlags, CPoint point)
{	
	if(n_drawStyle==Fill)
	{
		CClientDC  dc(this);
		CBrush brush(color);
		dc.SelectObject(brush);
		dc.ExtFloodFill(point.x,point.y,dc.GetPixel(point),FLOODFILLSURFACE);

	}
	m_point =point;
	flag=true;
	CView::OnLButtonDown(nFlags, point);
	//::MessageBox(AfxGetMainWnd()->m_hWnd,L"王祥儿子",L"凇杉爸爸",MB_OK);

}


void C截屏View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	
	if(nChar==VK_ESCAPE  )
	{
		CMainFrame * frm=(CMainFrame *)AfxGetMainWnd();
		frm->PostMessage(WM_CLOSE);
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}




void C截屏View::OnLButtonUp(UINT nFlags, CPoint point)
{

	flag=false;
	CMainFrame * frm=(CMainFrame *)AfxGetMainWnd();
	CClientDC dc(this);
	CDC cdc;
	cdc.CreateCompatibleDC(&dc);
	CBitmap *bitmap=new CBitmap ;
	bitmap->CreateCompatibleBitmap(&dc,frm->w_x,frm->w_y);
	cdc.SelectObject(bitmap);
	cdc.BitBlt(0,0,frm->w_x,frm->w_y,&dc,0,0,SRCCOPY);
	frm->sk.push (bitmap);
	CView::OnLButtonUp(nFlags, point);
}


void C截屏View::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CClientDC  dc(this);
	if(flag)
	{
		if(n_drawStyle==m_Line)
		{
			dc.MoveTo(m_point);
			dc.LineTo(point);
			m_point=point;
			return ;
		}else
		{
		    //闪屏,创造兼容性DC
			CDC tempDC;
			tempDC.CreateCompatibleDC(&dc);
			CBitmap *bitmap=new CBitmap ;
			CMainFrame * frm=(CMainFrame *)AfxGetMainWnd();
			bitmap->CreateCompatibleBitmap(&dc,frm->w_x,frm->w_y);
			tempDC.SelectObject(bitmap);

			//----------消除轨迹-----------
			CDC cdc;
			cdc.CreateCompatibleDC(&dc);
			cdc.SelectObject(frm->sk.top());
			tempDC.BitBlt(0,0,frm->w_x,frm->w_y,&cdc,0,0,SRCCOPY);
			switch(n_drawStyle)
			{
				case m_Line:
					{
					CPen pen;
					pen.CreatePen(PS_SOLID,1,color);
					tempDC.SelectObject(pen);
					tempDC.MoveTo(m_point);
					tempDC.LineTo(point);
					}
					break;
				case m_Rectangle:
					{
					CBrush brush(HS_BDIAGONAL,color);
					tempDC.SelectObject(brush);
					tempDC.Rectangle(m_point.x,m_point.y,point.x,point.y);
					}
					break;
				case m_Round:
					{
					CBrush brush(color);
					tempDC.SelectObject(brush);
					tempDC.Ellipse(m_point.x,m_point.y,point.x,point.y);
					}
					break;
				
			}
			dc.BitBlt(0,0,frm->w_x,frm->w_y,&tempDC,0,0,SRCCOPY);
		}
	}
	CView::OnMouseMove(nFlags, point);
}
void C截屏View::Tool(UINT uid)
{
	n_drawStyle=uid-ID_Line;

}

C截屏Doc.h

// 截屏Doc.h : C截屏Doc 类的接口
#pragma once

class C截屏Doc : public CDocument
{
protected: // 仅从序列化创建
	C截屏Doc();
	DECLARE_DYNCREATE(C截屏Doc)
// 特性
public:
// 操作
public:
// 重写
public:
	virtual BOOL OnNewDocument();
	virtual void Serialize(CArchive& ar);
#ifdef SHARED_HANDLERS
	virtual void InitializeSearchContent();
	virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds);
#endif // SHARED_HANDLERS

// 实现
public:
	virtual ~C截屏Doc();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	DECLARE_MESSAGE_MAP()

#ifdef SHARED_HANDLERS
	// 用于为搜索处理程序设置搜索内容的 Helper 函数
	void SetSearchContent(const CString& value);
#endif // SHARED_HANDLERS
};

C截屏Doc.cpp

// 截屏Doc.cpp : C截屏Doc 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "截屏.h"
#endif
#include "截屏Doc.h"
#include <propkey.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// C截屏Doc

IMPLEMENT_DYNCREATE(C截屏Doc, CDocument)

BEGIN_MESSAGE_MAP(C截屏Doc, CDocument)
END_MESSAGE_MAP()


// C截屏Doc 构造/析构

C截屏Doc::C截屏Doc()
{
	// TODO: 在此添加一次性构造代码

}

C截屏Doc::~C截屏Doc()
{
}

BOOL C截屏Doc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: 在此添加重新初始化代码
	// (SDI 文档将重用该文档)

	return TRUE;
}




// C截屏Doc 序列化

void C截屏Doc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: 在此添加存储代码
	}
	else
	{
		// TODO: 在此添加加载代码
	}
}

#ifdef SHARED_HANDLERS

// 缩略图的支持
void C截屏Doc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds)
{
	// 修改此代码以绘制文档数据
	dc.FillSolidRect(lprcBounds, RGB(255, 255, 255));

	CString strText = _T("TODO: implement thumbnail drawing here");
	LOGFONT lf;

	CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT));
	pDefaultGUIFont->GetLogFont(&lf);
	lf.lfHeight = 36;

	CFont fontDraw;
	fontDraw.CreateFontIndirect(&lf);

	CFont* pOldFont = dc.SelectObject(&fontDraw);
	dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK);
	dc.SelectObject(pOldFont);
}

// 搜索处理程序的支持
void C截屏Doc::InitializeSearchContent()
{
	CString strSearchContent;
	// 从文档数据设置搜索内容。
	// 内容部分应由“;”分隔

	// 例如:  strSearchContent = _T("point;rectangle;circle;ole object;");
	SetSearchContent(strSearchContent);
}

void C截屏Doc::SetSearchContent(const CString& value)
{
	if (value.IsEmpty())
	{
		RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
	}
	else
	{
		CMFCFilterChunkValueImpl *pChunk = NULL;
		ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
		if (pChunk != NULL)
		{
			pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
			SetChunkValue(pChunk);
		}
	}
}

#endif // SHARED_HANDLERS

// C截屏Doc 诊断

#ifdef _DEBUG
void C截屏Doc::AssertValid() const
{
	CDocument::AssertValid();
}

void C截屏Doc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// C截屏Doc 命令

3.基于QT的C++版的

CenterWidget.h

#ifndef CENTERWIDGET_H
#define CENTERWIDGET_H

#include <QWidget>
#include<QList>
#include<QPoint>
#include<QRect>
#include<QMouseEvent>
#include<QLabel>
#include"shape.h"
#include"line.h"
#include"ellipse.h"
#include"rectangle.h"
class CenterWidget : public QWidget
{
    Q_OBJECT
    ~CenterWidget();
public:
    explicit CenterWidget(QWidget *parent = 0);
    void paintEvent(QPaintEvent *);
    void setDrawType(int type);
    void setcolorType(int color);
    void newDrawing();
    void openDrawing();
    void saveDrawing();
    bool getModifiedFlag(); //获取文档修改状态?????
signals:

public slots:
protected:
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *e);
private:
    QList<Shape*> shapes;
    //QList<QLine> lines;             //存贮线条的集合
    //QList<QRect> ellipses;          //存储椭圆的集合
    //QList<QRect> rects;              //存储矩形的集合
    QPoint p1,p2;                   //绘图过程的临时起点和终点
    int drawType;                   //当前绘图类型,0-直线,1-椭圆,2-矩形
    int colorType;
    bool beginDraw;
    QLabel* mousePosLabel;          ///
    bool isModified; //标识文档是否发生了修改
    QString fileName; //文件名,新建后为空
    void saveFile(QString fileName); //写文件的操作
    void openFile(QString fileName); //读文件的操作
};

#endif // CENTERWIDGET_H

CenterWidget.cpp

#include "centerwidget.h"
#include<QPainter>
#include<QStatusBar>
#include "mainwindow.h"
#include<QFileDialog>
#include<QTextStream>
CenterWidget::CenterWidget(QWidget *parent) :
    QWidget(parent){
    //lines.clear();
    //ellipses.clear();
    //rects.clear();
    shapes.clear();                    //
    beginDraw=false;
    colorType=0;

    isModified=false;
    fileName=tr("");
    mousePosLabel=new QLabel;
    mousePosLabel->setText("");
    mousePosLabel->setFixedWidth(150);
    MainWindow *p=(MainWindow *)parent;
    p->statusBar()->addPermanentWidget(mousePosLabel);

    setMinimumSize(500,400);
    setMouseTracking(true);
}
void CenterWidget::paintEvent(QPaintEvent *){
    QPainter p(this);
    /*for(auto const& line:lines)
        p.drawLine(line);
    for(auto const& ellipse:ellipses)
        p.drawEllipse(ellipse);
    for(auto const& rect:rects)
       p.drawRect(rect);
    if(beginDraw==true){
        switch(drawType){
        case 0: p.drawLine(p1,p2); break;
        case 1: p.drawEllipse(QRect(p1,p2)); break;
        case 2: p.drawRect(QRect(p1,p2)); break;
        }
    }*/
    QColor c;
    for(auto shape:shapes){
        switch(colorType){
        case 0:shape->setColor(Qt::black);c=Qt::black;break;
        case 1:shape->setColor(Qt::green);c=Qt::green;break;
        case 2:shape->setColor(Qt::red);c=Qt::red;break;
        }
        shape->draw(&p);                //在此处内部写入,修改颜色
    }

    Shape *temp=nullptr;
    switch(drawType){
    case 0: temp=new Line(p1,p2,c); break;
    case 1: temp=new Ellipse(p1,p2,c); break;
    case 2: temp=new Rectangle(p1,p2,c); break;
    }
    temp->draw(&p);
    delete temp;
}
void CenterWidget::setDrawType(int type){
    drawType=type;
}
void CenterWidget::setcolorType(int color){
    colorType=color;
}
void CenterWidget::mousePressEvent(QMouseEvent *e){
    p1=e->pos();                //鼠标按下得到第一个点
    p2=p1;
    beginDraw=true;
}
void CenterWidget::mouseReleaseEvent(QMouseEvent *e){
    p2=e->pos();                  //鼠标松开得到第二个点
    beginDraw=false;
    if(p1==p2)
        return;
    //switch (drawType) {
    //case 0:lines.append(QLine(p1,p2));break;
    //case 1:ellipses.append(QRect(p1,p2));break;
    //case 2:rects.append(QRect(p1,p2));break;}
    Shape *shape=nullptr;
    switch(drawType){
    case 0: shape=new Line(p1,p2); break;
    case 1: shape=new Ellipse(p1,p2); break;
    case 2: shape=new Rectangle(p1,p2); break;
    }
    shapes.append(shape);
    isModified=true;
    update();
}
void CenterWidget::mouseMoveEvent(QMouseEvent *e){
    mousePosLabel->setText("X:"+QString::number(e->x())+",Y:" +QString::number(e->y()));
    if(beginDraw==false)
        return;
    p2=e->pos();
    update();
}
bool CenterWidget::getModifiedFlag(){
    return isModified;
}
void CenterWidget::newDrawing(){                //新建绘图
   // lines.clear();
    //ellipses.clear();
    //rects.clear(); //清空图形内容
    for(auto shape:shapes)
        delete shape;
    shapes.clear();
    beginDraw=false;
    isModified=false;
    fileName=tr("");
    parentWidget()->setWindowTitle(tr("简单绘图程序 未命名"));
    update(); //更新窗口显示
}
void CenterWidget::openDrawing(){ //打开绘图
    fileName=QFileDialog::getOpenFileName(this, tr("打开文件对话框"),"/","绘图文件(*.draw);;所有文件(*.*)");
    if(fileName==tr(""))
        return;
    //lines.clear();
    //ellipses.clear();
    //rects.clear();
    for(auto shape:shapes)
        delete shape;
    shapes.clear();
    beginDraw=false;
    isModified=false;
    openFile(fileName); //存储文件
    parentWidget()->setWindowTitle(tr("简单绘图程序 ")+fileName);
    update();
}
void CenterWidget::saveDrawing(){
    if(fileName==tr("")){
        fileName=QFileDialog::getSaveFileName(this,tr("保存文件对话框"),"/","绘图文件(*draw);;所有文件(*.*)");
        if(fileName==tr(""))
            return ;
    }
    saveFile(fileName);
    parentWidget()->setWindowTitle(tr("绘图程序 ")+fileName);
    isModified=false;
}
void CenterWidget::saveFile(QString fileName){ //写文件操作
    QFile file(fileName);
    if(file.open(QFile::WriteOnly|QFile::Truncate)){
        QTextStream out(&file);
        /*out<<lines.length()<<endl;
        for(QLine line:lines)
            out<<line.p1().x()<<" "<<line.p1().y()<<" " <<line.p2().x()<<" "<<line.p2().y()<<endl;
        out<<ellipses.length()<<endl;
        for(QRect rect:ellipses)
            out<<rect.topLeft().x()<<" "<<rect.topLeft().y()<<" " <<rect.bottomRight().x() <<" "<<rect.bottomRight().y()<<endl;
        out<<rects.length()<<endl;
        for(QRect rect:rects)
            out<<rect.topLeft().x()<<" "<<rect.topLeft().y()<<" " <<rect.bottomRight().x() <<" "<<rect.bottomRight().y()<<endl;*/
        out<<shapes.length()<<endl;
        for(auto shape:shapes)
            shape->save(out);
        file.close();
    }
}
void CenterWidget::openFile(QString fileName){ //读文件操作
    QFile file(fileName);
    if(file.open(QFile::ReadOnly)){ //只读方式打开
        QTextStream in(&file);
        /*int lineNums;
        in>>lineNums;
        int x1,y1,x2,y2;
        for(int i=0;i<lineNums;++i){
            in>>x1>>y1>>x2>>y2; lines.append(QLine(x1,y1,x2,y2));
        }
        int ellipseNums;
        in>>ellipseNums;
        for(int i=0;i<ellipseNums;++i){
            in>>x1>>y1>>x2>>y2;
            ellipses.append(QRect(QPoint(x1,y1),QPoint(x2,y2)));
            }
        int rectNums;
        in>>rectNums;
        for(int i=0;i<rectNums;++i){
            in>>x1>>y1>>x2>>y2;
            rects.append(QRect(QPoint(x1,y1),QPoint(x2,y2)));
        }*/
        int nums;
        in>>nums;
        int type;
        Shape *curShape;
        for(int i=0;i<nums;++i){
            in>>type;
            switch(type){
            case 0: curShape=Line::read(in); break;
            case 1: curShape=Ellipse::read(in); break;
            case 2: curShape=Rectangle::read(in); break;
            }
            shapes.append(curShape);
        }
        file.close();
    }
}
CenterWidget::~CenterWidget(){
    for(auto shape:shapes)
        delete shape;
}

Shape.h

#ifndef SHAPE_H
#define SHAPE_H
#include<QColor>
#include<QPainter>
#include<QTextStream>
class Shape{
public:
    Shape(QColor c);
    QColor getColor()const;
    void setColor(QColor c);
    virtual void draw(QPainter *p)=0;
    virtual void save(QTextStream& s)=0;
protected:
    QColor color;
};

#endif // SHAPE_H

Shape.cpp

#include "shape.h"

Shape::Shape(QColor c):color(c){

}
void Shape::setColor(QColor c){
    color=c;
}
QColor Shape::getColor()const{
    return color;
}

Ellipse.h

#ifndef ELLIPSE_H
#define ELLIPSE_H
#include"shape.h"
class Ellipse : public Shape{
public:
    Ellipse(QPoint p1,QPoint p2,QColor c=Qt::black);
    QPoint topLeft()const;
    QPoint bottomRight()const;
    virtual void draw(QPainter *p);
    virtual void save(QTextStream& out);
    static Shape* read(QTextStream& in);
private:
    QPoint point1;
    QPoint point2;
};

#endif // ELLIPSE_H

Ellipse.cpp

#include "ellipse.h"

Ellipse::Ellipse(QPoint p1,QPoint p2,QColor c): point1(p1),point2(p2),Shape(c){
}
QPoint Ellipse::topLeft()const{
    return point1;
}
QPoint Ellipse::bottomRight()const{
    return point2;
}
void Ellipse::draw(QPainter *p){
    QPen pen(color,1,Qt::SolidLine);
    p->setPen(pen);
    p->drawEllipse(QRect(point1,point2));
}
void Ellipse::save(QTextStream &out){
    out<<"1 "<<topLeft().x()<<" "<<topLeft().y()<<" " <<bottomRight().x()<<" "<<bottomRight().y()<<endl;
}
Shape* Ellipse::read(QTextStream &in){
    int x1,y1,x2,y2;
    in>>x1>>y1>>x2>>y2;
    return new Ellipse(QPoint(x1,y1),QPoint(x2,y2));
}

Line.h

#ifndef LINE_H
#define LINE_H
#include<QPoint>
#include"shape.h"
class Line:public Shape{
public:
    Line(QPoint p1,QPoint p2,QColor c=Qt::black);
    QPoint p1()const;
    QPoint p2()const;
    virtual void draw(QPainter *p);
    virtual void save(QTextStream& out);
    static Shape* read(QTextStream& in);
private:
    QPoint point1;
    QPoint point2;
};
#endif // LINE_H

Line.cpp

#include "line.h"

Line::Line(QPoint p1,QPoint p2,QColor c): point1(p1),point2(p2),Shape(c){
}
QPoint Line::p1()const{
    return point1;
}
QPoint Line::p2()const{
    return point2;
}
void Line::draw(QPainter *p){
    QPen pen(color,1,Qt::SolidLine);
    p->setPen(pen);
    p->drawLine(point1,point2); //绘制线条
}
void Line::save(QTextStream &out){
    out<<"0 "<<p1().x()<<" "<<p1().y()<<" " <<p2().x()<<" "<<p2().y()<<endl;
}
Shape* Line::read(QTextStream &in){
    int x1,y1,x2,y2;
    in>>x1>>y1>>x2>>y2;
    return new Line(QPoint(x1,y1),QPoint(x2,y2));
}

Rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H
#include"shape.h"
class Rectangle : public Shape{
public:
    Rectangle(QPoint p1,QPoint p2,QColor c=Qt::black);
    QPoint topLeft()const;
    QPoint bottomRight()const;
    virtual void draw(QPainter *p);
    virtual void save(QTextStream& out);
    static Shape* read(QTextStream& in);
private:
    QPoint point1;
    QPoint point2;
};

#endif // RECTANGLE_H

Rectangle.cpp

#include "rectangle.h"

Rectangle::Rectangle(QPoint p1,QPoint p2,QColor c): point1(p1),point2(p2),Shape(c){
}
QPoint Rectangle::topLeft()const{
    return point1;
}
QPoint Rectangle::bottomRight()const{
    return point2;
}
void Rectangle::draw(QPainter *p){
    QPen pen(color,1,Qt::SolidLine);
    p->setPen(pen);
    p->drawRect(QRect(point1,point2));
}
void Rectangle::save(QTextStream &out){
    out<<"2 "<<topLeft().x()<<" "<<topLeft().y()<<" " <<bottomRight().x()<<" "<<bottomRight().y()<<endl;
}
Shape* Rectangle::read(QTextStream &in){
    int x1,y1,x2,y2;
    in>>x1>>y1>>x2>>y2;
    return new Rectangle(QPoint(x1,y1),QPoint(x2,y2));
}

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<centerwidget.h>
#include <QMainWindow>
#include<QMenu>
#include<QMenuBar>
#include<QAction>
#include<QToolBar>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected slots:
    void line();
    void ellipse();
    void rectangle();
    void newDrawing();
    void openDrawing();
    void saveDrawing();
    void closeEvent(QCloseEvent *);
    void black();
    void yellow();
    void green();
private:
    CenterWidget* centerWidget;
    QMenu *fileMenu;
    QMenu *drawMenu;
    QMenu *colorMenu;
    QAction *newAction;
    QAction *openAction;
    QAction *saveAction;
    QAction *exitAction;
    QAction *lineAction;
    QAction *ellipseAction;
    QAction *rectangleAction;
    QToolBar *drawToolBar;
    QAction *blackAction;
    QAction *greenAction;
    QAction *yellowAction;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include<QStatusBar>
#include<QActionGroup>
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent){
    setWindowTitle(tr("画图程序!"));
    centerWidget=new CenterWidget(this);
    setCentralWidget(centerWidget);

    fileMenu=menuBar()->addMenu(tr("文件"));
    newAction=new QAction(QIcon("new.gif"),tr("新建"),this);
    newAction->setShortcut(tr("Ctrl+N"));
    newAction->setStatusTip(tr("新建绘图文件"));
    openAction=new QAction(QIcon("open.gif"),tr("打开"),this);
    openAction->setShortcut(tr("Ctrl+O"));
    openAction->setStatusTip(tr("打开保存的绘图文件"));
    saveAction=new QAction(QIcon("save.gif"),tr("保存"),this);
    saveAction->setShortcut(tr("Ctrl+S"));
    saveAction->setStatusTip(tr("保存当前绘图文件"));
    exitAction=new QAction(tr("退出"),this);
    exitAction->setShortcut(tr("Ctrl+X"));
    exitAction->setStatusTip(tr("退出程序"));
    fileMenu->addAction(newAction);
    fileMenu->addAction(openAction);
    fileMenu->addAction(saveAction);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAction);

    lineAction=new QAction(QIcon("line.gif"),tr("线条"),this);
    lineAction->setShortcut(tr("Ctrl+L"));
    lineAction->setStatusTip(tr("绘制线条"));
    ellipseAction=new QAction(QIcon("ellipse.gif"),tr("椭圆"),this);
    ellipseAction->setShortcut(tr("Ctrl+E"));
    ellipseAction->setStatusTip(tr("绘制椭圆"));
    rectangleAction=new QAction(QIcon("rectangle.gif"),tr("矩形"),this);
    rectangleAction->setShortcut(tr("Ctrl+R"));
    rectangleAction->setStatusTip(tr("绘制矩形"));
    drawMenu= menuBar()->addMenu(tr("绘图"));
    lineAction->setCheckable(true);
    ellipseAction->setCheckable(true);
    rectangleAction->setCheckable(true);            

    blackAction=new QAction(tr("black"),this);
    blackAction->setStatusTip("黑色");
    greenAction=new QAction(tr("green"),this);
    greenAction->setStatusTip("绿色");
    yellowAction=new QAction(tr("yellow"),this);
    yellowAction->setStatusTip("黄色");
    colorMenu=this->menuBar()->addMenu(tr("color"));
    colorMenu->addAction(blackAction);
    colorMenu->addAction(greenAction);
    colorMenu->addAction(yellowAction);

    QActionGroup *group=new QActionGroup(this);
    group->addAction(lineAction);
    group->addAction(ellipseAction);
    group->addAction(rectangleAction);
    group->setExclusive (true);
    lineAction->setChecked(true);
    drawMenu->addAction(lineAction);
    drawMenu->addAction(ellipseAction);
    drawMenu->addAction(rectangleAction);

    drawToolBar=addToolBar(tr("Draw"));
    drawToolBar->addAction(newAction);
    drawToolBar->addAction(openAction);
    drawToolBar->addAction(saveAction);
    drawToolBar->addSeparator();
    drawToolBar->addAction(lineAction);
    drawToolBar->addAction(ellipseAction);
    drawToolBar->addAction(rectangleAction);

    statusBar()->show();

    connect(exitAction,SIGNAL(triggered()),this,SLOT(close()));
    connect(lineAction,SIGNAL(triggered()),this,SLOT(line()));
    connect(ellipseAction,SIGNAL(triggered()),this,SLOT(ellipse()));
    connect(rectangleAction,SIGNAL(triggered()),this,SLOT(rectangle()));
    connect(newAction,SIGNAL(triggered()),this,SLOT(newDrawing()));
    connect(openAction,SIGNAL(triggered()),this,SLOT(openDrawing()));
    connect(saveAction,SIGNAL(triggered()),this,SLOT(saveDrawing()));
    connect(blackAction,SIGNAL(triggered()),this,SLOT(black()));
    connect(greenAction,SIGNAL(triggered()),this,SLOT(green()));
    connect(yellowAction,SIGNAL(triggered()),this,SLOT(yellow()));
}

MainWindow::~MainWindow(){  
}
void MainWindow::line(){
    centerWidget->setDrawType(0);
}
void MainWindow::ellipse(){
    centerWidget->setDrawType(1);
}
void MainWindow::rectangle(){
    centerWidget->setDrawType(2);
}
void MainWindow::newDrawing(){
    if(centerWidget->getModifiedFlag()==true){ //文档已修改
          switch(QMessageBox::question(this,tr("文档保存提示"),
                                         tr("文档已经修改,是否保存文档"),
                                         QMessageBox::Ok|
                                         QMessageBox::Cancel|
                                         QMessageBox::No,
                                         QMessageBox::Ok)){
      case QMessageBox::Ok: centerWidget->saveDrawing(); break;
      case QMessageBox::Cancel: return;
      case QMessageBox::No: break;
      default: break;
    }
}
        centerWidget->newDrawing();
    }
void MainWindow::openDrawing(){
    if(centerWidget->getModifiedFlag()==true){ //文档已修改
        switch(QMessageBox::question(this,tr("文档保存提示"),
                                     tr("文档已经修改,是否保存文档"),
                                     QMessageBox::Ok|QMessageBox::Cancel |
                                     QMessageBox::No, QMessageBox::Ok)){
        case QMessageBox::Ok: centerWidget->saveDrawing(); break;
        case QMessageBox::Cancel: return;
        case QMessageBox::No: break;
        default: break;
        }
    }
    centerWidget->openDrawing();
}
void MainWindow::saveDrawing(){
    centerWidget->saveDrawing();
}
void MainWindow::closeEvent(QCloseEvent *event){
    if(centerWidget->getModifiedFlag()==true){ //文档已修改
        switch(QMessageBox::question(this,tr("文档保存提示"),
                                     tr("文档已经修改,是否保存文档"),
                                     QMessageBox::Ok|
                                     QMessageBox::Cancel |
                                     QMessageBox::No, QMessageBox::Ok)){
        case QMessageBox::Ok: centerWidget->saveDrawing(); event->accept(); break;
        case QMessageBox::Cancel: event->ignore(); break;
        case QMessageBox::No: event->accept(); break;
        default: event->accept(); break;
        }
    }
}
void MainWindow::black(){
    centerWidget->setcolorType(0);
    centerWidget->update();
}
void MainWindow::green(){
    centerWidget->setcolorType(1);
    centerWidget->update();
}
void MainWindow::yellow(){
    centerWidget->setcolorType(2);
    centerWidget->update();
}

  • 22
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值