绘图(VC_Win32)

来源:互联网 发布:都市天际线优化mod 编辑:程序博客网 时间:2024/05/29 12:39

GUI作图概述


作图步骤

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

流程图如下:

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

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

BeginPaint / GetDC 两种方式的区别:

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

代码示例:

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

BeginPaint 使用:

[cpp] view plaincopyprint?
  1. //获得资源DC 
  2. hdc=BeginPaint(hwnd,&ps); 
  3. //获得窗口大小 
  4. GetClientRect(hwnd,&rect); 
  5. //绘制文本 
  6. DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect, 
  7.     DT_SINGLELINE | DT_CENTER | DT_VCENTER); 
  8. //释放资源DC 
  9. EndPaint(hwnd,&ps); 

GetDC 使用:

[cpp] view plaincopyprint?
  1. //获得设备资源描述表 
  2. hdc = GetDC(hwnd); 
  3. //绘制带圆角矩形 
  4. RoundRect(hdc,10,10,110,60,10,10); 
  5. //释放设备资源描述表 
  6. ReleaseDC(hwnd,hdc); 

程序源码

运行结果:

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

在单击鼠标右键后

绘图操作分类

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

与设备描述表相关函数

  • 背景色:  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);
      参数说明:

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

            
  • 画椭圆弧线:   ArcTo
  • 画正圆弧线:  AngleArc
      函数原型:   BOOL AngleArc(HDC hdc,int X,int Y,DWORD dwRadius,FLOAT eStartAngle,FLOAT eSweepAngle);
      参数说:

          
  • 画一系列相连的直线:
    • Polyline
    • PolylineTo
    • PolyPolyline
  • 画线条:
    • 设置画笔起始位置:  MoveToEx
    • 设置画笔终止位置:  LineTo

位图


步骤:

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

流程图如下所示:

代码示例:

.rc 内容(位图资源):

[cpp] view plaincopyprint?
  1. IDB_BITMAP1             BITMAP                  "8c8a09f1gw1ds3qh4vtcyj.bmp" 

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

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

加载位图:

[cpp] view plaincopyprint?
  1. hBmp = LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BITMAP1)); 

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

[cpp] view plaincopyprint?
  1. hcmdc = CreateCompatibleDC(hdc); 
  2. SelectObject(hcmdc,hBmp); 

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

[cpp] view plaincopyprint?
  1. //获取窗口大小 
  2. GetClientRect(hwnd,&rect); 
  3. //获取位图信息(在 StretchBlt 时候有用到,而 BitBlt 没有) 
  4. GetObject(hBmp, sizeof(BITMAP), &bmp); 
  5. 显示位图: 
  6. //显示方式一,  按原图比例显示 
  7. BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,SRCCOPY); 
  8.  
  9. //显示方式二,  拉伸式显示 
  10. StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 

程序源码

运行结果:

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

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

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

文本输出


文本输出操作

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

有关文本操作:

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

设置画刷/画笔/字体


步骤:

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

如下图所示:

代码示例:

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

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

[cpp] view plaincopyprint?
  1. pen = CreatePen(PS_DOT,3,RGB(255,100,100)); 
  2. SelectObject(hdc,pen); 

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

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

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

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

[cpp] view plaincopyprint?
  1. MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2+50,NULL); 
  2. LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2+50); 

程序源码

运行结果:

程序源码


