2009-08-24 6 views
3

Ich habe eine angehängte Eigenschaft geschrieben, die ich in einem Fenster einstellen kann, um den Glasrahmen in den Clientbereich zu erweitern (unter Verwendung der DwmExtendFrameIntoClientArea API). Es funktioniert in den meisten Fällen gut. Jetzt möchte ich mein Fenster ohne Rand sein, so dass ich die folgenden Attribute auf meinem Fenster:Vista-Glaseffekt auf einem randlosen WPF-Fenster aktivieren

WindowStyle="None" 
    ResizeMode="NoResize" 
    Background="Transparent" 
    u:WinUtil.EnableGlass="True" 
    ShowInTaskbar="False" 

Aber mit diesen Attributen ist das Glas nicht zeigen: mein Fenster hat nur einen transparenten Hintergrund. Wenn ich ResizeMode-CanResize gesetzt, wird das Glas gezeigt, aber ich weiß nicht das Fenster der Größe veränderbar sein soll.

Ich vermute, dass es auf die Tatsache zurückzuführen ist, dass der Glaseffekt durch die Ausweitung des Nicht-Client-Rahmen in den Client-Bereich erhalten wird: mit WindowStyle = None und ResizeMode = NoResize, gibt es keinen nicht-Client-Rahmen ist, so gibt es nichts zu verlängern. Wenn ich die Größenänderung aktiviere, wird ein Rahmen um das Fenster herum erstellt, sodass der Rahmen erweitert werden kann.

Ich denke, es möglich sein sollte, um ein Fenster zu erstellen, die eine dünne Grenze hat, keine Titelleiste, und kann nicht geändert werden, indem die entsprechenden WS_ * Bits Einstellung, aber ich weiß nicht, was diejenigen genau

Also meine Fragen sind:

  1. Welche Stil-Bits gesetzt werden soll oder nicht gesetzt das gewünschte Aussehen und Verhalten haben?
  2. Wie kann ich die Style-Bits des Fensters initialisieren? Die Window-Klasse scheint nicht, etwas wie Windows CreateParams Eigenschaft Forms zu haben ... Ist es OK, um diese Bits zu setzen, nachdem der Griff erstellt wurde?
  3. Ich fand die HwndSource Klasse, die eine Antwort auf Frage 2 sein könnte, aber es scheint ein bisschen komplex zu verwenden, wenn Sie kein Win32-Experte sind ... Wäre es eine vernünftige Lösung für mein Problem?

Jede Beratung ist willkommen

Antwort

5

Haben Sie versucht, DwmEnableBlurBehindWindow mit? Dadurch können Sie einen bestimmten Teil des Client-Bereichs eines Fensters transparent machen.

+0

Es sieht vielversprechend aus, danke. Jetzt muss ich herausfinden, wie man es benutzt, aber es sieht nicht so schlecht aus;) –

+0

Bisher kein Glück, mein Fenster bleibt verzweifelt schwarz ... –

+3

OK, hab es geschafft ... Ich musste das 'CompositionTarget 'einstellen .BackgroundColor' zu 'Transparent' und' AllowsTransparency' zu True. Vielen Dank ! –

4

Ich hatte ein Fenster, das ich nur einem Glas Boarder geben wollte (keine Titelleiste und nicht größenveränderbar) und stieß auf das gleiche Problem wie Sie. Sie können dies nicht erreichen, indem Sie nur den Stil des Fensters festlegen. Meine Lösung war ResizeMode = „CanResize“ und Window = „None“, dann behandeln Sie das WM_NCHITTEST Ereignis zu konvertieren Größe veränderbare Grenze trifft auf nicht-veränderbare Grenze Treffer zu setzen. Es war auch notwendig, um den Stil der Fenster zu ändern zu deaktivieren maximiert und minimiert (Windows Shortcuts) und das Systemmenü:

private void Window_SourceInitialized(object sender, EventArgs e) 
{ 
    System.Windows.Interop.HwndSource source = (System.Windows.Interop.HwndSource)PresentationSource.FromVisual(this); 
    source.AddHook(new System.Windows.Interop.HwndSourceHook(HwndSourceHook)); 

    IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle; 
    IntPtr flags = GetWindowLongPtr(hWnd, -16 /*GWL_STYLE*/); 
    SetWindowLongPtr(hWnd, -16 /*GWL_STYLE*/, new IntPtr(flags.ToInt64() & ~(0x00010000L /*WS_MAXIMIZEBOX*/ | 0x00020000L /*WS_MINIMIZEBOX*/ | 0x00080000L /*WS_SYSMENU*/))); 
} 

private static IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{ 
    switch (msg) 
    { 
     case 0x0084 /*WM_NCHITTEST*/: 
      IntPtr result = DefWindowProc(hwnd, msg, wParam, lParam); 
      if (result.ToInt32() >= 10 /*HTLEFT*/ && result.ToInt32() <= 17 /*HTBOTTOMRIGHT*/) 
      { 
       handled = true; 
       return new IntPtr(18 /*HTBORDER*/); 
      } 
      break; 
    } 
    return IntPtr.Zero; 
} 

[System.Runtime.InteropServices.DllImport("user32.dll")] 
private static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); 
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)] 
private static extern IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex); 

Das gibt Ihnen ein Fenster in Windows 7 geeignet für Infobereich Flyouts (zB die Uhr oder Volumen Flyouts). BTW, Sie können die Schattierung am unteren Rand des Flyouts reproduzieren, indem Sie ein Steuerelement der Höhe 44 erstellen und seinen Hintergrund festlegen:

Verwandte Themen