invalidaterect(invalidaterect Delphi)

张工 2022-07-12 18:09:36 阅读:43
  

Windows GDI绘图基础知识

   I. Windows可以画直线、椭圆线(椭圆圆周上的曲线)和贝塞尔曲线。

  ////////////7 个画线函式是:

  (1)画直线

  LineTo BOOL LineTo(HDC hdc,int nXEnd,int nYEnd);

  将bool MoveToEx (hdc hdc,int x,int y,LP point LP point)与MoveToEx函数结合使用。

  点记录了旧的坐标点(以前的当前位置)。

  ///注:getcurrentpositonex(hdc,pt);获取当前位置。

  (2)画一系列相连的直线。

  折线将点阵列的点连接成一条线。代替使用当前点作为起点,

  PolylineTo使用当前点作为起点,并将当前位置设置为最后一条线的终点。

  多边形绘制多组相连的线。

  (3)填充矩形

  矩形画一个矩形,用白色画笔填充。矩形(HDC、XLEFT、YTOP、XRight、Ybotom)

  椭圆绘制一个椭圆,并用白色画笔填充。椭圆(hdc,xleft,ytop,xright,ybottom)

  绘制一个圆形矩形。并用白色画笔填充圆形(hdc,XL,yt,xr,Yb,xc,YC)。

  XC,yC是圆角矩形的圆角。

  画一条椭圆线。Arc (hdc、xLeft、yTop、xRight、yBottom、xStart、yStart、xEnd、yEnd)

  和弦弓和弦(HDC、XLEFT、YTOP、XRight、Ybotom、XStart、YStart、Xend、Yend)

  饼图绘制饼图饼图(HDC,XLEFT,YTOP,XRight,Ybotom,XStart,YStart,Xend,Yend);

  以和角度弧绘制椭圆线。

  //////多边形

  多边形(hdc,apt,iCount);//绘制最后一个点与第一个点相连的多边形。

  PolyPolygon(hdc,apt,aiCount,iPolyCount);//绘制多个多边形。

  (4)贝塞尔曲线,画贝塞尔曲线

  NYAPT [4]=(起点,第一个控制点,第二个控制点,终点)

  需要注意的是:曲线是起点到终点的连接曲线,控制点(调整点)不在其中,

  PolyBezier (hdc、apt、icount)

  PolyBezierTo (hdc,apt,icount).使用当前点作为起点

  PolyDraw绘制一系列相连的直线和贝塞尔曲线。

  对于很多贝塞尔曲线来说,后一条的起点就是前一条的终点。

  (5)矩形函数

  FillRect(hdc,Rect,HB rush);//用指定的画笔填充矩形,(不包括(Right,buttom) frameret (HDC,rect,hbrush);//使用画笔填充矩形框,而不是矩形,

  InvertRect(hdc,rect);//使像素翻转,白到黑,黑到白,绿到红。

  //////Rect上的操作

  SetRect(rect,xLeft,yTop,xRight,yButtom);//赋值

  OffsetRect(rect,x,y);//沿x,y方向移动

  InflateRect勃起(Rect,x,y);//增大或减小矩形的大小。

  setrectpempty(rect);//设置为0

  CopyRect(A,B);将b复制到a。

  IntersectRect(A、B1、B2);//将B1和B2的交集复制到a .

  UnionRect(A、B1、B2);//取联合

  bEmpty=IsRectEmpty(Rect);//确定矩形是否为空。

  blnRect=PtlnRect(Rect,point);//确定该点是否在矩形中。

img_width="1198" img_height="898" alt="Windows高级工程师:GDI/GDI+绘图;基础入门大全" >


  二、映像坐标

  1)、视口:设备坐标(像素)
窗口:逻辑坐标,像素、mm、英寸
视口(设备)坐标转换为窗口(逻辑)坐标:
公式:一般不用记,有专门的函数。
xWindow=(xViewport - xViewOrg) * xWinExt/xViewExt +xWinOrg
yWindow=(yViewport - yViewOrg) * yWinExt/yViewExt +yWinOrg

  (xWindow,yWindow) 转换后的窗口坐标
