Abrindo e analisando o projeto do Mep Texto

Por:
Ao abrir um programa criado por uma outra pessoa para modificação, você pode literalmente ficar louco. Especialmente quando você não participou do desenvolvimento desde o começo, não tem contato com o autor, etc., o que normalmente ocorre ao baixar programas open source. Para complicar ainda mais, o código fonte quase nunca é documentado, e o Mep Texto não é exceção. Em programas pequenininhos, muitas vezes com uma única tela de código, você pega toda a lógica e o esquema do programa com uma só olhada. Agora, em projetos maiores… O Mep Texto não é um programa “grande”, mas o código fonte da Unit principal dele, jogado para texto em Courier New tamanho 10, deu 78 páginas em papel A4. Aí dá para você ter uma idéia do que pode vir pela frente… Isso que foi o código do editor apenas, não das outras telas e funções, muito menos os componentes.

Como produtor único dele até o dia em que liberei o código fonte, comentarei agora algumas particularidades do projeto, para facilitar para outros programadores que queiram editá-lo. Claro que não comentarei tudo, cada linha de código, isso seria simplesmente impossível. Adianto que você não aprenderá muito sobre o programa lendo o código na ordem em que ele aparece no editor de código. Ele é formado por diversos blocos ou seções, normalmente, você deve verificar nos eventos do objeto selecionado o que você quer modificar. Mas uma coisa que eu gosto de fazer, quando tenho tempo e papel, é imprimir o código fonte, e lê-lo com calma. Às vezes assim eu contro coisas que podem ser modificadas, novas idéias e melhorias surgem, detecto problemas que no computador eu não encontrava, etc. Mas isso não é essencial, cada um é cada um…

Com todos os componentes necessários instalados, abra o arquivo “MepTexto.dpr”, da pasta do código fonte, no Delphi. Ele mostrará uma janela com o título “Mep Texto Open”, aparentemente, sem nada dentro. Esta é a tela inicial, a primeira ser carregada quando o programa é iniciado. O Mep Texto 5.0 ou superior é MDI, “Multiple Document Interface”, ele permite abrir vários arquivos dentro da mesma janela (atualmente existem botões para alternar entre eles, mas a idéia é aplicar abas, no futuro). Por isso essa janela inicial é tão vazia, ela não é a janela do editor em si. Ela servirá de base para agrupar as outras janelas. O usuário final do programa nem perceberá isso, pois logo ao abri-lo, ele já cria e carrega uma instância do formulário do editor.

Então, o formulário inicial é o “pai”, que é uma janela do tipo “MDIForm”. Ele é o primeiro a ser aberto, pois está definido como formulário padrão:
index_html_3be60eb8
Ele não tem nada visualmente, como falei, mas no código é ele quem possui a chamada para a função de abrir arquivos e novas abas, pois isso pode ser chamado tanto do formulário do editor como antes do editor estar aberto (por exemplo, ao abrir um arquivo com o duplo clique, pelo Windows Explorer).

Dica: Clicando no botão “View form” do Delphi (SHIFT + F12) você pode ver os outros formulários; tecle F12 simplesmente para alternar entre o formulário e o código relacionado a ele.

O “frmMepTexto” é o formulário que contém o editor em si, e é do tipo “MDIChild” (ou seja, poderão ser abertas diversas instâncias dele dentro do formulário pai). Ele é o que tem mais componentes visuais e também cuja unit (unidade de código) é a que possui o maior código :p
index_html_12be80e5
Não estranhe, “Tonight” é o codename da versão 5. Para editar os menus você deve dar um duplo clique sobre eles, devido particularidades do componente; idem para as barras de ferramentas (é diferente dos menus padrões do Windows). Ao dar um duplo clique sobre a faixa que contém os menus “Arquivo, Editar, Exibir, etc…” será aberta esta tela:
index_html_m70584b23
Ela permite editar os itens, adicionar novos, etc. Para editar o código de ação de um item de menu (aquilo que será realizado quando o usuário clicar no menu), abra a tela de edição do menu desejado, selecione o item e dê um duplo clique nele. Ou, com ele selecionado, dê um duplo clique no evento “onClick”, da aba “Events” do “Object Inspector” (aquela tabelinha de duas colunas que fica à esquerda do Delphi; na imagem de tela, está logo acima do botão “Iniciar” do Windows).

