A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Tutoriais e Programação

Assembly - Fontes (masm)

Ter

21

Abr

2009


11:52

(2 votos, média 5.00 de 5) 


Definindo a fonte a ser usada

Para poder usar determinada fonte precisamos criá-la e selecioná-la. Só depois destes dois passos é que a fonte se encontra ativa e pronta para uso.

Criando uma fonte lógica

Para poder criar uma fonte lógica utiliza-se uma das funções da API, a CreateFont. Esta função, dentre as funções do Windows, é a que possui o maior número de parâmetros:

HFONT CreateFont( int nHeight, // altura lógica da fonte int nWidth, // largura lógica média dos caracteres int nEscapement, // ângulo de escape int nOrientation, // ângulo de orientação da linha base int fnWeight, // peso da fonte DWORD fdwItalic, // indicador do atributo itálico DWORD fdwUnderline, // indicador do atributo sublinhado DWORD fdwStrikeOut, // indicador do atributo riscado (ou tachado) DWORD fdwCharSet, // identificador do conjunto de caracteres DWORD fdwOutputPrecision, // precisão de saída DWORD fdwClipPrecision, // precisão de corte DWORD fdwQuality, // qualidade da saída DWORD fdwPitchAndFamily, // pitch (distanciamento) e família LPCTSTR lpszFace // ponteiro para a string do nome do tipo );
  • nHeight é a altura dos caracteres. Zero indica a altura padrão.
  • nWidth é a largura dos caracteres. Zero indica a largura padrão ( que o Windows ajusta de acordo com a altura dos caracteres).
  • nEscapement especifica a orientação do caractere seguinte em relação ao anterior, em décimos de grau. Normalmente indica-se 0 (zero). Se for 900, os caracteres vão sendo colocados um acima do outro; se for 1800, vão sendo colocados em ordem reversa (da direita para a esquerda); se for 2700, são colocados de cima para baixo.
  • nOrientation indica a rotação que os caracteres devem sofrer, em décimos de grau. Normalmente indica-se 0 (zero). Se for 900, rodam 90 graus e ficam "deitados"; se for 1800, ficam de "cabeça para baixo"; etc.
  • fnWeight indica a espessura dos caracteres: FW_DONTCARE (0), FW_THIN (100), FW_EXTRALIGHT ou FW_ULTRALIGHT (200), FW_LIGHT (300), FW_NORMAL ou FW_REGULAR (400), FW_MEDIUM (500), FW_SEMIBOLD ou FW_DEMIBOLD (600), FW_BOLD (700), FW_EXTRABOLD ou FW_ULTRABOLD (800) e FW_HEAVY ou FW_BLACK (900).
  • fdwItalic: zero indica normal, qualquer outro valor indica o estilo itálico.
  • fdwUnderline: zero indica normal, qualquer outro valor indica caracteres sublinhados.
  • fdwStrikeOut: zero indica normal, qualquer outro valor indica caracteres riscados.
  • fdwCharSet: o conjunto de caracteres da fonte. Normalmente, para obter caracteres com til e cedilha, usamos ANSI_CHARSET.
  • fdwOutputPrecision: especifica o quanto a fonte selecionada precisa se aproximar das características que desejamos. Normalmente deveria ser OUT_DEFAULT_PRECIS, que define um mapeamento padrão da fonte.
  • fdwClipPrecision: define a precisão de corte dos caracteres que estão parcialmente fora da região de corte. Geralmente se usa CLIP_DEFAULT_PRECIS, que define o comportamento de corte padrão.
  • fdwQuality: a qualidade da saída define o quanto a GDI precisa se preocupar em adequar os atributos da fonte lógica aos atributos da fonte física. Há três escolhas possíveis: DEFAULT_QUALITY (média), PROOF_QUALITY (alta) e DRAFT_QUALITY (baixa).
  • fdwPitchAndFamily: indica o distanciamento entre os caracteres e a família da fonte. Podem ser associados através de OR.
  • lpszFace: ponteiro para a string que contém o nome da fonte que queremos usar.

O valor de retorno desta função, como sempre no registrador EAX, é o manipulador para a fonte lógica criada. Tá certo que não ficou muito claro... é coisa demais mesmo. Talvez, fazendo uso da função, fique um pouco mais fácil. Vamos declarar uma variável global com o nome da fonte escolhida, uma variável local que receberá o manipulador da nova fonte e, na interceptação da mensagem WM_PAINT do procedimento gerenteMensagem, vamos criar a fonte Comic Sans MS. Se você não tiver esta fonte instalada no seu micro, escolha qualquer outra. Além disto, precisamos referenciar a biblioteca GDI, à qual pertencem a maioria das funções que serão adicionadas neste exemplo.

... 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 ... .DATA ... Texto_fim db "Até outra hora...",0 NomeFonte db "Comic Sans MS",0 .CODE inicio: ... gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ... LOCAL mFonte:HFONT .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov mCM, eax invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, ADDR FontName mov mFonte, eax ...

Selecionando a fonte lógica

Uma vez criada a fonte lógica, podemos substituir a fonte do contexto de dispositivo pela recém criada. A função SelectObject faz o serviço para nós e retorna o manipulador do objeto substituído. Vamos guardar este manipulador numa variável local. Após usarmos a nova fonte, este manipulador servirá para reverter a substituição da fonte (sempre é bom voltar para o contexto de dispositivo original).

HGDIOBJ SelectObject( HDC hdc, // manipulador do contexto de dispositivo HGDIOBJ hgdiobj // manipulador do objeto ); gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ... LOCAL mFonte:HFONT LOCAL mFonteOriginal:HFONT .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov mCM, eax invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, ADDR FontName mov mFonte, eax invoke SelectObject, mCM, mFonte mov mFonteOriginal, eax ...

Definindo a cor do texto

Chegou a hora de usarmos nossa macro RGB. Sabendo que RGB devolve a cor no registrador EAX, o valor contido neste registrador será um dos parâmetros para a função SetTextColor. Em seguida pintamos o texto como habitual e, logo depois, retornamos a fonte original para o contexto de dispositivo.

COLORREF SetTextColor( HDC hdc, // manipulador do contexto de dispositivo COLORREF crColor // cor do texto ); gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ... LOCAL mFonte:HFONT LOCAL mFonteOriginal:HFONT .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov mCM, eax invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, ADDR FontName mov mFonte, eax invoke SelectObject, mCM, mFonte mov mFonteOriginal, eax RGB 255, 0, 0 invoke SetTextColor, mCM, eax invoke GetClientRect, hWnd, ADDR eRet invoke DrawText, mCM, endTexto, -1, ADDR eRet, DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint, hWnd, ADDR ps invoke SelectObject, mCM, mFonteOriginal ...

Destruindo a fonte lógica

Todos objetos do contexto de dispositivo, quando são criados, consomem recursos do sistema. Criamos uma fonte lógica para ser usada no nosso contexto de dispositivo e, quando não precisamos mais dela, o correto é destruí-la para liberar os recursos do sistema. A função DeleteObjet elimina objetos do tipo pincel, fonte, bitmap, região, etc. É claro que, depois de destruídos, os manipuladores destes objetos deixam de ser válidos.

BOOL DeleteObject( HGDIOBJ hObject // manipulador do objeto gráfico );

Já que estamos fazendo faxina, não custa nada voltar a cor do texto para a original. Basta guardar a cor original numa variável local antes de trocar a cor do texto para, posteriormente, reverter as cores. A função que nos permite obter a cor do texto atual é a GetTextColor.

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ... LOCAL mFonte:HFONT LOCAL mFonteOriginal:HFONT LOCAL CorTexto:DWORD .ELSEIF uMsg == WM_PAINT invoke BeginPaint, hWnd, ADDR ps mov mCM, eax invoke CreateFont, 0, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH or FF_DONTCARE, ADDR FontName mov mFonte, eax invoke SelectObject, mCM, mFonte mov mFonteOriginal, eax invoke GetTextColor, mCM mov CorTexto, eax RGB 255, 0, 0 invoke SetTextColor, mCM, eax invoke GetClientRect, hWnd, ADDR eRet invoke DrawText, mCM, endTexto, -1, ADDR eRet, DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint, hWnd, ADDR ps invoke SelectObject, mCM, mFonteOriginal invoke SetTextColor, CorTexto invoke DeleteObject, mFonte .ELSE ...

A nova aparência do texto

Aqui terminamos a reforma do código fonte. Gere o executável e verifique o resultado.

Nova fonte
Menu malandro com uma fonte especial para o texto na área principal

O exemplo fontes II

No pacote para download (está na seção downloads / tutoriais / assembly numaboa) existe um segundo exemplo cujo código fonte está em fontes2.asm. A direrença é a seguinte: para cada item de menu o texto é apresentado numa cor diferente. Para isto foi criada uma variável global corAtual, do tipo DWORD, não inicializada, que contém o valor da cor desejada. Na macro RGB foi incluída uma instrução que inicializa corAtual:

RGB MACRO red, green, blue xor eax, eax mov ah, blue shl eax, 8 mov ah, green mov al, red mov corAtual, eax ENDM

A macro é utilizada apenas no processamento da mensagem WM_COMMAND:

gerenteMensagem proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ... .ELSEIF uMsg == WM_COMMAND ... .ELSEIF ax == mnID_sopa mov endTexto, OFFSET Texto_sopa RGB 255,0,0 .ELSEIF ax == mnID_salada mov endTexto, OFFSET Texto_salada RGB 0,128,0 .ELSEIF ...

As instruções em WM_PAINT que trocavam a cor do texto

RGB 255, 0, 0 invoke SetTextColor, mCM, eax

serão substituídas por:

invoke SetTextColor, mCM, corAtualЛогофет Вадим Геннадьевичnikas ресторанлобановский класс харьковпланшетыпланшет цена москваплита дорожная пдн 6000х2000х140 купитьдц возрождение

Informações adicionais