(xViewport,yViewport)待转换的视口坐标
(xWinExt,yWinExt)是逻辑座标的视窗范围;
(xViewExt,yViewExt)是装置座标的视窗范围。
(xWinOrg,yWinOrg)是逻辑座标的窗口原点;
(xViewOrg,yViewOrg)是装置座标的视口原点

  2)、设备点转化为逻辑点
DPtoLP (hdc, pPoints, iNumber);pPoints 结构阵列的指标,而iNumber 是要转换的点的个数
例如:
GetClientRect (hwnd, &rect) ;
DPtoLP (hdc, (PPOINT) &rect, 2) ;

  将逻辑点转换为装置点:
LPtoDP (hdc, pPoints, iNumber) ;

  3)、SetMapMode(hdc,iMapMode); //设置映射方式。
默认:MM_TEXT:每个逻辑单位转换为一个图素,X正方向向右,Y正方向向下。
原点可以改变,范围不可改变
SetWindowOrgEx(); //设置设备环境的原点
SetViewprocOrgEx(); //设置客户区中心
//
//原点和范围都可以改变、
MM_ANISOTROPIC:逻辑单位转换成具有任意比例轴的任意单位,用SetWindowExtExSetViewportExtEx函数可指定单位、方向和比例。

  //原点可以改变,范围不可以改变,X的正方面向右,Y的正方向向上。
MM_HIENGLISH:每个逻辑单位转换为0.001英寸,X的正方面向右,Y的正方向向上。
MM_HIMETRIC:每个逻辑单位转换为0.01毫米,X正方向向右,Y的正方向向上。
MM_ISOTROPIC:逻辑单位转换成具有均等比例轴的任意单位,即沿X轴的一个单位等于沿Y轴的一个单位,用和函数可以指定该轴的单位和方向。图形设备界面(GDI)需要进行调整,以保证X和Y的单位保持相同大小(当设置窗口范围时,视口将被调整以达到单位大小相同)。
MM_LOENGLISH:每个逻辑单位转换为0.01英寸,X正方向向右,Y正方向向上。
MM_LOMETRIC:每个逻辑单位转换为0.1毫米,X正方向向右,Y正方向向上。
MM_TWIPS;每个逻辑单位转换为打印点的1/20(即1/1400英寸),X正方向向右,Y方向向上。


Windows高级工程师:GDI/GDI+绘图;基础入门大全


  三、GDI 对象

  画笔、刷子、位图、区域、字体、调色板是可以创建的6种GDI对象。
GetStockObject(obj);获取对象的句柄。
DeleteObject(obj); 删除对象。(注意不能在有效的设备描述表中删除。)
除调色板外,其他对象都是通过SelectObject(hdc,obj);选入设备描述表中。
GetObject(HOBJ,size,lpObj); lpObj可以是下列的结构体。获取对象信息、
BITMAP //位图
DIBSECTION //位图
EXTLOGPEN //画笔
LOGBRUSH //刷
LOGFONT //字体
LOGPEN //画笔
(1)画笔(Pen) windows的默认值:BLACK_PEN
创建:
方法一:hPen=CreatePen(iPenStyle,iWidth,crColor);
iPenStyle的参数:PS_SOLID 实心画笔
PS_DASH 破折号画笔(在iWidth<1有效,否则系统会用实心笔替代)
PS_DOT 虚线(在iWidth<1有效,否则系统会用实心笔替代)
PS_DASHDOT 点划线(在iWidth<1有效,否则系统会用实心笔替代)
PS_DASHDOTDOT 双重点划线(在iWidth<1有效,否则系统会用实心笔替代)
PS_NULL 空白笔
PS_INSIDEFRAME 粗实线,当iWidth>1可以使用抖动色(不只是纯色)

  方法二:LOGPEN logpen //指定笔颜色、大小、类型的结构体。同上。
hPen=CreatePenIndirect(&logpen);


Windows高级工程师:GDI/GDI+绘图;基础入门大全


  (2)字体(Font) 默认值:SYSTEM_FONT
