끝나지 않는 프로그래밍 일기

[API 탐방기]


최상위의 핸들을 찾는

FindWindow




먼저, FindWindow API에 대해 알아보기 전에 이 API의 원형을 한번 살펴보도록 합시다.

HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName);

원형에서 첫번째 인수를 먼저 살펴보면, IpClassName이 있는데, 우리가 검색 시에 사용할 윈도우의 클래스 이름을 말합니다. 만약 NULL이라면 모든 윈도우의 클래스를 검색하게 됩니다. 두번째 인수에서 IpWindowName은 윈도우의 제목을 말합니다. 이것 역시 NULL이면 모든 제목의 윈도우를 검색하게 됩니다. (대소문자는 구분하지 않습니다. 또한 부분 검색은 되지 않으며 완벽하게 일치해야만 합니다.)


만약 검색에 성공했으면 FindWindow는 윈도우의 핸들(Handle)을 반환합니다. 실패하면 NULL를 반환합니다. 여기서 핸들이란, 각 윈도우 마다 붙여진 번호입니다. 핸들은 운영체제가 부여해주며, 정수값을 가집니다.) 이제 어디한번, 아무 프로그램이나 킨 후에 그 프로그램이 켜져있는지, 꺼져있는지 알려주는 프로그램을 간단히 만들어보도록 합시다. 저같은 경우는 "지뢰 찾기"를 예를 들어 작성하겠습니다.


<지뢰 찾기 게임>


위 프로그램이 켜져있나, 꺼져있나 확인하기 위해 FindWindow API를 사용하겠습니다. 그리고 윈도우 창 제목(지뢰찾기)를 두번째 인수로 넘겨주고, 첫번째 인수는 NULL로 두었습니다.

#include <stdio.h>
#include <windows.h>

int main(void)
{
	HWND hWnd = FindWindow(NULL, TEXT("지뢰 찾기"));

	if (hWnd) 
		printf("지뢰 찾기가 실행 중 입니다.\n");
	else
		printf("지뢰 찾기를 실행하지 않았습니다.\n");

	return 0;
}

컴파일 후 결과를 확인해보면 지뢰 찾기의 실행 여부에 따라 출력되는 결과물이 달라짐을 알 수 있습니다.


만약 자식 윈도우를 검색하고 싶다면 FindWindow가 아닌 FindWindowEx를 쓰시면 됩니다.

HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter, LPCTSTR lpClassName, LPCTSTR lpWindowName);

첫번째 인수는 부모 윈도우의 핸들, 두번째 인수는 자식 윈도우의 핸들, 세번째 인수는 클래스명, 네번째 인수는 윈도우 창 제목입니다. (캡션이라 하기도 함) FindWindow와 마찬가지로 찾고자 하는 윈도우의 클래스명 혹은 제목을 NULL로 둘 수 있습니다. 이번에는 Visual Basic6으로 만들어진 프로그램 내에 있는 버튼의 핸들값을 구해보도록 하겠습니다.


<Visual Basic6으로 만들어진 간단한 프로그램>


#include <stdio.h>
#include <Windows.h>

int main(void)
{
	HWND h1 = FindWindow(NULL, TEXT("폼"));
	HWND h2 = FindWindowEx(h1, NULL, NULL, TEXT("버튼"));

	if (h1)
		printf("폼의 핸들값: %d\n버튼의 핸들값: %d\n", h1, h2);
	else
		printf("폼을 실행하지 않았습니다.\n");

	return 0;
}

결과:

폼의 핸들값: 330586

버튼의 핸들값: 265058

계속하려면 아무 키나 누르십시오 . . .


FindWindowEx API를 이용하면 나중에 배우게 될 SendMessage API를 사용하여 버튼의 핸들값을 구하고, 그 버튼을 클릭하게 하는 이벤트를 발생시킬 수 있습니다.