GDI 画刷(10)

Posted yenyuloong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDI 画刷(10)相关的知识,希望对你有一定的参考价值。

创建画刷

调用 CreateSoildBrushCreateHatchBrushCreateBrushIndirect 函数可以创建画刷。

CreateSoildBrush:创建实心画刷;

CreateHatchBrush:创建阴影画刷;

CreateBrushIndirect:根据 LOGBRUSH 结构的内容创建画刷;

Windows 使用被选入设备环境的画笔来描绘边线,使用被选入设备环境的画刷来填充图形。

画刷使用的示例代码:

// 定义画刷句柄(HBRUSH)
HBRUSH hBrush;

// 获取 GRAY_BRUSH 的句柄
hBrush = GetStockObject(GRAY_BRUSH);

// 将画刷选入当前的设备环境
SelectObject(hdc, hBrush);

将 NULL_PEN 画笔选入当前的设备环境,可以绘制不含边线的图形:

SelectObject(hdc, GetStockObject(NULL_PEN));

同样地,将 NULL_BRUSH 画刷选入当前的设备环境,可以绘制不填充内容的图形:

SelectObject(hdc, GetStockObject(NULL_BRUSH));

多边形填充(Polygon)

调用 Polygon 函数可以绘制一个带边框线且带填充效果的多边形,它的参数与 Polyline 函数类似:

BOOL Polygon(
    HDC hdc,                // 设备环境句柄
    CONST POINT *lpPoints,  // 端点的集合(POINT 类型数组)
    int nCount              // 端点的数量
);

调用 PolyPolygon 函数可以绘制多个待边框线且带填充效果的的多边形,它的参数与 PolyPolyline 函数类似:

BOOL PolyPolygon(
    HDC hdc,                  // 设备环境句柄
    CONST POINT *lpPoints,    // 所有端点的集合
    CONST INT *lpPolyCounts,  // 整型数组,每个元素是每个多边形各自的端点个数
    int nCount                // 多边形的数量
);

填充颜色取决于当前选入设备环境的画刷,填充模式可以调用 SetPolyFillMode 函数来设置:

  • ALTERNATE 模式(扫描线碰到奇数边则填充,偶数边则不填充)
  • WINDING 模式(能够一笔完成的图形则填充,否则不填充)
int SetPolyFillMode(
    HDC hdc,            // 设备环境句柄
    int iPolyFillMode   // 多边形填充模式,可选 ALTERNATE(交替)或 WINDING(螺旋)
);

五角星 Polygon 示例程序

#include <windows.h>
#include <math.h>

#define TIMES 200
#define PI 3.1415926535897932384626433832795

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {

    HDC hdc;
    PAINTSTRUCT ps;
    POINT ptCenter;
    POINT apt[5];
    HBRUSH hBrush, hOldBrush;

    static int cxClient, cyClient;

    switch (message) {

    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        ptCenter.x = cxClient / 2;
        ptCenter.y = cyClient / 2;

        apt[3].x = ptCenter.x;
        apt[3].y = ptCenter.y - TIMES;

        apt[1].x = (LONG)(ptCenter.x + cos(PI / 10) * TIMES);
        apt[1].y = (LONG)(ptCenter.y - sin(PI / 10) * TIMES);

        apt[4].x = (LONG)(ptCenter.x + cos(3 * PI / 10) * TIMES);
        apt[4].y = (LONG)(ptCenter.y + sin(3 * PI / 10) * TIMES);

        apt[2].x = (LONG)(ptCenter.x - cos(3 * PI / 10) * TIMES);
        apt[2].y = (LONG)(ptCenter.y + sin(3 * PI / 10) * TIMES);

        apt[0].x = (LONG)(ptCenter.x - cos(PI / 10) * TIMES);
        apt[0].y = (LONG)(ptCenter.y - sin(PI / 10) * TIMES);

        hBrush = CreateSolidBrush(RGB(255, 255, 0));
        hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);

        Polygon(hdc, apt, 5);
        
        DeleteObject(SelectObject(hdc, hOldBrush));
        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    LPCTSTR lpszClassName = TEXT("PolygonDemo");
    LPCTSTR lpszWindowName = TEXT("Polygon Demo Program");

    WNDCLASS wndclass;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hInstance = hInstance;
    wndclass.lpfnWndProc = WindowProc;
    wndclass.lpszClassName = lpszClassName;
    wndclass.lpszMenuName = NULL;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClass(&wndclass)) {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), lpszWindowName, MB_ICONERROR);
        return 0;
    }

    HWND hwnd = CreateWindow(
        lpszClassName,
        lpszWindowName,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

以上是关于GDI 画刷(10)的主要内容,如果未能解决你的问题,请参考以下文章

(转载)VS2010/MFC编程入门之五十一(图形图像:GDI对象之画刷CBrush)

win32day07-图形绘制/GDI绘图对象-画笔/画刷

简述WPF中的画刷(Brush)

WPF设计の画刷(Brush)

使用GDI时如何确定是否有内存泄漏

wpf 怎么用代码创建radialgradientbrush画刷