Windows 编程,画笔画刷以及几何图形的绘制

Windows编程,画笔画刷的介绍

画笔,可以用以下代码新建一个画笔对象:

HPEN hpen = CreatePen(PS_SOLID, 1, RGB(255,0,0));

可以看到,画笔的CreatePen()有三个参数(parameter),第一个参数表示画笔类型,第二个参数表示画笔宽度(注意以pixel为单位),第三个参数是画笔颜色。
除了上述的方法之外,还可以通过这两种方法获得画笔对象:
GetStockObject(WHITE_PEN),CreatePenIndirect(CONST LOGPEN*lplgpn)。
这三种方式的返回值都是HPEN,而他们的区别就是,Stock Pen,系统库存的pen的颜色,比如WHITE_PEN, BLACK_PEN, NULL_PEN,这些样式都可以直接从GetStockObject()函数中获得。
为了使我们要画的图形的线是我们设置好的画笔类型画出的线,就要在代码中使用SelectObject()函数,来具体调用画笔。
由于每次画笔的产生都要分配存储空间,故在使用完之后(程序结束后),使用DeleteObject()函数删除画笔对象。

那么,画笔类型有多少种呢?下面附上画笔的基本类型:

PS_DOT				//点状线
PS_DASHDOT   // 线段加点
PS_DASHDOTDOT//线段加点再加点
PS_DASH			//线段
PS_SOLID			//直线
PS_NULL           //无

想要使用不同类型的画笔,只需更改第一个参数即可

画刷,可以用以下代码新建一个画刷:

hBrush = CreateSolidBrush (crColor) ;//单色填充

hBrush = CreateHatchBrush (iHatchStyle,crColor) ; //阴影填涂

CreatePatternBrush

CreateDIBPatternBrushPt

hBrush = CreateBrushIndirect(&logbrush) ; //逻辑画刷

Windows提供了五种函数用于构建 画刷对象。
当然,同画笔一样,画刷也可以用GetStockObject()函数来获得windows自身所存的画刷类型(NULL_BRUSH 等)。
而画刷的类型如下:

		//HS_VERTICAL,    /* ||||| 垂直 */
		//	HS_HORIZONTAL,  /* ----- 水平 */
		//	HS_BDIAGONAL	/* 左斜线 */
		//	HS_FDIAGONAL	/* \\\\ 右斜线 */
		//	HS_CROSS,       /* +++++ 正十字 */
		//	HS_DIAGCROSS    /* xxxxx 斜十字 */

同样,为了使我们要画的图形的用上我们所设置的画刷类型,就要在代码中使用SelectObject()函数,来具体调用画刷。
由于每次画刷的产生都要分配存储空间,故在使用完之后(程序结束后),使用DeleteObject()函数删除画刷对象。

初步了解画笔和画刷后,让我们开始尝试绘制几何图形

几何图形的绘制

首先我们得明确在windows中提供的绘制几何图形的各类函数:

直角矩形:Rectangle()
具体:
WINGDIAPI BOOL WINAPI Rectangle(In HDC hdc, In int left, In int top, In int right, In int bottom);

椭圆 :Ellipse ()
具体:
WINGDIAPI BOOL WINAPI Ellipse( In HDC hdc, In int left, In int top, In int right, In int bottom);

圆角矩形:RoundRect()
具体:
WINGDIAPI BOOL WINAPI RoundRect(In HDC hdc, In int left, In int top, In int right, In int bottom, In int width, In int height);

椭圆周上的弧,两端以弦连接:Chord ()
具体:
WINGDIAPI BOOL WINAPI Chord( In HDC hdc, In int x1, In int y1, In int x2, In int y2, In int x3, In int y3, In int x4, In int y4);

椭圆上的饼图:Pie ()
具体:
WINGDIAPI BOOL WINAPI Pie(In HDC hdc, In int left, In int top, In int right, In int bottom, In int xr1, In int yr1, In int xr2, In int yr2);

多边形:Polygon ()
具体:
WINGDIAPI BOOL WINAPI Polygon(In HDC hdc, In_reads(cpt) CONST POINT *apt, In int cpt);

多个多边形:PolyPolygon()
具体:
WINGDIAPI BOOL WINAPI PolyPolygon(In HDC hdc, In CONST POINT *apt, In_reads(csz) CONST INT *asz, In int csz);

便于更好的理解和运用,我会逐个分析各个几何图形函数中参数的意义。
Rectangle()
它有5个参数,第一个参数(剩下的各个函数的第一个参数也都相同)是指设备描述表句柄,即在WM_PAINT中定义的一个HDC类的句柄,为了使函数能正常作用,必须将设备描述表句柄信息提供给函数。,这个函数剩余的四个参数的功能非常简单,就如定义所简写,表示两个点,矩形的左上角端点的横纵坐标和矩形的右下角端点的横纵坐标。

