我试图为我的应用程序制作启动画面。我有一个.PNG图像,它有一些部分透明的部分。
我已将该表单设为无边框并禁用了控件箱。但是,背景颜色会导致问题。
首先,我将图像放在图片框中。然后我以这种方式使表单背景透明:
this.BackColor = Color.Magenta;
this.TransparencyKey = Color.Magenta;
它有点奏效。屏幕的完全透明部分是透明的,但在部分透明的部分可以看到洋红色。
然后我尝试将图像作为表单的背景图像。我尝试使用此代码使表单的背景透明:
private void Form1_Load(object sender, EventArgs e)
{
this.SetStyle(System.Windows.Forms.ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = System.Drawing.Color.Transparent;
}
它也没有用。背景仍然不透明。 我该怎么办?
答案 0 :(得分:3)
为什么是洋红色?尝试使用白色。我将背面颜色设置为白色,透明度设置为白色。在下图中,带有图片的随机框是我的飞溅。
答案 1 :(得分:2)
TransparencyKey
会将表单设置为完全不透明,但指定的确切颜色的像素除外。 AFAIK它通过实际定义基于匹配颜色的像素的WindowRegion
窗口形状来实现这一点 - 这些像素不再是窗口的一部分,可以点击。
听起来你的PNG有一个alpha层,即透明度等级0..255,它们混合在你的背景色(洋红色)上,之后只有纯品红色像素变得透明。
你可以尝试:
Magenta
未在您的启动画中使用,并将其放在您的启动画面PNG中代替完全透明区域作为不透明像素PictureBox
下。然后,飞溅的部分透明区域会与背景图像混合,完全透明的区域将与TransparencyKey
匹配并且是透明的。
但是如果桌面的其他部分在启动时显示,如果你的启动画面移动等,那么你将获得视觉假象。
编辑:似乎有一个更简单的解决方案here而不使用TransparencyKey
答案 2 :(得分:1)
您可以使用layered windows
和UpdateLayeredWindow()
Api:
protected override CreateParams CreateParams
{
get
{
// Add the layered extended style (WS_EX_LAYERED) to this window
CreateParams createParam = base.CreateParams;
createParam.ExStyle = (createParam.ExStyle | APIHelp.WS_EX_LAYERED);
return createParam;
}
}
以您的格式load event
:
IntPtr memDc, hBmp, hOldBmp;
private void Form1_Load(object sender, EventArgs e)
{
APIHelp.BLENDFUNCTION blend;
//Only works with a 32bpp bitmap
blend.BlendOp = APIHelp.AC_SRC_OVER;
//Always 0
blend.BlendFlags = 0;
//Set to 255 for per-pixel alpha values
blend.SourceConstantAlpha = 255;
//Only works when the bitmap contains an alpha channel
blend.AlphaFormat = APIHelp.AC_SRC_ALPHA;
IntPtr screenDc;
screenDc = APIHelp.GetDC(IntPtr.Zero);
Bitmap bmp;
using (bmp = (Bitmap)Bitmap.FromFile(@"C:\.......png")) //the image must be the same size as your form
{
memDc = APIHelp.CreateCompatibleDC(screenDc);
hBmp = bmp.GetHbitmap(Color.FromArgb(0));
hOldBmp = APIHelp.SelectObject(memDc, hBmp); //memDc is a device context that contains our image
}
APIHelp.DeleteDC(screenDc);
APIHelp.Size newSize;
APIHelp.Point newLocation;
APIHelp.Point sourceLocation;
newLocation.x = this.Location.X;
newLocation.y = this.Location.Y;
sourceLocation.x = 0;
sourceLocation.y = 0;
newSize.cx = this.Width;
newSize.cy = this.Height;
APIHelp.UpdateLayeredWindow(Handle, IntPtr.Zero, ref newLocation, ref newSize, memDc, ref sourceLocation,
0, ref blend, APIHelp.ULW_ALPHA);
}
Class APIHelp:
class APIHelp
{
public const Int32 WS_EX_LAYERED = 524288;
public const Int32 ULW_ALPHA = 2;
public const byte AC_SRC_OVER = 0;
public const byte AC_SRC_ALPHA = 1;
[StructLayout(LayoutKind.Sequential)]
public struct Point
{
public Int32 x;
public Int32 y;
}
[StructLayout(LayoutKind.Sequential)]
public struct Size
{
public Int32 cx;
public Int32 cy;
}
[StructLayout(LayoutKind.Sequential)]
public struct ARGB
{
public byte Blue;
public byte Green;
public byte Red;
public byte Alpha;
}
[StructLayout(LayoutKind.Sequential)]
public struct BLENDFUNCTION
{
public Byte BlendOp;
public Byte BlendFlags;
public Byte SourceConstantAlpha;
public Byte AlphaFormat;
}
[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 pptSrc, uint crKey,
[In] ref BLENDFUNCTION pblend, uint dwFlags);
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC", SetLastError = true)]
public static extern IntPtr CreateCompatibleDC([In] IntPtr hdc);
[DllImport("gdi32.dll", EntryPoint = "SelectObject")]
public static extern IntPtr SelectObject([In] IntPtr hdc, [In] IntPtr hgdiobj);
[DllImport("user32.dll")]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
public static extern bool DeleteDC([In] IntPtr hdc);
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);
}
当表单关闭时释放资源:
APIHelp.SelectObject(memDc, hOldBmp);
APIHelp.DeleteObject(hBmp);
APIHelp.DeleteDC(memDc);