HB++: Criando campos com máscaras do tipo senha

Gostou deste artigo? Compartilhe!

CategoriasPalm OS, Handheld Basic
ComentáriosComentários (3)

Campo com Máscara do tipo Senha

Introdução

Ao desenvolvermos aplicações comerciais, é comum utilizarmos mecanismos de controle de acesso ao sistema através de autenticação do usuário. Esta autenticação, é feita normalmente através de nome de usuário e senha, previamente cadastrados em uma base de dados.

Assim como nas aplicações para computadores, em aplicações para PDAs também é uma boa prática utilizar máscaras para esconder a senha no momento da digitação, mostrando um caracter escolhido, como por exemplo o "*", utilizado na maioria dos casos.

O controle to tipo "caixa de texto" nativo do Palm OS, não oferece este recurso de máscara, e para piorar, não oferece eventos do tipo KeyDown ou KeyPress, para que fosse possível capturar os caracteres antes de eles aparecerem para o usuário e efetuar a substituição. Dessa forma, resta-nos apenas uma última alternativa: Utilizar uma fonte customizada.

Conceito

O Palm OS nos possibilita utilizar diferentes fontes de letra nas caixas de texto e até mesmo em outros controles do sistema operacional. Através de algumas funções da API, podemos alterar a fonte apenas dos controles que desejamos, sem interferir em outros controles.

As fontes de letra, possuem em geral 256 caracteres, obedecendo a tabela ASCII (do caracter 0 (zero) até o caracter 255 (duzentos e cinquenta e cinco)), assim, tudo o que temos de fazer, é criar uma fonte customizada, com 256 caracteres, onde todos os caracteres são desenhados com um único caracter específico, como o "*", por exemplo.

Criando a Fonte Customizada

Existem diversas ferramentas que permitem a criação de fontes customizadas para Palm OS, e uma das ferramentas mais utilizadas (e gratuita) é a xFont, utilizada neste exemplo. Caso não possua a xFont, faça o download na seção de downloads do PDAExpert

Crie uma nova fonte com o xFont, desenhe o caracter que deseja que apareça para seu usuário, e repita o desenho em todos os 256 caracteres da fonte utilizando os recursos de copiar e colar do xFont. Se preferir, pode importar qualquer uma das fontes existentes no Windows, escolher o caracter desejado e novamente utilizar os recursos copiar e colar do xFont, para criar as réplicas do desenho.

Criação da Fonte com o xFont

Com os 256 caracteres da fonte definidos, salve seu arquivo de fonte customizada em uma pasta de seu computador. O arquivo gerado terá a extensão ".pfn", e neste exemplo, o nome do arquivo é "Password.pfn".

Adicionando a fonte no projeto

Para adicionar esta fonte customizada em nosso projeto HB++, ela precisa ser compilada em um resource binário, através do compilador de resources PilRC. Caso não possua o PilRC, faça o download na seção de downloads do PDAExpert.

Para que o PilRC possa gerar nosso resource binário, precisamos criar um pequeno arquivo texto definindo o ID da fonte customizada e informar o caminho do arquivo ".pfn". Utilize seu editor de textos favorito e crie um arquivo chamado, por exemplo, "Password.rcp", com o seguinte conteúdo:

Criação do arquivo de definições da fonte para o PilRC

FONT ID 1 FONTID 128 "Password.pfn"

O próximo passo, é compilar este arquivo "Password.rcp" e gerar o resource binário, que será adicionado ao nosso projeto. A compilação é feita via linha de comando, bastando executar o compilador e informar o nome do arquivo com as definições:

Compilação da fonte customizada com o PilRC

PilRC Password.rcp

O PilRC irá gerar um arquivo com extensão .bin, com o nome começado por "NFNT". Este é o arquivo de resource que precisamos adicionar ao projeto. Assim, abra a aplicação no ambiente do Handheld Basic, adicionar este arquivo na pasta "Binary Resources" e compilar nossa aplicação.

Adicionando a fonte customizada no projeto HB++

Importante:

1-) Este exemplo assume que o arquivo gerado pelo xFont (.pfn) está na mesma pasta do arquivo ".rcp". Caso o arquivo ".pfn" esteja em uma pasta diferente, é necesário informar o caminho completo deste arquivo, utilizando-se o caracter "\" (barra invertida) duplicado, como por exemplo:

FONT ID 1 FONTID 128 "C:\\Sistemas\\MeuSistema\\Arquivos\\Password.pfn"

2-) O FONTID deve ser sempre um numero igual ou maior que 128, pois os números menores que 128 são reservados para fontes já existentes no sistema operacional Palm OS.

