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

Gostou deste artigo? Compartilhe!

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

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 smartphones, principalmente nas plataformas Windows Phone 7, Windows Mobile, Palm OS, e Symbian OS.

Atualmente suas principais ferramentas/tecnologias de trabalho incluem Visual Studio 2010, Silverlight, eMbedded Visual C++, .NET Compact Framework, C# .NET, Objective-C, CodeWarrior C++, Handheld Basic, 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;
  • MCPD - Microsoft Certified Professional Developer for Windows Phone 7;
  • MCTS - Microsoft Certified Technology Specialist for Windows Mobile;
  • MCSD - Microsoft Certified Solution Developer;
  • MCDBA - Microsoft Certified Database Administrator;
  • MCAD .NET - Microsoft Certified Application Developer;
  • MCSD .NET - Microsoft Certified Solution Developer for .NET.

Blog técnico: http://caioproiete.net

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

Artigos Relacionados

5 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

  4. cleverton em 25/12/2008 21:18

    parabens pelos artigos
    mas ainda confesso que não entendi uma coisa: como funciona a comunicação de palm com o banco de dados(por exemplo no msql)? a aplicação no palm pode ser somente considerada como estatica e a parte dinamica quem faria?
    posso desenvolver aplicações palm com vb.net? se não for abusar muito de sua compreensão tem como me enviar algumas apostilas que tratam desses assuntos
    obrigado

  5. Gomes em 11/10/2009 08:30

    Bom Dia !

    Caio, como consigo implementar esse password em meu sistema?

    Agradeço, desde já por sua resposta.

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