绘图(VC_Win32)

GUI作图概述

作图步骤

  • 获得设备描述表资源句柄
  • 绘图操作
  • 释放设备描述表资源句柄

流程图如下:

绘图(VC_Win32)_第1张图片

获取/释放设备资源描述表

  • 获取设备资源描述表:   BeginPaint / GetDC
  • 释放设备资源描述表:  EndPaint / ReleaseDC

BeginPaint / GetDC 两种方式的区别:

             BeginPaint            GetDC            
使用环境         只用于图形刷新时获取设备环境   使用较为广泛
操作区域         无效区              特定窗口的客户区或者整个窗口
释放设备环境所用函数   ReleaseDC ()          EndPaint ()

代码示例:

在 WM_PAINT 添加 BeginPaint 事件,在 WM_LBUTTONDOWN 添加 GetDC 事件.

BeginPaint 使用:

//获得资源DC
hdc=BeginPaint(hwnd,&ps);
//获得窗口大小
GetClientRect(hwnd,&rect);
//绘制文本
DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect,
    DT_SINGLELINE | DT_CENTER | DT_VCENTER);
//释放资源DC
EndPaint(hwnd,&ps);

 GetDC 使用: 

//获得设备资源描述表
hdc = GetDC(hwnd);
//绘制带圆角矩形
RoundRect(hdc,10,10,110,60,10,10);
//释放设备资源描述表
ReleaseDC(hwnd,hdc);

程序源码

运行结果:

单击鼠标右键和重绘窗口时

绘图(VC_Win32)_第2张图片

在单击鼠标右键后

绘图(VC_Win32)_第3张图片

绘图操作分类

  • 描绘图形
  • 位图
  • 文本输出

与设备描述表相关函数

  • 背景色:  GetBkColor  SetBkColor
  • 背景模式:  GetBkMode  SetBkMode
  • 位图:  CreateBitMap  CreateBitMapIndirect  CreateCompatibleBitmap  SelectObject
  • 画刷:  CreateBrushIndirect  CreateDIBPatternBrush  CreateHatchBrush  CreatePatternBrush  CreateSolidBrush  SelectObject
  • 画刷起始位置:  GetBrushOrg  SetBrushOrg  UnrealizeObject
  • 剪裁域:  ExcludeClipRect  IntersectClipRect  OffsetClipRgn  SelectClipPath  SelectObject  SelectClipRgn
  • 颜色调色板:  CreatePalette  RealizePalette  SelectPalette
  • 绘图方式:  GetROP2  SetROP2
  • 字体:  CreateFont  CreateFontIndirect  SelectObject
  • 字符间距:  GetTextCharacterExtra  SetTextCharacterExtra
  • 映射方式:  GetMapMode  SetMapMode
  • 画笔:  CreatePen  CreatePenIndirect  SelectObject
  • 多边形填充方式:  GetPolyFillMode  SetPolyFillMode
  • 缩放模式:  SetStretchBltMode  GetStretchBltMode
  • 文本颜色:  GetTextColor  SetTextColor
  • 视图范围:  GetViewportExtEx  SetViewportExtEx  ScaleViewportExtEx
  • 视图原点:  GetViewportOrgEx  SetViewportOrgEx
  • 窗口范围:  GetWindowExtEx  SetWindowExtEx  ScaleWindowExtEx
  • 窗口原点:  GetWindowOrgEx  SetWindowOrgEx    

描绘图形

常用绘图函数:

  • 画贝塞尔曲线:
    • PolyBezier
    • PolyDraw
  • 画点:  SetPixel
  • 画矩形:  Rectangle
  • 画带圆角的矩形:  RoundRect()
      函数原型:  BOOL RoundRect( HDC hdc, int nLeftRect, int nTopRect,int nRightRect,int nBottomRect,int nWidth,int nHeight);
      参数说明:

            绘图(VC_Win32)_第4张图片
  • 画椭圆:  Ellipse
  • 画椭圆的一部分(即画一个弦):  Chord
  • 画一个扇形区并用当前画刷填充:  Pie
  • 画椭圆弧线:   Arc
      函数原型:  BOOL Arc(HDC hdc,int nLeftRect, int nTopRect,int nRightRect,int nBottomRect,int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc);
      参数说明:

            绘图(VC_Win32)_第5张图片
  • 画椭圆弧线:   ArcTo
  • 画正圆弧线:  AngleArc
      函数原型:   BOOL AngleArc(HDC hdc,int X,int Y,DWORD dwRadius,FLOAT eStartAngle,FLOAT eSweepAngle);
      参数说:

          绘图(VC_Win32)_第6张图片
  • 画一系列相连的直线:
    • Polyline
    • PolylineTo
    • PolyPolyline
  • 画线条:
    • 设置画笔起始位置:  MoveToEx
    • 设置画笔终止位置:  LineTo

位图

步骤:

  • 建立位图资源
  • 载入/创建位图资源
  • 获取设备内存
  • 选入内存设备
  • 贴图

流程图如下所示:

绘图(VC_Win32)_第7张图片

代码示例:

.rc 内容(位图资源):

