C# Windows Mobile에서 Win32 API를 이용한 반투명 윈도우 폼 구현

Windows Mobile 환경의 .NET Compact Framework에서는 데스크톱 .NET Framework와 달리 폼의 투명도를 직접 제어할 수 있는 Opacity 속성을 기본적으로 지원하지 않습니다. 따라서 윈도우 폼을 반투명하게 만들기 위해서는 P/Invoke를 통해 coredll.dll에 존재하는 Win32 API를 직접 호출해야 합니다.

반투명 폼을 구현하기 위해 주로 사용되는 핵심 Win32 API는 다음 세 가지입니다.

  • GetWindowLong: 현재 윈도우의 확장 스타일 정보를 가져옵니다.
  • SetWindowLong: 윈도우에 WS_EX_LAYERED 확장 스타일을 추가하여 레이어링을 활성화합니다.
  • SetLayeredWindowAttributes: 활성화된 레이어 윈도우에 알파 블렌딩(투명도) 값을 적용합니다.

핵심 구현 로직

폼의 핸들을 사용하여 현재 스타일을 가져온 뒤, 레이어 스타일을 비트 연산으로 추가하고 최종적으로 투명도 값을 설정하는 메서드는 다음과 같습니다.

private void ApplyFormOpacity(byte alphaValue)
{
    IntPtr handle = this.Handle;
    
    // 현재 확장 윈도우 스타일 조회
    uint currentExStyle = GetWindowLong(handle, GWL_EXSTYLE);
    
    // WS_EX_LAYERED 스타일 추가
    SetWindowLong(handle, GWL_EXSTYLE, currentExStyle | WS_EX_LAYERED);
    
    // 알파 블렌딩 적용
    SetLayeredWindowAttributes(handle, 0, alphaValue, LWA_ALPHA);
}

전체 소스 코드

아래는 트랙바(TrackBar) 컨트롤을 사용하여 실시간으로 폼의 투명도를 조절할 수 있도록 구현한 전체 코드입니다. P/Invoke 선언부와 이벤트 핸들러가 포함되어 있습니다.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WmTransparentForm
{
    public partial class MainForm : Form
    {
        // Win32 API 상수 정의
        private const int GWL_EXSTYLE = -20;
        private const uint WS_EX_LAYERED = 0x00080000;
        private const uint LWA_ALPHA = 0x00000002;

        // coredll.dll P/Invoke 선언
        [DllImport("coredll.dll", SetLastError = true)]
        private static extern uint GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("coredll.dll", SetLastError = true)]
        private static extern uint SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);

        [DllImport("coredll.dll", SetLastError = true)]
        private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);

        public MainForm()
        {
            InitializeComponent();
            this.Load += MainForm_Load;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            // 화면 중앙에 폼 위치
            var screenBounds = Screen.PrimaryScreen.WorkingArea;
            this.Location = new Point(
                (screenBounds.Width - this.Width) / 2,
                (screenBounds.Height - this.Height) / 2
            );
        }

        /// <summary>
        /// 현재 폼에 지정된 알파 투명도를 적용합니다.
        /// </summary>
        /// <param name="alphaValue">투명도 레벨 (0 ~ 255)</param>
        private void ApplyFormOpacity(byte alphaValue)
        {
            try
            {
                IntPtr handle = this.Handle;
                uint currentExStyle = GetWindowLong(handle, GWL_EXSTYLE);
                SetWindowLong(handle, GWL_EXSTYLE, currentExStyle | WS_EX_LAYERED);
                SetLayeredWindowAttributes(handle, 0, alphaValue, LWA_ALPHA);
            }
            catch (Exception ex)
            {
                MessageBox.Show("투명도 적용 실패: " + ex.Message);
            }
        }

        private void opacityTrackBar_ValueChanged(object sender, EventArgs e)
        {
            byte currentAlpha = (byte)opacityTrackBar.Value;
            opacityLabel.Text = $"Opacity (0~255): {currentAlpha}";
            ApplyFormOpacity(currentAlpha);
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

위 코드에서 opacityTrackBar 컨트롤의 최소값은 0, 최대값은 255로 설정해야 하며, 값이 변경될 때마다 ApplyFormOpacity 메서드가 호출되어 실시간으로 윈도우의 투명도가 업데이트됩니다.

태그: C# Windows Mobile .NET Compact Framework Win32 API P/Invoke

6월 17일 05:58에 게시됨