FormBorderStyle.NoneのフォームにAeroの影を付ける
FormBorderStyle.Noneのフォームは、枠がなくなると同時に、周囲の影も消えてしまう。
下記コードを適用することで、Aeroの影を復活することができる。
public partial class Form1 : Form { #region Win32API [StructLayout(LayoutKind.Sequential)] private struct MARGINS { public int leftWidth; public int rightWidth; public int topHeight; public int bottomHeight; } [DllImport("dwmapi.dll")] private static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins); private enum DWMWINDOWATTRIBUTE : uint { NCRenderingEnabled = 1, NCRenderingPolicy, TransitionsForceDisabled, AllowNCPaint, CaptionButtonBounds, NonClientRtlLayout, ForceIconicRepresentation, Flip3DPolicy, ExtendedFrameBounds, HasIconicBitmap, DisallowPeek, ExcludedFromPeek, Cloak, Cloaked, FreezeRepresentation } [DllImport("dwmapi.dll", PreserveSig = true)] private static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attr, ref int attrValue, int attrSize); [DllImport("dwmapi.dll")] private static extern int DwmIsCompositionEnabled(out bool enabled); const int WM_NCPAINT = 0x85; #endregion public Form1() { InitializeComponent(); this.FormBorderStyle = FormBorderStyle.None; } [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_NCPAINT: // デザイン時は処理しない if (!DesignMode) { // Vista以降のOSのみ if (Environment.OSVersion.Version.Major >= 6) { // Aeroが使用可能か確認 bool bolAeroEnabled = false; DwmIsCompositionEnabled(out bolAeroEnabled); if (bolAeroEnabled == true) { int intAttrValue = 2; int intAttrSize = sizeof(int); DwmSetWindowAttribute(this.Handle, DWMWINDOWATTRIBUTE.NCRenderingPolicy, ref intAttrValue, intAttrSize); MARGINS objMargins = new MARGINS() { leftWidth = 1, rightWidth = 1, topHeight = 1, bottomHeight = 1 }; DwmExtendFrameIntoClientArea(this.Handle, ref objMargins); } } } break; } base.WndProc(ref m); } }
余談:WPFの場合は、GlowWindowを使うと綺麗にできる。
ディスカッション
コメント一覧
OnHandleCreated をオーバーライドして処理すればいい気がしますが
何故 NC_PAINT が来るたびに処理しているのでしょうか?