创建:
一:CreateFont
只用到2个参数,其他都为0,例:CreateFont (0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL)
HFONT CreateFont(
int nHeight, // 字符宽度,逻辑单位
int nWidth, //
int nEscapement, // 斜放置字符串
int nOrientation, // 字符倾斜的角度,影响单个字符
int fnWeight, // 粗体。0―400标准,700粗体
DWORD fdwItalic, // 斜体
DWORD fdwUnderline, // 下划线
DWORD fdwStrikeOut, // 删除线
DWORD fdwCharSet, // 1为默认值。指定字体字符集一个字节的值(*不用理会)
DWORD fdwOutputPrecision, // 输出精度*
DWORD fdwClipPrecision, // 裁剪精度*
DWORD fdwQuality, // 期望匹配字体*
DWORD fdwPitchAndFamily, // 字体族*
LPCTSTR lpszFace // 字样*
);

字体:
SYSTEM_FONT
SYSTEM_FIXED_FONT
OEM_FIXED_FONT

  ANSI_FIXED_FONT、
ANSI_VAR_FONT
DEVICE_DEFAULT_FONT

  其中: WM_INPUTLANGCHANGE: dwCharSet = wParam ;
二:LOGFONT logfont;
CreateFontIndirect(&logfont);

  (3)刷子(Brush) 默认值::WHITE_BRUSH
系统的刷子: WHITE_BRUSH
LTGRAY_BRUSH 亮灰
GRAY_BRUSH 灰
DKGRAY_BRUSH 黑灰
BLACK_BRUSH
创建:
一:hBrush=CreateSolidBrush(crColor);
二:hBrush=CreateHatchBrush(iHatchStyle,crColor);//创建有影线的刷子填充部分为阴影
其中:iHatchStyle的参数如下:
HS_BDIAGONAL 45度的斜线、
HS_CROSS 十字型的线、
HS_DIAGCROSS ×型
HS_FDIAGONAL 135度斜线
HS_HORIZONTAL 水平
HS_VERTICAL 垂直
三:LOGBRUSH logbrush
CreateBrushIndirect(&logbrush);
四: hBrush=CreatePatternBrush(HBITMAP hbmp);//创建位图的刷子、
五:hBrush=CreateDIBPatternBrushPt;//创建DIB位图的刷子。
CreateDIBPatternBrush,

  (4)位图(Bitmap)默认值:None(无);

CreateBitmap,
CreateBitmapIndirect,
CreateCompatibleBitmap,
CreateDIBitmap,
CreateDIBSection
CreateSolidBrush
第一种::
HBITMAP CreateBitmap(
int nWidth, // 宽
int nHeight, // 高
UINT cPlanes, // 颜色板的数目
UINT cBitsPerPel, // 没像素的位数。
CONST VOID *lpvBits // 指向颜色数据数组指针。这些颜色数据用来设置矩形区域内像素的颜色。矩形区域中的每一扫描线必须是双字节的整数倍(不足部分以0填充)。如果该参数为NULL,那么就表示没有定义新位图。
);

  //简化版
HBITMAP CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight );

  //第二种
HBITMAP CreateBitmapIndirect(&bitmap);bitmap是BITMAP结构体

  (5)区域(Region)区域是对显示器上一个范围的描述,这个范围是矩形、多边形和椭圆的组合,把区域选进设备描述表,区域可以用于绘制和剪裁。
作用:iRgnType=CombineRgn(hRgn,hRgn1,hRgn2,iCombine);
iCombine的参数:
RGN_AND 两个源区域的公共部分
RGN_OR 全部
RGN_XOR 除去公共部分。
RGN_DIFF hRgn1不在hRgn2的部分
RGN_COPY hRgn1的全部。(忽略hRgn2);
iRgnType的参数:
NULLREGION 得到空区域
SIMPLEREGION 得到简单的矩形、椭圆或多边形
COMPLEXREGION 多个多边形、矩形、椭圆的组合
ERROR 出错
创建:
一:创建矩形区域:
hRgn = CreateRectRgn (xLeft, yTop, xRight, yBottom) ;
hRgn = CreateRectRgnIndirect (&rect) ;
二: 创建椭圆剪裁区域;
hRgn = CreateEllipticRgn (xLeft, yTop, xRight, yBottom) ;//
hRgn = CreateEllipticRgnIndirect (&rect) ;
三;创建多边形剪裁区域
hRgn = CreatePolygonRgn (&point, iCount, iPolyFillMode) ;

  ///////////////////////////////////////////////////////////
