Click here to Skip to main content
15,879,326 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi there fellow coders!

I've ran into a GDI+ problem. I'm coding C# on .NET Framework 3.5. The problem I'm having is slow response in my application when drawing with my own-developed graphics tools. I'm drawing via the MouseMove events of a Control and the CreateGraphics() method on the Control, but first on my doublebuffer Image. It works great when I use the tools on small rectangles but when I increase the size the drawing goes down in fps to less than 1, using 2 screens on my computer.

What is the proper way to draw like im trying to do? I've tried Invalidate methods to improve performance with no luck. The problem if of course less when not doublebuffering, but then it is flickering and I get other problems like erasing the temporary rectangle when drawing so it don't leaves traces.

This is a video I made of the problem.
The quality isn't that good but you can still see the problem quite clear, the drawing is always behind the mouse, not like in other programs where the drawing seems instant.

http://screencast.com/t/ZDY3ZmRkM2I

Im sorry, I've tried your solutions but it still is slow in response. I made a small testform to try this and even that suffers from this problem I'm having. Neither of you mentioned how to make the drawing happen so I assumed via Invalidate() ?

Here is the code:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

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

    }

    Point down = Point.Empty;
    Point now = Point.Empty;

    Pen b = Pens.Black.Clone() as Pen;

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        if (down != Point.Empty)
            e.Graphics.DrawRectangle(b, down.X, down.Y, now.X - down.X, now.Y - down.Y);
    }

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        down = e.Location;
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        down = Point.Empty;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        now = e.Location;
        if(down != Point.Empty)
            this.Invalidate();
    }
}


When the form is small, the response is ok, but when enlarged it goes bananas. My next thought on this is, is it even possible to get it better than this without moving on to XNA or something else with acceleration?

Appreciate your efforts and tips very much, and the fast responds!
Posted
Updated 28-Jan-10 6:46am

Elof Wecksell wrote:
and the CreateGraphics() method on the Control, but first on my doublebuffer Image


Two bad moves. First, use the Paint event, second tell Winforms to double buffer for you.

VB
this.SetStyle( 

  ControlStyles.AllPaintingInWmPaint | 

  ControlStyles.UserPaint | 

  ControlStyles.DoubleBuffer,true);
 
Share this answer
 
It looks like you're creating a drawing program. The reason you're having such bad response times, is that your design is horribly flawed. CreateGraphics shouldn't need to be used, because it doesn't persist changes on minimise or resize.

I created a program somewhat like this a while ago, and it worked something like this:

  1. The user clicks and drags. The MouseDown event is invoked and the current location is stored, and a new DrawableRectangle instance is created and added to a list. When the user moves the mouse, the DrawableRectangle instance is altered (calculation of offsets, like you seem to be doing now)
  2. On the Paint event, iterate through every DrawableRectangle and paint them

You could make this more complex through inheritance, and support Undo through the use of a Stack instead of a list
 
Share this answer
 
Elof Wecksell wrote:
Im sorry, I've tried your solutions but it still is slow in response.


Then you've probably hit the limits of GDI+ and need to use XNA, etc, yes. you could try using WPF, that gives you DirectX for free, kind of.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900