Documentação XML no Código Fonte Delphi, estilo JavaDoc

Escrito em 28 de Março de 2007 em Delphi por Leonel Togniolli

Muita gente não sabe, mas a partir do Delphi 8 é possível documentar seu código com comentários especialmente formatados, e assinalar uma opção que irá fazer o compilador gerar um arquivo XML com essa documentação. O arquivo XML pode então ser processado por ferramentas que geram documentação em vários formatos, sendo possível inclusive integrar esse conteúdo no help do Delphi.

 Para gerar essa documentação, é fácil. Basta incluir os comentários no seu código fonte, usando três barras para os comentários, e não duas como usual. Assim:

type
  /// Formulario de cadastro
  TFormCadastro = class(TForm)
    /// Handler do evento OnCreate
    procedure FormCreate(Sender: TObject);
  end;

var
  /// Variavel global do formulario
  FormCadastro: TFormCadastro;

Depois disso, deve-se assinalar a opção de geração de documentação nas opções do projeto, aba Compiler:

 

Essa opção é o equivalente de chamar o compilador de linha de comando, dcc32, com a opção –doc.

Depois de compilar seu projeto, serão gerados arquivos XML para cada unit com informações sobre as classes, variáveis, métodos, propriedades, incluindo os comentários que você adicionou. Do meu formulário de exemplo acima, foi gerado o seguinte:

A partir daí, você pode processar esse XML como quiser para ter uma documentação do seu sistema, ou utilizar algum programa como Doc-O-Matic para automatizar esse processo.

Um novo recurso do Delphi 2007 são warnings do compilador para auxiliar na documentação das classes. São eles:

W1201 XML comment on '%s' has badly formed XML -- 'Whitespace is not allowed at this location.'
W1202 XML comment on '%s' has badly formed XML -- 'Reference to undefined entity '%s'.'
W1203 XML comment on '%s' has badly formed XML -- 'A name was started with an invalid character.'
W1204 XML comment on '%s' has badly formed XML -- 'A name contained an invalid character.'
W1205 XML comment on '%s' has badly formed XML -- 'The character '%c' was expected.'
W1206 XML comment on '%s' has cref attribute '%s' that could not be resolved
W1207 XML comment on '%s' has a param tag for '%s', but there is no parameter by that name

 A geração de documentação a partir do código fonte é um recurso que está disponível para facilitar a nossa vida - não deixe de utilizá-lo.

Se você é novo por aqui, não deixe de assinar o feed RSS ou notificações por email. Não perca novos artigos!

Video Aula - Frames utilizando Frames

Escrito em 27 de Março de 2007 em Orientação a Objetos, VCL/RTL, Video Aulas por leosimas

Olá pessoal!
Está é minha segunda video-aula sobre delphi para o TechTips.

Nesta video aula, vocês poderão ver o quanto é util uma hierarquia de frames que podem utilizar outros frames. Os frames criados na video-aula anterior foram reutilizados para mostrar mais uma vez como isso é prático.

 

Para ver a video-aula, clique aqui.

Melhorias no Debugger do Delphi 2007 para Win32 - Parte 1

Escrito em 27 de Março de 2007 em Delphi por Leonel Togniolli

O Debugger ganhou algumas melhorias no Delphi 2007 para facilitar nossa vida. Algumas vezes são as pequenas coisas que acabam chamando nossa atenção, e esse novo recurso é uma dessas coisas que chamou a minha: simples, rápido, e bastante prático.

No Delphi 2007 para Win32 foi adicionada uma opção para adicionar um breakpoint diretamente na call stack. Quando você está depurando sua aplicação e nota que um método na pilha de chamadas é interessante e você gostaria de investigá-lo mais profundamente, você tem algumas opções: utilizar Shift-F8 para ir até o método que chamou o atual, e repetir isso algumas vezes até chegar onde quer. Outra opção é ir até o método selecionado, colocar um breakpoint em uma parte do código que ainda não foi executada, e rodar e deixar a execução parar lá.

