콘텐츠로 건너뛰기

윈도우가 다른 윈도우에 가려졌는지 확인

화면을 제어하는 프로그램에서 내가 만든 윈도우 또는 제어해야 하는 윈도우가 다른 윈도우에 가려졌는지 확인해야 하는 경우가 있습니다. 다른 화면에 완전히 가려진 경우 사용자 관점에서는 보이지 않는 윈도우이므로 없는 것 처럼 처리해야 합니다. 윈도우가 다른 윈도우에 가려졌는지 확인 방법에 대해 알아보도록 하겠습니다.

윈도우가 겹치는 케이스 유형

Win32API에서 Window Handle(HWND) 기반으로 최소화 되었는지 실제 보여지는 윈도우 인지 쉽게 파악할 수 있으나 다른 윈도우에 가려진 여부는 Win32API만 가지고 쉽게 파악할 수 없습니다.

일반적으로 윈도우가 겹치는 경우는 다음 그림과 같이 4개 유형으로 나누어 살펴볼 수 있습니다.

윈도우 겹치는 유형
  • Case #1: 다른 윈도우와 겹치는 않는 경우
  • Case #2: 다른 윈도우에 일부 겹친 경우
  • Case #3: 다른 윈도우에 가려져 보이지 않는 경우
  • Case #4: 다른 윈도우에 가려졌으나 윈도우가 투명도가 존재하여 화면이어서 보이는 경우

윈도우가 다른 윈도우에 가려졌는지 확인하기

대상 윈도우 Region에서 상위 윈도우 Region을 빼고 남은 영역이 없으면 다른 윈도우에 가려졌다고 판단할 수 있습니다. 단, 상위 윈도우에 투명 속성이 있을 경우는 계산에서 제외합니다

이렇게 Region을 계산을 할 경우 아래 그림과 같이 표현할 수 있습니다.

남아 있는 영역 계산
남아 있는 영역 계산

소스 코드

Window Handle이 겹쳐 있는지 확인하는 코드는 다음과 같습니다.

BOOL IsObscuredWindow(HWND hwnd)
{
	BOOL ret = FALSE;
	HWND window_handle = hwnd;

	RECT target_rect = { 0, };
	GetWindowRect(hwnd, &target_rect);
	HRGN target_region = CreateRectRgnIndirect(&target_rect);

	if ( NULL == target_region )
	{
		return FALSE;
	}

	RECT current_rect = { 0, };
	HRGN current_region = NULL;

	LONG_PTR style = 0L;

	while ( (window_handle = GetNextWindow(window_handle, GW_HWNDPREV)) != NULL )
	{
		if ( !IsWindowVisible(window_handle) )
		{
			continue;
		}

		style = GetWindowLongPtrW(window_handle, GWL_EXSTYLE);

		if ((style & WS_EX_LAYERED) || (style & WS_EX_NOREDIRECTIONBITMAP) || (style & WS_EX_TRANSPARENT))
		{
			continue;
		}

		GetWindowRect(window_handle, &current_rect);
		current_region = CreateRectRgnIndirect(&current_rect);

		if ( NULL == current_region )
		{
			continue;
		}

		if ( NULLREGION == CombineRgn(target_region, target_region, current_region, RGN_DIFF) )
		{
			ret = TRUE;
			break;
		}

		DeleteObject(current_region);
	}

	DeleteObject(target_region);

	return ret;
}

참고 자료

답글 남기기

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