출처 : http://blog.naver.com/gml81/40037809685

MapWindowPoints : CWnd의 좌표계로부터 다른 윈도우의 좌표계로 지정된 점들을 매핑시 킨다.
ClientToSreen : 클라이언트 좌표계를 화면 좌표계로 변환한다.
ScreenToClient : 화면 좌표계를 클라이언트 좌표계로 변환한다. 
-----------------------------------------------------------------------------

OnPrepareDC()에서

    dc.SetMapMode(MM_ISOTROPIC);

    dc.SetWindowExt(1000,1000);

    dc.SetViewportExt(2000,2000);

      CClientDC dc (this);
     OnPrepareDC (&dc);
     dc.DPtoLP (&point);
point가 마우스 좌표라면 논리 좌표로 변환해 주는 코드입니다.

 ----------------------------------------------------------------------------------

jpg 이미지가 255*255 픽셀 크기인데요...
출력을하면은 255*255 크기가 아니고 적게 출력이 되는데.
무슨 이유입니까??

좌표계가 MM_TEXT로 설정되어 있어서 그럴겁니다

 MM_TEXT 좌표계는 하나의 픽셀이 기준이 됩니다
질문하셨다 시피 jpg 이미지가 255*255 크기라면   
좀 픽셀이 큰 모니터에서는 이미지가 더 크게 나오겠죠?

출력을 할때도 마찬가지로
프린터 장치의 dpi라고 하죠 1인치 사각형안에 얼마나 많은 점들을 찍을수 있느냐 하는 건데
(보통 300dpi 뭐 이런 얘기 많이 들어보셨을 겁니다)
이 프린터의 dpi에 따라 이미지 사진이 더 크게나올수도 있고 작게나올수도 있는겁니다

왜냐하면 기준이 픽셀이기 때문이죠 

그럼 화면과 출력물의 크기가 같아지기 위해서는 어떻게 해야하느냐 하면
MM_LOMETRIC같은 좌표계를 쓰시는 겁니다

MM_LOMETRIC은 자표계 기준이 0.1미리 입니다
따라서 MM_LOMETRIC좌표계 기준으로 1000*1000의 그림은
화면에서나 출력에서나 10cm * 10cm로 동일하게 출력되는 것이죠

쉽게 말씀드리면

 SetMapMode() 함수를 이용해서 좌표계를 바꿔주라는 이야기 입니다 ^^
SetMapMode(hPrinterDC, MM_LOMETRIC); // 이런식으로요

물론 출력하실때 좌표계가 바뀌었으니 출력될 좌표는 신경쓰셔야 겠죠 ^^
참고로 MM_LOMETRIC은 MM_TEXT와는 달리

y축이 아래로 가면 - 값 입니다

덧붙이자면

BOOL DPtoLP() // 디바이스 좌표를 로직좌표계로 바꿔주는 함수와 그 반대 함수들이 존재하니 참고 하시구요

 -----------------------------------------------------------------------

 DPtoLP는 함수 이름 대로 디바이스 좌표를 논리적 좌표로 변경해주는 함수입니다...
 디바이스 좌표는 화면의 한 Pixel, 프린터의 한 Dot를 뜻합니다.
논리적 좌표는 논리적으로 단위를 정한 좌표입니다.(예로 10cm단위로 1, 2, 3...)
 일반적으로 GetDC()를 하게 되면 리턴되는 DC는 MM_TEXT 모드가 됩니다.
MM_TEXT는 디바이스 좌표와 논리 좌표가 1:1 대응(화면의 한 점이 1이 됩니다.)됩니다.
결국 DPtoLP를 해도 값의 변화가 없겠죠...

하지만 map mode를 MM_HIMETRIC으로 변경했다고 가정하면 논리적 좌표 1은
0.01mm를 나타내기 때문에 화면의 한 pixel은 화면 DPI에 따라 1이 아닌 다른 논리적 값이 됩니다...

[출처] [MFC] 좌표계|작성자 영희

출처 : http://tong.nate.com/gayanim/27925620

