Develop

[c] 윈도우 API Viewport와 Window

by hooni posted Apr 23, 2013
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄
디바이스 좌표를 가지고 있는 어떤 좌표 평면의 영역이을 Viewport라고 하고 로직좌표를 가지고 있는 어떤 좌표 평면을 Window라고 한다.
이런 개념을 쓰는 이유는 좌표 평면의 정보를 수정하고자 할경우가 있기 때문이다.
그림의 (a)처럼  MM_TEXT에서는 좌측 상단 이 (0,0)의 초기점이다. 이때 때로는 화면 영역의 중앙이 (0,0)으로 하고자 할경우가 있다 그림의 (b)처럼 말이다. 이럴 경우 SetWindowOrgEx라는 함수를 사용하여 이동시킬수 있다.

viewport.gif

BOOL SetWindowOrgEx(
    HDC hdc, // 디바이스 컨텍스 핸들
    int X, // 이동 X좌표
    int Y, // 이동 Y좌표
    LPPOINT lpPoint // 이전 좌표
);

예를 들어 화면의 현재 전체 영역이 (400,400)이라고 가정을 하고 (b)같은 좌표로 전환하고자 할 경우 다음과 같이 할수 있다.

SetWindowOrgEx(hdc,200,200,NULL);

SetWindowOrg라는 함수는 로직 좌표계에서 초기 좌표를 이동하는 함수이다.
전항목에서 좌표계를 디바이스 좌표계와 로직좌표계 두 개를 사용한다고 하였습니다.
SetWindowOrg함수에 의해서 로직 좌표계의 좌표원점이 이동하였다하여도 디바이스 좌표계의 원점이 이동되는 것은 아닙니다.
다바이스 좌표계의 원점을 이동하고자 한다면 SetViewportOrgEx라는 함수를 사용한다.

BOOL SetViewportOrgEx(
    HDC hdc, // 디바이스 컨텍스 핸들
    int X, // 이동 X좌표
    int Y, // 이동 Y좌표
    LPPOINT lpPoint // 이전 좌표
);

MM_LOMETRIC 로 맵핑모드를 설정하고 로직좌표와 디바이스좌표 중앙에 원점을 설정하고자 한다면 다음과 같은 형식이 될것이다.

1) 클라이언트 전체 영역을 얻는다.
   GetClientRect(hwnd,&rect)
    
2) rect좌표는 dc와 상관되는 좌표가 아닙니다. 이좌표는 디바이스 좌표이다.
   디바이스좌표를 이용하여 원점을 이동하는 함수가 SetViewportOrg이므로
SetViewportOrgEx(hdc,rect.right/2,rect.bottom/2,NULL);

3) 이제 rect를 로직좌표로 전환을 하고 로직좌표계의 원점을 이동한다.
DPtoLP(hdc,(PPOINT)&rect,2);
SetWindowOrgEx(hdc,rec,right/2,rect.bottom/2,NULL);

좌표를 리턴하는 함수들중에 디바이스 좌표만 리턴하는 경우의 함수들이 있다.
위의 예에서 보듯이 GetClientRect함수는 dc에서 얻는 함수가 아니기 때문에 디바이스 좌표를 리턴한다.
이외에 GetDeviceCaps라는 함수는 DC를 이용하지만 로직좌표계가 아닌 디바이스좌표를 리턴한다.
프로그래밍 할 경우 특정 맵핑모드를 선언하였을 경우 함수가 디바이스좌표를 리턴하는가? 또는 로직좌표를 리턴하는가에 대해서 주의를 해주어야 한다.
좌표평면 정보를 수정할 경우 어떤 좌표평면을 수정할것인가를 알려주어야 하기 때문에 디바이스 좌표평면을 보통 Viewport라고하며 로직좌표 평면을 Window라고 한다.