관리 메뉴

ㄴrㅎnㅂrㄹrㄱi

[강좌 17] 폰트 본문

API 관련/API 강좌모음

[강좌 17] 폰트

님투 2007. 10. 26. 03:42
반응형

[API]강좌(17)<--폰트






폰트에 대해 알아 보겠습니다. 윈도우즈 95에서 제공하는 제공하는
트루타입폰트를 다루는 것은 그렇게 어렵지 않습니다. 보통 어떤 프로그램이든지
보면 프로그램에서 사용하는 폰트를 사용자가 선택할수 있는 기능이 있는데 이
기능을 구현할때에는 윈도우즈에서 기본적으로 제공하는 폰트 선택 대화상자를
이용해서 합니다. 그러나 우리는 지금 이 대화상자를 이용하지 않고 직접 함수를
이용해서 원하는 폰트를 선택하는 방법에 대해 알아보고자 합니다. 대화상자를
가지고 선택하는 방법은 뒤의 인터페이스 부분에서 설명드리도록 하겠습니다.
전반적으로 구현하는 방법은 간단합니다. 먼저 폰트의 핸들을 의미하는 HFONT
변수를 선언한뒤에 폰트를 생성하는 함수를 이용해서 원하는 폰트를 생성합니다.
물론 이 함수의 리턴값은 HFONT형이 됩니다. 그리고 우리가 앞에서 자주 사용한
SelectObject() 함수를 이용해서 이 폰트를 사용하겠다는 것을 명시해주고 출력
하면 바로 생성한 폰트로 문자를 출력할수 있습니다. 원리는 상당히 간단하죠.
그러면 폰트를 생성하는 함수를 보도록 합시다.
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
);
상당히 복잡하죠? 그러면 각 파라미터에 대해 알아 봅시다.
먼저 nHeight와 nWidth는 글자의 크기를 의미하는 것입니다. 만약에 nWidth가 0이
라면 nHeight크기에 적합한 폭의 글자가 생성됩니다. nEscapement는 폰트의 출력
각도를 의미하는 것입니다. 보통 0의 값을 가져 가로로 출력하죠. 만약에 세로로
출력하고자 한다면 900으로 지정하면 됩니다. nOrientation은 베이스 라인의 각도
를 의미합니다. fnWeight은 글자의 진한 정도를 의미하는데 이 값으로 지정할수 있
는 예약어는 다음과 같습니다.
예약어 진한정도
FW_DONTCARE 0
FW_THIN 100
FW_EXTRALIGHT 200
FW_LIGHT 300
FW_NORMAL 400
FW_MEDIUM 500
FW_SEMIBOLD 600
FW_BOLD 700
FW_EXTRABOLD 800
FW_HEAVY 900
fdwItalic은 이탤릭체를 사용할것인지 지정하는것인데 이값이 1이면 사용하겠다는
것을 의미하고 0이면 사용하지 않겠다는 것을 의미하는 것입니다.
fdwUnderline은 밑줄이 그어진 글자를 출력할때 사용하는 파라미터인데 이 값이 1
이면 밑줄을 치고 0이면 밑줄을 치지 않습니다.
fdwStrikeOut은 글자의 가운데에 선이 그어진 형태를 지정할때 사용하는데 이 값이
1이면 선을 긋고 1이 아니면 선을 긋지 않습니다.
fdwCharSet은 문자세트를 지정할때 사용하는데 이 파라미터에 지정될수 있는 예약
어는 다음과 같습니다.
ANSI_CHARSET
UNICODE_CHARSET
SYMBOL_CHARSET
SHIFTJIS_CHARSET
HANGEUL_CHARSET
CHINESEBIG5_CHARSET
OEM_CHARSET
fdwOutputPrecision은 정밀도를 지정하는 것인데 이 파라미터에 지정될수 있는 예
약어는 다음과 같습니다.
OUT_DEFAULT_PRECIS
OUT_STRING_PRECIS
OUT_CHARACTER_PRECIS
OUT_STROKE_PRECIS
OUT_TT_PRECIS
OUT_DEVICE_PRECIS
OUT_RASTER_PRECIS
OUT_TT_ONLY_PRECIS
OUT_OUTLINE_PRECIS
fdwClipPrecision은 클리핑 정밀도를 지정할때 사용하는데 이 파라미터에 지정될
수 있는 예약어는 다음과 같습니다.
CLIP_DEFAULT_PRECIS
CLIP_CHARACTER_PRECIS
CLIP_STROKE_PRECIS
CLIP_MASK
CLIP_LH_ANGLES
CLIP_TT_ALWAYS
CLIP_EMBEDDED
fdwQuality은 역시 정밀도를 지정하는 것인데 이 파라미터에 지정될수 있는 예약어
는 다음과 같습니다.
DEFAULT_QUALITY
DRAFT_QUALITY
PROOF_QUALITY
fdwPitchAndFamily은 글자의 피치를 지정하는 것인데 이 파라미터에 지정될수 있는
예약어는 다음과 같습니다.
DEFAULT_PITCH
FIXED_PITCH
VARIABLE_PITCH
FF_DECORATIVE
FF_DONTCARE
FF_MODERN
FF_ROMAN
FF_SCRIPT
FF_SWISS
lpszFace은 구체적인 글자의 폰트 이름을 지정해 주면 됩니다. 이 폰트 이름에는
다음과 같은 것들이 오면 됩니다.
Arial
Arial Bold
Arial Bold Italic
Arial Italic
Comic Sans MS
Courier
Courier New
Courier New Bold
Courier New Bold Italic
Courier New Italic
Modern
MS Sans Serif
MS Serif
Roman
Script
Small Fonts
Symbol
Times New Roman
Times New Roman Bold
Times New Roman Bold Italic
Times New Roman Italic
아마 여러분들도 이 폰트 이름을 본적이 있을 겁니다. 바로 윈도우즈에 설치되어
있는 폰트의 이름이죠. 자 그러면 실제로 폰트를 생성해서 그 폰트를 이용해서 출
력하는 프로그램을 만들어 봅시다.
MyMenu MENU
BEGIN
POPUP "&Font"
BEGIN
MENUITEM "&Ms Sans Serif", 100
MENUITEM "&Roman", 200
MENUITEM "&Symbol", 300
END
END
#include <windows.h>
#include <string.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HFONT SelectMyFont(int nIndex);
int WINAPI WinMain
(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
static char szAppName[] = "Font Example";
HWND hWnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = "MyMenu";
WndClass.lpszClassName = szAppName;
if(!RegisterClass(&WndClass))
return FALSE;
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
static HFONT hFont;
LPSTR szFontTest = "This is Font Test.";
switch(message)
{
case WM_PAINT :
hDC = BeginPaint(hWnd, &ps);
SelectObject(hDC, hFont);
TextOut(hDC, 50, 50, szFontTest, strlen(szFontTest));
DeleteObject(hFont);
EndPaint(hWnd, &ps);
return 0;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
hFont = SelectMyFont(0);
InvalidateRect(hWnd, NULL, TRUE);
break;
case 200 :
hFont = SelectMyFont(1);
InvalidateRect(hWnd, NULL, TRUE);
break;
case 300 :
hFont = SelectMyFont(2);
InvalidateRect(hWnd, NULL, TRUE);
break;
}
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
HFONT SelectMyFont(int nIndex)
{
HFONT hFont;
if(nIndex == 0)
{
hFont = CreateFont(
20, 0,
0, 0,
FW_NORMAL,
1, 0, 0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"MS Sans Serif"
);
}
else if(nIndex == 1)
{
hFont = CreateFont(
20, 0,
0, 0,
FW_NORMAL,
1, 1, 0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"Roman"
);
}
else if(nIndex == 2)
{
hFont = CreateFont(
20, 0,
0, 0,
FW_NORMAL,
1, 1, 1,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"Symbol"
);
}
return hFont;
}
뭐 그렇게 새로운 것은 없군요. 어떤 메뉴 아이템을 선택했는냐에 따라서 해당
문자열을 그 폰트로 출력하는 프로그램입니다. 간단하죠. InvalidateRect()함수
만 이해한다면 크게 문제되는 점은 없을 겁니다. 그러면 프로그램을 하나더 만들
어 보죠. 이것도 위 프로그램과 크게 다른점은 없습니다. 여러분들이 한번 보시기
바랍니다. 이 정도는 이해 할수 있겠죠?
MyMenu MENU
BEGIN
POPUP "&Font"
BEGIN
POPUP "&Size"
BEGIN
MENUITEM "20", 100
MENUITEM "30", 200
MENUITEM "40", 300
MENUITEM "50", 400
END
POPUP "&Weight"
BEGIN
MENUITEM "&Light", 500
MENUITEM "&Normal", 600
MENUITEM "&Bold", 700
END
MENUITEM "&UnderLine", 800
MENUITEM "Strike&Out", 900
MENUITEM SEPARATOR
MENUITEM "S&elect", 1000
END
END
#include <windows.h>
#include <string.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HFONT SelectMyFont(int nSize, int nWeight, DWORD dwUnderLine, DWORD dwStrike);
int WINAPI WinMain
(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArg, int nCmdShow)
{
static char szAppName[] = "Font Example";
HWND hWnd;
MSG msg;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW|CS_VREDRAW;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName = "MyMenu";
WndClass.lpszClassName = szAppName;
if(!RegisterClass(&WndClass))
return FALSE;
hWnd = CreateWindow(
szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK
WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
HMENU hMenu;
static HFONT hFont;
static int nSize, nWeight;
static DWORD dwUnderLine, dwStrike;
static BOOL bUnderLine, bStrike;
LPSTR szFontTest = "This is Font Test.";
switch(message)
{
case WM_PAINT :
hDC = BeginPaint(hWnd, &ps);
SelectObject(hDC, hFont);
TextOut(hDC, 50, 50, szFontTest, strlen(szFontTest));
DeleteObject(hFont);
EndPaint(hWnd, &ps);
return 0;
case WM_COMMAND :
switch(LOWORD(wParam))
{
case 100 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 100, MF_CHECKED);
CheckMenuItem(hMenu, 200, MF_UNCHECKED);
CheckMenuItem(hMenu, 300, MF_UNCHECKED);
CheckMenuItem(hMenu, 400, MF_UNCHECKED);
nSize = 20;
break;
case 200 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 100, MF_UNCHECKED);
CheckMenuItem(hMenu, 200, MF_CHECKED);
CheckMenuItem(hMenu, 300, MF_UNCHECKED);
CheckMenuItem(hMenu, 400, MF_UNCHECKED);
nSize = 30;
break;
case 300 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 100, MF_UNCHECKED);
CheckMenuItem(hMenu, 200, MF_UNCHECKED);
CheckMenuItem(hMenu, 300,MF_CHECKED);
CheckMenuItem(hMenu, 400, MF_UNCHECKED);
nSize = 40;
break;
case 400 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 100, MF_UNCHECKED);
CheckMenuItem(hMenu, 200, MF_UNCHECKED);
CheckMenuItem(hMenu, 300, MF_UNCHECKED);
CheckMenuItem(hMenu, 400, MF_CHECKED);
nSize = 50;
break;
case 500 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 500, MF_CHECKED);
CheckMenuItem(hMenu, 600, MF_UNCHECKED);
CheckMenuItem(hMenu, 700, MF_UNCHECKED);
nWeight = FW_LIGHT;
break;
case 600 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 500, MF_UNCHECKED);
CheckMenuItem(hMenu, 600, MF_CHECKED);
CheckMenuItem(hMenu, 700, MF_UNCHECKED);
nWeight = FW_NORMAL;
break;
case 700 :
hMenu = GetMenu(hWnd);
CheckMenuItem(hMenu, 500, MF_UNCHECKED);
CheckMenuItem(hMenu, 600, MF_UNCHECKED);
CheckMenuItem(hMenu, 700, MF_CHECKED);
nWeight = FW_BOLD;
break;
case 800 :
hMenu = GetMenu(hWnd);
if(!bUnderLine)
{
CheckMenuItem(hMenu, 800, MF_CHECKED);
dwUnderLine = 1;
}
else
{
CheckMenuItem(hMenu, 800, MF_UNCHECKED);
dwUnderLine = 0;
}
bUnderLine = !bUnderLine;
break;
case 900 :
hMenu = GetMenu(hWnd);
if(!bStrike)
{
CheckMenuItem(hMenu, 900, MF_CHECKED);
dwStrike = 1;
}
else
{
CheckMenuItem(hMenu, 900, MF_UNCHECKED);
dwStrike = 0;
}
bStrike = !bStrike;
break;
case 1000 :
hFont = SelectMyFont(nSize, nWeight, dwUnderLine,
dwStrike);
InvalidateRect(hWnd, NULL, TRUE);
break;
}
return 0;
case WM_DESTROY :
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
HFONT SelectMyFont(int nSize, int nWeight, DWORD dwUnderLine, DWORD dwStrike)
{
HFONT hFont;
hFont = CreateFont(
nSize, 0,
0, 0,
nWeight,
1, dwUnderLine,
dwStrike,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"Roman"
);
return hFont;
}
반응형

'API 관련 > API 강좌모음' 카테고리의 다른 글

[강좌 19] 초기화 파일  (0) 2007.10.26
[강좌 18] 파일과 디렉토리  (0) 2007.10.26
[강좌 16] 멀티미디어4  (0) 2007.10.26
[강좌 15] 멀티미디어3  (0) 2007.10.26
[강좌 14] 멀티미디어2  (0) 2007.10.26
Comments