É isso que o novo recurso faz. É possível clicar na Call Stack e adicionar um breakpoint diretamente em um dos métodos da pilha de chamadas. O breakpoint é colocado nesse método, logo após a função que foi chamada para chegar no ponto de execução atual. Dessa forma, basta rodar a aplicação daquele ponto e a execução será interrompida assim que chegar no método que te interessa.

Veja como funciona:

Legal, não?

Help! - Documentação do Delphi 2007 para Win32

Escrito em 26 de Março de 2007 em Delphi por Leonel Togniolli

Estou começando a publicar uma série de artigos sobre o Delphi 2007, e o primeiro tópico não poderia deixar de ser a documentação, que recebeu uma atenção especial nessa versão.

Até o Delphi 7, o help testava os limites do formato WinHelp. WinHelp já era um formato ultrapassado, sem melhorias ou suporte, inclusive não funcionando diretamente em uma instalação padrão do Windows Vista hoje em dia. Quando foi impossível incluir mais conteúdo sem estourar esse limite, uma alternativa teve que ser encontrada. A solução foi passar para o formato HTML Help 2, que tinha que comportar as mais de 38mil páginas de documentação que compõe o Help. Essa migração afetou a qualidade da documentação, que perdeu a praticidade que existia nas consultas do help anterior, e parte do conteúdo.

O Delphi 2007  para Win32 teve como um dos principais focos a melhoria da documentação, tanto no conteúdo, na sua apresentação, e na integração com a IDE. O processo foi árduo, mas teve resultados que são bastante visíveis:

O screenshot mostra a documentação de um TButton, documentação acessível a partir de F1 do designer de formulários, ou sobre uma variável desse tipo no código. Está visível a hierarquia completa da classe, com links para a documentação de cada classe ancestral, a unit onde ele é declarado, e texto especifico sobre essa classe. Temos de volta a lista de de componentes,funções e procedimentos em cada unit:

  

E a lista de propriedades, métodos e campos de cada componente:

A parte de procedures inclui vários tutoriais passo-a-passo ensinando a fazer diversas tarefas relacionadas a VCL, Banco de Dados e outros assuntos, contando inclusive com trechos de código:

A documentação é novamente um lugar onde iniciantes podem ler e aprender a trabalhar com o Delphi e a VCL, ou programadores mais experientes podem usar para descobrir o que aquela determinada propriedade realmente deveria fazer.

Configurando o ViewState em ASP.Net

Escrito em 26 de Março de 2007 em Asp.Net por Leonel Togniolli

 Já vimos o que é o ViewState e como utilizá-lo. Existem algumas configurações mais avançadas que podem ser feitas na sua aplicação para controlar como o ViewState é gerado, e vou passar por uma delas agora.

Já comentei que, para evitar que o ViewState seja alterado por alguém que queira tentar explorar alguma vulnerabilidade na sua aplicação web, é gerado um hash do seu conteúdo e, no postback, esse hash é conferido para garantir a integridade dos dados. Se esse valor não está correto, o ASP.Net gera uma exceção e não permite o carregamento da página:

Esse hash não é gerado de uma forma igual em todos os servidores, é claro. Caso fosse, seria bastante simples alterar os dados e gerar um novo hash para driblar esse mecanismo de segurança. Para gerá-lo, é usada uma chave única em cada máquina, baseada no endereço MAC da placa de rede desse servidor.

O problema aparece quando estamos utilizando uma aplicacão ASP.Net em um ambiente com balanceamento de carga. Cada servidor vai ter uma chave diferente, e se uma página for gerada em um servidor e no postback cair em outro, vai ser gerada uma bela exceção para seu usário.

É possível desabilitar a geração desse hash, adicionando a seguinte entrada no web.config da sua aplicação:

<system.web>
  <pages enableViewStateMac="false" />
</system.web>

Isso desabilita a segurança, e geralmente não é uma boa idéia. A solução real é simples, e é bom conhecê-la antes que seus usuários comecem a ter problemas: basta gerar uma chave única, e utilizá-la em todos os servidores da sua web farm.

