可以用API实现,不过操作系统本身有好多缓冲,加一个内存DC的方法对闪烁并没有明显的改善,避免闪烁要根据具体情况设置最少的重画区,在重画函数中执行尽量少的绘图函数.

解决方案 »

  1.   

    this.SetStyle(ControlStyles.DoubleBuffer|ControlStyles.AllPaintingInWmPaint,true);
      

  2.   

    this.SetStyle(ControlStyles.DoubleBuffer|ControlStyles.AllPaintingInWmPaint,true);
      

  3.   


      public void DrawShapeOnForm(object sender,PaintEventArgs e)
     {
    Rectangle rect;
    Brush     brush;
    Pen       pen;
    Graphics  g;
    Bitmap    bitmap; rect   = form.ClientRectangle;
    bitmap = new Bitmap(rect.Width,rect.Height);
    g      = Graphics.FromImage(bitmap);

    brush  = new SolidBrush(form.BackColor);
    g.FillRectangle(brush,rect); pen = new Pen(form.ForeColor,1);
    foreach(Shape shape in Server.ShapeList)
    shape.Draw(g,pen);
    g.Flush();

    e.Graphics.DrawImage(bitmap,0,0);
    g.Dispose();
    brush.Dispose();
    pen.Dispose();
    } 先在另外一个Graphics对象里面画,然后画到窗体的Graphics上。
    程序用橡皮条方法画图形,重画的时候会产生闪烁,只要在刷新的时候不擦除背景就行了。[System.Runtime.InteropServices.DllImport("USER32.dll")]
    private extern static bool InvalidateRect(IntPtr hwnd,uint rect,bool erase);
    private void timer1_Tick(object sender, System.EventArgs e)
    {
    InvalidateRect(this.Handle,0,false);
    }还有,我的程序中需要把窗口的内容复制到一个Graphics对象中,我实在不知道用C#怎么实现,就用Visual C++写了个动态链接库来实现:#include <windows.h>HBITMAP CopyWindow(HWND hwnd)
    {
    HDC     hdc,hMemDC;
    RECT    rect;
    HBITMAP hBitmap = NULL;
    int     width,height; GetClientRect(hwnd,&rect);
    width  = rect.right  - rect.left;
    height = rect.bottom - rect.top; hdc = GetDC(hwnd); hMemDC = CreateCompatibleDC(hdc);
    hBitmap = CreateCompatibleBitmap(hdc,width,height);
    SelectObject(hMemDC,hBitmap); BitBlt(hMemDC,0,0,width,height,hdc,0,0,SRCCOPY); ReleaseDC(hwnd,hdc);
    DeleteDC(hMemDC); return hBitmap;
    }然后在C#中调用它:[System.Runtime.InteropServices.DllImport("CopyWindow.dll")]
    private extern static IntPtr CopyWindow(IntPtr hwnd);if (bitmap != null) bitmap.Dispose();
    bitmap = Bitmap.FromHbitmap(CopyWindow(this.Handle));
    画图时先把保存的窗口内容画上去,再画新的内容(很少),就不会闪烁了:
    g = Graphics.FromHwnd(this.Handle);
    g.DrawImage(bitmap,0,0);
    curshape.end = new Point(e.X,e.Y);
    pen = new Pen(this.ForeColor,1);
    curshape.DrawTemp(g,pen);
    我对Visual C++ 6.0下的API编程比较熟,但的确是C#新手,绝没有在此炫耀技术的意思。
    我只是想,不论用那种开发工具,Windows编程应该是相通的。