12

背景が半透明のボーダレスでサイズ変更できない WPF フォーム (WindowStyle=None、allowsTransparency=True、ResizeMode=NoResize) があります。以下は、フォーム (半透明の赤い四角形) が現在どのように表示され、メモ帳の上で実行されているかを示しています。

メモ帳の上に現在表示されているフォーム

ただし、Aero ガラスのように、背景をぼかす必要があります。ただし、凝ったウィンドウの境界線と縞模様の色付きの背景は除きます。自分で処理したいと思います。これが私がどのように見せたいかのモックアップです:

私が望む形 - その下にあるものをぼかす

可能な限り最も効率的な方法でこれを達成するにはどうすればよいですか?

WinForms または WPF は私には問題ありません。うまくいけば、下の画面領域をビットマップとしてキャプチャしてそれをぼかすようなクレイジーなものではなく、Aero グラスが使用するものと同じものを使用する必要があります (Aero が有効になっている場合にのみ機能します)。

ここに私が望まないものの写真があります:

エアロガラスの窓全体のクロームは欲しくない

私はこれが可能であることを知っており、その方法も知っていますが、Aero ガラス ウィンドウのクロム全体、境界線とタイトル バー、またはウィンドウにユーザーが設定した Aero ガラスの色を持たせたくありません。ウィンドウ/フォームの下にあるものをぼかします。

4

2 に答える 2

10

Aero ブラーを使用する場合は、 DwmEnableBlurBehindWindow APIを使用できます。これを利用した派生ウィンドウの例を次に示します。

public class BlurWindow : Window
{
    #region Constants

    private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
    private const int DWM_BB_ENABLE = 0x1; 

    #endregion //Constants

    #region Structures
    [StructLayout( LayoutKind.Sequential )]
    private struct DWM_BLURBEHIND
    {
        public int dwFlags;
        public bool fEnable;
        public IntPtr hRgnBlur;
        public bool fTransitionOnMaximized;
    }

    [StructLayout( LayoutKind.Sequential )]
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    } 
    #endregion //Structures

    #region APIs

    [DllImport( "dwmapi.dll", PreserveSig = false )]
    private static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);

    [DllImport( "dwmapi.dll" )]
    private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);

    [DllImport( "dwmapi.dll", PreserveSig = false )]
    private static extern bool DwmIsCompositionEnabled(); 

    #endregion //APIs

    #region Constructor
    public BlurWindow()
    {
        this.WindowStyle = System.Windows.WindowStyle.None;
        this.ResizeMode = System.Windows.ResizeMode.NoResize;
        this.Background = Brushes.Transparent;
    } 
    #endregion //Constructor

    #region Base class overrides
    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized( e );

        if ( Environment.OSVersion.Version.Major >= 6 )
        {
            var hwnd = new WindowInteropHelper( this ).Handle;
            var hs = HwndSource.FromHwnd( hwnd );
            hs.CompositionTarget.BackgroundColor = Colors.Transparent;

            hs.AddHook( new HwndSourceHook( this.WndProc ) );
            this.InitializeGlass( hwnd );
        }
    } 
    #endregion //Base class overrides

    #region Methods

    #region InitializeGlass
    private void InitializeGlass(IntPtr hwnd)
    {
        if ( !DwmIsCompositionEnabled() )
            return;

        // fill the background with glass
        var margins = new MARGINS();
        margins.cxLeftWidth = margins.cxRightWidth = margins.cyBottomHeight = margins.cyTopHeight = -1;
        DwmExtendFrameIntoClientArea( hwnd, ref margins );

        // initialize blur for the window
        DWM_BLURBEHIND bbh = new DWM_BLURBEHIND();
        bbh.fEnable = true;
        bbh.dwFlags = DWM_BB_ENABLE;
        DwmEnableBlurBehindWindow( hwnd, ref bbh );
    }
    #endregion //InitializeGlass

    #region WndProc
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if ( msg == WM_DWMCOMPOSITIONCHANGED )
        {
            this.InitializeGlass( hwnd );
            handled = false;
        }

        return IntPtr.Zero;
    } 
    #endregion //WndProc 

    #endregion //Methods
}

BlurWindow の使用例を次に示します。

var w = new BlurWindow();
w.Width = 100;
w.Height = 100;
w.MouseLeftButtonDown += (s1, e1) => {
    ((Window)s1).DragMove();
    e1.Handled = true;
};
w.Background = new SolidColorBrush( Color.FromArgb( 75, 255, 0, 0 ) );
w.Show();
于 2012-10-23T17:45:07.723 に答える
1

私は一度似たようなことをしましたが、次のものは必要ありませんでした:

  1. フォームをあまり動かす必要はありませんでした。
  2. 私のフォームの下で動きはありませんでした。

私がしたこと:

  1. 以前は、フォーム ウィンドウを一時的に (プログラムによって) 最小化していました。
  2. サイズと同じ座標の画像スニップをキャプチャするために使用されるフォーム。
  3. を適用した後、その画像を背景として設定しBlurBitmapEffectます。

素晴らしい答えではないと思いますが、私がやったことを書いているだけです!

このアプローチに興味がある場合は、この記事が役立ちます: http://www.codeproject.com/Articles/91487/Screen-Capture-in-WPF-WinForms-Application

于 2012-07-09T10:03:55.987 に答える