Winforms 自定义绘制Aero标题栏,无需延伸到客户端区域

Winforms 自定义绘制Aero标题栏,无需延伸到客户端区域,winforms,aero,aero-glass,Winforms,Aero,Aero Glass,我的WinForms应用程序在Vista/Windows 7上具有标准的Aero glass外观 我想自定义绘制窗口标题栏,使其保留Aero glass外观,并带有glass min/max/close按钮,但没有标题文本和窗口图标。我尝试过覆盖WM_NCPAINT,但覆盖此事件始终会导致玻璃被移除 有人知道如何在玻璃就位的情况下覆盖WM_NCPAINT,以便有效地正确绘制玻璃区域吗?我没有涉及WM_NCPAINT的解决方案,但我有一个解决方案,可以实现您想要的功能,并且可能比WM_NCPAIN

我的WinForms应用程序在Vista/Windows 7上具有标准的Aero glass外观

我想自定义绘制窗口标题栏,使其保留Aero glass外观,并带有glass min/max/close按钮,但没有标题文本和窗口图标。我尝试过覆盖WM_NCPAINT,但覆盖此事件始终会导致玻璃被移除


有人知道如何在玻璃就位的情况下覆盖WM_NCPAINT,以便有效地正确绘制玻璃区域吗?

我没有涉及
WM_NCPAINT
的解决方案,但我有一个解决方案,可以实现您想要的功能,并且可能比
WM_NCPAINT
版本更干净

首先定义这个类。您将使用其类型和功能来实现所需的功能:

internal class NonClientRegionAPI
{
    [DllImport( "DwmApi.dll" )]
    public static extern void DwmIsCompositionEnabled( ref bool pfEnabled );

    [StructLayout( LayoutKind.Sequential )]
    public struct WTA_OPTIONS
    {
        public WTNCA dwFlags;
        public WTNCA dwMask;
    }

    [Flags]
    public enum WTNCA : uint
    {
        NODRAWCAPTION = 1,
        NODRAWICON = 2,
        NOSYSMENU = 4,
        NOMIRRORHELP = 8,
        VALIDBITS = NODRAWCAPTION | NODRAWICON | NOSYSMENU | NOMIRRORHELP
    }

    public enum WINDOWTHEMEATTRIBUTETYPE : uint
    {
        /// <summary>Non-client area window attributes will be set.</summary>
        WTA_NONCLIENT = 1,
    }

    [DllImport( "uxtheme.dll" )]
    public static extern int SetWindowThemeAttribute(
        IntPtr hWnd,
        WINDOWTHEMEATTRIBUTETYPE wtype,
        ref WTA_OPTIONS attributes,
        uint size );
}
结果如下:


我通常会创建一个基类,用我所有时髦的扩展行为来实现表单,然后让我的实际表单实现该基类,但如果只需要一个表单,就把它全部放在那里。

这看起来比简单地清除图标和窗口标题属性要复杂得多。从截图上看,我看不出有什么区别。你看不到窗口图标和标题消失了吗?它们通常画在左上角,以防你不知道。是的,明白了。如果清除设计器中的图标和窗口标题属性,它们也不会在那里绘制。这个问题是关于WinForms的,对吗?标签上是这么写的。我可以发誓我会先试试,呵呵。在任何情况下,我现在都无法测试您的声明,我下班时是Linux用户。他的问题是如何“自定义绘制窗口标题栏,使其保留带有最小/最大/关闭按钮的Aero glass外观,但没有标题文本和窗口图标”。我的解决方案(或者你的,如果你是对的)与扩展客户端区域相结合,可以让你在标题区域中自定义绘制任何你想要的内容。等等,现在我记得为什么你想使用我的解决方案而不是你的:它让你在任务栏中有一个图标和标题。如果我没记错的话,你的解决方案不允许这样。
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // Set your options. We want no icon and no caption.
        SetWindowThemeAttributes( NonClientRegionAPI.WTNCA.NODRAWCAPTION | NonClientRegionAPI.WTNCA.NODRAWICON );
    }

    private void SetWindowThemeAttributes( NonClientRegionAPI.WTNCA attributes )
    {
        // This tests that the OS will support what we want to do. Will be false on Windows XP and earlier,
        // as well as on Vista and 7 with Aero Glass disabled.
        bool hasComposition = false;
        NonClientRegionAPI.DwmIsCompositionEnabled( ref hasComposition );
        if( !hasComposition )
            return;

        NonClientRegionAPI.WTA_OPTIONS options = new NonClientRegionAPI.WTA_OPTIONS();
        options.dwFlags = attributes;
        options.dwMask = NonClientRegionAPI.WTNCA.VALIDBITS;

        // The SetWindowThemeAttribute API call takes care of everything
        NonClientRegionAPI.SetWindowThemeAttribute(
            this.Handle,
            NonClientRegionAPI.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT,
            ref options,
            (uint)Marshal.SizeOf( typeof( NonClientRegionAPI.WTA_OPTIONS ) ) );
    }
}