검색결과 리스트
어셈블리 강좌에 해당되는 글 5건
글
튜토리얼 5: More about Text
이번 시간에는 폰트나 컬러와 같은 텍스트 속성들에 대해서 살펴볼 것입니다.
Theory:
Windows 의 색상 시스템은 RGB 값(R=Red, G=Green, B=Blue)을 바탕으로 하고 있습니다. Windows 에서 어떤 색상을 표현하려면, 이 세가지 색으로 표현해야만 합니다. 각각의 색은 0 에서 255 (byte 범위) 사이의 값입니다. 예를들어, 순수한 빨강은 255.0.0 입니다. 새하얀 색은 255.255.255 로 나타낼 수 있습니다. 예제를 통해 보신것 처럼, 색을 섞고 비교하는데 뛰어난 사람이 아닌 이상, 이 시스템 방식으로 원하는 색상을 만들어 내는 것이, 매우 어렵습니다.글씨의 전경색과 배경색을 지정하기 위해서는 SetTextColor 와 SetBkColor 를 사용하면 됩니다. 이 함수를 사용하기 위해서는 32-bit RGB 값과 Device-Context 가 필요합니다. 32-bit RGB 값의 구조체는 다음과 같이 정의되어 있습니다.
RGB_value struct unused db 0 blue db ? green db ? red db ? RGB_value ends
<font color="#474747">RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm</font>
사용하려면 include 파일에 이 매크로를 넣으면 됩니다.
폰트를 만드려면 CreateFont 나 CreateFontIndirect 함수를 사용하면 됩니다. 두 함수의 차이점은 CreateFontIndirect 의 파라미터는 logical font 구조체인 LOGFOT 구조체를 가리키는 포인터 하나라는 것입니다. 만약 프로그램에서 빈번하게 폰트를 변경해야 한다면, CreateFontIndirect 가 더 편리합니다. 그러나 이번 예제에서는 단 하나의 font 만 생성할 것이기 때문에, CreateFont 를 사용할 것입니다. CreateFont 를 호출하고 나면, 선택한 device context 의 폰트에 대한 핸들이 리턴됩니다. 이후 부터는 선택한 device context 안에서의 모든 텍스트 관련 API 함수 사용시, 해당 폰트가 적용됩니다.
Content:
.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
RGB macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm
.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
TestString db "Win32 assembly is great and easy!",0
FontName db "script",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL hfont:HFONT
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
ADDR FontName
invoke SelectObject, hdc, eax
mov hfont,eax
RGB 200,200,50
invoke SetTextColor,hdc,eax
RGB 0,0,255
invoke SetBkColor,hdc,eax
invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
invoke SelectObject,hdc, hfont
invoke EndPaint,hWnd, ADDR ps
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
Analysis:
invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH or FF_SCRIPT,\
ADDR FontName
CreateFont 는 입력한 파라미터와 font 의 데이터가 가장 일치하는 logical 폰트를 만들어 줍니다. 이 함수는 다른 windows 함수들보다 훨씬 많은 파라미터를 가지고 있습니다. 그리고 SelectObject 함수에서 사용하는 logical 폰트의 핸들을 리턴해 줍니다. 이 함수의파라미터에 대해서 좀 더 알아 보도록 하겠습니다.
CreateFont proto nHeight:DWORD,\
nWidth:DWORD,\
nEscapement:DWORD,\
nOrientation:DWORD,\
nWeight:DWORD,\
cItalic:DWORD,\
cUnderline:DWORD,\
cStrikeOut:DWORD,\
cCharSet:DWORD,\
cOutputPrecision:DWORD,\
cClipPrecision:DWORD,\
cQuality:DWORD,\
cPitchAndFamily:DWORD,\
lpFacename:DWORD
nHeight 원하는 문자의 높이. 0 은 기본 사이즈.
nWidth 원하는 문자의 너비. 보통 이 값은 windows 가 높이에 따라 자동으로 맞추도록 0 을 사용합니다. 그러나 예제에서는 기본 너비값으로는 문자를 읽기 힘듦니다. 그래서 너비를 16 으로 하였습니다.
nEscapement 앞 문자 대비 다음 문자의 출력방향을 정의합니다. 이때 값은 '0.1 도' 단위입니다. 일반적으로 0 을 사용합니다. 만약 900 이라면 처음 문자 이후로는 문자들이 위로 올라갈 것입니다. 그리고 1800 이라면 문자들이 뒤로 쓰여질 것이고, 2700 이라면 아래로 쓰여지겠죠.
nOrientation 출력할 때, 문자의 회전각을 정의합니다. 이때 값은 '0.1 도' 단위입니다. 예를들어 값이 900 이라면 문자는 직각으로 눕여지고, 1800 이라면 위아래가 뒤집혀 질 것입니다.
nWeight 각 문자의 라인 두께를 지정합니다. windows 아래와 같이 값을 정의하고 있습니다.
FW_DONTCARE equ 0
FW_THIN equ 100
FW_EXTRALIGHT equ 200
FW_ULTRALIGHT equ 200
FW_LIGHT equ 300
FW_NORMAL equ 400
FW_REGULAR equ 400
FW_MEDIUM equ 500
FW_SEMIBOLD equ 600
FW_DEMIBOLD equ 600
FW_BOLD equ 700
FW_EXTRABOLD equ 800
FW_ULTRABOLD equ 800
FW_HEAVY equ 900
FW_BLACK equ 900
cUnderline 일반적으로 0. 다른 값이 들어갈 경우 문자에 밑줄이 그어집니다.
cStrikeOut 일반적으로 0. 다른 값이 들어갈 경우 문자의 가운데에 가로선(취소선)이 그어집니다.
cCharSet 폰트의 문자집합(Character-set). 일반적으로 Windows 가 O/S 에 종속적으로 선택하도록 OEM_CHARSET 을 사용합니다.
cOutputPrecision 얼마나 우리가 지정한 특성에 맞게 표현해야 하는지 정의합니다. 일반적으로 기본적인 폰트 맵핑을 이미하는 OUT_DEFAULT_PRECIS 를 사용합니다.
cClipPrecision 얼마나 정밀하게 클리핑(clipping) 할 것인지 정밀도를 정의합니다. 이 값은 문자가 클리핑 영역 밖으로 잘려나갔을 때, 어떻게 처리할 것인지를 결정합니다. 기본값으로 CLIP_DEFAULT_PRECIS 를 사용할 수 있습니다.
cQuality 출력의 퀄리티(quality)를 정의합니다. 출력의 퀄리티는 GDI 가 얼마나 정교하게 논리적 폰트(logical-font)의 속성을 물리적 폰트(physical-font)의 속성과 일치시킬 것인지에 따라 달라집니다. 여기에는 DEFAULT_QUALITY, PROOF_QUALITY, DRAFT_QUALITY 중 하나가 사용됩니다.
cPitchAndFamily 폰트의 피치(pitch)와 군(family) 를 나타냅니다. "or" 연산자를 통해 pitch 와 family 값을 합쳐서 표현할 수 있습니다.
lpFacename 폰트의 이름을 나타내는 문자열(null-terminated)을 가리키는 포인터.
위에서는 간단히 핵심만 설명했습니다. 더 자세히 알고 싶다며 Win32 API 레퍼런스를 참고하시기 바랍니다.
invoke SelectObject, hdc, eax
mov hfont,eax
logical 폰트의 핸들을 구한 뒤에는, SelectObject 를 호출하여 device context 내에 폰트를 설정해 주어야 합니다. SelectObject 는 펜, 브러쉬, 폰트와 같은 GDI object 들을 GDI 함수가 사용하는 devce context 안에 지정해 줍니다. 이 함수는 저장해 두었다가 나중에 복구할 때 SelectObject 함수를 통해 사용할 수 있도록, 교체될(현재의) object 핸들을 리턴해 줍니다. SelectObjec 함수를 호출하고 나면, 이 device cotext 에 대한 모든 Text 출력 함수는 방금 지정한 폰트 사용하게 됩니다.
RGB 200,200,50
invoke SetTextColor,hdc,eax
RGB 0,0,255
invoke SetBkColor,hdc,eax
SetColorText 와 SetBkColor 에서 사용하는 32-bit RGB 값을 만들기 위해서는 RGB 매크로를 사용하세요.
invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
Client 영역에 문자를 나타내기 위해서는 TextOut 함수를 사용하세요. 텍스트가 우리가 앞서 지정한 폰트와 색깔로 나타날 것입니다.
invoke SelectObject,hdc, hfont
폰트를 사용하다보면, device context 안에서 이전 폰트로 되돌려야 할 때가 있습니다. 이럴때는 device context 에서 변경했던 이전 object 로 복구시키면 됩니다.
'Microsoft > MASM32' 카테고리의 다른 글
[MASM 강좌] 튜토리얼 7 : Mouse Input (0) | 2010.12.12 |
---|---|
[MASM 강좌] 튜토리얼 6 : Keyboard Input (0) | 2010.12.12 |
[MASM 강좌] 튜토리얼 4 : Painting with Text (0) | 2010.11.29 |
[MASM 강좌] 튜토리얼 3 : A Simple window (0) | 2010.11.29 |
[MASM 강좌] 튜토리얼 2 : MessageBox (1) | 2010.11.29 |
RECENT COMMENT