자료 저장소

Mapping Mode

학습 목표

  1. Mapping Mode 이해하기
  2. 논리좌표와 물리좌표의 차이점 이해하기
  3. WindowsPort와 ViewPort 차이점 이해하기
  4. Primary DC의 설정 방법 익히기

 

Mapping Mode의 이해

  • 이전의 윈도우 프로그램에서는 실행 중 윈도우 크기를 변경하면
    • 윈도우 크기가 변경되면서 여러가지 Data값들이 달라지게 됨
    • 해결방법 :
      • WM_SIZE에 윈도우 크기를 계산하고, 상대적 영역 좌표를 사용하는 방법
      • 보다 전문적인 Mapping Moder를 사용하는 방법
  • WM_SIZE : 윈도의 크기가 변경 후 발생되는 메시지
  • 이렇게 윈도우 크기가 변경될 때, 그때까지 움직이던 모든 데이터는 다시 초기화
    • 번거로움 (작성되었던 모든 소스 모두 변경)
    • Mapping Mode 사용 (상대적 영역 계산 필요없음)

논리 좌표와 물리 좌표

  • 논리좌표     
    • 우리가 생각하는 좌표
  • 물리좌표
    • 실제 Display장치(Window)에 표현되는 좌표단위와 체계
    • 지금까지는 논리적 단위와 물리적 단위의 두 체계가 같았기 때문에 문제가 없었음

p.X += 20;

OffsetRect(&m_Rect, 100, 0);

// 20과 100의 단위 ? Pixel (논리와 물리좌표 같이 설정됨)

            

  • 서로 다른 두 좌표체계에서 나타나는 현상은 무엇일까?
    • 지구에서 한 걸음을 뛸 때와 달에서 한 걸음 뛸 때 어떻게 다를까?
    • 논리적 개념
      • 한 걸음
    • 물리적 개념
      • 지구 (A 모드)
      • 달 (B 모드)

 

매핑 방식의 변경

  • DC :
    • 펜이나 브러쉬, 폰트 같은 것들 외에도 많은 정보를 지님
    • 물리적(Device) 좌표 체계에 대한 정보를 가지고 있음
  • SetMapMode함수 :
    • 매핑모드의 결정
      • 미리 설정된 몇 가지의 단위 체계를 선택하여 변경하는 방법
      • 임의의 단위로 설정하여 변경하는 방법

    

(예 1)

    SetMapMode(hdc,MM_LOMETRIC);

    OffsetRect(&m_Rect, 100, 0);

  • 논리적 단위 1을 물리적 단위 0.1mm로 매핑함
  • 100*0.1mm = 10mm 이동

(예 2)

    SetMapMode(hdc,MM_HIMETRIC);

    OffsetRect(&m_Rect, 100, 0);

  • 논리적 단위 1을 물리적 단위 0.01mm로 매핑함
  • 100*0.01mm = 1mm 이동

     

  • 임의의 단위로 설정하여 변경하는 방법
    • MM_ANISOTROPIC
    • MM_ISOTROPIC

다음 함수의 사용 수반

  • SetWindowExtEx
  • SetViewportExtEx

 

  • 단위의 임의 설정 모드를 사용하면
    • 논리적 단위와 물리적 단위를 모두 설정할 수 있는데, 이렇게 되면 논리적 단위와 물리적 단위간의 Scale은 상대적인 개념이 됨

       

 

 

 

  • 논리적(WindowPort)에서 물리적(ViewPort)로의 매핑공식

    xViewPort/xViewExt = xWindowPort / xWinExt

    xWindowPort = xWinExt * (xViewPort/xViewExt)

    Case 1 : xWindow = 50 * 10/100 = 5의 위치

    Case 2 : xWindow = 500 * 10/100 = 50의 위치

    xViewPort = xViewExt *(xWindowPort / xWinExt)

    Case 1 : xViewPort = 100 * 5/50 = 10의 위치

    Case 2 : xViewPort = 100 * 50/500 = 10의 위치

    LPtoDP (Logic-> Device)

    DPtoLP (Device-> Logic)

 

  • Case 1의 경우

    SetMapMode(hdc, MM_ISOTROPIC);

    SetViewportExtEx(hdc, 50, 50, NULL);

    SetWindowExtEx(hdc, 100, 100, NULL);

    • Case 2의 경우

    SetMapMode(hdc, MM_ISOTROPIC);

    SetViewportExtEx(hdc, 500, 500, NULL);

    SetWindowExtEx(hdc, 100, 100, NULL);

 

  • MM_ISOTROPIC과 MM_ANISOTROPIC
    • 종횡비를 1:1 로 고정 여부
    • 예: 반경(50,50)의 동일한 원을 그릴 때

            MM_ISOTROPIC은 원

            MM_ANISOTROPIC은 타원

  • 상대적 비율의 개념
    • 물리적 뷰포트/논리적 윈도우포트
    • 논리적 크기가 고정되면, 물리적 크기가 작아질수록 상대적으로 작게 보여지며, 물리적 크기가 클수록 상대적으로 크게 보임