Para gerar uma chave, existem algumas ferramentas disponíveis. Uma delas é o <machineKey> Generator, uma aplicação online onde basta configurar alguns parâmetros, gerar a chave e colar o resultado dentro do nó <system.web> do web.config de sua aplicação, e replicá-lo em todas os seus servidores web. Também é possível alterar o machine.config de cada máquina para evitar incluir essa informação em cada aplicação.

Utilizando o ViewState em ASP.Net

Escrito em 24 de Março de 2007 em Asp.Net por Leonel Togniolli

Já mostrei o que é o ViewState e como os controles de ASP.Net fazem para guardar informações dentro dele. Agora vamos ver como podemos guardar nossos próprios dados nesse campo oculto.

A classe que representa uma página, no ASP.Net, possui uma propriedade ViewState. Ela, é, basicamente, uma coleção de items armazenados por Nome/Valor. Podemos guardar qualquer informação nesse campo, e obtê-la novamente a qualquer momento, desde que seja na mesma página.

Para servir como exemplo, vamos criar uma aplicação com um TextBox, um botão e um Label. O objetivo é, ao clicar no botão, ler um número do TextBox, e acumular esse valor, mostrando a soma total no Label. O acumulador começa em zero.

Podemos implementar esse problema assim:

procedure TWebForm1.Button1_Click(sender: System.Object; e: System.EventArgs);
const
  ChaveTotal = 'Total';
var
  Valor: Integer;
  Total: Integer;
begin
  Valor := Int32.Parse(TextBox1.Text);
  if Assigned(ViewState[ChaveTotal]) then
    Total := Integer(ViewState[ChaveTotal])
  else
    Total := 0;
  Total := Total + Valor;
  ViewState[ChaveTotal] := System.Object(Total);
  Label1.Text := Total.ToString;
end;

Dessa forma, estamos guardando um valor que sobrevive atualizações de página em um campo oculto dentro dela. O valor não é compartilhado por outros usuários que estejam acessando o site ou por outras páginas que esse mesmo usuário possa visitar. Quando o browser for fechado, o valor é perdido. E, como já vimos anteriormente, é fácil decodificar o viewstate (apesar de ser mais difil alterá-lo), portanto não armazene informações confidenciais dessa maneira.

Gerenciador de Tarefas, e Uso de Memória no FireFox

Escrito em 21 de Março de 2007 em Gerenciamento de Memória por Leonel Togniolli

Vendo uma “dica” sobre como fazer o Firefox utilizar menos memória, mais uma vez me surprendo como as pessoas não entendem como o Windows gerencia memória, se confundem com o números dados pelo gerenciador de tarefas e tomam decisões que acabam diminuindo a performance de seu sistema.

Para começar, quero deixar bem claro um ponto: não utilize o Gerenciador de Tarefas, em hipótese alguma, para falar sobre memória. Ele não diz quanto de memória é usada pela sua aplicação, não serve pra determinar se alguém está vazando memória, nem mesmo se uma aplicação utiliza mais memória que a outra.

A informação que é passada na coluna de uso de memória, no gerenciador de tarefas, é o Working Set. Working Set de um processo é o conjunto de páginas de memória fisica atualmente reservadas para este processo. Se a memória que sua aplicação está usando é menor que o Working Set, páginas livres estão disponíveis para atender requisições de alocação de memória rapidamente. Se sua aplicação utiliza mais memória que o Working Set reservado pra ela, parte dessa memória é jogada para o cache em disco - chamado de arquivo de troca, ou swap file. Além disso, o Working Set também soma o tamanho de DLLs carregadas, inclusive as de sistema, mesmo que estejam sendo compartilhadas por vários processos. Memory Mapped Files também contam como páginas para o Working Set mesmo não utilizando um byte de memória.

O Windows geralmente mantém reservadas no Working Set mais páginas do que a aplicação utiliza no momento, para que aplicações façam menos swap e tenham uma performance melhor quando precisarem alocar mais memória. Afinal, memória não alocada é memória desperdiçada, e quando for necessário mais memória do que está livre fisicamente, os working sets são diminuídos conforme for necessário.

