自定义绘图Aero标题栏,而无需扩展到客户区域 [英] Custom draw Aero title bar without extending into client area

查看:105
本文介绍了自定义绘图Aero标题栏,而无需扩展到客户区域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My WinForms application has the standard Aero glass appearance on Vista/Windows 7.

我想自定义绘制窗口标题栏,以便保留带有玻璃的最小/最大/关闭按钮,但没有标题文本和窗口图标。我通过覆盖WM_NCPAINT进行了尝试,但是覆盖此事件始终会导致玻璃被移除。

I want to custom draw the window title bar so it retains the Aero glass appearance with the glass min/max/close buttons but without the title text and window icon. I have tried this by overriding WM_NCPAINT but overriding this event always causes the glass to be removed.

有人知道如何使用玻璃覆盖WM_NCPAINT以便有效绘制

Does anyone know how to override WM_NCPAINT with glass in place in order to effectively draw over the glass area correctly?

推荐答案

我没有涉及 WM_NCPAINT ,但是我有一个解决方案可以满足您的要求,并且可能比 WM_NCPAINT -version更加干净。

I don't have a solution involving WM_NCPAINT, but I have a solution that does what you want it to do, and perhaps cleaner than the WM_NCPAINT-version would be.

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

First define this class. You'll use its types and functions to achieve your desired functionality:

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 );
}

接下来,在您的表单中,您只需执行以下操作:

Next, in your form, you simply do this:

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 ) ) );
    }
}

结果如下:

http://img708.imageshack.us/img708/1972/noiconnocaptionform.png

我通常会创建一个基类,该基类以所有时髦的扩展行为来实现Form,然后让我的实际表单实现该基类,但是如果您只需要它对于一种表格,只需将其全部放在其中即可。

I normally make a base class that implements Form with all my funky extended behavior and then let my actual forms implement that base class, but if you only need it for one Form, just put it all in there.

这篇关于自定义绘图Aero标题栏,而无需扩展到客户区域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