Ellipse()
几乎和矩形一样,注意,windows中的构建椭圆(圆形),是通过先建立矩形确定范围,再画出椭圆,所以后四个参数也是先构建的矩形的左上角端点坐标和右下角端点坐标。

RoundRect()
圆角矩形,比起普通的矩形函数多了最后两个参数,这两个参数也是 int类型,具体功能是改变圆角矩形圆角的弯曲程度,数值设置的较高,则弯曲程度越强。

Pie(),
饼图,它有八个int类型的参数,前四个也是表示先构建的矩形左上角端点和右下角端点。后四个,注意,是由圆心衍生的两条半径的端点的坐标。或者说是坐标点 与 圆心 相连的线,在运行后会保留线在圆内的部分,从而实现饼图。

Polygon()
其中,第二个参数 是一个 POINT 结构的数组,第三个参数 是点的个数。如果数组中最后一个点与第一个点不同,则 Windows 会再加一条线连接最后一个点与第一个点。(在 Polyline 函数中不会这么做。)

PolyPolygon()
最后一个参数是绘制的多边形的个数。对每个多边形,第二个参数数值给出了多边形顶点的个数。数组中含有全部多边形的所有顶点。

了解上述基础知识后,以下是一个使用visual studio 2017 编写的 实现 基本几何图形绘制 和 画笔画刷类型应用的程序;

//WindowsProject3.cpp: 定义应用程序的入口点。
//

#include "stdafx.h"
#include "WindowsProject3.h"

#define MAX_LOADSTRING 100

// 全局变量: 
HINSTANCE hInst;                                // 当前实例
WCHAR szTitle[MAX_LOADSTRING] = TEXT("2_1");                  // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名

// 此代码模块中包含的函数的前向声明: 
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 在此放置代码。

    // 初始化全局字符串
    //LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT3, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化: 
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT3));

    MSG msg;

    // 主消息循环: 
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT3));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT3);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释: 
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 将实例句柄存储在全局变量中

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
   /* case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择: 
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;*/
	case WM_PAINT:
	{
		//hBru[i] = CreateHatchBrush(sBru[i], RGB(255, 0, 0))
		HBRUSH hBrush;//添加画刷
					  //HBRUSH hBrush2;//添加画刷

		HPEN  hPen;
		static HPEN hPen2;
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此处添加使用 hdc 的任何绘图代码...
		//hBrush2 = (HBRUSH)GetStockObject(NULL_BRUSH);//空心,画刷取空
		//SelectObject(hdc, hBrush2);
		hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));//red
		SelectObject(hdc, hPen);
		//SelectObject(hdc, hBrush);
		Ellipse(hdc, 0, 150,150,0);
		hPen = CreatePen(PS_DASHDOT, 1, RGB(0, 255, 0));//green
		SelectObject(hdc, hPen);
		hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);//空心,画刷取空
		SelectObject(hdc, hBrush);
		Ellipse(hdc, 50, 0, 200, 150);
		hPen = CreatePen(PS_DOT, 1, RGB(0, 255, 255));//blue
		SelectObject(hdc, hPen);
		//hBrush = (HBRUSH)GetStockObject(NULL_BRUSH);//空心,画刷取空
		//SelectObject(hdc, hBrush);
		Ellipse(hdc, 50, 50, 200, 200);
		hPen = CreatePen(PS_DASHDOTDOT, 1, RGB(0, 0, 255));// blue
		SelectObject(hdc, hPen);
		Ellipse(hdc, 0, 50, 150, 200);
		//
		//以上圆圈绘制完毕
		//
		//开始饼图绘制
		//
		//
		//hBrush = CreateHatchBrush(HS_VERTICAL, RGB(255, 255, 255));
		hPen2 = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));//red
		SelectObject(hdc, hPen2);
		hBrush = CreateSolidBrush(RGB(0, 255, 255));//设置画刷,纯色填充 蓝
		SelectObject(hdc, hBrush);
		Pie(hdc, 50, 300, 250, 500, 100, 300, 80, 500);
		hBrush = CreateSolidBrush(RGB(255, 0, 0)); //红
		SelectObject(hdc, hBrush);
		Pie(hdc, 50, 300, 250, 500, 80, 500, 250, 400);
		hBrush = CreateSolidBrush(RGB(255, 255, 0));//
		SelectObject(hdc, hBrush);
		Pie(hdc, 50, 300, 250, 500, 250, 400, 100, 300);
		//以上饼图的绘制结束
		//
		//
		//
		//开始绘制正方形
		//下排正方形的绘制
		//
		//
		//
		hPen2 = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));//red
		SelectObject(hdc, hPen2);
		//第一排圆角正方形
		//
		//
		hBrush = CreateSolidBrush(RGB(0, 0, 0));//1
		SelectObject(hdc, hBrush);
		RoundRect(hdc, 600, 0, 700, 100, 30, 30);
		hBrush = CreateSolidBrush(RGB(50, 50, 50));//2
		SelectObject(hdc, hBrush);
		RoundRect(hdc, 700, 0, 800, 100, 30, 30);
		hBrush = CreateSolidBrush(RGB(130, 130, 130));//3
		SelectObject(hdc, hBrush);
		RoundRect(hdc, 800, 0, 900, 100, 30, 30);
		hBrush = CreateSolidBrush(RGB(255, 255, 255));//4
		SelectObject(hdc, hBrush);
		RoundRect(hdc, 600, 100, 700, 200, 30, 30);
		hBrush = CreateSolidBrush(RGB(180, 180, 180));//5
		SelectObject(hdc, hBrush);
		RoundRect(hdc, 700, 100, 800, 200, 30, 30);
		hBrush = CreateSolidBrush(RGB(255, 255, 255));//6
		SelectObject(hdc, hBrush);
		RoundRect(hdc, 800, 100, 900, 200, 30, 30);


		Pie();
		Rectangle();
		Ellipse();
		Chord();
		RoundRect();
		Polygon();
		PolyPolygon();


		//HS_VERTICAL,    /* ||||| 垂直 */
		//	HS_HORIZONTAL,  /* ----- 水平 */
		//	HS_BDIAGONAL	/* 左斜线 */
		//	HS_FDIAGONAL	/* \\\\ 右斜线 */
		//	HS_CROSS,       /* +++++ 正十字 */
		//	HS_DIAGCROSS    /* xxxxx 斜十字 */
		//hBrush = CreateHatchBrush(HS_VERTICAL, RGB(220, 220, 220));//黄
		//SelectObject(hdc, hBrush);
		
	
		//
		//第二排正方形
		//
		hBrush = CreateHatchBrush(HS_BDIAGONAL, RGB(200, 200, 200));//1
		SelectObject(hdc, hBrush);
		Rectangle(hdc, 600, 200, 700, 300);
		hBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(200, 200, 200));//2
		SelectObject(hdc, hBrush);
		Rectangle(hdc, 700, 200, 800, 300);
		hBrush = CreateHatchBrush(HS_FDIAGONAL, RGB(200, 200, 200));//3
		SelectObject(hdc, hBrush);
		Rectangle(hdc, 800, 200, 900, 300);
		//
		hBrush = CreateHatchBrush(HS_CROSS, RGB(200, 200, 200));//4
		SelectObject(hdc, hBrush);

		Rectangle(hdc, 600, 300, 700, 400);
		hBrush = CreateHatchBrush(HS_HORIZONTAL, RGB(200, 200, 200));//5
		SelectObject(hdc, hBrush);
		Rectangle(hdc, 700, 300, 800, 400);
		hBrush = CreateHatchBrush(HS_VERTICAL, RGB(200, 200, 200));//6
		SelectObject(hdc, hBrush);
		Rectangle(hdc, 800, 300, 900, 400);




		//最后delete 画刷

		EndPaint(hWnd, &ps);
	}
	break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// “关于”框的消息处理程序。
