F.R.I.D.A.Y.

GetWindowRect vs GetClientRect 본문

DEV/C C++

GetWindowRect vs GetClientRect

F.R.I.D.A.Y. 2021. 4. 7. 11:17
반응형

GetWindowRect와 GetClientRect 함수의 차이를 알아봅니다.


윈도우의 구성

  윈도우는 다음과 같이 구성되어 있습니다.

 Windows에서 제공하는 테두리와 실제 개발자가 작성하고 관리하는 클라이언트 영역, 두 영역으로 나뉘어 있습니다.

 

비클라이언트 영역

 비클라이언트 영역은 Windows에서 관리합니다.

 비클라이언트 영역(non-client area)을 포함하는 윈도우 크기를 가져올 때는 GetWindowRect 함수를 사용합니다.

 

클라이언트 영역

 클라이언트 영역은 개발자가 관리합니다.

 클라이언트 영역의 윈도우 크기를 가져올 때는 GetClientRect 함수를 사용합니다.

 

Direct2D에서의 사용

 Direct2D는 렌더링 타겟의 크기를 기준으로 대상을 그립니다. 따라서 렌더링 타겟의 크기를 정하는 것은 굉장히 중요합니다.

 

 두 가지 경우로 설명하겠습니다. 마우스 클릭을 할때 마우스 중심으로 크기 30인 사각형이 출력되도록 구성 했습니다.

 

GetWindowRect로 설정한 경우

 좌측 상단에서부터 우측 하단으로 갈수록 마우스로 클릭한 부분과 출력되는 사각형의 중심이 다릅니다.

 

GetClientRect로 설정한 경우

 좌측 상단이던 우측 하단이던 마우스 클릭한 부분과 출력이 되는 사각형의 중심이 같습니다.

 

원인

 Windows의 Direct2D는 그리기를 픽셀 단위로 하지 않습니다. 모든 디바이스 크기에 맞추어 동일한 크기를 위해 Device-Independent Pixels, DIPs라 불리는 단위를 사용합니다. 때문에 디스플레이의 물리적인 픽셀의 크기와 다를 수 있습니다. WM_LBUTTONDOWN의 lParam에서 전달된 마우스 좌표 단위와 HwndRenderTarget에서 사용하는 좌표 단위가 다르기 때문에 발생하는 문제였습니다.

 

 단위가 다르다보니 좌표가 계산되는 위치가 다릅니다. 그래서 이런 문제가 발생한 것이었습니다. 따라서 GetWindowRect 대신 GetClientRect 함수를 이용하면 문제가 해결됩니다.

 

추가 내용

 이 문제는 단순히 GetWindowRect를 이용해 좌표 계산을 하면 되겠지만, 디스플레이 배율 레이아웃에서 디스플레이 배율이 달라지면 계산 단위가 또 달라집니다. 그래서 이 문제를 해결하려면 픽셀 단위를 DIPs로 변경하는 로직을 추가로 구성해야합니다.

 

# index

728x90
반응형
Comments