C# Winform - 프로그램이 최소화 될 때 작업 표시줄 창 깜빡이기 (FlashWindowEx)

반응형

개요

이번 포스팅에서는 C# Winform 프로그램의 창을 깜빡이게 하는 방법을 설명한다.

또한 예제를 통해 프로그램이 최소화되었을 때 창이 깜빡이고,

다시 창이 원상태로 바뀌었을 때에는 창이 깜빡이지 않는 기능을 구현해 보도록 한다.

<최소화 시 작업표시줄의 아이콘이 깜빡이는 C# 애플리케이션>

 

포스팅에서 설명하는 예제 프로젝트는 깃허브에서 다운로드 가능하다.

 

GitHub - luvris2/CSharp-Winforms-Example

Contribute to luvris2/CSharp-Winforms-Example development by creating an account on GitHub.

github.com


C# 애플리케이션의 창이 깜빡이려면 다음의 함수를 사용해야 한다.

FlashWindowEx 함수 (winuser.h)

FlashWindowEx 함수 설명

지정된 창을 깜빡인다. 창의 활성 상태는 변경되지 않는다.

이와 동일한 기능을 하는 FlashWindow 함수가 있다.

FlashWindow 함수는 지정된 창을 한 번만 깜빡인다.

 

FlashWindowEx 함수 구문 (문법)

BOOL FlashWindowEx(
  [in] PFLASHWINFO pfwi
);
  • [in] pfwi : FLASHWINFO 구조체에 대한 포인터를 뜻한다.

FLASHWINFO 구조체 정보

typedef struct {
  UINT  cbSize;
  HWND  hwnd;
  DWORD dwFlags;
  UINT  uCount;
  DWORD dwTimeout;
} FLASHWINFO, *PFLASHWINFO;
  • cbSize : 구조체의 크기(바이트)
  • hwnd : 깜빡일 창에 대한 핸들, 창을 열거나 최소화할 수 있다.
  • dwFlags : 플래시 상태, 이 매개 변수는 다음 값 중 하나 이상의 상태를 갖는다.
의미
FLASHW_ALL
0x00000003
창 캡션 및 작업 표시줄 단추를 모두 플래시합니다.
FLASHW_CAPTION
0x00000001
창의 캡션을 깜빡입니다.
FLASHW_STOP
0
깜박이는 것을 중지합니다. 시스템은 창을 원래 상태로 복원합니다.
FLASHW_TIMER
0x00000004
FLASHW_STOP 플래그가 설정될 때까지 계속 플래시합니다.
FLASHW_TIMERNOFG
0x0000000C
창이 전경으로 올 때까지 계속 깜박입니다.
FLASHW_TRAY
0x00000002
작업 표시줄 단추를 플래시합니다.
  • uCount : 창을 플래시할 횟수를 지정한다.
  • dwTimeout : 창이 깜빡이는 속도(밀리초)를 지정한다. 값이 0일 경우 기본 커서 깜빡이 속도를 갖는다.

C# Winform에서 FlashWindowEx 함수 사용하기

FlashWindowEx를 사용하기 위한 DLL 파일 호출

  • FlashWindowEx 함수를 C# 코드에서 사용할 수 있도록 DLL 파일을 호출한다.
  • FlashWindowEx 함수는 user32.dll 파일에 정의되어 있으며 기본적으로 제공되어 있다.
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

 

FLASHWINFO 구조체 정의

  • FlashWindowEx 함수의 매개 변수는 FLASHWINFO 구조체의 데이터를 참조한다.
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
private struct FLASHWINFO
{
    public UInt32 cbSize; // 크기 지정
    public IntPtr hwnd; // 깜빡일 윈도우 핸들
    public UInt32 dwFlags; // 깜빡임 옵션
    public UInt32 uCount; // 깜빡일 횟수
    public UInt32 dwTimeout; // 깜빡임 간격
}

 

FlashWindowEx 메서드 정의

  • 창이 깜빡이기 위한 세부 옵션을 설정한다.
  • 깜빡일 창의 핸들이 필요하므로 매개 변수에는 Form 이 필요하다.
  • 아래의 값은 예시로 넣었다.
public bool FlashWindowEx(Form form)
{
    FLASHWINFO fi = new FLASHWINFO();
    // 구조체의 크기를 계산해서 할당
    fi.cbSize = Convert.ToUInt32(System.Runtime.InteropServices.Marshal.SizeOf(fi));
    fi.hwnd = form.Handle; // 현재 창을 핸들로 사용
    fi.dwTimeout = 0; // 일반적인 커서 깜빡임 속도
    fi.dwFlags = 0x00000002; // 작업 표시줄 아이콘 깜빡이기
    fi.uCount = UInt32.MaxValue; // 깜빡임 횟수 무한 반복
    return FlashWindowEx(ref fi);
}

예제

윈도우 캡션바와 작업 표시줄 깜빡이게 하기

public Form1()
{
    InitializeComponent();
    
    // FlashWindowEx 함수 호출 : 창 깜빡이기
    FlashWindowEx(this);
}


