2009-08-24 81 views
3

我寫了一個附加屬性,可以在窗口上設置該屬性,以便將玻璃框架延伸到客戶區(使用DwmExtendFrameIntoClientArea API)。它在大多數情況下工作正常。現在,我希望我的窗口,是無國界的,所以我把我的窗戶以下屬性:在無邊框WPF窗口中啓用Vista玻璃效果

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

但隨着這些屬性,玻璃不會顯示在所有:我的窗口只是有一個透明背景。如果我將ResizeMode設置爲CanResize,則會顯示玻璃,但我不希望窗口可調整大小。

我懷疑這是由於玻璃的效果是通過延長非客戶幀到客戶區獲得的事實:與WindowStyle = NoneResizeMode = NoResize,沒有非客戶端框架,所以沒有什麼擴展。當我啓用調整大小時,它會在窗口周圍創建一個框架,以便可以擴展框架。

我想這應該可以創建具有細邊框,沒有標題欄的窗口,並且不能調整大小,通過設置適當的WS_ *位,但我不知道這究竟那些

所以我的問題是:

  1. 哪種樣式位應設置或取消具有所需的外觀和行爲?
  2. 如何初始化窗口的樣式位? Window類似乎沒有任何Windows窗體CreateParams屬性......可以在句柄創建後設置這些位嗎?
  3. 我發現HwndSource類可能是問題2的答案,但如果您不是Win32專家,使用它似乎有點複雜......這對我的問題是否合理?

任何意見是值得歡迎的

回答

5

您是否嘗試過使用DwmEnableBlurBehindWindow?這使您可以使窗口的客戶區域的特定部分透明。

+0

它看起來很有前途,謝謝。現在我必須弄清楚如何使用它,但它看起來不錯;) – 2009-08-24 20:50:20

+0

到目前爲止,沒有運氣,我的窗戶一直黑屏...... – 2009-08-24 21:59:24

+3

好吧,明白了......我必須設置'CompositionTarget .BackgroundColor'爲'Transparent',和'AllowsTransparency'爲true。謝謝 ! – 2009-08-24 22:16:10

4

我有一個窗口,我想給一個玻璃寄宿生(沒有標題欄和不可調整大小),並遇到同樣的問題。你只能通過設置窗口的樣式來完成。我的解決方案是設置ResizeMode =「CanResize」和WindowStyle =「None」,然後處理WM_NCHITTEST事件以將可調整大小的邊界點擊轉換爲不可調整大小的邊界點擊。此外,有必要修改窗口的風格禁用最大化和最小化(使用Windows快捷鍵),系統菜單:

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

這給了你在Windows 7適用於通知區域彈出按鈕的窗口下(如時鐘或卷彈出按鈕)。順便說一句,您可以通過創建高度控制44並將其設置爲背景來重現在彈出底部的底紋:

<Control.Background> 
    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> 
     <GradientStop Color="{x:Static SystemColors.GradientActiveCaptionColor}" Offset="0"/> 
     <GradientStop Color="{x:Static SystemColors.InactiveBorderColor}" Offset="0.1"/> 
    </LinearGradientBrush> 
</Control.Background>