当前位置 博文首页 > 无水wangyang:【计算机图形学】绘制一个基于GDI的图形程序

    无水wangyang:【计算机图形学】绘制一个基于GDI的图形程序

    作者:[db:作者] 时间:2021-09-06 13:30

    这学期选修了计算机图形学这门课,该合集用来记录课程所学知识。

    概念类的内容来自于百度文库:https://wenku.baidu.com/view/c3c5b36048d7c1c708a145a2.html

    概念介绍

    GDI:图形设备接口(Graphics Device Interface)

    GDI函数大致可分类为:

    设备上下文函数(如GetDC、CreateDC、DeleteDC)、

    画线函数(如LineTo、Polyline、Arc)、

    填充画图函数(如Ellipse、FillRect、Pie)、

    画图属性函数(如SetBkColor、SetBkMode、SetTextColor)、

    文本、字体函数(如TextOut、GetFontData)、

    位图函数(如SetPixel、BitBlt、StretchBlt)、

    坐标函数(如DPtoLP、LPtoDP、ScreenToClient、ClientToScreen)、

    映射函数(如SetMapMode、SetWindowExtEx、SetViewportExtEx)、

    元文件函数(如PlayMetaFile、SetWinMetaFileBits)、

    区域函数(如FillRgn、FrameRgn、InvertRgn)、

    路径函数(如BeginPath、EndPath、StrokeAndFillPath)、

    裁剪函数(如SelectClipRgn、SelectClipPath)等。

    这些函数在以后的学习过程中有可能遇到,所以在此稍作记录。

    ?画图步骤:

    1)申请设备?

    2) 创建画图工具

    3)使用画图工具画图

    4)删除画图工具

    5)删除设备

    相关函数解释:
    ?

       HPEN hP;//定义一个画笔句柄
        hP = (HPEN)GetStockObject(BLACK_PEN)
    
       //调用函数GetStockObject获取Windows系统定义的四种画笔
       //四种画笔为:WHITE_PEN  BLACK_PEN  DC_PEN  NULL_PEN
        
        hPen = CreatePen(int style, int width , COLORREF color); //创建新画笔
     //  style 确定的是画笔样式 有: PS_DASH  虚线笔  PS_DASHDOT  点划线  PS_DASHDOTDOT  双点划线  PS_DOT  点线  PS_INSIDEFRAME 实线  PS_NULL  无  PS_SOLID 实线
        //  需要注意的有  创建画笔后,必须调用SelectObject函数将其选入设备环境  SelectObject(hdc,hP)
        //  不再使用当前画笔时,需删除画笔,以免占内存  DeleteObject(hP)


    ? ??
    ??

     HBRUSH hBr;//创建一个画刷句柄
        hBr = (HBRUSH)GetStockObject(BLACK_BRUSH);//画刷的样式有: BLACK_BRUSH 黑色画刷  DKGRAY_BRUSH 深灰色画刷  GRAY_BRUSH 灰色画刷
                                                  //HOLLOW_BRUSH 虚画刷  LTGRAY_BRUSH 亮灰色画刷 NULL_BRUSH 空画刷  WHITE_BRUSH 白色画刷
        //hBr = CreateSolidBrush(COLORREF Rgb);  hBr = CreateHatchBruch (int nHctchStyle,COLORREF rgb);可以使用这两个函数来创建笔刷
        // CreateSoildBrush 创建具有指定颜色的单色笔刷  CreateHatchBrush 创建指定阴影图案和样色的笔刷
        // 其中nHctchStyle 的值可以为: HS_BDIAGONAL 45度从左上到右下   HS_DIAGCROSS 45度叉线  HS_FDIAGONAL 45度从左上到右下  HS_CROSS 垂直相交的阴影线  HS_HORIZONTAL 水平阴影线  HS_VERTICAL 垂直阴影线
        // SelectObject(hdc,hBr) 选入设备环境
        // 删除与删除画笔等同

    ?? ?

    //常用绘图函数
        // 设置画笔当前位置的函数MoveToEx
        BOOL MoveToEx(HDC hdc, int x, LPPOINT lp);
        //  X,Y 分别为新位置的逻辑坐标,lp为存放画笔位置的POINT结构地址
    
        //从当前位置向指定坐标画直线的函数LineToEx
        BOOL LineToEx(HDC hdc, int x, int y);
        // X,Y是线段的终点坐标
    
        //从当前位置开始,依次用线段连接lp中指定的各点
        BOOL Polyline(HDC hdc, LPPOINT lp, int count);
        //count 为POINT数组中点的个数
    
        //绘制椭圆弧线的函数Arc
        BOOL ARC(HDC hdc, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
        // 其中 X1,Y1 表示边框矩形左上角的逻辑坐标   X2,Y2表示边框矩形右下角的逻辑坐标  X3,Y3表示椭圆弧起始点坐标  X4,Y4表示椭圆弧终止点所画曲线
    
        //绘制矩形,使用当前画刷进行填充
        BOOL Rectangle(HDC hdc, int X1, int Y1, int X2,int Y2);
    
        //绘制圆角矩形,使用当前画刷填充
        BOOL RoundRect(HDC hdc, int x1, int y1, int x2, int y2, int Height, int width);
    
        //绘制椭圆
        //绘制多边形


    ? ??

    练习1:

    ?编制一个基于GDI的图形程序,实现两种以上(单一颜色或者位图)填充图形,如:矩形、任意多边形、椭圆或者其他图形,显示在同一窗口上。

    ?

    这段代码是在网上搜索找到后,改变部分函数,得到题里要求的结果。

    因为搜索到的代码来源较多,就未标明出处。

    #include <windows.h>
    static TCHAR szAppName[] = TEXT("Test");
    static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
    	HWND     hWnd;
    	MSG      msg;
    	WNDCLASS wndclass;
    
    	wndclass.style = CS_HREDRAW | CS_VREDRAW;
    	wndclass.lpfnWndProc = WndProc;
    	wndclass.cbClsExtra = 0;
    	wndclass.cbWndExtra = 0;
    	wndclass.hInstance = hInstance;
    	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndclass.lpszMenuName = NULL;
    	wndclass.lpszClassName = szAppName;
    
    	if (!RegisterClass(&wndclass))
    	{
    		MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
    		return 0;
    	}
    
    	hWnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 350, 180, NULL, NULL, hInstance, NULL);
    
    	ShowWindow(hWnd, iCmdShow);
    	UpdateWindow(hWnd);
    
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return msg.wParam;
    }
    
    //绘制实心圆
    static void DrawCircle(HDC hDC, int x, int y, int len, COLORREF color)
    {
    	HBRUSH hBrush = CreateSolidBrush(color);
    	HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
    
    	HPEN hPen = CreatePen(PS_SOLID, 1, color);
    	HPEN hOldPen = (HPEN)SelectObject(hDC, hPen);
    
    	Ellipse(hDC, x - len / 2, y - len / 2, x + len / 2, y + len / 2);
    
    	SelectObject(hDC, hOldBrush);
    	DeleteObject(hPen);
    
    	SelectObject(hDC, hOldPen);
    	DeleteObject(hOldBrush);
    }
    
    //绘制填充矩形
    static void DrawRect(HDC hDC, int left, int top, int width, int height)
    {
    
    	HBRUSH hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 0, 255));
    	HBRUSH hOldBrush = (HBRUSH)SelectObject(hDC, hBrush);
    
    	Rectangle(hDC, left, top, left + width, top + height);
    
    	SelectObject(hDC, hOldBrush);
    	DeleteObject(hOldBrush);
    
    }
    
    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	HDC         hDC;
    	PAINTSTRUCT ps;
    
    	switch (message)
    	{
    	case WM_CREATE:
    		return 0;
    
    	case WM_PAINT:
    	{
    		hDC = BeginPaint(hWnd, &ps);
    
    
    		//绘制圆
    		DrawCircle(hDC, 50, 50, 60, RGB(165, 50, 250));
    
    		DrawRect(hDC, 120, 10, 180, 100);
    
    	}
    	EndPaint(hWnd, &ps);
    	return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hWnd, message, wParam, lParam);
    }
    

    ?

    cs