2010-02-22 7 views
2

Mon application WinForms a l'apparence standard de verre Aero sous Vista/Windows 7.dessiner personnalisée barre de titre Aero sans étendre dans la zone client

Je veux dessiner sur mesure la barre de titre de la fenêtre il conserve l'aspect de verre Aero avec le Boutons de min/max/fermeture de verre mais sans le titre du texte et l'icône de la fenêtre. J'ai essayé ceci en surchargeant WM_NCPAINT mais en surchargeant cet événement fait toujours enlever le verre. Est-ce que quelqu'un sait comment remplacer WM_NCPAINT avec du verre en place afin de dessiner efficacement sur la zone de verre correctement?

Répondre

8

Je n'ai pas une solution impliquant WM_NCPAINT, mais j'ai une solution qui fait ce que vous voulez faire, et peut-être plus propre que la WM_NCPAINT -version serait.

Définissez d'abord cette classe. Vous utiliserez ses types et fonctions pour atteindre votre fonctionnalité désirée:

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

Ensuite, dans votre formulaire, vous faites simplement ceci:

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

Voici le résultat:

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

Normalement, je crée une classe de base qui implémente Form avec tout mon comportement génial étendu, puis laisse mes formes réelles implémenter cette classe de base, mais si vous avez seulement besoin de i t pour un formulaire, mettez tout cela là-dedans.

+0

Cela semble beaucoup plus compliqué que de simplement effacer l'icône et les propriétés du titre de la fenêtre. De la capture d'écran, je ne peux pas dire quelle est la différence. –

+0

Vous ne pouvez pas voir que l'icône de la fenêtre et le titre sont partis? Ils sont normalement dessinés dans le coin supérieur gauche, au cas où vous ne le saviez pas. – Alex

+0

Yup, j'ai compris. Ils ne sont * également * pas dessinés ici si vous effacez les propriétés de l'icône et du titre de la fenêtre dans le concepteur. Cette question * est * à propos de WinForms, non? C'est ce que les tags disent. –

Questions connexes