본문 바로가기
.NET C#

Aero Glass(에어로 글래스) 사용하기

by 태디 2008. 8. 24.
728x90

WPF에서 에어로 글래스를 사용하기 위해서는 DwmExtendFrameIntoclientAero API를 호출해야 합니다.

 참고 : DWM : DeskTop Window Manager

윈도우의 투명색은 다른 여러가지 색으로도 변경이 가능하며 무채색으로도 효과를 줄 수 있습니다. DeskTop Window Manager 사용하기 위해서는 PInvoke(Platform Invoke)를 사용해야 합니다. WPF에 관리되지 않는 코드이기 때문에 Win32의 API를 호출해야 합니다.

using System.Runtime.InteropServices;

네임스페이스에 Win32 API를 호출하기 위한 네임스페이스를 선언합니다.

[DllImport("dwmapi.dll", PreserveSig = false)]
static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);
 
[DllImport("dwmapi.dll", PreserveSig = false)]
static extern bool DwmIsCompositionEnabled();

C#에서 Win32 Api 호출


xaml code
<Window x:Class="WpfAeroGlass.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="320" Width="480">
    <Grid>
       
    </Grid>
</Window>


AeroGrassHelper
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
using System.Runtime.InteropServices;
using System.Windows.Interop;
 
namespace WpfAeroGlass
{
    public class AeroGlassHalper
    {
        public struct MARGINS
        {
            public MARGINS(Thickness t)
            {
                Left = (int)t.Left;
                Right = (int)t.Right;
                Top = (int)t.Top;
                Bottom = (int)t.Bottom;
            }
 
            public int Left;
            public int Right;
            public int Top;
            public int Bottom;
        }
 
        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);
 
        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern bool DwmIsCompositionEnabled();
 
        public static bool ExtendGlassFrame(Window window, Thickness margin)
        {
            if (!DwmIsCompositionEnabled())
                return false;
 
            IntPtr hwnd = new WindowInteropHelper(window).Handle;
            if(hwnd == IntPtr.Zero)
                throw new InvalidProgramException("The Window must be shown before extending glass.");
 
            window.Background = Brushes.Transparent;
            HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
 
            MARGINS margins = new MARGINS(margin);
            DwmExtendFrameIntoClientArea(hwnd, ref margins);
            return true;
        }
    }
} 

window.Background = Brushes.Transparent;
HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;
위의 코드는 WPF와 Win32 모두 투명한 배경으로 설정합니다.

cs code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
namespace WpfAeroGlass
{
    ///<summary>
    /// Window1.xaml에 대한 상호 작용 논리
    ///</summary>
    public partial class Window1 : Window
    {
        private bool neverRendered = true;
 
        public Window1()
        {
            InitializeComponent();
 
            this.SourceInitialized += new EventHandler(Window1_SourceInitialized);
        }
 
        void Window1_SourceInitialized(object sender, EventArgs e)
        {
            AeroGlassHalper.ExtendGlassFrame(this, new Thickness(-1));
        }
 
        protected override void OnContentRendered(EventArgs e)
        {
            if (neverRendered)
            {
                SizeToContent = SizeToContent.Manual;
 
                FrameworkElement root = this.Content as FrameworkElement;
 
                if (root != null)
                {
                    root.Width = double.NaN;
                    root.Height = double.NaN;
                }
 
                this.neverRendered = false;
            }
 
            base.OnContentRendered(e);
        }
 
    }
}
 

AeroGlassHalper 클래스의 ExtendGlassFrame메소드는 윈도우의 크기를 확장할때 그 크기에 맞추어 에어로 글래스 효과를 줄지 결정하는 역활을 합니다. 윈도우의 모든 영역을 투명창으로 하려면 -1를 넘겨줍니다. 인수타입은 Thickness 입니다.

오버라이드 된 OnContentRendered 이벤트에서 base.OnContentRendered(e);를 계속 호출하는 것은 윈도우가 랜더링 될때마다 윈도우의 전체영역에서 투명효과를 주기위해서 입니다.

사용자 삽입 이미지




사용자 삽입 이미지



저의 노트북 바탕화면을 실버라이트 심벌로 해놨습니다.^^ 그 위에 WPF 윈도우창이 에어로 글래스 효과를 주어 반투명창 효과가 나타났고 그 뒤에 윈도우의 배경화면이 보입니다.,

참고 사이트 및 도서
http://blogs.msdn.com/adam_nathan/archive/2006/05/04/589686.aspx (에덤네이선의 블로그)
에덤네이선의 WPF 언리쉬드(참고도서)

※ AeroGrassHelper 의 원본코드의 저작권은 에덤네이선(Adam Nathan)에게 있음을 알려드립니다.

댓글