IDB_BITMAP1             BITMAP                  "8c8a09f1gw1ds3qh4vtcyj.bmp"

位图(8c8a09f1gw1ds3qh4vtcyj.bmp 尺寸信息:440*622):

绘图(VC_Win32)_第8张图片

在鼠标左键单击事件中添加贴图操作:

加载位图:

hBmp = LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BITMAP1));

创建兼容 DC 并将位图选入兼容 DC 中:

hcmdc = CreateCompatibleDC(hdc);
SelectObject(hcmdc,hBmp);

 获得窗口大小(被显示的区域),获得位图信息(要显示的区域)

//获取窗口大小
GetClientRect(hwnd,&rect);
//获取位图信息(在 StretchBlt 时候有用到,而 BitBlt 没有)
GetObject(hBmp, sizeof(BITMAP), &bmp);
 显示位图:
//显示方式一,  按原图比例显示
BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,SRCCOPY);

//显示方式二,  拉伸式显示
StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);

程序源码

运行结果:

  • 在未点击鼠标右键时候:

    绘图(VC_Win32)_第9张图片

  • 点击鼠标左键(用 BitBlt 方法):

    绘图(VC_Win32)_第10张图片

  • 点击鼠标左键(用 StretchBlt 方法):

    绘图(VC_Win32)_第11张图片

文本输出

文本输出操作

  • 文字输出:  TextOut
  • 显示字符串:  DrawText

有关文本操作:

  • 获取文字信息:  GetTextMetrics
  • 格式化文字:  GetTextExtentPoint32
  • 设置字体颜色和背景颜色:
    • 字体:  SetTextColor
    • 背景:  SetBkColor

设置画刷/画笔/字体

步骤:

  • 创建资源句柄
  • 创建自定义资源/调用系统资源
  • 将资源选入系统

如下图所示:

绘图(VC_Win32)_第12张图片

代码示例:

在窗口重画的时候添加创建新画笔操作:

创建新画笔,并将画笔选入设备描述表中

pen = CreatePen(PS_DOT,3,RGB(255,100,100));
SelectObject(hdc,pen);

为了区别创建画笔前和创建画笔后的作图的区别

在创建画笔前绘制一条直线:

//rect 为记录窗口大小的 RECT 结构体
MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2-50,NULL);
LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2-50);

在创建画笔后绘制一条直线:

MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2+50,NULL);
LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2+50);

程序源码

运行结果:

绘图(VC_Win32)_第13张图片

程序源码

#include<windows.h>
#include"resource.h"

HINSTANCE hinstance;

LRESULT CALLBACK textprom(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

int WINAPI WinMain(  HINSTANCE hInstance,  // handle to current instance
  HINSTANCE hPrevInstance,  // handle to previous instance
  LPSTR lpCmdLine,      // pointer to command line
  int nCmdShow          // show state of window
)
{
    WNDCLASS wndclass;
    HWND hwnd;
    MSG msg;

    //设计窗口类
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);
    wndclass.hInstance=hInstance;
    wndclass.lpfnWndProc=textprom;
    wndclass.lpszClassName="text";
    wndclass.lpszMenuName=NULL;
    wndclass.style=CS_HREDRAW | CS_VREDRAW;
    
    //注册窗口类
    if(!RegisterClass(&wndclass))
    {
        MessageBox(NULL,"create windows error!","error",MB_OK | MB_ICONSTOP);
    }

    //创建无菜单资源的窗口窗口
    hwnd=CreateWindow("text","hellow world",WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU,0,0,500,300,NULL,NULL,hInstance,NULL);


    //显示更新窗口
    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd);

    hinstance = hInstance;

    //消息循环
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK textprom(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
    HDC hdc,hcmdc;
    PAINTSTRUCT ps;
    RECT rect;
    HBITMAP hBmp;
    SIZE   size;
    BITMAP bmp;
    HPEN pen;

    switch(uMsg)
    {
    //重绘事件
    case WM_PAINT:
        hdc=BeginPaint(hwnd,&ps);
        //显示文本
        GetClientRect(hwnd,&rect);
        DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect,
            DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        //画笔
        MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2-50,NULL);
        LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2-50);
        pen = CreatePen(PS_DOT,3,RGB(255,100,100));
        SelectObject(hdc,pen);
        MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2+50,NULL);
        LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2+50);
        EndPaint(hwnd,&ps);
        break;
    //绘制圆角矩形
    case WM_LBUTTONDOWN:
        hdc = GetDC(hwnd);
        RoundRect(hdc,10,10,110,60,10,10);
        ReleaseDC(hwnd,hdc);
        break;
    //贴图
    case WM_RBUTTONDOWN:
        hdc = GetDC(hwnd);
        hBmp = LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BITMAP1));
        hcmdc = CreateCompatibleDC(hdc);
        SelectObject(hcmdc,hBmp);    
        GetClientRect(hwnd,&rect);
        GetObject(hBmp, sizeof(BITMAP), &bmp);
        StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
        //BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,SRCCOPY);
        ReleaseDC(hwnd,hdc);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}

你可能感兴趣的:(绘图(VC_Win32))