Você verá que este componente é muito prático e eficiente, e se você não conhecia ainda o ToolBar2000, muito provavelmente gostará tanto que passará a usá-lo nos seus outros projetos. As barras de ferramentas seguem o mesmo estilo, na verdade, qualquer uma pode ser tanto de menus como de ferramentas com esse componente, bastando ajustar algumas propriedades delas, como a exibição dos títulos, imagens, etc. Os menus pop-up são os que contém uma setinha do cursor de mouse com um “+” vermelhinho, no canto inferior direito; ao dar um duplo clique sobre eles, abre-se a mesma tela de edição de menus também.

Através do editor dos menus você pode alterar os atalhos de teclado, também. Basta selecionar o item do menu, e alterar a propriedade “Shortcut” dele, pelo Object Inspector. O Mep Texto possui diversos atalhos, muitos comuns em vários programas, e ainda faz uso intensivo das teclas de funções:

  • F1 = Ajuda: sem texto, no momento; Nas versões anteriores tinha, mas adicionei muitas coisas, mudei muitas outras, e ainda não deu tempo de escrever um manual de ajuda completo como eu gostaria 🙂
  • F2 = Visualizar no navegador: salva o texto atual num arquivo temporário, e abre no navegador (supondo tratar-se de HTML). Se for uma página “.htm” ou “.html’ que estiver sendo editada, então ele abre o arquivo diretamente, sem salvar nos temporários, para manter as referências a possíveis imagens ou links relativos.
  • Alt + F2 = Visualizar no navegador, com quebras de linha. Basicamente copia o texto do editor para um campo temporário, adiciona “<br>” a cada quebra de linha, salva num arquivo temporário e a seguir, abre no navegador. É útil para verificar postagens em blogs, eu uso muito isso, antes de copiar e colar no gerenciador do blog. Assim você digita o texto dando [enter]a cada linha, mas para visualizar num navegador, tecla Alt + F2, para que as quebras sejam aplicadas em HTML.
  • CTRL + F2 = Adiciona o conteúdo do arquivo “HTML.mep”, da pasta do editor, dentro do arquivo atual. Este serve como um modelo, criado pensando-se em quem mexe com HTML, mas o conteúdo do arquivo pode ser personalizado para qualquer coisa.
  • F3 = Tradicional “Localizar próxima”, para pesquisar textos.
  • F4 = Insere a tag “<br>”, do HTML. Só tem utilidade para quem mexe com HTML.
  • F5 = Copiar (além do CTRL + C, claro)
  • F6 = Colar
  • F7 = Recortar
  • F8 = Copiar tudo (seleciona tudo e já copia para a área de transferência do sistema)
  • F9 = Tela de inserção de textos rápidos (será comentada nos recursos especiais do Mep Texto, logo mais)
  • F10 = Não aplicada a nada, por enquanto :p
  • F11 = Abrir arquivo
  • F12 = Salvar arquivo (salvar comum, é mais cômodo teclar F12 do que CTRL + S ao salvar continuamente um texto que não se quer perder)
  • SHIFT + F12 = Salvar como
  • CTRL + F12 = Salvar e fechar (ideal para quando você termina de editar um arquivo, já salva e fecha direto). Como medida de precaução, ele verifica antes de fechar se o arquivo foi realmente salvo.