/*
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}*/

该程序我保留了部分默认初始化好的代码,运行结果如下图所示;
在这里插入图片描述

说明文档:制作类似windows画笔的程序 功能: 文件—— 新建 打开 保存 另存为 页面设置——画布大小变化 退出 编辑—— 剪切 复制 粘贴 删除选定区域(但是背景变成黑色的了?!) 查看—— 工具栏、状态栏、颜料盒的显示与隐藏 大尺寸、常规尺寸、自定义尺寸的缩放 图像—— 翻转功能实现(包括水平、垂直翻转,以及180度旋转,90与270度旋转理论上亦实现了,只是速度有些慢,只能适用于小图形) 图像反色 颜色—— 编辑颜色功能实现 帮助—— 弹出信息框 界面: 突出显示按件 鼠标移动显示坐标 使用铅笔在画布上任意绘画,且可以变化颜色 橡皮擦功能实现(橡皮擦大小的变化可以通过改变笔刷粗细后改变) 拾色器功能实现 油漆桶功能实现 直线、笔刷功能实现 屏幕输入文字 放大镜功能实现!!(——强烈注意:它又名奇异镜> <……即使用之后,所有画图功能(比如颜色反色出现,橡皮变成铅笔……填充的色块可以叠加……,O(∩_∩)O哈哈~所以使用之后,记得退出程序,重新开启……) 可以画空心或实心的矩形 可以画空心或实心的椭圆和圆 喷枪功能实现(只是在画笔变粗时,效果会有些恶心……,建议通过笔刷,选择1,然后使用) 另:支持各种快捷键,如ctrl+S/ctrl+x 等,详情请见菜单栏。 使用的API函数与ActiveX控件: API函数: GetCursorPos GetDC GetPixel RoundRect ActiveX控件: 通用对话框控件, 位于“Microsoft CommonDialog Control 6.0” 中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值