◆제 6장. 그래픽
◉6-5.폰트
●6-5-가. CreateFont
- 폰트를 만들어준다.
- 원형
- HFONT CreateFont(
int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight,
DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut,
DWORD fdwCharSet, DWORD fdwOutputPrecision, DWORD fdwClipPrecision,
DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCTSTR lpszFace
);
- 인자가 14개로 매우 복잡하다.
![](https://t1.daumcdn.net/cfile/tistory/2377CA50564C20D104)
- 실질적으로 변경해 주어야 할 필요가 있는 인수는 nHeight, lpszFacename정도이다.
●6-5-나. Font.dsw
- 소스<1>
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HFONT font, oldfont; char *str = TEXT("폰트 Test 1234"); switch (iMessage) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); font = CreateFont(50, 0, 0, 0, 0, 0, 0, 0, HANGEUL_CHARSET, 0, 0, 0, 0, "궁서"); oldfont = (HFONT)SelectObject(hdc, font); TextOut(hdc, 100, 100, str, lstrlen(str)); SelectObject(hdc, oldfont); DeleteObject(font); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProcA(hWnd, iMessage, wParam, lParam)); } |
- 소스<2>
- LOGFONT 구조체를 사용하고, CreateFontIndirect 함수로 만드는 방법도 있다.
- LOGFONT 구조체 원형.
- typedef struct tagLOGFONT { // lf
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;
- CreateFontIndirect 함수 원형.
- HFONT CreateFontIndirect( CONST LOGFONT *lplf);
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HFONT font, oldfont; char *str = TEXT("폰트 Test 1234"); LOGFONT lf; switch (iMessage) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); lf.lfHeight = 50; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = 0; lf.lfItalic = 0; lf.lfUnderline = 0; lf.lfStrikeOut = 0; lf.lfCharSet = HANGEUL_CHARSET; lf.lfOutPrecision = 0; lf.lfClipPrecision = 0; lf.lfQuality = 0; lf.lfPitchAndFamily = 0; lstrcpy(lf.lfFaceName, "궁서"); font = CreateFontIndirect(&lf); oldfont = (HFONT)SelectObject(hdc, font); TextOut(hdc, 100, 100, str, lstrlen(str)); SelectObject(hdc, oldfont); DeleteObject(font); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } |
- 결과
- 소스는 다르지만, 결과는 동일하다.
![](https://t1.daumcdn.net/cfile/tistory/273E8E50564C20D321)
●6-5-다. 문자열의 색상
- SetBkColor은 글자 뒤쪽의 배경 색상을 지정하는 함수이다.
- SetBkMode는 배경색상을 사용할 방법을 설정한다.
- 방법은 총 2가지가 있다.
![](https://t1.daumcdn.net/cfile/tistory/216B7F50564C20D60F)
- 소스
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HFONT font, oldfont; char *str = TEXT("폰트 Test 1234"); HBRUSH MyBrush, OldBrush; switch (iMessage) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); MyBrush = CreateHatchBrush(HS_CROSS, RGB(0, 0, 255)); OldBrush = (HBRUSH)SelectObject(hdc, MyBrush); Rectangle(hdc, 50, 50, 400, 200); SelectObject(hdc, OldBrush);
font = CreateFont(30, 0, 0, 0, 0, 0, 0, 0, HANGEUL_CHARSET, 0, 0, 0, 0, "궁서"); oldfont = (HFONT)SelectObject(hdc, font); SetTextColor(hdc, RGB(255, 0, 0)); SetBkColor(hdc, RGB(255, 255, 0)); TextOut(hdc, 100, 100, str, lstrlen(str)); SetBkMode(hdc, TRANSPARENT); TextOut(hdc, 100, 150, str, lstrlen(str));
SelectObject(hdc, oldfont); DeleteObject(MyBrush); DeleteObject(font); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } |
- 결과
![](https://t1.daumcdn.net/cfile/tistory/252CA350564C20D531)
●6-5-라. 글자 회전시키기.
- CreateFont의 3번째 인자인 nEscapement를 설정하면 문자열의 각도를 수정할 수 있다.
- 소스
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; int i; char *str = TEXT(" Beautiful Korea"); HFONT MyFont, OldFont; switch (iMessage) { case WM_PAINT: hdc = BeginPaint(hWnd, &ps); for (i = 0; i<901; i += 300) { MyFont = CreateFont(30, 0, i, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, "Times New Roman"); OldFont = (HFONT)SelectObject(hdc, MyFont); TextOut(hdc, 0, 300, str, lstrlen(str)); SelectObject(hdc, OldFont); DeleteObject(MyFont); } EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } |
- 결과
![](https://t1.daumcdn.net/cfile/tistory/21579850564C20D719)
◉Game 만들기
●헤더파일<smart.h>
- <smart.h>
smart.h
- 헤더파일을 만들어 길이에 관한 값들을 전부 define 한다.
![](https://t1.daumcdn.net/cfile/tistory/25020042564C306301)
- WndProc을 메시지 맵으로 처리한다.
![](https://t1.daumcdn.net/cfile/tistory/240FE542564C306535)
●메인 소스
- 기존의 switch문을 메시지 맵으로 전환한다.
- 모든 case를 각각 함수화 한다.
●분할 컴파일
- <main.c>
main.c
- <game.c>
Game1.c
- WinMain의 경우 프로그램이 실행하는 동안 변화가 없다.
- 분할 컴파일을 한다.
- 변화가 없으므로 WinMain 파일은 컴파일 하지 않고 넘어간다.
●맵
- 지도를 저장한다.
- 블록으로 막혀있고, 길로 뚫려있다.
- mapping 기법.
- 공간만큼을 키보드에 있는 아스키 코드로 채운다.
- insert키를 사용하여 스페이스바로 길로 사용할 부분을 채운다.
- 소스
UCHAR ucMap[YFRAME][XFRAME+1] = { "###############" , "# ## ##" , "###### # ## ##" , "###### ##### ##" , "## ##" , "## ############" , "## # ##" , "## ######### ##" , "## ##" , "###############" };
![](https://t1.daumcdn.net/cfile/tistory/26203D4D564C38CF2A)
|