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

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

概念类的内容来自于百度文库: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);
}

猜你喜欢

转载自blog.csdn.net/weixin_40874586/article/details/82946638