GDI+.NET 1.0Visual Studio .NET 2003Windows 2003.NET 1.1Windows 2000Windows XPMFC中级开发Visual StudioWindowsC++.NETC#
使用 GDI 和 GDI+ 混合绘制橡皮筋线条






3.52/5 (18投票s)
2003年6月24日

128730

1772
使用 GDI 和 GDI+ 混合,在 GDI+ 中绘制橡皮筋线
引言
正如每位程序员所知,绘制自擦除线条最简单、最快速的方法是使用 XOR 模式绘制线条。但在 .NET 中,我没有看到任何可以绘制自擦除线条的方法,因此我被迫以混合模式使用 GDI 和 GDI+。我认为,使用 GDI+ 没有办法绘制自擦除线条。我见过一些发明的方法来绘制自擦除线条,但其中大部分都使用 BitBlt
或将整个屏幕推送到缓冲区,然后弹出缓冲区来擦除它们。
代码
/* to be example to the xoring problem
* i ve written a simple namespace to referance to standat GDI.
* But the GDIDraw namespace
* doesnt referance to whole methots such as drawing
* rectangles or other shapes
* but can easily be enhanged if necessary */
namespace GDIDraw
{
public enum PenStyles
{
PS_SOLID=0
,PS_DASH=1
,PS_DOT=2
,PS_DASHDOT=3
,PS_DASHDOTDOT=4
,PS_NULL=5
,PS_INSIDEFRAME=6
,PS_USERSTYLE=7
,PS_ALTERNATE=8
,PS_STYLE_MASK=0x0000000F
,PS_ENDCAP_ROUND= 0x00000000
,PS_ENDCAP_SQUARE= 0x00000100
,PS_ENDCAP_FLAT= 0x00000200
,PS_ENDCAP_MASK = 0x00000F00
,PS_JOIN_ROUND= 0x00000000
,PS_JOIN_BEVEL= 0x00001000
,PS_JOIN_MITER= 0x00002000
,PS_JOIN_MASK= 0x0000F000
,PS_COSMETIC= 0x00000000
,PS_GEOMETRIC= 0x00010000
,PS_TYPE_MASK= 0x000F0000
}
public enum drawingMode
{
R2_BLACK= 1 /* 0 */
,R2_NOTMERGEPEN= 2 /* DPon */
,R2_MASKNOTPEN= 3 /* DPna */
,R2_NOTCOPYPEN= 4 /* PN */
,R2_MASKPENNOT= 5 /* PDna */
,R2_NOT= 6 /* Dn */
,R2_XORPEN= 7 /* DPx */
,R2_NOTMASKPEN= 8 /* DPan */
,R2_MASKPEN= 9 /* DPa */
,R2_NOTXORPEN= 10 /* DPxn */
,R2_NOP= 11 /* D */
,R2_MERGENOTPEN= 12 /* DPno */
,R2_COPYPEN= 13 /* P */
,R2_MERGEPENNOT= 14 /* PDno */
,R2_MERGEPEN= 15 /* DPo */
,R2_WHITE= 16 /* 1 */
,R2_LAST= 16
}
public class GDI
{
private IntPtr hdc;
private System.Drawing.Graphics grp;
public void BeginGDI(System.Drawing.Graphics g)
{
grp=g;
hdc=grp.GetHdc();
}
public void EndGDI()
{
grp.ReleaseHdc(hdc);
}
public IntPtr CreatePEN(
PenStyles fnPenStyle, // pen style
int nWidth, // pen width
int crColor // pen color
)
{
return CreatePen(fnPenStyle,nWidth,crColor);
}
public bool DeleteOBJECT(IntPtr hObject)
{
return DeleteObject(hObject);
}
public IntPtr SelectObject(
IntPtr hgdiobj // handle to object
)
{
return SelectObject(hdc,hgdiobj);
}
public void MoveTo(int X,int Y)
{
MoveToEx(hdc,X,Y,0);
}
public void LineTo(int X,int Y)
{
LineTo(hdc,X,Y);
}
public int SetROP2(drawingMode fnDrawMode)
{
return SetROP2(hdc,fnDrawMode);
}
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern int SetROP2(
IntPtr hdc, // handle of device context
drawingMode fnDrawMode // drawing mode
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern bool MoveToEx(
IntPtr hdc, // handle to device context
int X, // x-coordinate of new current position
int Y, // y-coordinate of new current position
int oldp// pointer to old current position
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern bool LineTo(
IntPtr hdc, // device context handle
int nXEnd, // x-coordinate of line's ending point
int nYEnd // y-coordinate of line's ending point
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern IntPtr CreatePen(
PenStyles fnPenStyle, // pen style
int nWidth, // pen width
int crColor // pen color
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject
// handle to graphic object
);
[System.Runtime.InteropServices.DllImportAttribute(
"gdi32.dll")]
private static extern IntPtr SelectObject(
IntPtr hdc, // handle to device context
IntPtr hgdiobj // handle to object
);
public static int RGB(int R,int G,int B)
{
return (R|(G<<8)|(B<<16));
}
}
}