Boa parte dos atalhos citados acima não estão nos menus, eles ficam “ocultos”. Há um menu “Oculto”, que usei para poder aplicar estes atalhos, ele na verdade redireciona os eventos dos seus itens (também ocultos) para os itens correspondentes dos outros menus. Isso permite que também sejam aplicados os tradicionais, como CTRL + A, CTRL + T, etc, sendo estes tradicionais os exibidos ao usuário. Esse menu oculto pode ser visto no editor dos menus, ele fica após o “Infodoido”, e este depois do “Ajuda”.

Nota: o menu “Infodoido” criei e deixei oculto por padrão, inicialmente para aplicar testes de novos recursos. Marcando a opção “Ativar na interface visual opções avançadas ou adicionais, algumas em beta”, na tela “Outras configurações” das opções, esse menu aparece para o usuário final. Atualmente contém dois itens apenas, um que converte o texto do editor substituindo algumas letras por números, g3r4nd0 73×705 4551m, e outro que reconverte estes textos doidos em textos normais, substituindo os números pelas letras.

Ainda sobre os menus, eu apliquei um efeito agradável para muita gente, que lembra bem – mas é diferente – os menus do Office 2000 ou o “Iniciar > Programas”, do Windows Me/2000 ou superiores. Eles exibem apenas as opções mais comuns ou mais usadas, mas no Mep Texto elas são fixas e definidas durante o projeto do programa. No final dos menus há uma setinha, para expandi-los e assim exibir os outros itens:
index_html_41fac7a7
Os componentes usados não fornecem um meio de gerenciar esse tipo de menu, eu usei um artifício: deixando os itens desejados ocultos, e alterando a propriedade “Visible” deles para True quando o usuário passar o mouse sobre o item que contém a setinha, tem-se o efeito desejado. O item que contém a setinha é um item de menu normal, apenas com as propriedades devidamente configuradas para ficar sem texto, e com a imagem da setinha alinhada ao meio. Da mesma forma, como os menus podem ser abertos a qualquer momento, ao clicar nos menus (Arquivo, Editar, etc.) a propriedade “Visible” dos itens desejados é mudada para False. Isso na verdade com uma mesma função (a “AplicaMenusReduzidos”), que recebe como parâmetro um valor booleano, decidindo se ocultará ou não os itens dos menus. Isso é controlado pela variável global no editor, “menusRed”, que é inicializada ao carregar as opções. O usuário pode desativar esse recurso nas opções, fazendo com que os menus sempre apareçam completos. Para localizar no código, procure os eventos “Arquivo1Popup”, que é comum a todos os menus, e “maisArquivoSelect”, que é comum aos últimos itens da maioria dos menus, que são justamente os itens que contém a setinha. Digo da maioria dos menus, pois menus que possuem poucos itens não precisam disso (como o “Ajuda”), já exibindo todos os itens diretamente.

Dentro do formulário do editor, alguns eventos importantes são o onCreate e o onClose, do formulário “frmMepTexto”. Selecionando o “frmMepTexto” na listinha do topo do Object Inspector, e então clicando na aba “Events”, você poderá acessá-los facilmente.

O evento onCreate do formulário do editor é muito importante. Ele é chamado sempre que o editor é criado, ou seja, quando o programa é aberto, ou quando uma nova aba é aberta. As principais funções chamadas por ele são:

– VerificaConfiguracoes – Carrega as opções do registro, alterando em tempo de execução, diversas opções do editor. Esta função é pública, pois será chamada também pela tela das opções. Quando o usuário clicar em “Aplicar” na tela das opções, as mesmas serão gravadas no registro, e esta função será chamada do editor, para recarregar as novas opções.

– CarregaFonte – Verifica e aplica o tipo de letra do editor, cor e tamanho.

– CarregaMensagens – Esta carregaria os textos da interface, baseando-se numa escolha feita pelo usuário. Este recurso não está implementado, eu coloquei pensando em torná-lo multilíngue, mas isso me tomaria um tempo impraticável, dado o avanço do programa, a quantidade de coisas a mexer e alterar, etc. No entanto, ela é chamada pois define alguns textos, mesmo em português, para alguns itens de menus e da interface.