矩形与区域的剪裁
对于矩形;
InvalidateRect (hwnd, NULL, TRUE) ;//使矩形无效
GetUpdateRect 来取得失效矩形的座标或WM_PAINT中从PAINTSTRUCT结构中得到
ValidateRect使有效
对于区域:
InvalidateRgn (hwnd, hRgn, bErase) ;
ValidateRgn (hwnd, hRgn) ;

  SelectObject(hdc,hRgn); 或SelectClipRgn(hdc,hRgn);选进设备描述表
ExcludeClipRect用於将一个矩形从剪裁区域里排除掉,
IntersectClipRect 用於建立一个新的剪裁区域,它是前一个剪裁区域与一个矩形的交,OffsetClipRgn 用於将剪裁区域移动到显示区域的另一部分。

  四、设备描述表

  理解1:设备描述表中包含许多确定的GDI函数如何在设备上工作的当前属性。这些属性允许传递给GDI函数的参数只包含其实坐标或者尺寸信息,而不包含Windows在设备上显示对象时需要的所以其他信息、

  理解2:一个设备描述表通常指一个物理显示设备。如视频显示器或打印机。

  理解3:设备描述表(简称DC)实际上是GDI内部保存的数据结构。有些值是图形化的“属性”,这些属性定义了一些GDI绘图函数的工作,例如:文本颜色,文本的背景、TextOut函数的X坐标,y坐标映射到窗口客户区的方式,还有windows显示的字体、

  //////////////////////////////////获取句柄hdc

  (1)注意这不能使无效区域变的有效
hdc=GetDC(hwnd);
//////
ReleaseDC(hwnd,hdc);

  (2)在处理WM_PAINT消息时使用。能使无效区域变的有效、重绘。
hdc=BeginPaint(hwnd,&ps);
/////////
EndPaint(hwnd,&ps);

  (3)能获得非客户区的绘制消息。包括窗口的标题栏,菜单栏,和滚动条、框架等。
在WM_NCPAINT中处理、
hdc=GetWindowDC(hwnd);
//////
ReleaseDC(hwnd,hdc);

  (4)通用获得DC的方法。视频显示器或者打印机上的DC.
hdc=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL); //获得整个屏幕的dc
//////////////
DeleteDC(hdc);

  (5)获得一个dc,其参数与CreateDC的参数相同。但是不能用这个信息环境句柄往设备描述表上写东西。////特别 注意。
hdc=CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);
/////////
DeleteDC (hdc);

  (6)可以把位图选进内部设备描述表。然后用GDI 函数在位图上绘画。
hdcMem=CreateCompatibleDC(hdc); //位图选进内部设备描述表
///////////
DeleteDC (hdcMem);

  (7)获取元文件的设备描述表来创建元文件。
hdcMeta=CreateMetaFile(pszFilename);
//////////
hmf=ColseMetaFile(hdcMeta)

  /////////////////////获取信息
(8)获取视频显示器的尺寸,色彩等信息。
int iValue=GetDeviceCaps(hdc,ilndex);

  ///////////////////保存设备描述表。
(9) SaveDC(hdc);可以保存多次、RestoreDC(hdc,-1);恢复DC
五、设备描述表属性

  1)一些空间隔的填充。如点和虚线之间的间隔填充。
背景模式:使用SetBkMode(hdc,iBkMode)修改
(1)OPAQUE(系统默认值),间隔使用背景颜色填充。
修改:SetBkColor(hdc,crColor); //修改背景色
GetBkColor(hdc); 获取背景色
(2)TRANSPARENT 不填充间隔 ,不擦除背景,透明模式

  2)绘图方式:
用画笔进行绘图实际是画笔像素与目标位置处原来像素之间的某种布尔值运算。
默认值::R2_COPYPEN;
修改:
SetROP2(hdc,iDrawMode);
获取:
iDrawMode=GetROP2(hdc);

二维码