15.windows绘图(二)

1.GDI绘图对象 - 画笔

  (1)作用

     线的颜色、线型、线粗

  (2)使用

     a.创建句柄

       HPEN CreatePen( int              fnPenStyle,  //画笔的样式

                                         int              nWidth,      //画笔的粗细

                                         COLORREF  crColor);     //画笔的颜色

       成功,返回画笔句柄

       画笔样式:PS_SOLID - 实线,可支持多个像素宽,其他线型只能是一个像素宽,其他像素则全是实线

                              PS_DASH - 虚线

                              PS_DOT - 点线

                              PS_DASHDOT - 虚线和一个点交替出现

                              PS_DASHDOTDOT - 虚线和两个点交替出现

     b.将画笔应用到DC中

       HGDIOBJ SelectObject( HDC         hdc,         //绘图设备句柄

                                                  HGDIOBJ  hgdiobj);  //GDI绘图对象句柄,画笔句柄

       成功,返回原来的GDI绘图对象句柄(注意保存原来DC的画笔)。

     c.绘图

     d.取出DC中的画笔

       将原来的画笔用SelectObject函数放入到设备DC中,就会将我们创建的画笔取出。

     e.释放画笔

       BOOL DeleteObject( HGDIOBJ hObject);

       只能删除不被DC使用的画笔,所以释放前必须将画笔从DC中取出

2.GDI绘图对象 - 画刷

  (1)作用

     封闭图形的填充颜色、图案

  (2)使用

     a.创建画刷

      //创建实心画刷(给封闭图形填充单一颜色)

      HBRUSH CreateSolidBrush( COLORREF crColor);

      //创建阴影画刷

      HBRUSH CreateHatchBrush( int             fnStyle,  //阴影线样式

                                                         COLORREF  clrref);   //阴影线颜色

      //创建位图画刷

      HBRUSH CreatePatternBrush(HBITMAP hbmp);

     b.将画刷应用到DC中

     c.绘图

     d.将画刷从DC中取出

      SelectObject

     e.删除画刷

      DeleteObject

  (4)其他

     可以使用GetStockObject函数获取系统维护的画刷、画笔等,如果不使用画刷填充,需要使用NULL_BRUSH参数,获取不填充的画刷。

     GetStockObjcct返回的画刷不需要DeleteObject      

     HGDIOBJ GetStockObject( int  fnObject ); 

4.GDI绘图对象 - 位图

  (1)位图相关

     光栅图形:记录图像中每一个点的颜色等信息

     矢量图形:记录图像算法、绘图指令等

  (2)使用

     a.在资源中添加位图资源

     b.从资源中加载位图LoatBitmap

     c.创建一个与当前DC相匹配的DC(内存DC)

      HDC CreateCompatibleDC( HDC hdc);//当前DC句柄,可以为NULL(使用屏幕DC)

      返回创建好的DC句柄

     d.将位图放入匹配的DC中

      SelectObject

     e.成像(1:1)

      BOOL BitBlt( HDC        hdcDest,  //目的DC

                                    int          nXDest,   //目的左上角X坐标

                                    int          nYDest,   //目的左上角Y坐标

                                    int          nWidth,   //目的宽度

                                    int          nHeight,  //目的高度

                                    HDC       hdcSrc,    //源DC

                                    int          nXSrc,     //源左上角X坐标

                                    int          nYSrc,     //源左上角Y坐标

                                    DWORD  dwRop);  //成像方法,SRCCOPY

     f.取出位图

      SelectObject

     g.释放位图

      DeleteObject

     h.释放匹配的DC

      DeleteDC

     i.其他

      使用获取位图信息

      int GetObject( HGDIOBJ   hgdiobj,       //绘图对象句柄

                                      int            cbBuffer,      //缓冲区大小

                                      LPVOID     lpvObject);   //缓冲区地址

  (3)缩放   

     BOOL BitBlt( HDC        hdcDest,  //目的DC

                                 int          nXDest,   //目的左上角X坐标

                                 int          nYDest,   //目的左上角Y坐标

                                 int          nWidth,   //目的宽度

                                 int          nHeight,  //目的高度

                                 HDC       hdcSrc,    //源DC

                                 int          nXSrc,     //源左上角X坐标

                                 int          nYSrc,     //源左上角Y坐标

             int          nWidth,   //源宽度

                                 int          nHeight,  //源高度

                                 DWORD  dwRop);  //成像方法,SRCCOPY

  相关示例代码:

#include "stdafx.h"

HINSTANCE g_hInstance = 0;  //接收当前程序实例句柄
int g_kind = 0;//标志量

