我正在开发一个需要透明背景的exe。我已经在Photoshop
制作了图像并且它具有所有整洁的东西(阴影/不透明度,反射等)。
我一直在努力使用 TransparentColor + BackColor +背景图像让它工作,但我总是最终得到一些不透明的像素。所以我切换到 UpdateLayeredWindow ,它工作正常,但现在没有控制。
以下是我的一些代码
private void Form1_Load(object sender, EventArgs e)
{
UpdateFormDisplay(this.BackgroundImage);
}
protected override void OnPaint(PaintEventArgs e)
{
UpdateFormDisplay(this.BackgroundImage);
}
public void UpdateFormDisplay(Image backgroundImage)
{
IntPtr screenDc = API.GetDC(IntPtr.Zero);
IntPtr memDc = API.CreateCompatibleDC(screenDc);
IntPtr hBitmap = IntPtr.Zero;
IntPtr oldBitmap = IntPtr.Zero;
try
{
//Display-image
Bitmap bmp = new Bitmap(backgroundImage);
hBitmap = bmp.GetHbitmap(Color.FromArgb(0)); //Set the fact that background is transparent
oldBitmap = API.SelectObject(memDc, hBitmap);
//Display-rectangle
Size size = bmp.Size;
Point pointSource = new Point(0, 0);
Point topPos = new Point(this.Left, this.Top);
//Set up blending options
API.BLENDFUNCTION blend = new API.BLENDFUNCTION();
blend.BlendOp = API.AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;
blend.AlphaFormat = API.AC_SRC_ALPHA;
API.UpdateLayeredWindow(this.Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, API.ULW_ALPHA);
//Clean-up
bmp.Dispose();
API.ReleaseDC(IntPtr.Zero, screenDc);
if (hBitmap != IntPtr.Zero)
{
API.SelectObject(memDc, oldBitmap);
API.DeleteObject(hBitmap);
}
API.DeleteDC(memDc);
}
catch (Exception)
{
}
}
以下是一些可以更好地解释的图片
答案 0 :(得分:0)
如果要在使用UpdateLayeredWindow
API的分层窗口中使用常规控件,则需要覆盖控件的OnPaint
方法,将绘图重定向到屏幕后的位图,稍后您将使用该位图更新窗口外观的UpdateLayeredWindow
方法。
如果您不想深入了解控件代码,或者没有多少自定义控件,可以使用WM_PRINT
消息强制控件将自己绘制到提供的设备上下文中。经典窗口子类化(SetWindowLong
/ GetWindowLong
)用于捕捉控件无效的时刻是有用的,但可能有点危险 - 你必须注意回调链。
最后,您可以使用轻量级(无窗口)控件。他们使用表单消息队列来接收事件并自己绘制,因此只需要表单绘制代码修改。一些标准winforms控件支持此模式。