No evento onClose ele verifica se existe apenas uma aba aberta. Se existir, ele fecha o programa inteiro, supondo que o usuário tenha fechado o programa, ou que seja a última aba a ser fechada. Caso contrário, ele fecha apenas a aba atual liberando a memória dela, mas deixando a aplicação aberta, devido às outras abas. Isso será chamado, por exemplo, quando o usuário clicar no X da janela para fechá-la, ou ao escolher a opção “Sair e fechar tudo” no menu “Arquivo”.

Além desse onClose, logo abaixo dele há um item muito importante num editor, que lida com arquivos do usuário. Trata-se do evento onCloseQuery. Ele é chamado sempre que o usuário tentar fechar a tela do programa, mas pode impedir o fechamento, se for o caso (devolvendo a variável CanClose como True, então pode fechar; caso contrário, não pode). Aqui coloquei uma chamada à função de nome “ChecaArquivoSalvo”, que traz um resultado de um tipo definido por mim no programa, que pode ser “mSalvar”, “mNaoFechar”, ou “mDescartar”. Ela justamente verifica se o arquivo está salvo ou não, vendo a propriedade “modified” do editor, além do nome do arquivo. A tela exibida perguntando se o usuário quer salvar o arquivo ou não, é um formulário a parte, “frmSalvar”:
index_html_bc2478b
Muitos programas para Windows usam nessa hora uma janela de mensagem padrão (normalmente da própria API do Windows), como esta, por exemplo:
index_html_1ec16e2e
No Mep Texto as mensagens e a janela são personalizadas, trazendo uma interface mais didática e agradável ao usuário final, além de possuir um link “Mostrar dicas de salvamento”. Esta mesma tela, chamada pela mesma função ” ChecaArquivoSalvo”, será exibida caso o usuário esteja com um arquivo aberto e tente criar um novo, sem salvar o atual, por exemplo. O código para ela é o mesmo e único, eis uma das vantagens da programação orientada a objetos: o reaproveitamento de código, tendo um programa mais “limpo”. Dependendo do resultado que ela retornar (que obviamente, dependerá do botão em que o usuário clicar), o programa executará uma ação aí sim, variável conforme de onde foi chamada. Por exemplo, ao fechar um arquivo não salvo, se o usuário pedir para não salvar, o editor será fechado. Mas ao criar um novo arquivo, se o usuário não quiser salvar o atual, o editor não será fechado, mas sim o novo arquivo será criado. Isso chamado por lugares diferentes, no caso o meu “Arquivo > Novo” e o evento “onCloseQuery” do formulário, mas usando uma só função de verificação, a “ChecaArquivoSalvo”. Normalmente os nomes das funções estão em português, afinal o Mep Texto foi desenvolvido do zero por mim, sem ser baseado em nenhum outro programa. Porém, funções aproveitadas de outros códigos ou programas, ou as que respondem a eventos gerados automaticamente pelo Delphi, estarão em inglês, como “item1click”, “btn2dblclick”, etc.

O “FormConfigurar” é a tela das opções, o código também é grandinho, mas não se compara ao do editor:
index_html_1d50f90b
Se você curiar nas outras abas em tempo de desenvolvimento, não se esqueça de voltar para a primeira antes de fechar e compilar o projeto, senão a última guia exibida ficará como padrão e será apresentada aberta para o usuário final.

Quando você adicionar ou remover opções, é bom alterar as funções “AplicaConf” e “CarregaConfig” do “FormConfigurar”. Elas são carregadas pelo editor com a “VerificaConfiguracoes”, já comentada, na unidade de código do “frmMepTexto”. Elas são chamadas, respectivamente, pelo evento “onClick” do botão “Aplicar” e pelo “onCreate” do “FormConfigurar”. É bom também colocar um item para redefinir (remarcar um checkbox, por exemplo) as suas novas opções padrões, quando o usuário clicar no “Restaurar para a configuração padrão…”.

