简短版:
目标: 在C#的无边框WinForm中实现深色Windows 7阴影。
已知解决方案1: 使用CreateParams实现简单的XP样式阴影。
问题: 效果不够强烈、亮度过低,不够美观。
已知解决方案2: 将窗体的GDI替换为位图。
问题: 无法使用控件,只能作为闪屏功能。
本帖目的: 寻找一个中间解决方案或者更好的解决方案。
. . .
详细版:
(编辑:如果没有表述清楚,我指的是任何窗体边框上的阴影。) 我知道在C#中可以使用以下方法制作XP样式的阴影:
C#代码1 - 简单的XP样式阴影(问题:亮度过低、效果不够强烈、不够美观)
// Define the CS_DROPSHADOW constant
private const int CS_DROPSHADOW = 0x00020000;
// Override the CreateParams property
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_DROPSHADOW;
return cp;
}
}
然而,我正在尝试找出如何使它们看起来像在Windows 7中一样(更深更大的阴影),但无法找到最好的方法来实现这一点。我现在有一个方法可以让我覆盖整个表单GDI并显示出类似于闪屏的效果(荣誉不属于我): C#代码2:用位图替换表单GDI(问题:无法使用表单控件,难以维护GUI)
public void SetBitmap(Bitmap bitmap, byte opacity)
{
if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");
// 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
{
hBitmap = bitmap.GetHbitmap(Color.FromArgb(0)); // grab a GDI handle from this GDI+ bitmap
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(this.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);
}
}
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;
}
}
然而,这确实给了我一个完整的32位背景(因为我需要手动添加投影效果),但我失去了创建可见表单元素的能力。
所以基本上,我正在尝试找出这两种方法之间的中间方法。某些东西可以在不失去其他功能或导致过多的重绘要求的情况下,给我深沉而黑暗的投影效果。