2

I have a border-less windows form that i created a shadow behind it using the code below.
However when I click on the parent form the shadow disappears.

can anyone help me out on how to keep the shadow even when clicking on anther form/parent form?
The shaddow is visable against a diffrent window (chrome for example) but not against it's parent form

(I tried google but couldn't find anything)

Update
I do notice that if i minimize the window and maximize it again the shadow does come back

My Code

    private const int CS_DROPSHADOW = 0x00020000;
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ClassStyle |= CS_DROPSHADOW;
            return cp;
        }
    }

Thanks in advance

JoelE
  • 169
  • 3
  • 12
  • 1
    There's a check (for security reasons) on the class when the visibility changes, in specific circumstances, that reapplies the class styles. You can override it, re-setting the class style yourself. Override `OnActivated`, get the current Styles from `CreateParams`, call `base` then call [`SetClassLongPtr`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setclasslongptrw): `CreateParams cp = this.CreateParams; base.OnActivated(e); SetClassLongPtr(this.Handle, GCL_STYLE, (IntPtr)(cp.ClassStyle | CS_DROPSHADOW)); this.Invalidate(false);`. – Jimi Mar 29 '20 at 13:33
  • This reapplies the `CS_DROPSHADOW` style to the class when you restore a Form after it has been minimized. If this is what you're referring to. It's not really clear from the description. There are other methods, but see whether this applies. – Jimi Mar 29 '20 at 13:36
  • Thanks, i'd appreciate it if you could explain a bit more, my C# skills are intermediate at best, i feel like this is going into a whole different world that I don't really know – JoelE Mar 29 '20 at 15:09

1 Answers1

5

Pls try the below steps and revert back for any errors:

Add the below code to a new code file named DropShadow.cs;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Core
{
    public class DropShadow
    {
        #region Shadowing

        #region Fields

        private bool _isAeroEnabled = false;
        private bool _isDraggingEnabled = false;
        private const int WM_NCHITTEST = 0x84;
        private const int WS_MINIMIZEBOX = 0x20000;
        private const int HTCLIENT = 0x1;
        private const int HTCAPTION = 0x2;
        private const int CS_DBLCLKS = 0x8;
        private const int CS_DROPSHADOW = 0x00020000;
        private const int WM_NCPAINT = 0x0085;
        private const int WM_ACTIVATEAPP = 0x001C;

        #endregion

        #region Structures

        [EditorBrowsable(EditorBrowsableState.Never)]
        public struct MARGINS
        {
            public int leftWidth;
            public int rightWidth;
            public int topHeight;
            public int bottomHeight;
        }

        #endregion

        #region Methods

        #region Public

        [DllImport("dwmapi.dll")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);

        [DllImport("dwmapi.dll")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);

        [DllImport("dwmapi.dll")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public static extern int DwmIsCompositionEnabled(ref int pfEnabled);

        [EditorBrowsable(EditorBrowsableState.Never)]
        public static bool IsCompositionEnabled()
        {
            if (Environment.OSVersion.Version.Major < 6) return false;

            bool enabled;
            DwmIsCompositionEnabled(out enabled);

            return enabled;
        }

        #endregion

        #region Private

        [DllImport("dwmapi.dll")]
        private static extern int DwmIsCompositionEnabled(out bool enabled);

        [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
        private static extern IntPtr CreateRoundRectRgn
        (
            int nLeftRect,
            int nTopRect,
            int nRightRect,
            int nBottomRect,
            int nWidthEllipse,
            int nHeightEllipse
         );

        private bool CheckIfAeroIsEnabled()
        {
            if (Environment.OSVersion.Version.Major >= 6)
            {
                int enabled = 0;
                DwmIsCompositionEnabled(ref enabled);

                return (enabled == 1) ? true : false;
            }
            return false;
        }

        #endregion

        #region Overrides

        public void ApplyShadows(Form form)
        {
            var v = 2;

            DwmSetWindowAttribute(form.Handle, 2, ref v, 4);

            MARGINS margins = new MARGINS()
            {
                bottomHeight = 1,
                leftWidth = 0,
                rightWidth = 0,
                topHeight = 0
            };

            DwmExtendFrameIntoClientArea(form.Handle, ref margins);
        }

        #endregion

        #endregion

        #endregion
    }
}

In your form, add this line below InitializeComponent();

(new Core.DropShadow()).ApplyShadows(this);
D J
  • 845
  • 1
  • 13
  • 27
  • You're a geniuses, iv'e been looking for this all day long. I don't fully understand what's going on in the DropShadow class but it's working. Is it your code? or can you point somewhere that has an explanation There is one small thing, there's a very small white strip at the bottom, my form is panted so it's visible, is there a way to pain that? – JoelE Mar 29 '20 at 16:30
  • @TheITGuy: Look for 'bottomHeight' in the code. Just set bottomHeight = 0 instead of bottomHeight = 1 and it should work. – D J Mar 29 '20 at 17:07
  • i assumed so but when i tried it removed the shadow completely – JoelE Mar 29 '20 at 17:18
  • I just tried moving the strip to the top and it looks better for my specific application, so this works for me. Thank you again very much! – JoelE Mar 29 '20 at 17:22
  • @TheITGuy: Good, the problem is sorted now. However, if you get this problem in the future, you can add a panel instead of directly painting the form. You can add controls to the panel. – D J Mar 29 '20 at 17:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210536/discussion-between-d-j-and-the-it-guy). – D J Mar 29 '20 at 17:25