也是通过API函数实现,codeproject有例子,不过我觉得在C#下用双缓冲技术比较好

解决方案 »

  1.   

    英雄!能再多给点提示吗?codeproject在哪?
      

  2.   

    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;
    }
    }

    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());
    }
    }
    }
      

  3.   

    不会吧!全得用API,那GDI+没用啦?
      

  4.   

    GDI+是无状态的...
    有没有别的办法我不知道。
    codeproject上的皮筋线文章我看过,觉得不好。
      

  5.   

    建议还是使用双缓冲技术吧,功能很强大,我想你既然用了C#来做,会允许速度上不如VC的
      

  6.   

    我实现双缓冲的具体步骤:1、 在内存中建立一块“虚拟画布”:Bitmap bmp = new Bitmap(600, 600);2、 获取这块内存画布的Graphics引用:Graphics g = Graphics.FromImage(bmp);3、 在这块内存画布上绘图:g.FillEllipse(brush, i * 10, j * 10, 10, 10);4、将内存画布画到窗口中this.CreateGraphics().DrawImage(bmp, 0, 0);
    但到第三步还显示不出来,第四步显示出来了却又没法擦掉重绘了,迷糊兄再指点一下
      

  7.   

    双缓冲方式我理解是用缓冲绘图区保存某一时刻的图形,画面绘图时相结合不断擦除显示
    看起来就如同异或模式画出的一样,我参照网站上提供的]AVA程序用C#写了一个,但老不
    成功,有没有哪位好心人,各个小demo指点一下?
      

  8.   

    // 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)
    {

    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。