Click here to Skip to main content
15,890,670 members
Articles / Multimedia / GDI+
Tip/Trick

Winforms Transparent Background Image with Gradient Alpha Colors

Rate me:
Please Sign up or sign in to vote.
4.24/5 (12 votes)
11 Jan 2018MIT2 min read 24.4K   1.2K   16   2
Create a draggable, proper splash screen in DotNet, with gradient transparency!

Introduction

I could not find a single article that got me a proper splash screen using WinForms, with true transparency, using gradient alpha colors, which could actually be dragged around, and also allows designing it using the Winforms Designer. After experimenting and combining articles, I created a solution with near perfect results.

Background

You cannot use an alpha channel image as a background image in winforms, you can only substitute a color to be treated as transparent. This does not allow gradient transparency.

Using the Code

The solution was to have a second form which takes care of the background image rendering. That second form has logic to mimic the movements of the primary form containing the controls, and which is editable using the winforms designer.

You start out adding an image with transparency to your project's resources. Use png for the best results. In my demo, I've named it Splash.png.

The primary form with all the controls is set to have a transparent background color, using the Form's property: TransparencyKey.

C#
//
// winforms designer code
//
this.BackgroundImage = global::Splash.Properties.Resources.Splash;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.BackColor = System.Drawing.Color.Gold;
this.TransparencyKey = System.Drawing.Color.Gold;

Making the form draggable when clicking anywhere on the background can be done using this code snippet.

C#
protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    //support dragging the window
    if (m.Msg == ApiHelper.WM_NCHITTEST && (int)m.Result == ApiHelper.HTCLIENT)
    {
        m.Result = new IntPtr(ApiHelper.HTCAPTION);
    }
}

To initialize the background form, you should construct it in the constructor of the primary form. Make sure you clear your primary form's background image, or you'll get weird graphical artefacts!

C#
public frmSplash()
{
    InitializeComponent();

    this.BackgroundImage = null;
    _background = new frmBackground(Resources.Splash, this);
}

The only downside of this is that you have to set the background image of the form, as well as at the constructor code. If you change the image to have a different name, you have to change this at both places. If you don't set the background image of your primary form, you can't see what it looks like in the Designer, and it becomes hard to position the controls:

Image 1

The primary form code looks like this:

C#
using System;
using System.Drawing;
using System.Windows.Forms;
using Splash.Properties;

namespace Splash
{
    public partial class frmSplash : Form
    {
        private frmBackground _background;
        public frmSplash()
        {
            InitializeComponent();

            //remove this form's background, because it causes weird graphics
            this.BackgroundImage = null;
            _background = new frmBackground(Resources.Splash, this);
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            //support dragging the window
            if (m.Msg == ApiHelper.WM_NCHITTEST && (int)m.Result == ApiHelper.HTCLIENT)
            {
                m.Result = new IntPtr(ApiHelper.HTCAPTION);
            }
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}

The background form sets the image with alpha transparency into some graphical layer, for which I found the code here: https://blogs.msdn.microsoft.com/llobo/2006/02/07/creating-non-rectangular-splash-screen-using-alpha-channel/. The rest of the code is to mimic the movements of the first form, and making sure the z-position of the background form is always 2nd in line, using form.BringToFront() for both forms.

The end result looks perfect, and behaves like any other form, so can be dragged around, etc.

Image 2

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer (Senior)
New Zealand New Zealand
Born in The Netherlands, Walter has been developing DotNet software developer for 10+ years. He's moved to New Zealand in 2016 and is currently working as a Contractor Team Lead at Vista Entertainment Solutions Ltd in Auckland, New Zealand.

Comments and Discussions

 
QuestionMessage Closed Pin
9-Jun-21 3:52
DEV 6ShadoW6 (Invincible)9-Jun-21 3:52 
Questionwhere is the transparency and gradient example ? Pin
BillWoodruff16-Jan-18 13:22
professionalBillWoodruff16-Jan-18 13:22 
Questionis WndProc call necessary? Pin
Southmountain12-Jan-18 8:20
Southmountain12-Jan-18 8:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.