FormBorderStyle.NoneのフォームにAeroの影を付ける

2017-03-06

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を使うと綺麗にできる。