자, 이제 공부를 더 하기 위해서 음.. 뭔가에 대해서 깊숙히 들어가기 보단, 기록과 기억의 측면에서 포스팅을 해보기로 하자.
 이번에 공부할것은 출력. 몇일 전에 했던 LPCTSTR의 문자열 출력이 아닌 이상에야 뭐 그리 어려울건 없다. 따라서 윈도우즈 툴에서 출력하는 방법과 출력하는 함수들의 원형 및 사용방법을 익히면 될것이다.

시작해보자.

우선, 출력이라는 것에 있어서의 필요한것에 대해 알아보자, 일단 출력이란, 우리가 가장 간단하게 상상할수 있는 console style의 문자열이 있겠다. console style만 보더라도, 흰색글자에 검은색 바탕화면, 맨 왼쪽 위부터 출력이 차례대로 진행된다. 하지만 이거슨 도스시절의 이야기. 윈도우와 도스의 가장큰 차이점중 하나를 꼽으라면 뭐가 있을까? 일단 멀티테스킹이 있겠다. 그러면서 윈도우창이 바뀌고, 윈도우창이 움직일수도 있다.
 자, 그러면 두개의 프로그램을 실행중에 있는데 한나의 프로그램에서 출력하고 있던것은 다른 프로그램이 활성화가 된다면 비활성화가 된 프로그램과 같이 보이지 않아야하고 다시 그 프로그램을 활성화 시킨다면 다시 보여져야 한다.
 그리고 윈도우 창을 움직인다면 그 출력이 따라서 움직여야 할것이다.
 그리고 도스시절부터 있을수 있었던 이야기인, 함수의 원형에 무엇이 들어가야 하는가?에 대한 문제이다. 일단, 글자의 시작위치가 들어갈수 있겠다. 도스에서는 그냥저냥 첫줄부터 했지만, 윈도우에서는 어디서부터라도 글자나 그림의 위치가 실행이 가능하다. 글자의 크기, 폰트, 색깔, 등등등 여러가지가 있다. 음... 하지만 정작 생각을 해보면, 시작위치, 프로그램의 핸들만 알려주면 그냥 디폴트 정해주면 안되? 라고 해서 만든것이 DC(Device Context)다. 이 DC에 기타 여러가지의 기능들을 디폴트로 해놓든가 따로 수정을 해주면 알아서 해줄수 있도록 편하게 만들어 놓았다.

자, 그럼 간단한 코드를 보도록 하겠다.

LRESULT CALLBACK WndProc(HWND, hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;

switch(iMessage)
{
case WM_DESTROY: PostQuitMessage(0);return 0;
case WM_LBUTTONDOWN:
hdc=GetDC(hWnd);
TextOut(hdc,100,100,Text("Beautiful Korea"),15);
ReleaseDC(hWnd,hdc);
return 0;  
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

자, 여기서 중요한건, HDC와 GetDC, TextOut, ReleaseDC
뭐, 다중요하네 ㅋㅋ

일단 HDC는 DC의 식별번호(Handle)를 담을수 있는 거고, GetDC는 hWnd를 GetDC 함수에 넘겨줘서 리턴값을 hdc로 대입한다. 핸들은 카테고리처럼 프로그램마다 지정되는거니까 :)
자, 그리고 TextOut을 보기전에 오선 ReleaseDC를 보자하면, 이거슨 생성자와 소멸자, 아니, new와 delete의 관계에 가깝다. 반드시 해줘야한다는 것이지.
 자, 그러면 Text Out을 보도록 하자, TextOut의 경우는
 TextOut(HDC hdc, int x, int y, LPCWSTR lpString, int c);
요롷게 된다. 맨처음은, dc를 사용할 핸들값이겠고, x,y는 출력할 xy의 좌표이다. 이 xy좌표의 원점. 즉, 0,0은 메뉴 부분(non-client area)를 제외한 가장 왼쪽 위부터 시작된다.따라서 오른쪽으로 1만큼 아래로 1만큼 움직이려면, 1, -1이 되는것이다.
 그리고 나오는 LPCWSTR은 물론 LPCTSTR도 사용할수 있으며 출력할 값을 나타낸다.
 그리고 그 뒤에오는 int c는 lpString의 최대길이를 나타낸다.
 만약 마지막의 이것을 쓰기 귀찮은 경우에는

void MyTextOut(HDC hdc, int x, int y, LPCTSTR Text)
{TextOut(hdc,x,y,Text,lstrlen(Text));}

이것과 같이 마지막을 lstrlen(Text)를 해줘서 없애고 MyTextOut이란 함수를 만들면 된다.


그리고 아래는 좌표에 따른 정렬방법.

SetTextAlign(HDC hdc, UINT align);

align::
TA_TOP 지정한 좌표가 상단 좌표
TA_BOTTOM  " 하단 좌표
TA_CENTER   " 중앙 좌표
TA_LEFT " 왼쪽 자좌표
TA_RIGHT " 오른쪽 좌표.
TAUPDATECP  지정한 좌표 대신CP(Current Position)를 사용하여 문자열 출력후에 CP를 저장하고 다음에 출력할 경우 그 CP 다음에 출력한다.
TA_NOUPDATECP CP를 사용하지 않고 지정한 좌표를 사용하며 CP를 변경하지 않는다.

보통 CP는 TA_LEFT|TA_TOP 에 Default로 있다가 어느 한 Text아웃이 발생하면 그 Text의 끝에 붙는다.
따라서 만약 이 CP를 옮기고 싶지 않을때는 TA_NOUPDATECP를 해주어야 한다.

그리고 중간에 변수를 넣을 경우에는 wsprintf나 sprintf를 사용해주면 된다.
wsprintf(LPWSTR, LPWSTR,...);
이것인데, 처음에는 LPWSTR은 버퍼.
그다음 LPWSTR은 버퍼에 넣을 서식이고, ... 는 인수값들이다.


+ Recent posts