简体   繁体   English

具有高CPU使用率的GDI绘图应用程序

[英]GDI drawing application with high CPU usage

I have an application where the user draws some shapes. 我有一个应用程序,用户可以在其中绘制一些形状。 When I click over a shape and I drag it, the CPU goes 100% because of Invalidate() inside MouseMove. 当我单击某个形状并将其拖动时,由于MouseMove中的Invalidate(),CPU的运行速度为100%。 If I a use a timer and call Invalidate() from tick event the moving is not so smooth. 如果我使用计时器,并从滴答事件中调用Invalidate(),移动就不会那么顺利。 Is there any other approach to minimize CPU and have smooth moving? 还有其他方法可以最大程度地减少CPU并使移动平稳吗?

  ` Point startDragMousePoint;
    Point startShapeLocation;
    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if(isMouseDown)
        {
            Point deltaPoint = Point.Subtract(e.Location, new Size(startDragMousePoint));
            shape.Location = Point.Add(startShapeLocation, new Size(deltaPoint));
            Invalidate();
        }
    }

    private void Canvas_Paint(object sender, PaintEventArgs e)
    {
       shape.Render(e.Graphics);
    }`

There are three general solutions. 有三种通用解决方案。

1) Don't draw while your moving, this was the solution in windows for a long time, when you dragged a window, it just disapeard and you saw the outline of a window. 1)不要在移动时画图,这是很长一段时间以来在窗户上的解决方案,当您拖动窗户时,窗户消失了,您看到了窗户的轮廓。

2) Create a bitmap object and only move that. 2)创建一个位图对象,然后将其移动。 Note you will have to redraw the area under it. 请注意,您将不得不重新绘制其下方的区域。

3) Don't invalidate the hole window, just the area you are changing. 3)不要使孔窗口无效,仅使要更改的区域无效。 Drawing to a buffer (a bitmap) can help you reuse areas. 绘制到缓冲区(位图)可以帮助您重用区域。

Also, if GDI isn't the fastest drawing functions in the world. 另外,如果GDI不是世界上最快的绘图功能。 If your shape is very complex, you might want to consider using OpenGL, DirectX or SDL. 如果形状非常复杂,则可能需要考虑使用OpenGL,DirectX或SDL。

Instead of invalidating the entire area you could invalidate the portion of the control that has changed by using: 除了使整个区域无效之外,您还可以使用以下方法使已更改的控件部分无效:

Rectangle changedArea = new Rectangle(cX, cY, cW, cH);
this.Invalidate(changedArea);

Also make sure your control is set to use DoubleBuffering 还要确保您的控件设置为使用DoubleBuffering

 this.DoubleBuffered = true;

From the limited code that you have put up, I think the invalidate will not cause any problem. 从您提供的有限代码来看,我认为无效不会造成任何问题。 Most probably the problem may be inside the real rendering code of yours shape.Render(). 问题很可能出在您shape.Render()的真实渲染代码中。 In the past I have written similar application where I have called Invalidate in the mouse move and the applications has worked fine. 过去,我编写过类似的应用程序,其中我在鼠标移动时调用了Invalidate,并且应用程序运行良好。 Only there were some flickering which is gone on enabling double buffering. 启用双缓冲后,只有一些闪烁发生了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM