We wanted to create a transparent form with a PNG image, but we encountered a problem. We searched for a solution on Stack Overflow and found this link that seemed promising. However, when we tried it, it did not work as expected. We were disappointed and frustrated, so we looked for other ways to fix our issue. We tried different methods and settings, but none of them gave us the result we wanted. Our form was either not transparent enough, or had unwanted artifacts or glitches. We felt stuck and hopeless. How can we solve this problem and build a transparent form with a PNG image?
We thought use this link on Stack Overflow will be solve my transparent problem. But We are wrong, so We had found many way to fix it, but that not give me a nice result.
On the nice day morning in weekend day. We had fit it with below code
Explore My Other Channel for More Cool and Valuable Insights
๐ Youtube Learn Tech Tips๐ Tiktok
๐ Facebook:See the picture
- The Number 1 is only use PNG transparent form on the stack overflow.
- The Number 2 is fix it with bitmap form
Now you're nervous wait, :), Let's start!
Create New projects with some class
1. Two form: frmEvent and frmMain
2. One Class: Win32.cs
Win32.cs
/*
* Develper: Webzone tech tips Zidane (huuvi168@gmail.com)
* Last modified: 2015-12-25
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace PNGDemo
{
class Win32
{
public enum Bool
{
False = 0,
True
};
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public Int32 x;
public Int32 y;
public Point(Int32 x, Int32 y) { this.x = x; this.y = y; }
}
[StructLayout(LayoutKind.Sequential)]
public struct Size
{
public Int32 cx;
public Int32 cy;
public Size(Int32 cx, Int32 cy) { this.cx = cx; this.cy = cy; }
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ARGB
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BLENDFUNCTION
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
public const Int32 ULW_COLORKEY = 0x00000001;
public const Int32 ULW_ALPHA = 0x00000002;
public const Int32 ULW_OPAQUE = 0x00000004;
public const byte AC_SRC_OVER = 0x00;
public const byte AC_SRC_ALPHA = 0x01;
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
[DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", ExactSpelling = true)]
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll", ExactSpelling = true)]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
[DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
public static extern Bool DeleteObject(IntPtr hObject);
}
}
FrmMain.cs
/*
* Develper: Webzone Tech Tips Zidane (huuvi168@gmail.com)
* Last modified: 2015-12-25
*/
using PNGDemo.Properties;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PNGDemo
{
public partial class FrmMain : Form
{
public FrmMain frm;
Bitmap bitMap;
FrmEvent pnl;
public FrmMain()
{
InitializeComponent();
FormBorderStyle = FormBorderStyle.None;
pnl = new FrmEvent();
bitMap = Resources.songuku;
SetBitmap(bitMap, 255);
// pnl.frm = this; // for minimize all windows
pnl.Show(this);
}
/// <summary>
/// Changes the current bitmap with a custom opacity level.
/// Here is where all happens!</para>
/// </summary>
/// <param name="bitmap">bitmap display</param>
/// <param name="opacity">opacity (trong suแปt)</param>
public void SetBitmap(Bitmap bitmap, byte opacity)
{
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");
// The ideia of this is very simple,
// 1. Create a compatible DC with screen;
// 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
// 3. Call the UpdateLayeredWindow.
IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;
try
{
// grab a GDI handle from this GDI+ bitmap
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));
oldBitmap = Win32.SelectObject(memDc, hBitmap);
Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
Win32.Point pointSource = new Win32.Point(0, 0);
Win32.Point topPos = new Win32.Point(Left, Top);
Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
blend.BlendOp = Win32.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = opacity;
blend.AlphaFormat = Win32.AC_SRC_ALPHA;
Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos,
ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
}
finally
{
Win32.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
Win32.SelectObject(memDc, oldBitmap);
Win32.DeleteObject(hBitmap);
}
Win32.DeleteDC(memDc);
}
}
/// <summary>
/// Move Window whe drag mouse on window title
/// </summary>
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0084 /*WM_NCHITTEST*/)
{
m.Result = (IntPtr)2; // HTCLIENT
return;
}
base.WndProc(ref m);
}
/// <summary>
/// Buffer move: for not lag
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
return cp;
}
}
/// <summary>
/// Move the FrmMain and FrmEvent together
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frmMain_Move(object sender, EventArgs e)
{
Point p = new Point();
p.X = this.Location.X;
p.Y = this.Location.Y;
pnl.Location = p;
}
}
}
FrmEvent.cs
/*
* Develper: Webzone Tech Tips Zidane (huuvi168@gmail.com)
* Last modified: 2015-12-25
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PNGDemo
{
public partial class FrmEvent : Form
{
public FrmMain frm;
public FrmEvent()
{
InitializeComponent();
}
}
}
Do you love this article. If you have any questions or feedbacks, please leave your comment, we happy to discuss it together!
Regards!
Webzone tech tips Zidane