[StructLayout (LayoutKind.Sequential)] public class POINT { public int x; public int y; }
public class Apis { [DllImport("USER32.DLL", EntryPoint = "GetDC")] public static extern IntPtr GetDC(IntPtr hwnd); [DllImport("USER32.DLL", EntryPoint = "ReleaseDC")] public static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc); [DllImport("GDI32.DLL", EntryPoint = "SetROP2")] public static extern IntPtr SetROP2(IntPtr hdc, R2 nDrawMode); //该函数创建一个具有指定颜色的逻辑刷子 [DllImport("GDI32.DLL", EntryPoint = "CreateSolidBrush")] public static extern IntPtr CreateSolidBrush(IntPtr hdc, long crColor); //为指定的设备场景指定一个新的当前画笔位置。前一个位置保存在lpPoint中 [DllImport("GDI32.DLL", EntryPoint = "MoveToEx")] public static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, POINT p); //用当前画笔画一条线,从当前位置连到一个指定的点。这个函数调用完毕,当前位置变成x,y点 [DllImport("GDI32.DLL", EntryPoint = "LineTo")] public static extern IntPtr LineTo(IntPtr hdc, int x, int y); //用当前选定的画笔描绘矩形,并用当前选定的刷子进行填充 [DllImport("GDI32.DLL", EntryPoint = "Rectangle")] public static extern IntPtr Rectangle(IntPtr hdc, int x1, int y1, int x2, int y2); }
class MainForm : System.Windows.Forms.Form { bool isStart = false; Point current; Point temp; IntPtr hdc;
public MainForm() { InitializeComponent(); }
// This method is used in the forms designer. // Change this method on you own risk void OnMyMouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
if(!isStart) { isStart = true; current = new Point(e.X, e.Y); temp = new Point(e.X, e.Y); hdc = Apis.GetDC(this.Handle); Apis.SetROP2(hdc, R2.R2_NOT); } else { MyDrawLine(current, temp); MyDrawLine(current, new Point(e.X, e.Y)); Apis.ReleaseDC(this.Handle, hdc); isStart = false; } }
参看
http://www.codeproject.com/csharp/flicker_free.asp
里面有用Bitblt的例子,但不是XOR划线的,但是调用方法一样。
......
ControlPaint.DrawReversibleLine(s, e, Color.Empty);
{
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public enum R2 : int
{
// R2_NOT = 6,
// R2_NOTXORPEN = 10,
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
}
[StructLayout (LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}
public class Apis
{
[DllImport("USER32.DLL", EntryPoint = "GetDC")]
public static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("USER32.DLL", EntryPoint = "ReleaseDC")]
public static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);
[DllImport("GDI32.DLL", EntryPoint = "SetROP2")]
public static extern IntPtr SetROP2(IntPtr hdc, R2 nDrawMode);
//该函数创建一个具有指定颜色的逻辑刷子
[DllImport("GDI32.DLL", EntryPoint = "CreateSolidBrush")]
public static extern IntPtr CreateSolidBrush(IntPtr hdc, long crColor);
//为指定的设备场景指定一个新的当前画笔位置。前一个位置保存在lpPoint中
[DllImport("GDI32.DLL", EntryPoint = "MoveToEx")]
public static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, POINT p);
//用当前画笔画一条线,从当前位置连到一个指定的点。这个函数调用完毕,当前位置变成x,y点
[DllImport("GDI32.DLL", EntryPoint = "LineTo")]
public static extern IntPtr LineTo(IntPtr hdc, int x, int y);
//用当前选定的画笔描绘矩形,并用当前选定的刷子进行填充
[DllImport("GDI32.DLL", EntryPoint = "Rectangle")]
public static extern IntPtr Rectangle(IntPtr hdc, int x1, int y1, int x2, int y2);
}
class MainForm : System.Windows.Forms.Form
{
bool isStart = false;
Point current;
Point temp;
IntPtr hdc;
public MainForm()
{
InitializeComponent();
}
// This method is used in the forms designer.
// Change this method on you own risk
void OnMyMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(!isStart)
{
isStart = true;
current = new Point(e.X, e.Y);
temp = new Point(e.X, e.Y);
hdc = Apis.GetDC(this.Handle);
Apis.SetROP2(hdc, R2.R2_NOT);
}
else
{
MyDrawLine(current, temp);
MyDrawLine(current, new Point(e.X, e.Y));
Apis.ReleaseDC(this.Handle, hdc);
isStart = false;
}
}
void OnMyMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(isStart)
{
MyDrawLine(current, temp);
MyDrawLine(current, new Point(e.X, e.Y));
temp = new Point(e.X, e.Y);
}
}
void MyDrawLine(Point pt1, Point pt2)
{
Apis.MoveToEx(hdc, pt1.X, pt1.Y, null);
// Apis.CreateSolidBrush(hdc,100); // Apis.Rectangle(hdc, pt1.X, pt1.Y,pt2.X, pt2.Y);
// Apis.CreateSolidBrush(hdc,100);
Apis.LineTo(hdc, pt2.X, pt2.Y);
}
void InitializeComponent()
{
this.SuspendLayout();
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
this.ClientSize = new System.Drawing.Size(608, 453);
this.Cursor = System.Windows.Forms.Cursors.Cross;
this.Name = "MainForm";
this.Text = "This is my form";
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OnMyMouseUp);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMyMouseMove);
this.ResumeLayout(false);
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new MainForm());
}
}
}