Além de quando o Windows tem pressão de memória, o Working Set de uma aplicação geralmente também é diminuído quando a aplicação é minimizada. É fácil fazer o teste: pegue uma aplicação que você está usando faz algum tempo, olhe o Working Set dela no gerenciador de tarefas, minimize essa aplicação e veja como o Working Set diminuiu. A aplicação utiliza a mesma quantidade de memória que utilizava antes de ser minimizada, mas agora possui menos memória reservada para ela (e corre risco maior de cair no swap se a memória fisica estiver curta).

Uma terceira forma de diminuir o Working Set de uma aplicação é chamar a API SetWorkingSetSize(); para zerar o Working Set de uma aplicação, tendo o mesmo efeito de minimizá-la. Apesar de o propósito útil da API seja reservar um Working Set maior que o atual para evitar constante swaping ao realocar memória frequentemente, muita gente utiliza a API para o contrário, muita vezes em um timer, para manter os números sua aplicação no Gerenciador de Tarefas bonitos e aparentemente baixos. O resultado prático disso é, obviamente, uma maior lentidão para alocar memória e maior proabilidade de sua aplicação entrar no swap.

A decisão de manter o working set quando minimizado está documentada em páginas e páginas de discussão no bug que corrigiu o demorado reínicio após um grande período de inatividade. Um comentário no código fonte do Firefox diz que se alguém reclamar do uso de memória do Firefox quando minimizado, vai ter a discussão completa sobre o bug tatuada nas costas. Espero que, entendendo o que é o Working Set, você não corra esse risco.

Delphi Tour 2007 em Curitiba 21/03/2007

Escrito em 21 de Março de 2007 em TechTips por leosimas

Pessoal do news que participou do evento Delphi Tour 2007 em Curitiba.

Achei o evento melhor que do ano passado.

Ps: Foto tirada com o celular do SEOB.

Entendendo o ViewState em ASP.Net

Escrito em 17 de Março de 2007 em Asp.Net por Leonel Togniolli

Quando expliquei sobre o tempo de vida de uma página ASP.Net, disse que existem mecanismos que uma aplicação pode utilizar para guardar estado entre requisições. Um desses mecanismos é o ViewState.

ViewState é uma string armazenada em um campo oculto, dentro do HTML gerado para a sua página. Se você criar uma nova aplicação ASP.Net, sem nada, rodar, e olhar o código fonte da página vazia que foi gerada, vai encontrar algo parecido com isso:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
    <title></title>
  </head>

  <body>
     <form name="_ctl0" method="post" action="WebForm1.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE" value="dDwtNjU0MzcyMTk1Ozs++0nkj9wYEIHhJubPoNiG5UGjjaI=" />

     </form>
  </body>
</html>

É fácil de ver o viewstate nesse código fonte. Ele é um conjunto de dados sobre a página e seus componentes, concatenado com um hash gerado no servidor para evitar ataques onde alguma pessoa maliciosa altere o conteúdo dessa string e faça um postback para o seu servidor. Essa string está em Base64, e é simples decodificar, como por exemplo usando o ViewState Decoder. Vamos ver o que o viewstate da nossa página vazia possui:

<?xml version="1.0" encoding="utf-16"?>
<viewstate>
  <Triplet>
    <String>-654372195</String>
  </Triplet>
</viewstate>

Não existe nada de interessante ainda, apenas o hash da página, que evita alterações não permitidas.

Cada componente colocado em uma página ASP.Net vai salvar seu estado no ViewState, para que cada vez que acontecer um postback esse componente possa voltar a ser exibido exatamente como estava antes, sem precisar fazer nova inicialização ou trazer os dados novamente do banco de dados, e assim por diante. Isso é prático, mas pode deixar o ViewState incrivelmente grande e aumentar bastante o tamanho da sua página - e o tempo de carregamento por consequência.

