【问题标题】:Border-less winform form shadow无边框winform窗体阴影
【发布时间】:2020-07-09 19:25:43
【问题描述】:

我有一个无边框窗口窗体,我使用下面的代码在它后面创建了一个阴影。
但是,当我单击父窗体时,阴影消失了。

任何人都可以帮助我了解如何在单击另一个表单/父表单时保持阴影吗?
阴影对不同的窗口(例如chrome)是可见的,但对它的父窗体不可见

(我尝试了谷歌但找不到任何东西)

更新
我确实注意到,如果我最小化窗口并再次最大化它,阴影确实会回来

我的代码

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

提前致谢

【问题讨论】:

  • 当可见性发生变化时,对类进行检查(出于安全原因),在特定情况下会重新应用类样式。您可以覆盖它,自己重新设置类样式。覆盖OnActivated,从CreateParams获取当前样式,调用base然后调用SetClassLongPtrCreateParams cp = this.CreateParams; base.OnActivated(e); SetClassLongPtr(this.Handle, GCL_STYLE, (IntPtr)(cp.ClassStyle | CS_DROPSHADOW)); this.Invalidate(false);
  • 这会将CS_DROPSHADOW 样式重新应用于类,当您在最小化后恢复表单时。如果这就是你所指的。从描述中并不是很清楚。还有其他方法,但看看这是否适用。
  • 谢谢,如果您能多解释一下,我将不胜感激,我的 C# 技能充其量只是中等水平,我觉得这将进入一个我不知道的完全不同的世界

标签: c# winforms


【解决方案1】:

请尝试以下步骤并恢复任何错误:

将以下代码添加到名为 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
    }
}

在您的表单中,在 InitializeComponent(); 下方添加这一行

(new Core.DropShadow()).ApplyShadows(this);

【讨论】:

  • 你真是个天才,我整天都在找这个。我不完全理解 DropShadow 类中发生了什么,但它正在工作。是你的代码吗?或者你能指出一个有解释的地方吗?有一个小东西,底部有一条很小的白色条带,我的表格被喘着气,所以它是可见的,有什么办法可以解决这个问题吗?
  • @TheITGuy:在代码中查找“bottomHeight”。只需设置 bottomHeight = 0 而不是 bottomHeight = 1 就可以了。
  • 我假设是这样,但是当我尝试它时,它完全消除了阴影
  • 我只是尝试将条带移到顶部,它看起来更适合我的特定应用程序,所以这对我有用。再次非常感谢!
  • @TheITGuy:很好,现在问题已经解决了。但是,如果以后遇到这个问题,可以添加一个面板,而不是直接绘制表单。您可以向面板添加控件。
猜你喜欢
  • 1970-01-01
  • 2012-11-23
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多