void OnCommand(HWND hWnd, WPARAM wParam)
{
    g_kind = LOWORD(wParam);
    switch (LOWORD(wParam))
    {
    case ID_PT:
    case ID_LINE:
    case ID_RECT:
    case ID_ELL:
    case ID_ARC:
    case ID_BMP:
        InvalidateRect(hWnd, NULL, TRUE);
        break;
    }
}
void DrawPoint(HDC hdc)
{
    for (int i = 0; i < 256; i++)
    {
        for (int j = 0; j < 256; j++)
        {
            SetPixel(hdc, i, j, RGB(i, j, 0));
        }
    }
}
void DrawLine(HDC hdc)
{
    MoveToEx(hdc, 100, 100, NULL);
    LineTo(hdc, 300, 300);
    LineTo(hdc, 0, 300);
    LineTo(hdc, 100, 100);
}
void DrawRec(HDC hdc)
{
    Rectangle(hdc, 100, 100, 300, 300);
    RoundRect(hdc, 300, 100, 500, 300, 200, 200);
}
void DrawEll(HDC hdc)
{
    Ellipse(hdc, 100, 100, 300, 300);
    Ellipse(hdc, 300, 100, 600, 300);
}
void DrawArc(HDC hdc)
{
    SetArcDirection(hdc, AD_CLOCKWISE);//顺时针取弧
    Arc(hdc, 100, 100, 300, 300, 100, 100, 300, 300);
}
void DrawBmp(HDC hdc)
{
    //1.添加位图资源
    //2.加载位图
    HBITMAP hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); 
    //动态获取位图的信息
    BITMAP bmpInfo = { 0 };
    GetObject(hBmp, sizeof(bmpInfo), &bmpInfo);
    
    //3.创建一个与当前DC相匹配的DC
    //创建了一个内存DC,同时在内存中构建了一个虚拟区域
    //本质是:创建了一个内存DC,同时申请相应大小的一块内存
    HDC hMemdc = CreateCompatibleDC(hdc);

    //4.将位图放入匹配的DC中
    //将图片送给内存DC后,内存DC会立即将图片在虚拟区域中 绘制出来 
    //本质是:将图片的数据扔到内存DC找到的那块内存中
    HGDIOBJ nOld = SelectObject(hMemdc, hBmp);

    //5.成像
    //将内存中图片的数据一次性拷贝到显存中
    BitBlt(hdc, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hMemdc, 0, 0, SRCCOPY);

    //缩放成像
    StretchBlt(hdc, 100, 100, 96, 96, hMemdc, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, SRCCOPY);

    //6.取出位图
    SelectObject(hMemdc, nOld);

    //7.释放位图
    DeleteObject(hBmp);

    //8.释放匹配的DC
    DeleteDC(hMemdc);
}
void OnPaint(HWND hWnd)
{
    PAINTSTRUCT pt = { 0 };
    HDC hdc = BeginPaint(hWnd, &pt);  //当前DC,在窗口中画图

    HPEN hPen = CreatePen(PS_DASH, 1, RGB(255, 0, 0));
    HGDIOBJ nOldPen = SelectObject(hdc, hPen);
    //创建绿色实心画刷
    //HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
    //创建绿色水平垂直线阴影画刷
    HBRUSH hBrush = CreateHatchBrush(HS_CROSS, RGB(0, 255, 0));
    //得到透明画刷
    //HGDIOBJ hBrush = GetStockObject(NULL_BRUSH);
    //HBITMAP hBmp = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
    //HBRUSH hBrush = CreatePatternBrush(hBmp);
    HGDIOBJ nOldBrush = SelectObject(hdc, hBrush);

    switch (g_kind)
    {
    case ID_BMP:
        DrawBmp(hdc);//绘制位图
        break;
    case ID_ARC:
        DrawArc(hdc);//绘制弧线
        break;
    case ID_ELL:
        DrawEll(hdc);//绘制圆
        break;
    case ID_RECT:
        DrawRec(hdc);//绘制矩形
        break;
    case ID_LINE:
        DrawLine(hdc);//绘制直线
        break;
    case ID_PT:
        DrawPoint(hdc);//绘制点
        break;
    }
    SelectObject(hdc, nOldPen);
    DeleteObject(hPen);
    SelectObject(hdc, nOldBrush);
    DeleteObject(hBrush);
    EndPaint(hWnd, &pt);
}
//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_PAINT:
        OnPaint(hWnd);
        break;
    case WM_COMMAND:
        OnCommand(hWnd, wParam);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}
//注册窗口类
BOOL Register(LPSTR lpClassName, WNDPROC wndProc)
{
    WNDCLASSEX wce = { 0 };

    wce.cbSize        = sizeof(wce);
    wce.cbClsExtra    = 200;
    wce.cbClsExtra    = 200;
    wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3);
    wce.hCursor       = NULL;
    wce.hIcon         = NULL;
    wce.hIconSm       = NULL;
    wce.hInstance     = g_hInstance;
    wce.lpfnWndProc   = wndProc;
    wce.lpszClassName = lpClassName;
    wce.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
    wce.style         = CS_HREDRAW | CS_VREDRAW;

    ATOM nAtom = RegisterClassEx(&wce);
    if (0 == nAtom)
    {
        return FALSE;
    }
    return TRUE;
}
//创建主窗口
HWND CreateMainWindow(LPSTR lpClassName, LPSTR lpWndName)
{
    HWND hWnd = CreateWindowEx(0, lpClassName, lpWndName, WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, g_hInstance, NULL);
    return hWnd;
}
//显示窗口
void Display(HWND hWnd)
{
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
}
//消息循环
void Message()
{
    MSG nMsg = { 0 };
    while (GetMessage(&nMsg, NULL, 0, 0))
    {
        TranslateMessage(&nMsg);
        DispatchMessage(&nMsg);
    }
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
    g_hInstance = hInstance;
    Register("Main", WndProc);
    HWND hWnd = CreateMainWindow("Main", "window");
    Display(hWnd);
    Message();

    return 0;
}
View Code

  运行结果:

  (1)虚线画笔

    

  (2)横竖线画刷

    

  (3)位图成像和缩放

    

 

      

      

posted @ 2016-07-01 22:28  甩锅侠  阅读(353)  评论(0)    收藏  举报