Tutorial 5: Más sobre Textos

Experimentaremos más sobre los atributos de los textos, es decir, sobre las fuentes y los colores.

Baja el archivo ejemplo aquí.

Teoría:

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.
 

Contenido:

.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
    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
 

Análisis:

        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 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:

cItalic   0 para normal, cualquier otro valor para caracteres en itálicas.
cUnderline   0 para normal, cualquier otro valor para caracteres subrayados.
cStrikeOut   0 para normal, cualquier otro valor para caracteres con una línea a través del centro.
cCharSet  Especifica la configuración de la fuente [character set]. Normalmente debería ser OEM_CHARSET lo cual permite a Windows seleccionar la fuente dependiente del sistema operativo.
cOutputPrecision  Especifica cuánto la fuente seleccionada debe coincidir con las características que queremos. Normalmente debería ser OUT_DEFAULT_PRECIS que define la conducta de proyección por defecto de la fuente.
cClipPrecision  Especifica la presisión del corte. La precisión del corte define cómo recortar los caracteres que son parcialmente fuera de la región de recorte. Deberías poder obtenerlo con CLIP_DEFAULT_PRECIS que define la conducta por defecto del recorte.
cQuality  Especifiica la cualidad de la salida. La cualidad de salida define cuán cuidadosamente la GDI debe intentar hacer coincidir los atributos de la fuente lógica con los de la fuente física actual. Hay tres posibilidades: DEFAULT_QUALITY, PROOF_QUALITY and  DRAFT_QUALITY.
cPitchAndFamily  Especifiica la pitch y familia de la fuente. Debes combinar el valor pitch value y el valor de familia con el operador "or".
lpFacename  Un puntero a una cadena terminada en cero que especifica la tipografía de la fuente.

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.


Índice

Siguiente

[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 ]

www.000webhost.com