WPF C#에서 반투명 윈도우 만들기

윈도우10 계산기 앱 처럼 반투명하게 해주는거 궁금해서 검색해보고 테스트 해본담에 여기 정리해둠.

결론부터 적자면 원청업체가 “무조건 반투명 기능 있어야 한다” 라고 말하는거 아니면 안쓰길 추천함. 노트북이 구려서 그런지 별다른 기능도 없는 기본 앱인데 계산기 앱보다 창 이동시 뭔가 버벅거림이 느껴짐 (위 이미지는 광고가 붙어있지만 테스트 할때는 광고 코드 빼고 해봤음)

public class AcrylicTransparency {

    [DllImport("user32.dll")]
    internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

    public enum WindowCompositionAttribute { 
        WCA_ACCENT_POLICY = 19 
    }
    public enum AccentState {
        ACCENT_DISABLED = 0,
        ACCENT_ENABLE_GRADIENT = 1,
        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
        ACCENT_ENABLE_BLURBEHIND = 3,
        ACCENT_INVALID_STATE = 4
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct WindowCompositionAttributeData {

        #region Field 
        public WindowCompositionAttribute Attribute;
        public IntPtr DataHandle;
        public int DataCount;
        #endregion
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct AccentPolicy {
        public AccentState AccentState;
        public int AccentFlags;
        public int GradientColor;
        public int AnimationId;
    }
 
    public static void turnOn(Window win) {
        IntPtr hwnd = new WindowInteropHelper(win).Handle;

        if (hwnd == IntPtr.Zero)                                                 
            throw new InvalidProgramException("에러!!!!!");

        win.Background = Brushes.Transparent;                          
        HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent;

        AccentPolicy accent = new AccentPolicy();
        int accentStructSize = Marshal.SizeOf(accent);

        accent.AccentState = AccentState.ACCENT_ENABLE_BLURBEHIND;

        IntPtr accentPtr = Marshal.AllocHGlobal(accentStructSize);
        Marshal.StructureToPtr(accent, accentPtr, false);

        WindowCompositionAttributeData data = new WindowCompositionAttributeData();
        data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
        data.DataCount = accentStructSize;
        data.DataHandle = accentPtr;

        SetWindowCompositionAttribute(hwnd, ref data);

        Marshal.FreeHGlobal(accentPtr);
    }
}

위 클래스를 소스에 넣어주고

public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        this.SourceInitialized += MainWindow_SourceInitialized;
    }

    private void MainWindow_SourceInitialized(object? sender, EventArgs e) {
        //AcrylicTransparency.turnOn(this);
    }

    private void Window_Loaded(object sender, RoutedEventArgs e) {
        AcrylicTransparency.turnOn(this);
    }
}

Loaded 에서 실행하면 타이틀바는 반투명이 되지 않고 (위 스샷 처럼)
SourceInitialized에서 실행하면 타이틀바 까지 반투명이 됨.

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" 
        MinHeight="600"
        MinWidth="990"
        Height="600" Width="990"
        Loaded="Window_Loaded">
    
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Border Grid.Column="0" 
                BorderThickness="0"
                Background="#50000000">
            <StackPanel>
                <TextBlock Text="테스트" Foreground="White"
                       FontSize="20"/>
                <TextBlock Text="테스트" Foreground="White"
                       FontSize="20"/>
            </StackPanel>
        </Border>

        <Grid Grid.Column="1" 
                Background="#5f0000ff"
                Name="border1">
            <StackPanel>
                <TextBlock Text="테스트" Foreground="White"
                       FontSize="20"/>
                <TextBlock Text="테스트" Foreground="White"
                       FontSize="20"/>
            </StackPanel>
        </Grid>
    </Grid>
</Window>

이건 MainWindow.xaml입니다.


Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다