3-) Podemos compilar diversas fontes customizadas em um único arquivo binário de resource, basta definir IDs diferentes para cada uma, e informar os arquivos correspondentes, como por exemplo:

FONT ID 1 FONTID 128 "Password.pfn"
FONT ID 2 FONTID 129 "Arial.pfn"
FONT ID 3 FONTID 130 "Verdana.pfn"
FONT ID 4 FONTID 131 "Tahoma.pfn"

Programação

Com a fonte compilada em um resource binário e adicionada em nosso projeto. Precisamos carregá-la na memória antes da utilização, e definir quais controles irão utilizar a fonte customizada. O Palm OS possui uma função API chamada FntDefineFont, responsável em carregar fontes em memória a partir do ID e do arquivo de resource. Assim, o primeiro passo é criar a declaração da função API em um módulo do projeto:

'Declaração da API FntDefineFont, responsável em carregar a fontes customizadas em memória
Public Declare Function	FntDefineFont(ByVal fontId As Byte, ByVal fontPtr as Long) As Integer Trap &HA321

Em seguida, no formulário onde a fonte será utilizada, declaramos as variáveis que serão utilizadas para acessar o arquivo de resource a partir de nossa aplicação:

'Código de identificação de fonte customizada
'Nota: hbFontCustomBase é igual a 128
Protected Const fntPasswordFontID As Integer = hbFontCustomBase

'Variáveis de acesso à fonte customizada
Protected m_passwordFontRes As StreamMemory
Protected m_passwordFontPtr As Long

Com as variáveis de acesso declaradas no formulário, devemos carregar a fonte em memória no evento Form_Load, que é o evento executado antes do formulário ser mostrado na tela.

Private Sub Form_Load()
    'Obtém o resource da fonte customizada
    Set m_passwordFontRes = App.Resource("NFNT", 1)

    'Trava o rssource e obtém um ponteiro de acesso protegido
    m_passwordFontPtr = Lock(m_passwordFontRes)

    Dim lErro As Long
    'Carrega a fonte em memória para ser utilizada
    lErro = FntDefineFont(fntPasswordFontID, m_passwordFontPtr)

    'Se conseguiu carregar a fonte, lErro é igual a zero
    If lErro = 0 Then
        txtSenha.Font = fntPasswordFontID
    Else
        'Não conseguiu carregar a fonte...
        'Libera o ponteiro de acesso
        If Not m_passwordFontRes Is Nothing Then
            Unlock(m_passwordFontRes)
        End If

        'Libera a memória utilizada
        Set m_passwordFontRes = Nothing

        'Mostra mensagem de erro
        MsgBox "Não foi possível carregar a fonte customizada", hbMsgBoxError
    End If

    'Define o cursor de foco na caixa
    'de texto do nome do usuário
    Set Focus = txtUsuario
End Sub

A associação da fonte customizada ao controle de caixa de texto é feita através da propriedade Font da caixa de texto. No exemplo, o código txtSenha.Font = fntPasswordFontID altera o valor da propriedade Font para 128, que corresponde ao ID da fonte customizada adicionada ao projeto.

Ao deixarmos de utilizar a fonte, precisamos liberar a memória por ela utilizada. Assim, no evento Form_Unload, evento executado apenas quando o formulário for fechado, efetuamos a liberação da memória:

Private Sub Form_Unload()
    'Formulário está sendo fechado...
    'Libera o ponteiro de acesso.    
    If Not m_passwordFontRes Is Nothing Then
        Unlock(m_passwordFontRes)
    End If

    'Libera a memória utilizada
    Set m_passwordFontRes = Nothing
End Sub

O resultado, é uma caixa de texto com máscara de senha, que impede que os caracteres digitados apareçam na caixa de texto.

Solução Alternativa Utilizando o Evento Form_KeyPress

Existe uma solução alternativa à utilização de fontes customizadas, adotada por alguns desenvolvedores, e que de certa forma produz um efeito semelhante, embora possua alguns pontos negativos. Como apontado no inicio do artigo, o controle to tipo "caixa de texto" nativo do Palm OS, não oferece eventos do tipo KeyDown ou KeyPress, para que fosse possível capturar os caracteres antes de eles aparecerem para o usuário e efetuar a substituição. No entanto, o formulário em si possui um evento KeyPress, onde são capturados todos os caracteres digitados em qualquer controle deste formulário, permitindo, então, controlar os caracteres que aparecem para o usuário. Veja este exemplo:

