Baja el archivo ejemplo aquí.
El sistema de colores de Windows está basado en valores RGB, R=red (rojo), G=Green (verde), B=Blue (azul). Si quieres especificar un color en Windows, debes establecer el color que desees en términos de estos tres colores mayores. Cada valor de color tiene un rango desde 0 a 255 (un valor de un byte). Por ejemplo, si quieres un color rojo puro, deberías usar 255,0,0. O si quieres un color blanco puro, debes usar 255,255,255. Puedes ver en los ejemplos que obtener el color que necesitas es muy difícil con este sistema ya que tienes que tener una buena comprensión de como mezclar y hacer corresponder los colores.
Para el color del texto y del fondo, usas SetTextColor y SetBkColor, que requieren un manejador al contexto del dispositivo y un valor RGB de 32-bit. La estructura dvalor RGB de 32-bit está definida así:
RGB_value
struct
unused db 0
blue db ?
green db ?
red db ?
RGB_value
ends
Nota que no se emplea el primer byte y que debería ser cero. El orden de los restantes tres bytes es inverso, es decir. azul, verde y rojo. Sin embargo, no usaremos esta estructura ya que es embarazoso inicializarla y usarla. Más bien crearemos una macro. La macro recibirá tres parámetros: los valores rojo, verde y azul. Esto producirá el valor RGB 32-bit deseado y lo almacenará en eax. La macro es como sigue a continuación:
RGB
macro red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
endm
Puedes poner esta macro en el archivo include para usarla en el futuro.
Puedes "crear"
una fuente llamando a CreateFont o a CreateFontIndirect. La diferencia entre
las dos funciones es que CreateFontIndirect recibe sólo un parámetro:
un puntero a la estructura lógica de la fuente, LOGFONT. CreateFontIndirect
es la más flexible de las dos, especialmente si tus programas necesitan
cambiar de fuentes con frecuencia. Sin embargo, como en nuestro ejemplo "crearemos"
sólo una fuente para demostración, podemos hacerlos con CreateFont.
Después de llamada a CreateFont, regresará un manejador a la fuente
que debes seleccionar dentro del contexto de dispositivo. Después de
eso, toda función de texto de la API usará la fuente que hemos
seleccionado dentro del contexto de dispositivo.
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
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
CreateFont creará la fuente lógica que más coincida con los parámetros dados y con los datos de fuentes disponibles. Esta función tiene más parámetros que cualquier otra función en Windows. Regresa un manejador a la fuente lógica a ser usada por la función SelectObject. Examinaremos sus parámetros en detalle.
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
La altura deseada para los caracteres. 0 significa el tamaño por defecto.
nWidth
La ancho
deseado para los caracteres. Normalmente
este valor debería ser 0 que permite a Windows coordinar el ancho y el
alto. Sin embargo, en nuestro ejemplo, el ancho por defecto hace difícil
la lectura del texto, así que usaremos mejor un ancho de 16.
nEscapement
Especifica la orientación del próximo caracter de salida relativa
al previo en décimas de grados. Normalmente, se pone en 0. Si se pone
en 900 tendremos que todos los caracteres irán por encima del primer
caracter, 1800 los escribirá hacia atrás, o 2700 para escribir
cada caracter desde abajo.
nOrientation
Especifica cuánto debería ser rotado el caracter cuando tiene
una salida en décimas de grados. Si se pone en 900 todos los caracteres
reposaran sobre sus respaldos, 1800 se emplea para escribirlos upside-down,
etc.
nWeight
Establece el grosor de las líneas de cada caracter. Windows define los
siguientes tamaños:
La descripción anterior no tiene nada de comprensible. Deberías revisar la referencia de la APi de Win32 API para más detalles.
invoke SelectObject, hdc, eax
mov hfont,eax
Después de obtener el manejador lógico de la fuente, debemos usarlo para seleccionar la fuente dentro del contexto de dispositivo llamando a SelectObject. SelectObject pone los nuevos objetos GDI tales como bolígrafos, brochas, y fuentes dentro del contexto de dispositivo a ser usado por las funciones GDI. Este regresa el manejador del objeto reemplazado, el cual deberíamos salvar para su uso posterior a la llamada a SelectObject. Después de llamar a SelectObject, cualquier función de salida de texto, usará la fuente que seleccionamos dentro del contexto de dispositivo.
RGB 200,200,50
invoke SetTextColor,hdc,eax
RGB 0,0,255
invoke SetBkColor,hdc,eax
Usa la macro RGB para crear un valor de 32-bit RGB para ser usado por SetColorText y SetBkColor.
invoke TextOut,hdc,0,0,ADDR TestString,SIZEOF TestString
Llama a la función TextOut para dibujar el texto sobre el área cliente. El texto estará en la fuente y el color que especificamos previamente.
invoke SelectObject,hdc, hfont
Cuando estemos
trabajando con fuentes, deberíamos almacenar la fuente original dentro
del contexto de dispositivo. Deberías almacenar siempre el objeto que
reemplazaste en el contexto de dispositivo.
[Iczelion's Win32 Assembly HomePage]
n u M I T_o r's Programming Page
Este tutorial, original de Iczelion, ha sido traducido por: n u M I T_o r [ kUT ]