// 윈도우 크기 변화에 따른 실제적인 매핑모드 설정

    SetMapMode(hdc, MM_ISOTROPIC);

    GetClientRect(hWnd, &r);

    SetViewportExtEx(hdc, r.right, r.bottom, NULL);

    SetWindowExtEx(hdc, 760, 510, NULL);

// 글자 크기 단위의 좌표체계

    SetMapMode(hdc, MM_ANISOTROPIC);

    SetViewportExtEx(hdc, charSize.cs, charSize.cy, NULL);

    SetWindowExtEx(hdc, 1, 1, NULL);

* charSize는 GetTextExtentPoint32()나 GetTextMetrics()함수로 알아냄

* 모니터의 해상도나 기타 시스템 정보는 GetSystemMetrics()나 GetDeviceCaps()로 알아냄

 

논리좌표와 물리좌표 사이의 변환

  • 마지막 매핑모드를 설정한 프로그램에서, 윈도우 크기가 변경된 후에는 마우스르르 클릭하여 드래깅해도 바가 움직이지 않음
  • 실제 마우스가 눌려진 위치가 논리적인 Bar의 영역에 있지 않기 때문
  • 마우스가 눌려지면 시스템은 WM_LBUTTONDOWN과 함께 좌표를 전달하는데, 이때 전달되는 좌표는 무조건 Device좌표임
  • 이때의 마우스 Device 좌표는 실제 프로그램에서 처리되고 있는 수치(논리적 좌표)와 일치하지 않음
  • 윈도우와 관련하여 시스템에 의해 WndProc에 전달되는 모든 좌표는 항상 언제나 Client 공간내로 국한되는 Device좌표로 통일되어 있음
  • WM_LBUTTONDOWN, WM_MOUSEMOVE, WM_LBUTTONUP 등이 이에 해당함 (GetClientRect도 마찬가지)
  • case WM_LBUTTONDOWN :

            p = MakePoint(lParam);

            if(PtInRect(&m_BarRect, p))

                m_bFlag = TRUE;

            break;

  • 마우스가 눌렸을 때 이 위치가 바의 영역에 있는가를 검사하는 항상 참이 될 수 없음
  • 따라서 이때 Device좌표를 Logic좌표로 변화해야 할 필요가 있음
  • DPtoLP(), LPtoDP()함수 제공
  • DPtoLP()를 사용하여 윈도우 시스템에 의해 전달된 Device좌표를 논리좌표로 변환

 

Primary DC의 설정과 사용

  • 지금까지 모든 DC에 관한 설정 변경, 예를 들면 펜이나 브러쉬를 설정하는 경우에 프로그램에서 매번 SelectObject를 그때그때 설정해 줌
  • 실제로 시스템은 BeginPaint나 GetDC에 의해 얻어지는 DC설정에 대해 그 상태를 매번 보존하지 않음
  • 항상 기본적인 상태의 DC를 반환해주는데, 좀 더 정확히는 이를 Default DC라고 함
  • 앞의 예에서 WM_SIZE에서 처리했던 DC에 대한 Mapping Mode 설정은 해당 메시지가 처리된 후 끝나면서 그 설정 상태가 보존되지 않음 => DC를 얻어 처리하는 모든 곳에서 그런 Mapping Mode설정을 일일이 해주어야 함

    => DC 설정 상태의 보존성이 요구됨

      

        ==>> Primary DC의 설정과 사용을 허용

  • Primary DC의 설정은 WinMain에서 다음과 같이 Window Style에 그 속성을 설정

        

    wc.style = CS_HREDRAW | CS_VREDREDRAW | CS_OWNDC;

 

시스템은 그 DC의 변경 상태를 유지시켜줌

특정 부분에서 한번만 속성 설정

주의 사항 : Primary DC를 사용하면서 GetDC로 설정을 변경하는 경우에는 ReleaseDC를 호출하지 않음

상세한 예시는 비트맵파트에서 다룸

[출처] Mapping Mode|작성자 키론의 빛

'프로그래밍 > MFC' 카테고리의 다른 글

MFC :: DDX / DDV (Code Project)  (0) 2011.09.29
MFC :: DDX / DDV  (0) 2011.09.28
MFC :: Tip 1  (0) 2011.09.13
MFC :: 키보드 입력 관련  (0) 2011.09.12
한글 입력 관련 윈도우 메시지  (0) 2011.09.12
댓글 로드 중…

최근에 게시된 글