As opções são gravadas no registro, sob a chave “HKEY_CURRENT_USER Software Mep Mep Texto”. Se você quiser mudar esse caminho, use o recurso do menu “Search > Find in files” do Delphi e substitua as ocorrências de “SoftwareMepMep Texto” pelo que quiser.

Como são muito usadas, eu criei duas funções para escrita e leitura no registro, e inclusive as utilizo em outros programas também, simplificando bastante o trabalho do programador (em vez de criar uma variável de registro, abrir a chave, o valor, editar o valor, fechar a chave e destruir a variável todas as vezes, repetindo isso para cada opção, basta chamar estas funções, dizendo que chave será modificada, o valor a ser gravado, o tipo dele, etc). Estas (e outras) funções estão na unit “MepUtil2.pas”.

A sintaxe da função que lê os dados do registro é esta:

function LeReg(mepRoot: Cardinal; Chave: String; const Key: String; KeyType: TKeyType; DefValue: Variant): Variant; Exports LeReg;

Estes são os parâmetros (estou comentando pois certamente você precisará desta função, caso adicione ou remova configurações que possam ser personalizadas pelo usuário):

  • mepRoot: a chave root. Use HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, etc.
  • Chave: a chave em si. No caso, usei uma espécie de constante, chamei-a de minhaChave, para não ficar digitando toda hora. Por exemplo, use SoftwareSeuNomeSeuPrograma.
  • Key: o valor a ser lido, dentro da chave fornecida no parâmetro anterior.
  • KeyType: o tipo de dado. Os valores possíveis estão definidos na “MepUtil2.pas”, e são: ktString (para textos), ktBoolean (para valores booleanos, verdadeiro ou falso), ktInteger (para números inteiros), ktCurrency (valores monetários), ktDate (datas), e ktTime (horas). Dispensam maiores comentários.
  • DefValue: o valor padrão que a função retornará se o valor não existir no sistema do usuário (por exemplo, na primeira abertura do programa).

A que grava dados no registro, é a EscreveReg, cuja sintaxe é esta:

procedure EscreveReg(mepRoot: Cardinal; Chave: String; const Key: String; const Value: Variant; KeyType: TKeyType); Exports EscreveReg;

É similar à anterior, e agora também dispensa comentários. Note apenas o parâmetro “Value”, que contém o valor a ser gravado, ele é do tipo Variant, e será gravado no registro usando o tipo definido em KeyType. Estas funções se tornam um importante aliado na praticidade para gravar e ler dados em qualquer chave do registro, mesmo que não seja para este projeto.

Estas funções podem ser usadas em qualquer tela do Mep Texto, se o formulário não possuir, basta adicionar a unit “MepUtil2.pas” na cláusula “Uses” da unidade do formulário que você quiser. A maioria das telas dele já incluem essa referência.

Comentado agora rapidamente as outras telas… Relacionada às opções, temos o “frmMRU”, um agrupamento para personalização da lista de arquivos recentes:
index_html_3243fd
Ela é chamada ao clicar no “link” “Alterar as opções da lista dos últimos arquivos abertos”, na tela das opções principais. O código de gravação das opções é feita pelo código do evento “onClick” desse link, na unit de código do “FormConfigurar”, e não por esse formulário pequeno, “frmMRU”.

