2011-12-20 37 views
4

我有一個自定義窗口邊框的WPF應用程序(.NET Framework 4)。我已使用WPF Shell Integration Library禁用了玻璃邊框,並繪製了我自己的邊框。不過,我想在未最大化時在窗口邊框周圍添加DropShadow。我添加了一個陰影像這樣:刪除最大化WPF自定義窗口的DropShadow

private static bool DropShadow(Window window) 
{ 
    try 
    { 
     WindowInteropHelper helper = new WindowInteropHelper(window); 
     int val = 2; 
     int ret1 = DwmSetWindowAttribute(helper.Handle, 2, ref val, 4); 

     if (ret1 == 0) 
     { 
      Margins m = new Margins { Bottom = 0, Left = 0, Right = 0, Top = 0 }; 
      int ret2 = DwmExtendFrameIntoClientArea(helper.Handle, ref m); 
      return ret2 == 0; 
     } 
     else 
     { 
      return false; 
     } 
    } 
    catch (Exception ex) 
    { 
     // Probably dwmapi.dll not found (incompatible OS) 
     return false; 
    } 
} 

有關詳細信息,請參閱:用WindowState.Normal工作時DropShadow for WPF Borderless Window

這個解決方案正常工作!但是,當我最大化應用程序並禁用DWMWA_NCRENDERING_POLICY窗口的背景變得稍微透明,我的大多數控件渲染完全不同於我以前。

在下圖中,您會看到最初的最大化狀態以及影子代碼。正如你所看到的,它完全改變了影子代碼窗口的透明度:0 enter image description here

有什麼我失蹤了嗎?我一直在讀通過DWM Function library但無法找到答案......

+1

它可能使你受益在這裏使用[Snoop](http://snoopwpf.codeplex.com/) - 這是一個非常好的WPF間諜工具,它允許您查看WPF應用程序的所有不同渲染層以及當前屬性值。 – 2011-12-22 12:11:37

+0

偵聽我的應用程序時,沒有出現任何內容,兩個實例完全相同!它在winapi中出現錯誤,我只是不知道爲什麼......因爲我在應用程序最大化時很好地禁用了渲染策略! – Kolky 2011-12-23 10:51:45

回答

2

過了一會兒,我重新從不同的角度的問題,並想出一個更好的解決方案:

public class GlassWindow : Window 
{ 
    [SuppressUnmanagedCodeSecurity] 
    internal static class DwmNativeMethods 
    { 
     [StructLayout(LayoutKind.Sequential)] 
     internal struct DwmMargins 
     { 
      public int cxLeftWidth; 
      public int cxRightWidth; 
      public int cyTopHeight; 
      public int cyBottomHeight; 

      public DwmMargins(bool fullWindow) 
      { 
       this.cxLeftWidth = this.cxRightWidth = this.cyTopHeight = this.cyBottomHeight = fullWindow ? -1 : 0; 
      } 
     } 

     [DllImport("DwmApi.dll")] 
     internal static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref DwmMargins m); 

     [DllImport("DwmApi.dll")] 
     internal static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize); 
    } 

    private IntPtr windowHandle; 

    protected override void OnSourceInitialized(EventArgs e) 
    { 
     base.OnSourceInitialized(e); 

     WindowInteropHelper interopHelper = new WindowInteropHelper(this); 
     this.windowHandle = interopHelper.Handle; 

     this.ToggleAreoGlass(this.WindowState != WindowState.Maximized); 

     this.StateChanged += this.GlassWindowStateChanged; 
    } 

    private void ToggleAreoGlass(bool value) 
    { 
     // Enable NcRenderingPolicy 
     int attrValue = 2; 
     int result = DwmNativeMethods.DwmSetWindowAttribute(this.windowHandle, 2, ref attrValue, 4); 

     if (result == 0) 
     { 
      // Extend DwmFrame 
      DwmNativeMethods.DwmMargins margins = new DwmNativeMethods.DwmMargins(value); 
      DwmNativeMethods.DwmExtendFrameIntoClientArea(this.windowHandle, ref margins); 
     } 
    } 

    private void GlassWindowStateChanged(object sender, EventArgs e) 
    { 
     this.ToggleAreoGlass(this.WindowState != WindowState.Maximized); 
    } 
}