namespace MyTest.Win32 { using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices;
public enum R2 : int { R2_NOT = 6, R2_NOTXORPEN = 10 }
[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 = "MoveToEx")] public static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, POINT p); [DllImport("GDI32.DLL", EntryPoint = "LineTo")] public static extern IntPtr LineTo(IntPtr hdc, int x, int y); }
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; } }
// project created on 2003-5-4 at 14:44 using System; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.Windows.Forms;namespace MyFormProject { class DoubleBufferForm : System.Windows.Forms.Form { Bitmap bmpOrigin; Bitmap bmpTarget; bool isStart =false;
// below code from www.codeproject.com [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")] private static extern bool BitBlt( IntPtr hdcDest, // handle to destination DC int nXDest, // x-coord of destination upper-left corner int nYDest, // y-coord of destination upper-left corner int nWidth, // width of destination rectangle int nHeight, // height of destination rectangle IntPtr hdcSrc, // handle to source DC int nXSrc, // x-coordinate of source upper-left corner int nYSrc, // y-coordinate of source upper-left corner System.Int32 dwRop // raster operation code ); // end
public DoubleBufferForm() { InitializeComponent(); Invalidate(); }
// THIS METHOD IS MAINTAINED BY THE FORM DESIGNER // DO NOT EDIT IT MANUALLY! YOUR CHANGES ARE LIKELY TO BE LOST void DoubleBufferFormMouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
{
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public enum R2 : int
{
R2_NOT = 6,
R2_NOTXORPEN = 10
}
[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 = "MoveToEx")]
public static extern IntPtr MoveToEx(IntPtr hdc, int x, int y, POINT p);
[DllImport("GDI32.DLL", EntryPoint = "LineTo")]
public static extern IntPtr LineTo(IntPtr hdc, int x, int y);
}
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.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());
}
}
}
有没有别的办法我不知道。
codeproject上的皮筋线文章我看过,觉得不好。
但到第三步还显示不出来,第四步显示出来了却又没法擦掉重绘了,迷糊兄再指点一下
看起来就如同异或模式画出的一样,我参照网站上提供的]AVA程序用C#写了一个,但老不
成功,有没有哪位好心人,各个小demo指点一下?
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Forms;namespace MyFormProject
{
class DoubleBufferForm : System.Windows.Forms.Form
{
Bitmap bmpOrigin;
Bitmap bmpTarget;
bool isStart =false;
// below code from www.codeproject.com
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, // handle to destination DC
int nXDest, // x-coord of destination upper-left corner
int nYDest, // y-coord of destination upper-left corner
int nWidth, // width of destination rectangle
int nHeight, // height of destination rectangle
IntPtr hdcSrc, // handle to source DC
int nXSrc, // x-coordinate of source upper-left corner
int nYSrc, // y-coordinate of source upper-left corner
System.Int32 dwRop // raster operation code
);
// end
public DoubleBufferForm()
{
InitializeComponent();
Invalidate();
}
// THIS METHOD IS MAINTAINED BY THE FORM DESIGNER
// DO NOT EDIT IT MANUALLY! YOUR CHANGES ARE LIKELY TO BE LOST
void DoubleBufferFormMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(!isStart)
{
DrawTargetBitmap();
GetOriginBitmap();
Graphics g = this.CreateGraphics();
g.DrawImage(bmpTarget, e.X, e.Y);
g.Dispose();
isStart = true;
}
else
{
Graphics g = this.CreateGraphics();
g.DrawImage(bmpTarget, e.X, e.Y);
g.Dispose();
bmpTarget.Dispose();
bmpOrigin.Dispose();
isStart = false;
}
}
void DoubleBufferFormMouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if(isStart)
{
Graphics g = this.CreateGraphics();
g.DrawImage(bmpOrigin, 0, 0);
g.DrawImage(bmpTarget, e.X, e.Y);
g.Dispose();
}
}
void GdiPlusDrawLines()
{
Graphics g = this.CreateGraphics();
Pen pen1 = new Pen(Color.Red, 2);
Pen pen2 = new Pen(Color.Blue, 2);
pen2.DashStyle = DashStyle.DashDotDot;
g.DrawLine(pen1, new Point(0,0), new Point(this.ClientRectangle.Right, this.ClientRectangle.Bottom));
g.DrawLine(pen2, new Point(this.ClientRectangle.Right, 0), new Point(0, this.ClientRectangle.Bottom));
pen1.Dispose();
pen2.Dispose();
g.Dispose();
}
void DrawTargetBitmap()
{
Graphics g;
bmpTarget = new Bitmap(200,200);
g = Graphics.FromImage(bmpTarget);
Brush brush = new SolidBrush(Color.Red);
g.FillEllipse(brush, new Rectangle(0,0, 200, 200));
g.Dispose();
}
void GetOriginBitmap()
{
Graphics g = this.CreateGraphics();
bmpOrigin = new Bitmap(this.ClientSize.Width, this.ClientSize.Height, g);
Graphics og = Graphics.FromImage(bmpOrigin);
IntPtr hdc = g.GetHdc();
IntPtr ohdc = og.GetHdc();
BitBlt(ohdc, 0, 0, bmpOrigin.Width, bmpOrigin.Height, hdc, 0, 0, 0x00cc0020);
og.ReleaseHdc(ohdc);
og.Dispose();
g.ReleaseHdc(hdc);
g.Dispose();
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
g.Dispose();
GdiPlusDrawLines();
if(isStart)
{
bmpOrigin.Dispose();
GetOriginBitmap();
}
}
void InitializeComponent() {
this.SuspendLayout();
//
// DoubleBufferForm
//
this.BackColor = System.Drawing.SystemColors.AppWorkspace;
this.ClientSize = new System.Drawing.Size(576, 397);
this.Text = "Doubel Buffer Form";
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.DoubleBufferFormMouseUp);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DoubleBufferFormMouseMove);
this.ResumeLayout(false);
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new DoubleBufferForm());
}
}
}-----------------------------------------------------------------------------由于我在Gdi+中没有找到BitBlt对应的函数, 将屏幕客户区拷贝到后备bitmap中还得用API。