[cpp] view plaincopyprint?
  1. #include<windows.h> 
  2. #include"resource.h" 
  3.  
  4. HINSTANCE hinstance; 
  5.  
  6. LRESULT CALLBACK textprom( 
  7.   HWND hwnd,     // handle to window 
  8.   UINT uMsg,     // message identifier 
  9.   WPARAM wParam, // first message parameter 
  10.   LPARAM lParam  // second message parameter 
  11. ); 
  12.  
  13. int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance 
  14.   HINSTANCE hPrevInstance, // handle to previous instance 
  15.   LPSTR lpCmdLine,     // pointer to command line 
  16.   int nCmdShow         // show state of window 
  17.     WNDCLASS wndclass; 
  18.     HWND hwnd; 
  19.     MSG msg; 
  20.  
  21.     //设计窗口类 
  22.     wndclass.cbClsExtra=0; 
  23.     wndclass.cbWndExtra=0; 
  24.     wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); 
  25.     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW); 
  26.     wndclass.hIcon=LoadIcon(NULL,IDI_ERROR); 
  27.     wndclass.hInstance=hInstance; 
  28.     wndclass.lpfnWndProc=textprom; 
  29.     wndclass.lpszClassName="text"
  30.     wndclass.lpszMenuName=NULL; 
  31.     wndclass.style=CS_HREDRAW | CS_VREDRAW; 
  32.      
  33.     //注册窗口类 
  34.     if(!RegisterClass(&wndclass)) 
  35.     { 
  36.         MessageBox(NULL,"create windows error!","error",MB_OK | MB_ICONSTOP); 
  37.     } 
  38.  
  39.     //创建无菜单资源的窗口窗口 
  40.     hwnd=CreateWindow("text","hellow world",WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU,0,0,500,300,NULL,NULL,hInstance,NULL); 
  41.  
  42.  
  43.     //显示更新窗口 
  44.     ShowWindow(hwnd,nCmdShow); 
  45.     UpdateWindow(hwnd); 
  46.  
  47.     hinstance = hInstance; 
  48.  
  49.     //消息循环 
  50.     while(GetMessage(&msg,NULL,0,0)) 
  51.     { 
  52.         TranslateMessage(&msg); 
  53.         DispatchMessage(&msg); 
  54.     } 
  55.  
  56.     return msg.wParam; 
  57.  
  58. LRESULT CALLBACK textprom( 
  59.   HWND hwnd,     // handle to window 
  60.   UINT uMsg,     // message identifier 
  61.   WPARAM wParam, // first message parameter 
  62.   LPARAM lParam  // second message parameter 
  63.     HDC hdc,hcmdc; 
  64.     PAINTSTRUCT ps; 
  65.     RECT rect; 
  66.     HBITMAP hBmp; 
  67.     SIZE   size; 
  68.     BITMAP bmp; 
  69.     HPEN pen; 
  70.  
  71.     switch(uMsg) 
  72.     { 
  73.     //重绘事件 
  74.     case WM_PAINT: 
  75.         hdc=BeginPaint(hwnd,&ps); 
  76.         //显示文本 
  77.         GetClientRect(hwnd,&rect); 
  78.         DrawText(hdc,"hellow my first windows program",strlen("hellow my first windows program"),&rect, 
  79.             DT_SINGLELINE | DT_CENTER | DT_VCENTER); 
  80.         //画笔 
  81.         MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2-50,NULL); 
  82.         LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2-50); 
  83.         pen = CreatePen(PS_DOT,3,RGB(255,100,100)); 
  84.         SelectObject(hdc,pen); 
  85.         MoveToEx(hdc,(rect.left+rect.right)/2-130,(rect.top+rect.bottom)/2+50,NULL); 
  86.         LineTo(hdc,(rect.left+rect.right)/2+130,(rect.top+rect.bottom)/2+50); 
  87.         EndPaint(hwnd,&ps); 
  88.         break
  89.     //绘制圆角矩形 
  90.     case WM_LBUTTONDOWN: 
  91.         hdc = GetDC(hwnd); 
  92.         RoundRect(hdc,10,10,110,60,10,10); 
  93.         ReleaseDC(hwnd,hdc); 
  94.         break
  95.     //贴图 
  96.     case WM_RBUTTONDOWN: 
  97.         hdc = GetDC(hwnd); 
  98.         hBmp = LoadBitmap(hinstance,MAKEINTRESOURCE(IDB_BITMAP1)); 
  99.         hcmdc = CreateCompatibleDC(hdc); 
  100.         SelectObject(hcmdc,hBmp);     
  101.         GetClientRect(hwnd,&rect); 
  102.         GetObject(hBmp, sizeof(BITMAP), &bmp); 
  103.         StretchBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 
  104.         //BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom-rect.top,hcmdc,0,0,SRCCOPY); 
  105.         ReleaseDC(hwnd,hdc); 
  106.         break
  107.     case WM_DESTROY: 
  108.         PostQuitMessage(0); 
  109.         break
  110.     } 
  111.     return DefWindowProc(hwnd,uMsg,wParam,lParam);