Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

An Easy Technique to Improve the Drawing of Background Images of Windows Forms

0.00/5 (No votes)
19 Jul 2008 1  
Improve drawing of controls with transparent background over a form with image background

Introduction

This article is about a simple trick to improve the drawing performance of Windows Forms. When a background image is used for a form and it has a number of controls, and especially when there are a lot of controls with a transparent background, you will definitely face an issue in rendering controls. You can individually render the controls just after loading the form. Even if you enable AllPaintingInWmPaint and do double-buffering using SetStyle, the performance will not improve.

(Double-buffering can create problems in a limited memory environment/ a terminal server environment / if you want to use OpenGL applications like VTK to draw over your window.)

This article shows you how to overcome this drawing issue without even using double-buffering.

Using the Code

The technique is overriding the background image property to return an image (Bitmap) which GDI can easily draw. Also, you can include the code to adjust the size. This will avoid the zoom/stretching needed while drawing and further improve performance.

//C++ Source code
property System::Drawing::Image^ BackgroundImage 
{
    virtual System::Drawing::Image^ BackgroundImage::get()override
    {
        return this->m_bmpRenderBitMap;
    }

    virtual void BackgroundImage::set(System::Drawing::Image ^value) override
    {
        if(nullptr==value)
        {
            m_bmpRenderBitMap = nullptr;
            return;
        }
        //Create new BitMap Object of the size 
        this->m_bmpRenderBitMap = gcnew System::Drawing::Bitmap(value->Width, 
           value->Height, 
           System::Drawing::Imaging::PixelFormat::Format32bppPArgb);

        //Create graphics from image
        System::Drawing::Graphics ^g = 
          System::Drawing::Graphics::FromImage(this->m_bmpRenderBitMap);

        //set the graphics interpolation mode to high
        g->InterpolationMode = Drawing::Drawing2D::InterpolationMode::High;
        
        //draw the image to the graphics to create the new image 
        //which will be used in the onpaint background
        g->DrawImage(value, Rectangle(0, 0, this->m_bmpRenderBitMap->Width, 
                        this->m_bmpRenderBitMap->Height));
    }
}

The same can be done in C# as well:

//C# Sample
public override Image BackgroundImage
{
    get
    {
        return bmpBackground;
    }
    set
    {
        if (value!=null)
        {
            //Create new BitMap Object of the size 
            bmpBackground = new Bitmap(value.Width,value.Height);

            //Create graphics from image
            System.Drawing.Graphics g = 
               System.Drawing.Graphics.FromImage(bmpBackground);
    
            //set the graphics interpolation mode to high
            g.InterpolationMode = 
               System.Drawing.Drawing2D.InterpolationMode.High;
    
            //draw the image to the graphics to create the new image 
            //which will be used in the onpaint background
            g.DrawImage(value, new Rectangle(0, 0, bmpBackground.Width, 
                        bmpBackground.Height)); 
        }
        else
            bmpBackground = null;
    }
}

After posting this article, when I searched on Google, a similar article was found in MSDN blog: http://blogs.msdn.com/mhendersblog/archive/2005/10/12/480156.aspx.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here