A tela da impressão (“frmImpressao”) é uma mera interface, basicamente todo o trabalho de impressão é comandado pelo componente SynEdit, do editor:
index_html_m3d6d776d
No mesmo estilo visual dela (tamanho e faixas superiores) há o “FormPrivacidade”, que permite, com um clique, limpar os dados pessoais do usuário, ideal para ser usado em computadores públicos:
index_html_m21002409
Sim, essa idéia retirei do Mozilla Firefox 🙂 Inclusive vai o atalho “Ctrl + Shift + Del”, ou pelo menu “Configurar > Limpar dados pessoais”. A limpeza limpa a lista de arquivos recentes, a pasta do Backup Paranóia (você conhecerá ela logo, logo, mais a frente, neste texto), e inclusive a pasta temporária do Mep Texto dentro da pasta “Temp” do perfil do usuário no Windows. Essa pasta é usada para salvar as páginas HTML quando usado o recurso “Visualizar no navegador”, mas os arquivos não são removidos automaticamente, daí a inclusão desse item nesta tela de limpeza. Se você pretende usar arquivos temporários, com dados de arquivos do usuário, essa pasta é um bom lugar para armazená-los (a pasta “Temp Mep Texto”, dentro da pasta “Temp” do perfil do usuário atual).

Temos ainda o “FormLicenca”, que exibe a tela de licença, puxando o texto do arquivo “license.txt” (que deve estar na mesma pasta do programa):
index_html_780114e5
Esta tela de licença é exibida na primeira execução do programa para cada usuário do computador. Ao clicar em “Aceitar”, será gravado o valor “Lic” com o valor 1, na chave de registro do programa (HKEY_CURRENT_USER Software Mep Mep Texto), e então esta tela não mais será exibida automaticamente na inicialização. Ela também será exibida ao clicar no item “Licença de uso” do menu Ajuda, mas aqui, sem os botões “Aceitar” e “Recusar”, basicamente modificando em tempo de execução a posição e o texto deles (veja como isso é feito no evento “onClick” do menu “Ajuda > Licença de uso”).

Ainda seguindo o mesmo estilo estético de janelas (tamanho, logo e faixa superiores), temos o “FormSubstLote”, que permite substituir ocorrências de texto em lote (tive problemas ao usar isso com alguns arquivos Unicode, funcionando perfeitamente em arquivos ASCII):
index_html_770e7b86
Devido a esse recurso (que pode ser acessado pelo menu “Pesquisar > Substituir texto em lote”), incluí também uma tela de progresso, o “frmProgresso”:
index_html_1a519cd7
Apesar destes formulários, todo o mecanismo de substituição e atualização da tela de progresso ficam por conta do código inserido na unit “frmMepTexto”, no evento “onClick” do item de menu “Pesquisar > Substituir texto em lote…”.

O Mep Texto inclui também um visualizador das fontes instaladas no Windows, apesar de ser um editor de textos puro e se dar melhor com fontes mono-espaçadas. Ele pode ser chamado pelo menu “Exibir > Visualizar fontes instaladas”:
index_html_m36763805
Finalizando, temos a tela “Sobre”, formada por algumas guias (“abas”), no “Form7_Sobre”. Essa idéia me veio do KDE, da tela “sobre” dele, utilizada em vários programas para Linux:
index_html_339aace
Ela exibe informações sobre o uso de memória, versão de Windows, e inclui o componente de HTML integrado do IE (o quadro branco, na imagem acima) onde é carregada uma página HTML.

Estas imagens de tela são das telas em tempo de desenvolvimento. No lugar dos quadros com pontilhados, ficarão imagens reais 🙂 Um bom exemplo disso são as telas que têm o mesmo tamanho e aparência no Mep Texto (como a de substituição de texto em lote, impressão, limpeza de dados pessoais, etc). Ele carrega estas imagens em tempo de execução, puxadas de um arquivo de recurso (o “mt.res”). Esse arquivo pode ser editado (para trocar as imagens) com editores de recursos, como o Resource Hacker, ou com editores inclusos em alguns ambientes de programação. Nada impede, no entanto, que você coloque outras imagens diretamente. Apliquei como “resources” devido o compartilhamento, elas são usadas em várias telas, e assim são armazenadas uma única vez no arquivo. Na verdade, em tempo de execução, as imagens serão puxadas do próprio executável do programa. Elas estão armazenadas neste arquivo para serem facilmente substituídas durante o desenvolvimento, mas este arquivo será embutido no executável durante a compilação.

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X