Private Sub Form_KeyPress(ByRef iChar As Integer, ByRef iKeyCode As Integer, ...)
    'Verifica se o foco (cursor) está na caixa de texto da senha
    If Me.Focus Is Control(txtSenha) Then
        'Verifica se o caracter digitado está na faixa a...z, A...Z
        If iChar >= 32 And iChar <= 128 Then
            'Armazena o caracter digitado na propriedade Tag da caixa de texto
            txtSenha.Tag = txtSenha.Tag & Chr(iChar)
        
            'Cancela a exibição do caracter para o usuário
            bForward = False

        'Varifica se o caracter digitado é o backspace
        ElseIf iChar = 8 And Len(txtSenha.Tag) > 0 Then
            'Simula um backspace, apagando o ultimo caracter digitado
            txtSenha.Tag = Left(txtSenha.Tag, Len(txtSenha.Tag) -1)

            'Cancela a exibição do caracter para o usuário
            bForward = False
        End If
    
        'Mostra o caracter "*" de acordo com a quantidade
        'de caracteres digitados pelo usuário
        txtSenha.Text = String(Len(txtSenha.Tag), "*")
    End If
End Sub

Embora aparentemente o exemplo acima produza os mesmos efeitos da utilização de uma fonte customizada, ele apresenta pelo menos dois pontos negativos:

  • Mudança de Comportamento da Caixa de Texto - A propriedade Text da caixa de texto perde sua funcionalidade padrão, pois ela não mais conterá os caracteres digitados pelo usuário, e sim, o caracter utilizado como máscara. Neste exemplo, a propriedade Text possuirá diversos caracteres "*", apenas. A senha real precisa ser armazenada em outro lugar do programa, como por exemplo na propriedade Tag, como no exemplo de código acima, ou em uma variável do formulário.
  • Não Funciona com o Teclado Virtual - Uma vez que a caixa de texto perde seu comportamento padrão, o teclado virtual não consegue detectar o texto digitado pelo usuário, e mostra o conteúdo real da caixa de texto, composto por diversos caracteres "*", e se o usuário digitar outros caracteres com o teclado virtual, estes não serão substituidos, pois o evento KeyPress não é executado durante a exibição do teclado virtual.
    Teclado Virtual

Pelos motivos descritos acima, esta solução alternativa utilizando o evento KeyPress do formulário, não é considerada a melhor solução, devendo o desenvolvedor optar pela utilização de uma fonte customizada, sempre que possível.

Histórico

  • 09/05/2007 - Primeira versão deste artigo.
  • 08/07/2007 - Inclusão de solução alternativa, utilizando o evento Form_KeyPress.

Agradecimentos à Ana Maria pela sugestão da solução alternativa, utilizando o evento KeyPress do formulário.

Sobre o Autor

Caio ProieteCaio Proiete é Arquiteto de Soluções, especialista em desenvolvimento de softwares para PDAs e telefones celulares, principalmente nas plataformas Palm OS, Windows Mobile e Symbian OS.

Atualmente suas principais ferramentas/tecnologias de trabalho incluem CodeWarrior C++, Handheld Basic, eMbedded Visual C++, .NET Compact Framework, C# .NET, e Carbide.c++.

Possui extensa experiência em arquitetura e desenvolvimento de sistemas baseados em web e smart-clients, gerenciamento de projetos e treinamento, e atua também como instrutor oficial Microsoft em centros de treinamentos (CLPS), e é detentor das seguintes certificações:

  • MCT - Microsoft Certified Trainer;
  • MCSD - Microsoft Certified Solution Developer;
  • MCDBA - Microsoft Certified Database Administrator;
  • MCAD .NET - Microsoft Certified Application Developer;
  • MCSD .NET - Microsoft Certified Solution Developer for .NET;
  • MCTS - Microsoft Certified Technology Specialist for Windows Mobile.

Veja o todos os artigos publicados por Caio Proiete no PDAExpert.

Artigos Relacionados

3 Comentários »

Comentários via RSS TrackBack URI

  1. Rafael - TreoClub em 17/07/2007 12:53

    Caio, parabéns pelas matérias. Abraço !

  2. Rodrigo Kravetz de Oliveira em 08/08/2007 17:45

    Sua metodologia de ensino é muito boa. Parabéns.
    O artigo é agradável e o aprendizado é fácil.
    Digno de um instrutor MS.

  3. Caio Proiete em 08/08/2007 18:41

    Obrigado pelos elogios, Rafael e Rodrigo.
    Estou me esforçando para escrever cada vez mais e melhor.

    Abraços,
    Caio Proiete

Envie seu comentário

ATENÇÃO: A área de comentários deve ser utilizada apenas para dúvidas sobre este artigo. Para dúvidas não relacionadas a este artigo, utilize o Fórum PDAExpert.net.

Nome

E-mail

URL

Comentário

XHTML: São permitidas as seguintes tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

campos obrigatórios