Vamos fazer um teste para ver como isso funciona: coloque um DropDownList, um botão e um ListBox em uma nova página ASP.Net. Coloque o seguinte código no PageLoad para popular o DropDownList com algumas opções:

procedure TWebForm1.Page_Load(sender: System.Object; e: System.EventArgs);
begin
  if not IsPostBack then
  begin
    DropDownList1.Items.Add('Um');
    DropDownList1.Items.Add('Dois');
    DropDownList1.Items.Add('Três');
  end;
end;

Escreva também o código apropriado no botão para adicionar no ListBox o item selecionado do DropDownList. Rode a aplicação, selecione alguns items diferentes e aperte botão para ir adicionando esses items. Repare como o DropDownList mantém os items mesmo não sendo preenchido toda vez, e como o ViewState vai aumentando o tamanho cada vez que você adiciona um item novo. Utilize a ferramenta que mostrei anteriormente para ver o que está dentro dele cada vez que você pressiona o botão.

Para ver o que o ViewState faz de verdade, vá até o DropDownList e altere a opção EnableViewState para False. Rode a aplicação de novo e perceba como após a primeira atualização de página, os items que tinham sidos adicionados no DropDownList não estão mais lá. Podemos alterar nosso código que carrega os items no PageLoad para fazer o carregamento toda vez, e não só quando não for Postback. Tirando o if, os items são carregados a cada requisição, diminuindo o tamanho do viewstate. Em uma aplicação mais realista, é bem possível que esses dados estivessem vindo do banco de dados, então estariamos fazendo bem mais consultas, o que geralmente é prejudicial à performance e à carga do servidor. Nesse caso deve se usar o bom senso e considerar o que é mais importante para cada situação: não há uma regra padrão.

Outro experimento interessante para entender o funcionamento do ViewState é desligar o ViewState da ListBox, e rodar o exemplo novamente. Acho que neste ponto você já consegue imaginar como a aplicação vai se comportar, e entender o motivo. O último teste a fazer é trocar a DropDownList por um TextBox, e rodar a aplicação com o ViewState da TextBox ligado e desligado. Surpreso por ver o conteúdo da TextBox sendo mantido mesmo com o ViewState desligado? É porque o conteúdo de campos em formulários é submetido normalmente a cada requisição, sem precisar de espaço extra no ViewState para isso.

O ViewState não serve apenas para guardar o estado de controles que estão na página - você pode guardar os dados da sua aplicação nesse campo oculto, se eles forem aplicáveis só para uma página. Vou explicar como fazer isso no próximo artigo.

Download do Delphi 2007 para Win32 já disponível

Escrito em 16 de Março de 2007 em Delphi por Leonel Togniolli

No último dia da CodeRage, a conferência virtual da CodeGear, veio a notícia que o Delphi 2007 foi finalizado e liberado para produção.

Uma das novidades dessa nova versão do Delphi é o instalador, que utiliza a tecnologia do InstallAware para apresentar uma experiência muito mais interessante durante instalação. Um dos recursos novos desse instalador é que ele permite a instalação online, a partir de um pequeno executável, e faz o download apenas dos pacotes que você precisa para sua versão e para os recursos que você selecionou.

Esse recurso é utilizado para a venda do D2007 por ESD, Eletronic Software Delivery, que é uma versão mais barata do Delphi 2007 sem o custo da mídia e da entrega. Quem comprar a versão por ESD também tem a opção de pagar a diferença e comprar o “Media Kit” para receber o DVD em casa depois de ter feito o download.

Antigamente, após uma versão do Delphi ser finalizada, demorava alguns semanas até a primeira pessoa receber a sua encomenda. Agora, conforme as lojas online receberem autorização para liberar o produto, ele já estará disponível instantaneamente para download. Pelo que estão falando, o Delphi 2007 já está disponível para Download nas lojas de alguns lugares do mundo, como na da Alemanha, pra quem comprou o item em pré-venda.

Pra quem ainda não fez o upgrade, e quer ver mais do Delphi 2007, não deixe de ir na Delphi Tour, daqui alguns dias, para ver as novidades em primeira mão.

Próxima Página »