GetWindowRect
윈도우의 현재 위치와 크기를 구해준다. (left, top)은 윈도우의 현재 좌상단 위치를 나타내는데 이 좌표는 전체 화면을 기준으로 한 좌표이다. (right, bottom)은 윈도우의 우하단 위치를 나타내며 역시 전체 화면을 기준으로 한 좌표이다. 윈도우의 현재 크기(폭과 높이)를 구하고 싶으면 right-left, bottom-top을 계산하면 된다.

GetClientRect
윈도우의 작업영역 크기를 계산해 준다. 크기만 계산해 주기 때문에 좌상단(left, top)값은 항상 0,0이며 우하단 좌표(right, bottom)가 곧 윈도우의 크기를 나타낸다. 작업영역이란 윈도우의 타이틀바, 스크롤 바, 경계선, 메뉴 등을 제외한 영역이며 윈도우가 그리기를 하는 대상 영역이다

 

ScreenToClient
화면의 원점을 기준으로 하는 좌표 lpPoint를 hWnd의 작업 영역을 기준으로 하는 좌표로 변환한다. hWnd윈도우의 작업 영역 원점의 화면 좌표가 cx, cy일 때 lpPoint는 lpPoint.x - cx, lpPoint - cy로 변환된다. GetCursorPos, MoveWindow, GetWindowRect 등과 같이 화면 좌표를 리턴하는 함수로부터 작업 영역의 좌표로 변환하고자 할 때 이 함수를 사용한다.

 

C++로 게임 개발을 할 때 몇몇 사람들이 MFC를 사용하기로 결정했다. 늘 저는 ASSERT(), VERIFY(), TRACE() 매크로들의 유익함을 발견한다. 그래서 윈도우 플랫폼을 위한 어떤 프로젝트에서든지 작업할 수 있도록 자신의 버전을 만들기로 했다.


ASSERT()는 값이 0이면 실행을 멈추도록 하기 위해 매개 변수을 평가한다. 릴리즈 모드에서는 assert가 아무 것도 전개되지 않도록 해야한다.


VERIFY()는 릴리즈 모드에서 매개 변수를 전개하도록 되어 있는 것을 제외하고는 ASSERT()와 아주 유사하다.
ASSERT()는 어떠한 함수 호출도 포함되어 있지 않는 표현으로 사용되어야만 한다. 함수 호출을 포함하는 표현을 위해 VERIFY()를 사용해야만 하고 그렇게 해서 함수 호출은 릴리즈 모드에서도 보전된다.


TRACE()는 디버그 윈도우에 출력되는 것을 제외하고는 printf()의 대응물이다. 릴리즈 모드에서는 TRACE() 또한 아무것도 전개하면 안된다.


세 개의 매크로들 중 어떤 것도 릴리즈 모드에서 어떤 런타임 벌점을 의미하지 않는다. 그 매크로들은 미리 정의된 _DEBUG 매크로를 사용해서 디버그 모드와 릴리즈 모드 사이를 구별한다. 이것은 Microsoft Visual C++에 특정적이다. 만약 다른 몇몇 다른 컴파일러를 사용하고 있다면 적절한 매크로를 사용해야만 할 것이다. 


ASSERT(), VERIFY(), TRACE()를 지원하는데 필요한 두 파일이 있다. 그것은 debug.h와 debug.cpp이다. 프로젝트의 몇몇 메인 헤더에 debug.h를 추가해야만 한다. 그것은 자신 안에 어떤 파일도 포함하지 않기 때문에 순환 포함(recurrent inclusion)에 의해 더럽혀지지 않는다. 또한 프로젝트의 소스 파일에 debug.cpp를 더해야만 한다.


Discuss this article in the forums
Date this article was posted to GameDev.net: 7/23/2002
(Note that this date does not necessarily correspond to the date the article was written)

See Also: Sweet Snippets


원문 : http://www.gamedev.net/reference/articles/article1846.asp

'C/C++언어' 카테고리의 다른 글

쉬프트 연산과 곱셈  (0) 2008.03.26
[리눅스프로그래밍] makefile  (1) 2008.03.07
템플릿 사용한 max 만들기  (0) 2008.03.03
<이클립스 디버그 방법>  (0) 2008.01.28
printf 문을 만들어보자  (0) 2008.01.28
사용자 삽입 이미지

