• 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)位图成像和缩放

        

     

          

          

  • 相关阅读:
    python之连接oracle数据库
    从一副牌中随机抽一张牌
    判断一个点是否在圆内
    判断每个月有多少天
    猜数字游戏
    求一元二次方程的2个跟
    Servlet细节处理
    Servlet
    Http协议
    Struts2(2)
  • 原文地址:https://www.cnblogs.com/csqtech/p/5634400.html
Copyright © 2020-2023  润新知