누구나 프로그래밍 작업 중에 오류 메시지 창의 귀찮음을 경험해본 적이 있을 것입니다. 특히 윈도우 버전의 문제로 발생하는 오류 메시지는 사소하지만 사용자의 작업 효율을 방해합니다. 이 글에서는 C#에서 제공하는 FindWindow()와 FindWindowEx() 함수를 이용하여 자동으로 해당 오류 창을 찾아서 닫는 방법을 소개합니다.
1. 오류 창 자동 닫기의 필요성
프로그램 사용 중 발생하는 오류는 다양한 원인이 있을 수 있습니다. 윈도우 버전과의 호환성 문제, 잘못된 입력, 외부 리소스 문제 등 다양한 요인이 있습니다. 이런 오류 메시지는 사용자에게 중요한 정보를 제공하기도 하지만, 때로는 단순한 정보 전달을 위한 것일 수 있습니다. 이런 오류 메시지를 매번 수동으로 닫는 것은 사용자의 작업 효율을 방해하고, 사용자 경험을 저하시킵니다.
그래서 만약 어플리케이션 에러가 뜨면 자동으로 꺼주는 프로그램을 만들어보았습니다.
2. 문제의 해결 접근방법
1. SPY++로 윈도우 핸들 찾기
윈도우의 각 요소에는 고유한 핸들이 있습니다. 이 핸들을 통해 프로그래밍 언어로 윈도우 요소를 제어할 수 있습니다. SPY++는 윈도우 API를 이용하여 윈도우의 핸들 정보를 제공하는 도구입니다. 이 도구를 통해 오류 메시지 창의 핸들 정보를 쉽게 얻을 수 있습니다.
2. FindWindow(), FindWindowEx() 함수의 활용
FindWindow()는 주어진 윈도우의 이름을 기반으로 그 윈도우의 핸들을 반환하는 함수입니다. 반환된 핸들을 통해 윈도우를 제어할 수 있습니다. FindWindowEx()는 특정 윈도우의 하위 윈도우 핸들을 찾는 함수입니다. 이 두 함수를 조합하면, 원하는 오류 메시지 창의 핸들을 찾아 제어할 수 있습니다.
소스는 다음과 같이 추가합니다.
Using System.Runtime.InteropServices;
using 구문을 꼭 추가해주어야 합니다.
그리고 FindWindow(), FindWindowEx() 함수는 윈도우 APIs 함수들이므로,
[DllImport("user32.dll")]
public static extern int FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);
[DllImport("user32")]
public static extern int SendMessage(int hwnd, int wMsg, int wParam, int lParam);
const int WM_LBUTTONDOWN = 0x0201;
const int WM_LBUTTONUP = 0x0202;
const int BM_CLICK = 0x00F5;
클래스 내부에 전역으로 선언을 해줍니다.
3. 클릭 이벤트 전송
윈도우의 핸들 정보를 얻었다면, SendMessage 함수를 이용하여 클릭 이벤트를 전송할 수 있습니다. 이를 통해 오류 메시지 창에 있는 "프로그램 닫기" 버튼을 자동으로 클릭하여 오류 창을 닫을 수 있습니다.
int nhwnd = FindWindow(null, "...MFC Application"); // 윈도우 창 제목
if (nhwnd > 0)
{
int hw1 = FindWindowEx(nhwnd, 0, "DirectUIHWND", "");
if (hw1 > 0)
{
int hw2 = FindWindowEx(hw1, 0, "CtrlNotifySink", "");
if (hw2 > 0)
{
while (true)
{
int hw3 = FindWindowEx(hw2, 0, "Button", "프로그램 닫기");
if (hw3 > 0)
{
SendMessage(hw3, BM_CLICK, 0, 1); //마우스 클릭이벤트
break;
}
hw2 = FindWindowEx(hw1, hw2, "CtrlNotifySink", "");
if (hw2 == 0)
{
break;
}
}
}
}
}
SPY++에서 보는 그림처럼 똑같은 클래스가 하위로 여러개 있는데 원하는 버튼이 들어있는 하위클래스를 찾기위해서는 hw1의 핸들 중 hw2의 핸들 다음번째 값을 넣어서 원하는 핸들 클래스로 넘어갑니다.
hw2 = FindWindowEx(hw1, hw2, "CtrlNotifySink", "");
소스파일
위에서 사용한 코드의 소스파일을 압축하여 첨부합니다.
결론
프로그래밍은 끊임없는 문제 해결 과정입니다. 오류 메시지 창은 때로는 중요한 정보를 제공하지만, 매번 수동으로 닫아야 하는 번거로움도 있습니다. C#의 FindWindow(), FindWindowEx() 함수를 활용하면, 이런 오류 메시지 창을 자동으로 찾아 닫는 프로그램을 만들 수 있습니다. 이를 통해 사용자의 작업 효율을 높이고, 더 나은 사용자 경험을 제공할 수 있습니다.
SPY++ 사용하는 방법 : [프로그래밍/etc] - spy++를 사용해서 사용클래스 및 핸들 알아보기
'Language > C# WPF' 카테고리의 다른 글
[C#] OpenFileDialog 활용하여 파일 선택하기 (0) | 2023.09.22 |
---|---|
C# 콘솔 창 실행 시 입력 대기하여 꺼지지 않도록 하기 (0) | 2023.09.09 |
[C#] 문자열에서 원하는 위치의 글자만 가져오기 (0) | 2023.08.28 |
[C#] Excel 엑셀파일 읽어서 DataGridView 출력하기 EPPlus (0) | 2023.04.06 |
[C#] Excel 엑셀파일 읽어서 원하는 셀 값 출력하기 (2) | 2023.04.03 |