2010-02-22 2 views
2

Моя WinForms приложение имеет стандартный стеклянный внешний вид Aero на Vista/Windows 7.Пользовательские рисовать Aero строку заголовка без расширения в клиентской области

Я хочу обычай рисовать заголовок окна, так что сохраняет внешний вид стекла Aero с стекла min/max/close, но без текста заголовка и значка окна. Я пробовал это, переопределяя WM_NCPAINT, но переопределение этого события всегда приводит к удалению стекла.

Кто-нибудь знает, как переопределить WM_NCPAINT со стеклом на месте, чтобы эффективно правильно нарисовать область стекла?

ответ

8

У меня нет решения с 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); 
} 

Далее в вашей форме, вы просто сделать это:

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

Обычно я делаю базовый класс, который реализует форму со всем моим расширенным поведением, и пусть мои фактические формы реализуют этот базовый класс, но если вам нужно только i t для одной Формы, просто поместите все это там.

+0

Это выглядит намного сложнее, чем просто очистить значок и свойства заголовка окна. На скриншоте я не могу сказать, в чем разница. –

+0

Вы не видите, что значок и название окна исчезли? Обычно они тянутся в верхнем левом углу, если вы не знаете. – Alex

+0

Да, понял. Они также * не отображаются там, если вы очищаете свойства заголовка значка и окна в дизайнере. Этот вопрос * * о WinForms, правильно? Вот что говорят теги. –