[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
private struct FLASHWINFO
{
    public UInt32 cbSize; // 크기 지정
    public IntPtr hwnd; // 깜빡일 윈도우 핸들
    public UInt32 dwFlags; // 깜빡임 옵션
    public UInt32 uCount; // 깜빡일 횟수
    public UInt32 dwTimeout; // 깜빡임 간격
}

public bool FlashWindowEx(Form form, bool flashState)
{
    FLASHWINFO fi = new FLASHWINFO();
    fi.cbSize = Convert.ToUInt32(System.Runtime.InteropServices.Marshal.SizeOf(fi));
    fi.hwnd = form.Handle;
    fi.dwFlags = 0x00000003; 
    fi.uCount = UInt32.MaxValue;
    fi.dwTimeout = 0;

    return FlashWindowEx(ref fi);
}

창이 최소화될 때 창 깜빡이게 하기

[ 깜빡임 상태를 제어하기 위한 함수 수정 ]

창의 상태에 따라 깜빡이고 깜빡이지 않고를 설정하기 위해 FlashWindowEx 함수를 수정해 보자.

위에서 정의한 함수에서 상태에 따라 값을 다르게 줄 수 있도록 bool 매개 변수를 하나 추가해 주고,

조건문을 걸어 상황에 따라 다른 값을 부여하도록 코드를 수정한다.

// bool 매개 변수를 추가하여 깜빡임 제어
public bool FlashWindowEx(Form form, bool flashState)
{
    FLASHWINFO fi = new FLASHWINFO();
    fi.cbSize = Convert.ToUInt32(System.Runtime.InteropServices.Marshal.SizeOf(fi));
    fi.hwnd = form.Handle;
    fi.dwTimeout = 0;

	// bool 매개 변수가 참일 경우 깜빡이기
    if (flashState)
    {
        fi.dwFlags = 0x00000002; // 작업 표시줄 아이콘 깜빡이기
        fi.uCount = UInt32.MaxValue; // 깜빡임 횟수
    }
    // bool 매개 변수가 거짓일 경우 깜빡임 중지
    else
    {
        // 깜빡임 중지
        fi.dwFlags = 0;
        fi.uCount = 0;
    }
    return FlashWindowEx(ref fi);
}

 

[ 창의 상태를 감지하기 위한 메서드 정의 ] 

창이 최소화될 때 깜빡이는 효과를 연출하려면,

C# 애플리케이션이 작업 표시줄 밑으로 내려놨는지(최소화 상태) 아닌지를 알아야 한다.

폼 메서드의 Resize를 이용하면 창이 최소화 상태인지 확인할 수 있다.

  • 디자인 창으로 이동해서 폼을 선택한다.
  • 속성 창에서 이벤트(번개모양)로 변경한다.
  • Resize 메서드를 정의한다.

Resize 메서드 정의는 Resize 오른쪽 빈칸에 정의할 메서드 이름을 쓰고 엔터를 누르면 된다.

포스팅에서는 Form_Resize로 정의하였다.

 

폼 이벤트의 Resize 메서드를 정의해 준다.

  • FormWindowState : 윈도우 폼 창이 표시되는 방법을 확인할 수 있다.
    • 최대화 : Maximized 혹은 2
    • 최소화 : Minimized 또는 1
    • 보통 : Normal 또는 0
  • 위에서 수정한 FlashWIndowEx 함수의 두 번째 매개 변수(bool)를 최소화될 때는 true, 원상태로 돌아왔을 때는 false로 값을 전달하여 깜빡임을 제어하였다. 
// Form Resize 메서드
private void Form_Resize(object sender, EventArgs e)
{
    // 프로그램이 최소화되었을 때 작업표시줄 깜빡이기
    if (WindowState == FormWindowState.Minimized)   FlashWindowEx(this, true);
    // 프로그램이 원래 상태로 돌아왔을 때 작업표시줄 깜빡임 중지
    else   FlashWindowEx(this, false);
}

 

[ 전체 소스 코드 ]

더보기
namespace C__Winform_Flash_Window
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

        }

        // FlashWindowEx를 사용하기 위한 DLL 파일 호출
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

        // FLASHWINFO 구조체 정의
        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        private struct FLASHWINFO
        {
            public UInt32 cbSize; // 크기 지정
            public IntPtr hwnd; // 깜빡일 윈도우 핸들
            public UInt32 dwFlags; // 깜빡임 옵션
            public UInt32 uCount; // 깜빡일 횟수
            public UInt32 dwTimeout; // 깜빡임 간격
        }

        // FlashWindowEx 메서드 정의
        public bool FlashWindowEx(Form form, bool flashState)
        {
            FLASHWINFO fi = new FLASHWINFO();
            fi.cbSize = Convert.ToUInt32(System.Runtime.InteropServices.Marshal.SizeOf(fi));
            fi.hwnd = form.Handle;
            fi.dwTimeout = 0;

            if (flashState)
            {
                fi.dwFlags = 0x00000002; // 작업 표시줄 아이콘 깜빡이기
                fi.uCount = UInt32.MaxValue; // 깜빡임 횟수
            }
            else
            {
                // 깜빡임 중지
                fi.dwFlags = 0;
                fi.uCount = 0;
            }
            return FlashWindowEx(ref fi);
        }

        // 창의 최소화/보통/최대화 상태 감지
        private void Form_Resize(object sender, EventArgs e)
        {
            // 프로그램이 최소화되었을 때 작업표시줄 깜빡이기
            if (WindowState == FormWindowState.Minimized)   FlashWindowEx(this, true);
            // 프로그램이 원래 상태로 돌아왔을 때 작업표시줄 깜빡임 중지
            else   FlashWindowEx(this, false);
        }
    }
}

참고

마이크로소프트 공식 문서 - FlashWindowEX 함수(winuser.h)

마이크로소프트 공식 문서 - FLASHWINFO 구조체(winuser.h)

마이크로소프트 공식 문서 - FormWindowState 열거형

반응형