간혹 이런 메시지가 뜨면 당혹스럽기도하다.
대부분 이런 메시지는 MFC가 만드는 자동 소스 생성 부분 (즉 위져드 부분)에서 에러난다.
무시하고 진행해도 되지만.. 그 많은 양의 소스를 일일이 치는건 역시 무리다..

이 문제를 해결하기위해 처음엔 Visual Studio 자체를 지웠다가 설치해 봤다.
하지만 문제는 해결되지 않았다.. 무엇이 문제일까 하다가..

역시나 네이버.. orz

문제는 internet Explorer 이였다.. 이참에 걍 불여우로 바꿔볼까 ...
하여간 문제 해결은 의외로 간단하였다.
사용자 삽입 이미지

익스플로어 기본설정을 원래대로 초기화 한뒤
스크립트 디버깅 사용안함부분이 체크되었는지 확인한뒤
사용자 삽입 이미지
좀 내리다 보면 UTF-8 URL 보내기가 체크되어있는데 이걸 해제한다.

그럼 문제없이 뜬다

일단 이것땜에 숙제, 턴프로젝트, 할일등 모두 내 팽겨쳐 졌다.. orz

유니코드는 이 아래에서 긁어온 자료와 같이 여러 종류가 있다고 한다.

하지만 지금 중요한건 저 글자를 파일로 저장한뒤 온전하게 불러오는데 목적이 있다.

예제는 한줄경우 어떻게 처리가 되었지만, 몇백줄 넘어가는 자료를 저장하면 그 나름대로 테크닉이
필요하다.

데브 피아 등 여러곳을 돌아다니가 결국 잘못된곳을 찾아냈다..

다음은 J-Notebook 프로그램의 파일 저장 소스 일부분이다.

if(dlg.DoModal() == IDOK)
 {
  CFile file;
  CFileException e;
  if(!file.Open(dlg.GetFileName(), CFile::modeWrite | CFile::modeCreate, &e))
  {
   e.ReportError();
   return;
  }
  // 파일을 쓴다. 음... file.Write가 \n 이 자동으로 붙고, \r\n하면 한줄씩 내려준다.
  // 유니코드 시작
  WORD  a;
  a = 0xFEFF;
                                   <- 16진수 변환 프로그램을 보니, 제대로 읽히는 파일은 FFFE로 시작한다.
                                       하지만 FEFF로 넣었다.. 왜냐? 윈도우는 리틀 앤디안이기 떄문이라;;;
  file.Write((void*)&a, sizeof(a));
                                // 맨 처음부분에 넣어준다. 왜인지 모르겠지만 아무래도 유니코드 식별인자 인거 같다;;

  // 유니코드에서 한줄내림은 코드는 0x0a인듯 하다..
  a = 0x0A;
  JWord note;
  CString strWord;
 
  int i=0;
  for(; i < pDoc->m_szNoteWord.size()-1; i++)
  {
   note = pDoc->m_szNoteWord[i];
   strWord.Format(L"%s;%s;%s;%d\r",note.word, note.yomigana, note.mean, note.count);
   // 글자를 쓰고,
   file.Write(strWord, strWord.GetLength()* sizeof(wchar_t));
   // 이 글자의  유니코드식별자? 를 추가해준다.. 파일흐름상 개행라인인거 같다.
   file.Write((void*)&a, sizeof(a));

  }
  // 마지막은 개행할 필요가 없으므로 따로 써준다.
  note = pDoc->m_szNoteWord[i];
  strWord.Format(L"%s;%s;%s;%d",note.word, note.yomigana, note.mean, note.count);
  file.Write(strWord, strWord.GetLength()* sizeof(wchar_t));
 }

이짓을 해주면. CFile::typeText | CFile::modeRead 로 문제없이 읽어온다.

하지만... 유니코드... 이거 난해해서.. 괜한 지뢰밭 들어간건 아닌지 걱정된다.

+ Recent posts