Короткая версия:
Цель: Глубокая, темная тень для Windows 7 в WinForm без полей в C #
Известные существующие решения 1: Простые тени в стиле XP с использованием CreateParams.
Проблема: Слишком слабый, слишком легкий, слишком уродливый.
Известные существующие решения 2: Заменить GDI формы на растровое изображение.
Проблема: Потерять возможность использовать элементы управления, работающие только в качестве заставки.
Цель этого поста: Найти медианное решение этой проблемы или все вместе лучшее.
.
,
.
Длинная версия:
(Редактировать: я имею в виду падающую тень, идущую вдоль границы любой формы окна, если это не было ясно.)
Я понимаю, что есть способ сделать тени в стиле XP в C #, используя:
C # Code 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 формы на Bitmap (Проблема: невозможно использовать элементы управления формы, сложно поддерживать графический интерфейс)
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-битный фон (так как мне требуется добавить тени), но я теряю возможность создавать видимые элементы формы.
Так что в основном я пытаюсь выяснить медиану между этими двумя методами. Что-то, что даст мне глубокие и темные тени без потери других функций / излишних требований к перекраске.