当前位置 博文首页 > 无水wangyang:【计算机图形学】绘制一个基于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);
}
?
cs