Introduction
This article addresses the issue and adds transparency support to the CheckBox
control. It makes the control draw in XP Style, when the FlatStyle
is set to FlatStyle.System
in correct manner.
There are some articles on the same topic, for e.g., True Transparency support for the .NET CheckBox control. But these articles advice us take over the drawing of the control. I found out a way to avoid this and use only standard Windows procedure for ComboBox
.
The Solution
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace CustomControls
{
[System.ComponentModel.DesignerCategory("Code")]
public class ThemedCheckBox : CheckBox
{
Bitmap backBufferImage = null;
protected override void OnLayout(LayoutEventArgs levent)
{
base.OnLayout(levent);
if (levent.AffectedProperty == "Bounds")
{
backBufferImage = new Bitmap(Width, Height);
}
}
protected override void WndProc(ref Message m)
{
if (FlatStyle != FlatStyle.System)
{
base.WndProc(ref m);
return;
}
switch(m.Msg)
{
case 0xF:
if (backBufferImage == null)
{
backBufferImage = new Bitmap(Width, Height);
}
Graphics bg = Graphics.FromImage(backBufferImage);
IntPtr hdc = bg.GetHdc();
Message bm = Message.Create(Handle, 0xF, hdc, IntPtr.Zero);
base.WndProc(ref bm);
bg.ReleaseHdc(hdc);
bg.Dispose();
PAINTSTRUCT ps = new PAINTSTRUCT();
hdc = m.WParam == IntPtr.Zero ? BeginPaint(Handle, ref ps) : m.WParam;
Graphics fg = Graphics.FromHdc(hdc);
backBufferImage.MakeTransparent(BackColor);
fg.DrawImage(backBufferImage, 0, 0);
fg.Dispose();
if (m.WParam != IntPtr.Zero)
{
EndPaint(Handle, ref ps);
}
break;
case 0x14:
break;
default:
base.WndProc(ref m); break;
}
}
#region API Declares
[StructLayout(LayoutKind.Sequential, Pack=4)]
public struct PAINTSTRUCT
{
public IntPtr hdc;
public bool fErase;
public Rectangle rcPaint;
public bool fRestore;
public bool fIncUpdate;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
public byte[] rgbReserved;
}
[DllImport("user32")]
private static extern IntPtr BeginPaint(IntPtr hwnd, ref PAINTSTRUCT lpPaint);
[DllImport("user32")]
private static extern bool EndPaint(IntPtr hwnd, ref PAINTSTRUCT lpPaint);
#endregion API Declares
}
}