Boletim Pascal #47 - 11 DE JULHO DE 2003
Índice
1. Algumas Palavras dos Editores
2. Guia de Performance Interbase (e II)
- Configuração do Interbase
· Backups e Restaurações Regulares
· Classe de Prioridade Interbase
· Desligue Async Writes
· Desligue a Coleta de Lixo
· Posições Hash de Bloqueio
· Tamano de Página do Banco
· Conjunto de Trabalho
· Cache do Banco
- Considerações de Desenvolvimento
· Sempre Trabalhe com a Menor Quantidade de Dados Possível
· Não Mantenha Transações Abertas Mais Tempo que o Necessário
· Sistemas Grandes, Muito Tráfego, Cache das Tabelas de Busca
· Programe Diretamente sobre a API do Interbase
· Use uma Conexão Remota
· Alimente e Teste seu Sistema Durante o Desenvolvimento
· Prepare e Parametrize suas Consultas
· Componentes VCL
· Pense Sobre o que Está Fazendo
· Algumas Coisas Serão Lentas
· Use o Cliente
· Veja o que sua Aplicação Realmente Faz ao Invés de Pensar que
ela Faz
· Use Componentes para Acesso Nativo
· Buscando Registros
- Outras Formas de Melhorar a Performance
· Atualize o Interbase
· Bancos de Dados Somente-Leitura
3. Usando Cabinet.dll para Criar seus Próprios Arquivos .CAB
4. Detetando Cliques do Botão Direito na Barra de Título
Como evitar que o menu de contexto da barra de título seja exibido
5. Temporização de Alta Precisão
Utilizando QueryPerformanceCounter para obter tomadas de tempo de
alta resolução
6. Assembler Inline em Delphi (IX) - Aritmética Inteira de 128 bits (3)
7. Fóruns / Listas
8. Delphi na Rede
- Sites em português
- Componentes, Bibliotecas e Utilidades
. Shareware/Comercial
. Freeware
· Atualizações do Delphi
- Artigos, Dicas e Truques
- Tutoriais
- Outros Links
- Notícias
________________________________________________________________________
1. Algumas Palavras dos Editores
Editorial da Versão em Português
--------------------------------
Mais uma edição do Boletim Pascal está pronta! Estamos definitivamente
em dia com o boletim e espero que permaneçamos assim por muito tempo!
Nessa edição gostaria de pedir a contribuição dos assinantes no envio
de artigos. Infelizmente até hoje não foi oferecido um artigo sequer
em português para publicação. Para aqueles que gostam de escrever e
têm algo interessante a mostrar, sejam meus convidados e enviem suas
propostas de artigo- vocês podem ser traduzidos e publicados para um
grupo de mais de 8000 assinantes do Boletim nos vários idiomas- nada
mal, não?
Agora chega de conversa. Divirtam-se com nosso boletim!
Demian Lessa
demian@knowhow-online.com.br
Editor da versão em português
Editorial da Versão em Inglês
-----------------------------
Como sempre, peço desculpas pela demora. Bem, acho que todos sabem como
é, não é mesmo?
No código do artigo "Enumerando Conexões de Rede" publicado na última
edição, a memória atribuída pela chamada a GlobalAlloc não foi liberada
por GlobalFree já que o ponteiro foi modificado entre as chamadas na
interação dos itens da enumeração. Um ponteiro auxiliar deve ser usado
de modo a preservar o valor retornado por GlobalAlloc. Agradeço a Wim
van Nifterick por identificar o problema e outro agradecimento especial
a Bill Boulton por me ajudar com os aspectos de compatibilidade com o
Delphi 3.
Agora é hora de agradecer aos autores que contribuíram com artigos nessa
edição: Peter Mc Leod, Vimil Saju, James Clements e Michael Darling.
Fico feliz em entregar os prêmios dessa edição para:
* Vimil Saju (Usando Cabinet.dll para Criar seus Próprios Arquivos .CAB)
· SDL Component Suite 7.0 - por Software Development Lohninger ($99)
O SDL Component Suite oferece uma ampla variedade de componentes para
aplicações científicas e de engenharia (matemática, estatística,
química, gráficos, visualização de dados, transformações de Fourier,
plotagem em 3D, mapas geográficos, ajuste de curvas, etc). Disponível
para Delphi 3-7 e BCB 4-6.
http://www.lohninger.com/sdlindex.html
* James Clements (Detetando Cliques do Botão Direito na Barra de Título)
· NTTools 7 For Delphi - por i-tivity (US$39.95)
Para de debater-se com a API de segurança do Windows NT! Tenha sua
cópia do NTTools 7 para Delphi 4/5/6/7 agora e economize incontáveis
horas com essa coleção de 40 componentes VCL escritos especificamente
para lidar com as funções de segurança do Windows NT. Código fonte
completo está incluído com o produto.
http://www.i-tivity.biz/nttools.htm
Para o próximo número, teremos os seguintes prêmios para dois de nossos
colaboradores:
* SMImport v1.75 - por Scalabium Software ($30 padrão, $50 com fontes)
Pacote nativo da VCL que permite a importação de dados para um dataset
sem o uso de bibliotecas externas. Suporta importação de dados a
partir do: MS Access (usando DAO/MS Jet), MS Excel (sem OLE/DDE),
Lotus 123, QuattroPro, texto, HTML, XML (incluindo o formato
TClientDataset), Paradox, dBase e qualquer descendente de TDataSet.
Novidades na versão 1.75: construtor visual de expressões; importação
do MS Word; importação direta do dBase, sem BDE; carga de campos BLOB
para XML; estilos estendidos para os diálogos dos assistentes; evento
OnCreateStructure que permite a criação de dataset com colunas
processadas antes da importação propriamente dita; e muito mais.
http://www.scalabium.com/
* EurekaLog v4.1.1 - por Fabio Dell'Aria (Std $24, Pro $49, Ent $99)
EurekaLog permite que sua aplicação (GUI, Console, Web, etc.) capture
todas as exceções ocorridas, gere um registro detalhado (com
informações de unidade, classe, método e número de linha) da execeção
e o envie por e-mail. Totalmente integrado no IDE, você só precisa
fazer um Rebuild de seu projeto para acrescentar a funcionalidade a
sua aplicação. Não interfere com a performance e aumenta o tamanho do
executável final em apenas 0,5%-4%. Compatível com Delphi 3-7 e todas
as plataformas Windows.
http://www.eurekalog.com/bannerclick.php?id=15
Cordialmente,
Ernesto De Spirito
pascal-newsletter-owner@yahoogroups.com
__________________
Colaboraram nesse número: Dave Murray e Bill Boulton
________________________________________________________________________
Junte-se ao maior e mais influente grupo de discussão Delphi em língua
portuguesa. http://groups.yahoo.com/group/delphi-br
________________________________________________________________________
2. Guia de Performance Interbase (e II)
Por Peter Mc Leod <PeterMcLeod@practical.com.au>
Tradução: Demian Lessa
Configuração do Interbase
=========================
Backups e Restaurações Regulares
--------------------------------
Seu banco de dados é uma fonte de vantagem competitiva para seus
clientes por causa da informação que contém. Realizar backups regulares
é essencial para garantir a integridade dos dados de seus clientes.
Restaurações são tão importantes já que otimizam o banco ao:
- reconstruir índices,
- eliminar versões obsoletas de registros (coleta de lixo),
- desfragmentar páginas do banco,
- reescrever as tabelas de forma contígua e
- recalcular estatísticas do banco.
Uma boa ferramenta para realizar backups e restaurações é o IBBackup que
está disponível a partir de www.ibphoenix.com
Nota: Aconselha-se que antes de restaurar seu banco de dados, você faça
uma cópia do original e então proceda com a restauração. Isso se
deve ao fato de que uma restauração realiza verificações de
integridade no banco- uma atividade intensa em processamento. Como
resultado, pode ser que um backup apresente problemas e não possa
ser restaurado. A idéia do backup é conferir segurança sem impacto
de performance.
Classe de Prioridade Interbase
------------------------------
A Classe de Prioridade Interbase deve ser definida como alta (versão
SuperServer no Windows) para assegurar que o Interbase pode solicitar
mais recursos do sistema. Isso pode ser feito através do IBConsole na
versão Windows. Ou editando o arquivo ibconfig e definindo a propriedade
SERVER_PRIORITY_CLASS como 2 (remova o marcador de comentário '#').
Desligue Async Writes
---------------------
No Windows NT, o Interbase está configurado por padrão para executar
escritas forçadas. Isso significa que as operações de escrita para o
Interbase vão direto ao banco e não passam pelo sistema de cache do
sistema operacional, normalmente lento. No Linux, o inverso ocorre.
Isso pode resultar em diferenças de performance de mais de 300% para
algumas operações.
O problema é que se você desliga Async Writes no Windows, e o sistema
operacional cai enquanto o Interbase escreve em disco, você corre o
risco de perder dados e corromper seu banco. Como Linux é naturalmente
mais estável esse não é um risco tão grande. Se você deseja desligar
Async Writes tenha certeza de manter seus backups em dia e confirme
que seu sistema de UPS no servidor está funcionando:
GFIX -WRITE ASYNC/SYNC MYDATABASE.GDB
Desligue a Coleta de Lixo
-------------------------
Por padrão, o Interbase realiza uma varredura do banco para coletar
o lixo de registros velhos, quando eles se acumulam. Infelizmente,
isso pode causar sérios efeitos na performance do processo cliente
que fez esse limite ser atingido. Para desabilitar a colta de lixo
automática, você deve emitir o seguinte comando a partir do Gfix:
gfix -h 0
Nota: Backups e restaurações regulares realizarão a coleta de lixo no
banco. Essa é outra razão pela qual os backups e restaurações
devem ser realizadas na máxima freqüência permitida.
Posições Hash de Bloqueio
-------------------------
O parâmetro Lock Hash Slots (Posições Hash de Bloqueio) é utilizado para
determinar o tamanho da tabela de hash usada para encontrar os bloqueios
em um objeto particular do banco (exceto nos sistemas VAX/VMS). O número
deve ser primo para facilitar o algoritmo a gerar uma boa distribuição.
Normalmente a primeira indicação de problema com esse parâmetro é a
redução de performance do servidor (com vários usuários e um cache de
páginas grande). Para determinar se o problema está na tabela, produza
uma saída impressa da tabela (enquanto o sistema estiver em uso) e
examine o comprimento médio do hash. Se for maior que 10 você está
com problemas. Para calcular um novo valor para o Lock Hash Slots
multiplique o comprimento médio pela quantidade atual de posições e
divida o resultado por nove. Ajuste para maior para garantir que o
número seja primo, mas que fique entre 101 e 2048 (os limites do
parâmetro). Para alterar o parâmetro edite o arquivo ibconfig e mude
o valor (remova o marcador de comentário '#'). Eu normalmente uso
LOCK_HASH_SLOTS com valor 503 para a maioria das instalações Interbase.
Se você realizar essa operação na versão Super Server, você deve
aumentar o tamanho da tabela de bloqueio também.
Tamano de Página do Banco
-------------------------
O tamano da página do banco determina a quantidade de dados que pode ser
recuperada com um acesso lógico ao banco. O padrão para o Interbase é
1Kb, com valores permitidos de 2Kb, 4Kb e 8Kb.
Para bancos pequenos, (menores que 4GB), defina o tamanho da página do
banco para 4096 bytes (4KB); para bancos grandes, esse valor deve ser
estabelecido em 8192 bytes (8K). Testes de performance em bancos de
dados indicam que uma mudança no tamanho de página de 1KB para 4KB pode
aumentar a performance em até 20%.
Ao utilizar páginas de 4KB para a maioria dos bancos, as operações de
E/S do banco combinam com seus tamanhos de página com as do sistema
operacional, resultando em maior eficiência e performance. Outras
vantagens de páginas maiores incluem:
· Menor fragmentação de registros e maior quantidade de registros
por página
· Menor quantidade de páginas retornadas por consulta (já que os
registros são armazenados de forma mais contígua)
· Índices em Árvore-B são mais rasos
· E/S é mais contígua
Os tamanhos de página indicados acima são diretrizes; recomenda-se que
testes sejam realzados para a determinação do tamanho de página ótimo
aplicável a cada sistema.
Para que a alteração do tamanho de página do banco entre em
funcionamento, será preciso realizar um backup e uma restauração do
banco.
Conjunto de Trabalho
--------------------
Os parâmetros de configuração do conjunto de trabalho só são aplicáveis
ao Interbase rodando sobre o Windows (arquitetura Super Server). Essas
configurações determinam quanta memória RAM fica dedicada ao processo
do Interbase. O conjunto de trabalho mínimo define a quantidade mínima
de RAM física que é garantida ao processo do Interbase. O conjunto de
trabalho máximo define a quantidade de memória a partir da qual o
Interbase começará a usar o cache do sistema. Eu recomendo que o
conjunto de trabalho mínimo seja determinado pelo valor de alocação das
páginas de cache do banco somado a 3 MB. Deixando o conjunto de trabalho
máximo em zero irá permitir que o próprio sistema determine o ponto no
qual o Interbase deve ser transferido para disco. O conjunto de trabalho
máximo deve ser sempre maior (ou zero) que o cache do banco ou o sistema
irá paginar todas as operações contiuamente para disco.
Cache do Banco
--------------
O cache do banco de dados é um cache da quantidade de páginas do banco
que serão mantidas no cache RAM do servidor. Alguma experimentação na
definição do cache do banco (usando o ibconfig) a valores entre 256 e
10.000 produzem performances crescentes até um determinado ponto. Após
esse ponto, performance reduzida é percebida.
É uma boa idéia definir o cache de seu banco através do GFIX com o
comando a seguir:
Gfix -buffers 10000 -user sysdba -password masterkey mydatabase.gdb
Se você tem um banco de dados pequeno, você deve utilizar estatísticas
para determinar quantas páginas seu banco possui. Você não deve definir
o cache para um valor maior que a quantidade de páginas do seu banco já
que uma página do disco ocupará apenas uma página do cache.
Considerações de Desenvolvimento
================================
Sempre Trabalhe com a Menor Quantidade de Dados Possível
--------------------------------------------------------
Tráfego de rede é um fator preponderante na percepção da performance
de sua aplicação. Se você possui 100.000 registros e você realiza algo
como "SELECT * FROM myTable" você estará descarregando todos os
registros. Utilizar filtros para retornar apenas um subconjunto dos
dados reduz a quantidade de registros. Se possível, evite o uso de
visões tabulares para conjuntos de dados grandes. Use o SQLMonitor (ou
equivalente) para avaliar seus comandos SQL e verificar o que DE FATO
ocorre enquanto sua aplicação roda.
Não Mantenha Transações Abertas Mais Tempo que o Necessário
-----------------------------------------------------------
Manter uma transação aberta pode travar registros em um banco. Manter
transações abertas por períodos longos de tempo também irá aumentar a
quantidade de memória que o Interbase requer para guardar o estado
dessas transações. Ao invés de iniciar uma transação logo que a tela
de entrada de dados é aberta e só confirmá-la quando o usuário
pressionar o botão Salvar, é melhor manter uma cópia dos dados, iniciar
uma transação e confirmá-la quando o usuário pressionar o botão Salvar.
Um número de técnicas facilitam essa abordagem como, por exemplo,
ClientDatasets. Essas técnicas apresentam inúmeras vantagens:
· Reduzem o tráfego da rede
· Reduzem o risco de bloqueios do banco
· Reduzem o tempo de vida das transações
· Reduzem a quantidade de memória necessária para o Interbase manter
essas transações
Sistemas Grandes, Muito Tráfego, Cache das Tabelas de Busca
-----------------------------------------------------------
Se você possui dados que não mudam (como estados ou países), então você
possui a oportunidade de disponibilizar esses dados em cache através de
um ClientDataset na máquina do cliente (ao invés de recuperar os
detalhes do servidor); você pode então simular uma ligação no lado do
cliente através de um campo calculado. Isso permite reduzir o número de
buscas no banco, reduzindo o tráfego na rede.
Programe Diretamente sobre a API do Interbase
---------------------------------------------
Se velocidade é uma absoluta necessidade, então um programa escrito em
C com SQL embutido terá preformance melhor que uma aplicação Interbase
cliente passando por camadas de middleware (como BDE). Esse tipo de
aplicação é programada diretamente sobre a API em GDS32.DLL, que produz
o ganho de performance.
Use uma Conexão Remota
----------------------
Quando desenvolver sua aplicação não use uma conexão local para
conectar-se ao banco (c:\path\mydatabase.gdb), já que esse tipo
de conexão usa arquivos mapeados em memória para comunicação com
o banco. Em algumas versões do Interbase o uso simultâneo de conexões
locais e remotas pode causar a corrupção física do banco de dados.
Use uma conexão remota sempre, já que essa modalidade de conexão
oferecerá uma melhor indicação da real performance do seu sistema
(servername:c:\path\mydatabase.gdb) e permitirá a identificação de
problemas mais cedo. Melhor ainda, desenvolva sua aplicação
conectando-se a um banco de dados numa máquina em outro ponto da rede.
Alimente e Teste seu Sistema Durante o Desenvolvimento
------------------------------------------------------
Desenvolvedores normalmente utilizam um sistema limitado para testes
na máquina de desenvolvimento. A desvantagem dessa abordagem é que a
recuperação de alguns poucos registros (ou mesmo algumas centenas) no
ambiente local será extremamente rápida. A realidade é que você deverá
desenvolver um sistema cliente-servidor que irá executar em rede e que
poderá ter alguns milhares ou mesmo milhões de transações. Para testar
seu sistema, rode-o na rede e certifique-se de que o banco está
alimentado devidamente (eu recomendaria alimentá-lo com aproximadamente
1/3 a mais de registros que o sistema de produção). Preferivelmente,
realize seus testes no hardware mínimo e no ambiente de rede que você
espera que seu sistema rode.
Prepare e Parametrize suas Consultas
------------------------------------
Sempre que possível, escreva uma consulta que possa ser parametrizada e
prepare a consulta antes de executá-la (ela só precisa ser preparada uma
vez já que fica preparada até que você desprepare-a explicitamente ou
altere o conteúdo da propriedade SQL). Consultas parametrizadas e
preparadas são mais rápidas que consultas parametrizadas e não
preparadas ou preparadas e não parametrizadas.
Componentes VCL
---------------
Um componente TQuery foi projetado para uso em aplicações cliente-
servidor e deve ser utilizado sempre ao invés de TTable, que é para
desenvolvimento de sistemas locais. Quanto utilizar TQuery, permita
ao servidor lidar com atualizações, exclusões e conflitos definindo
RequestLive como False. Não use Locate ou RecordCount já que esses
métodos recuperam todos os registros. Use uma cláusula where para
garantir que o servidor realiza a filtragem dos dados para você.
Pense Sobre o que Está Fazendo
------------------------------
Quando projetar seu sistema lembre-se que só porque o Interbase permite
que você faça algo não significa que é uma boa idéia. Todas as ações
têm conseqüências. Pense no seu projeto, desenvolvimento e suas
ramificações, na rede e nos clientes. Lembre-se que é possível que
alguém tenha que dar manutenção nesse sistema.
Algumas Coisas Serão Lentas
---------------------------
Quando desenvolver um sistema se você tiver que realizar a mesma tarefa
repeditamente, um milhão de vezes, digamos, será um processo lento não
importa quão rápido sejam seus clientes e seu servidor. Se for esse o
caso, verifique se sua filosofia de projeto permite que esse tipo de
processamento seja retirado do sistema. Em alguns casos isso não será
possível e você terá que empregar um mecanismo através do qual a tarefa
é executada fora do expediente normal de uso do cliente.
Use o Cliente
-------------
Num sistema cliente-servidor, você não tem que enviar tudo de volta ao
servidor para processamento. Você pode distribuir a carga realizando
algum processamento no lado do cliente. Se você mantém detalhes de seus
cálculos em cache, a vantagem é a redução no tráfego da rede, transações
mais curtas e não ocupar o servidor com cada processamento. Um exemplo
disso seria o cálculo do custo de cada item de um pedido de compra e o
total da compra no cliente.
Veja o que sua Aplicação Realmente Faz ao Invés de Pensar que ela Faz
---------------------------------------------------------------------
Ferramentas como o SQL Monitor permitem que você tenha uma visão ampla
da forma como sua aplicação solicita dados do Interbase. Essas
ferramentas são valiosas ao permitir que você veja coisas como:
· Conexão/Desconexão
· Transações
· Execução de Comandos
· Operações sobre Comandos
Váriso componentes da VCL se comportam de formas diferentes. Utilizando
o SQL Monitor permite que você investigue o que está acontecendo por
trás dos bastidores com esses componentes e também o que acontece quando
você faz alterações no projeto de seu sistema.
Outras ferramentas que devem estar no seu arsenal de desenvolvimento
incluem:
· Interbase Performance Monitor por Craig Stuntz
(requer Interbase 7.0 ou superior)
· Interbase Plan Analyser por Craig Stuntz
· Sleuth QA Suite por TurboPower Software
(permite ajustar a performance de aplicarivos Delphi/C++ Builder)
Use Componentes para Acesso Nativo
----------------------------------
O BDE é agora um sistema obsoleto e não será mais suportado pela
Borland. Componentes como IBX, FibPlus e IBObjects oferecem um ganho de
performance de aproximadamente 40% em comparação com o BDE. Eles também
oferecem acesso a mais recursos internos do Interbase. Para usar esses
compontnetes, no entanto, amarra seu desenvolvimento ao Interbase.
Se esse for um problema, então os componentes dbExpress oferecem a
possibilidade de conectar-se ao Interbase e outros bancos ainda que
mantendo uma boa performance (não tão boa quanto IBX etc, mas de certo
muito melhor que o BDE).
Buscando Registros
------------------
Soundex é um método de inexação, desenvolvido pelo departamento
de recenseamento americano, para agrupar nomes que soam de forma
semelhante. Como exemplo, realizar uma pesquisa de 300.000 registros
para o nome "smith" pode levar 2,95s para completar enquanto que uma
pesquisa usando soundex poderia retornar o resultado em 0,77s, exceto
que o resultado incluiria, além do nome "smith", os nomes de todos
que soam como "smith". Para uma boa introdução sobre a criação e
utilização da função Soundex veja o artigo "Implementing a Soundex
Function" por John Midwinter e encontrado em http://www.ibphoenix.com
Outras Formas de Melhorar a Performance
=======================================
Atualize o Interbase
--------------------
Cada nova versão do Interbase (ou Firebird) traz melhorias que aumentam
a performance do SGBD ou aumentam a flexibilidade do pragramador através
de extensões de linguagem. A performance e a funcionalidade aumentadas
permitem construir sistemas cliente-servidor melhores. Dada as recentes
melhorias desses produtos, qualquer um usando uma vesão do Interbase
anterior à versão 7.0 deve considerar uma atualização. Se essa não é
uma opção, considere autalizar para a versão mais recente do Firebird.
Bancos de Dados Somente-Leitura
-------------------------------
Um banco normalmente reserva algum espaço livre em suas páginas (em
torno de 25%) para permitir a inclusão de novos registro. Num banco de
dados onde o principal objetivo é a recuperação e visualização de dados,
mais páginas precisam ser recuperadas para permitir a visualização. Para
esses bancos somente-leitura, essas páginas podem ser preenchidas de
modo que os dados estejam mais contíguos e menos páginas tenham que ser
recuperadas. Utilize o seguinte comando GBAK:
GBAK -C -USE_ALL_SPACE backup.gbk mydatabase.gdb
________________________________________________________________________
Delphi BUGS?
Catch & Log every BUG showing Unit, Class, Method, Line #.
Now with support for command-line compiler and IntraWeb applications.
http://www.eurekalog.com/bannerclick.php?id=15
________________________________________________________________________
3. Usando Cabinet.dll para Criar seus Próprios Arquivos .CAB
Por Vimil Saju vimil@mec.ac.in
Tradução: Demian Lessa
Eu criei um componente que permite comprimir arquivos no formato .CAB.
O componente precisa da cabinet.dll que normalmente fica na pasta do
sistema. O componente é constituido de duas unidades. A primeira contém
todas as estruturas necessárias ao componente.
Eu atualizei a unidade Cabinet e agora arquivos podem ser acrescentados
utilizando caracteres coringa. A comrpessão agora ocorre em uma thread
separada de modo que seu programa não congele. Eu consertei o problema
com o OnStatusEvent e agora ele exibe o progresso corretamente. Também
acrescentei uma função Abort que pode ser chamada durante o processo de
compressão para cancelar a operação. Agora é possível especificar a
pasta na qual você deseja descompactar o arquivo utilizando a função
AddFile.
Eu acrescentei uma funcionalidade de descompressão, mas ainda não está
perfeita. O compressor e o decompressor rodam em threads separadas de
modo que a aplicação não congele. Também é possível listar os arquivos
de um arquivo .CAB sem extrai-los. Vários problemas foram corrigidos.
Agora são dois componentes: TCabCompressor and TCabDecompressor.
Para selecionar um arquivo individual para descomprimir, você deve antes
selecioná-lo através da chamada CabDecompressor1.Files[0].Select. Para
selecionar todos os arquivos, utilize CabDecompressor1.SelectAllFiles e
para selecionar utilizando caracteres coringa, utilize a chamada
CabDecompressor1.SelectFilesByWildCard.
O evento BeforeCopyFile na classe TCabDecompressor foi atualizado para
incluir um parâmetro chamado Overwrite que indica se o arquivo sendo
processado deve sobrescrever um arquivo existente.
As duas unidades juntamente com um programa de exemplo encontram-se no
arquivo zip anexado.
__________________
A versão mais atual deste artigo e seu código fonte encontram-se em
Delphi3000.com: http://www.delphi3000.com/articles/article_1820.asp
________________________________________________________________________
TsiLang Components Suite, by SiComponents. A full set of professional
components for building elegant, useful and user friendly multilingual
applications in a snap. http://www.sicomponents.com/tsilang1.html
________________________________________________________________________
4. Detetando Cliques do Botão Direito na Barra de Título
Como evitar que o menu de contexto da barra de título seja exibido
Por James Clements <essexboy @ bigfoot.com>
Tradução: Demian Lessa
Como detetar um clique do botão direito do mouse na barra de título
ou como bloquear a exibição do menu de contexto na barra de título?
Esse é um problema relativamente simples. Você apenas deve conhecer
a mensagem do Windows a capturar. Eis aqui como fazer:
Declaração:
procedure WMNCRButtonDown(var Msg : TWMNCRButtonDown);
message WM_NCRBUTTONDOWN;
Definição:
procedure TMainFrm.WMNCRButtonDown(var Msg : TWMNCRButtonDown);
begin
if (Msg.HitTest = htCaption) then
begin
// seu código aqui
// a linha a seguir impede a exibição do menu de contexto
Msg.HitTest := 0;
end
else
inherited;
end;
Informações adicionais:
* NC significa área não cliente (non-client)
* WMNCLButtonDown ou WMNCMButtonDown podem ser usados caso se deseje
processar os botões da esquerda ou do meio respectivamente
* Nenhuma mensagem WM_NCRBUTTONUP é gerada- apenas uma mensagem
WM_RBUTTONUP quando o botão do mouse for solto
Esse procedimento foi testado com o Delphi 5 nos Windows 2000, 95, 98 e
NT 4.0. Deve funcionar também com outras versões do Delphi mas essas não
foram testadas ainda.
________________________________________________________________________
Resource Builder 2.0, by SiComponents. A full-featured tool for visually
building RC scripts and resource files for your apps. Includes powerful
image editors and JPEG support. http://www.sicomponents.com/rbldr.html
________________________________________________________________________
5. Temporização de Alta Precisão
Utilizando QueryPerformanceCounter para obter tomadas de tempo de
alta resolução
Por Michael Darling <michael.darling @ which.net>
Tradução: Demian Lessa
As rotinas padrão Time e Now e até mesmo o TTimer são precisos apenas
na ordem de 55 milisegundos, já que todos utilizam o relógio do PC.
Para tomadas de tempo de maior precisão, o Windows oferece um contador
de alta performance que pode ser acessado através das chamadas de API
QueryPerformanceCounter e QueryPerformanceFrequency. A classe
apresentada implementa interfaces Delphi a essas duas chamadas.
A unidade em anexo impelmenta a classe THighResTimer para simplificar
o uso das chamadas de API QueryPerformanceCounter e
QueryPerformanceFrequency. Pode ser estendida de modo a oferecer
funcionalidades do tipo WriteToFile, LogToDB, etc.
Apenas acrescente a unidade na sua cláusula uses e crie uma instância de
THighResTimer quando preciso.
Nota: A unidade contém IFDEFs para lidar com a mudança para
TLargeInteger nas versões 3, 4 & 5+ do Delphi.
Uma vez criado, o objeto só precisa ser disparado antes de realizar a
ação e parado uma vez terminada a ação. O tempo resultante pode ser
obtido na forma de um TDateTime através da propriedade Time ou como um
inteiro através da propriedade Ticks.
Exemplo:
var
MyHighResTimer: THighResTimer;
i, j: Integer;
begin
MyHighResTimer := THighResTimer.Create;
try
MyHighResTimer.Start;
for i := 0 to 1000 do
begin
j := i;
end;
MyHighResTimer.Stop;
ShowMessage(Format('A operação levou'#13'Time: %8.8f'#13
+ 'Ticks:%d', [MyHighResTimer.Time, MyHighResTimer.Ticks]));
finally
MyHighResTimer.Free;
end;
end;
________________________________________________________________________
* LMD StoragePack - by LMD Innovative - Shareware (EUR 59)
Eight components for saving/restoring of configuration data (e.g. at
design time, via extended Property Selection dialog) to/from the
Windows Eegistry or Ini-, XML- and binary files, being easy to switch
between these formats. Full source code and demo projects included.
http://www.lmdinnovative.com/products/vcl/lmdstoragepack/
________________________________________________________________________
6. Assembler Inline em Delphi (IX) - Aritmética Inteira de 128 bits (3)
Por Ernesto De Spirito <eds2008 @ latiumsoftware.com>
Tradução: Demian Lessa
Nessa terceira e última parte da série sobre inteiros de 128-bit (que
chamamos de inteiros gigantes, inteiros enormes ou inteiros largos)
vamos finalmente lidar com a aritimética propriamente dita- as quatro
operações fundamenteais (adição, subtração, multiplicação e divisão).
Antes de iniciar, gostaria de avisar que as rotinas introduzidas nas
duas partes anteriores foram corrigidas e também otimizadas. Ainda
não pude testá-las tanto quanto gostarias. Se você encontrar erros ou
tiver algum comentário sobre os fontes, por favor me envie um e-mail.
Adição
======
Como somamos dois números, cada um formado de quatro inteiros de 32-bit?
Bem, é bem fácil. Simplesmente somamos como faríamos com dois números de
quatro dígitos decimais (como 3597 e 0015, por exemplo), exceto que cada
dígito aqui pode ter aproximadamente 4 bilhões (2^32) de valores
distintos ao invés de apenas dez. O algoritmo é algo como:
function AddWithCarry(x: Longint; y: Longint;
var Carry: Boolean): Longint; forward;
function HugeAdd(x: Hugeint; y: Hugeint): Hugeint;
// Result := x + y;
var
Carry: Boolean;
begin
Carry := False;
Result[0] := AddWithCarry(x[0], y[0], Carry);
Result[1] := AddWithCarry(x[1], y[1], Carry);
Result[2] := AddWithCarry(x[2], y[2], Carry);
Result[3] := AddWithCarry(x[3], y[3], Carry);
end;
AddWithCarry é uma função fictícia que retorna um inteiro com os 32 bits
de mais baixa ordem do resultado da adição dos dois argumentos, mais um
se Carry (o terceiro argumento) for True. A rotina também altera o valor
de Carry com True o False dependendo da adição ter gerado um excesso ou
não (ou se o carry é 1 ou 0, se você prefere ver dessa forma). Na
prática, essa função não precisa ser fictícia:
function AddWithCarry(x: Longint; y: Longint;
var Carry: Boolean): integer;
asm
// if Carry then CF := 1 else CF := 0;
test byte ptr [ecx], -1 // efeito colateral: CF := 0;
jz @@NoCarry
stc // CF := 1;
@@NoCarry:
// Result := x + y + CF; CF := GeneratedCarry;
adc eax, edx
// Carry := CF;
setc byte ptr [ecx]
end;
É mais eficiente codificar HugeAdd inteiramente em assembler:
function HugeAdd(x: Hugeint; y: Hugeint): Hugeint;
// Result := x + y;
// Parameters: EAX = @x; EDX = @y; ECX = @Result
asm
push esi
mov esi, [eax+_0_] // ESI := x[0];
add esi, [edx+_0_] // ESI := ESI + y[0];
mov [ecx+_0_], esi // Result[0] := ESI;
mov esi, [eax+_1_] // ESI := x[1];
adc esi, [edx+_1_] // ESI := ESI + y[1] + Carry;
mov [ecx+_1_], esi // Result[1] := ESI;
mov esi, [eax+_2_] // ESI := x[2];
adc esi, [edx+_2_] // ESI := ESI + y[2] + Carry;
mov [ecx+_2_], esi // Result[2] := ESI;
mov esi, [eax+_3_] // ESI := x[3];
adc esi, [edx+_3_] // ESI := ESI + y[3] + Carry;
mov [ecx+_3_], esi // Result[3] := ESI;
pop esi
end;
Subtração
=========
A subtração acontece de forma semelhante à adição mas, ao invés de gerar
um excesso, a operação gera um "empréstimo" (também representado pelo
flag Carry) se o minuendo (primeiro operando) é menor que o subtraendo
(segundo operando):
function SubtractWithBorrow(x: Longint; y: Longint;
var Borrow: Boolean): Longint; forward;
function HugeSub(x: Hugeint; y: Hugeint): Hugeint;
// Result := x - y;
var
Borrow: Boolean;
begin
Borrow := False;
Result[0] := SubtractWithBorrow(x[0], y[0], Borrow);
Result[1] := SubtractWithBorrow(x[1], y[1], Borrow);
Result[2] := SubtractWithBorrow(x[2], y[2], Borrow);
Result[3] := SubtractWithBorrow(x[3], y[3], Borrow);
end;
function SubtractWithBorrow(x: Longint; y: Longint;
var Borrow: Boolean): Longint;
asm
// if Borrow then CF := 1 else CF := 0;
test byte ptr [ecx], -1 // Side-effect: CF := 0;
jz @@NoBorrow
stc // CF := 1;
@@NoBorrow:
// Result := x - y - CF; CF := NeededBorrow;
sbb eax, edx
// Borrow := CF;
setc byte ptr [ecx]
end;
Você deve estar pronto para escrever uma versão de HugeSub inteiramente
em assembler já que é análoga à HugeAdd; tudo que você deverá fazer é
substituir ADD e ADC com SUB e SBB respectivamente.
Número Oposto
=============
Dado um número, essas implementações de HugeNeg retornam seu oposto
(complemento de dois):
function HugeNeg(x: Hugeint): Hugeint;
begin
// Result := (Not x) + 1;
Result := HugeAdd(HugeNot(x), IntToHuge(1));
end;
function HugeNeg(x: Hugeint): Hugeint;
begin
// Result := 0 - x;
Result := HugeSub(IntToHuge(0), x);
end;
A segunda é mais simples e rápida pois involve uma operação apenas e, já
que sabemos subtrair, podemos implementá-la em assembler:
function HugeNeg(x: Hugeint): Hugeint;
// Result := -x;
// Parameters: EAX = @x; EDX = @Result
asm
// Result := 0 - x;
push esi
xor esi, esi
mov ecx, [eax+_0_] // x[0]
sub esi, ecx // 0 - x[0]
mov ecx, 0
mov [edx+_0_], esi // Result[0]
mov esi, [eax+_1_] // x[1]
sbb ecx, esi // 0 - x[1] - Borrow
mov esi, 0
mov [edx+_1_], ecx // Result[1]
mov ecx, [eax+_2_] // x[2]
sbb esi, ecx // 0 - x[2] - Borrow
mov ecx, 0
mov [edx+_2_], esi // Result[2]
mov esi, [eax+_3_] // x[3]
sbb ecx, esi // 0 - x[3] - Borrow
mov [edx+_3_], ecx // Result[3]
pop esi
end;
Multiplicação
=============
Uma forma de multiplicar números é através de um laço de adições:
function HugeMul(x: Hugeint; y: Hugeint): Hugeint;
begin
SetZero(Result);
while not HugeIsZero(y) do begin
Result := HugeAdd(Result, x);
HugeSub(y, 1)
end;
end;
Em termos computacionais, esse algoritmo é bastante pobre. Por exemplo,
se o valor de "y" for 4 milhões, o laço se repetiria 4 milhões de vezes!
De qualquer forma, a idéia ainda é boa se pudéssemos de alguma forma
acelerar o processo. Vamos então brincar um pouco com álgebra de bits:
x * y = x * (y[3]*2^96 + y[2]*2^64 + y[1]*2^32 + y[0]*2^0)
= (x*y[3])*2^96 + (x*y[2])*2^64 + (x*y[1])*2^32 + (x*y[0])*2^0
Agora nós reduzimos o problema de multiplicar dois inteiros gigantes
ao de multiplicar um inteiro gigante por um inteiro de 32-bit. Quando
multiplicamos o primeiro operando pelos quatro inteiros que compõem o
segundo operando, então deslocamos os resultados parciais por 0, 32,
64 e 96 bits (multiplicação por 2^0, 2^32, 2^64 e 2^96) e finalmente
somamos esses valores para obter o resultado final.
function HugeMulInt(x: Hugeint; y: Longint): Hugeint; forward;
function HugeMul(x: Hugeint; y: Hugeint): Hugeint;
begin
Result := HugeShl(HugeMulInt(x, y[3]), 96)
+ HugeShl(HugeMulInt(x, y[2]), 64)
+ HugeShl(HugeMulInt(x, y[1]), 32)
+ HugeMulInt(x, y[0]);
end;
Essa é a exata forma que multiplicamos números decimais quando usamos
papel, exceto que aqui a base é 2^32 ao invés de dez. Vejamos como
multiplicar um inteiro gigante por um inteiro:
function MultiplyWithCarry(x: Longint; y: Longint;
var Carry: Longint): Longint; forward;
function HugeMulInt(x: Hugeint; y: Longint): Hugeint;
// Result := x * y;
var
Carry: Longint;
begin
Carry := 0;
Result[0] := MultiplyWithCarry(x[0], y, Carry);
Result[1] := MultiplyWithCarry(x[1], y, Carry);
Result[2] := MultiplyWithCarry(x[2], y, Carry);
Result[3] := MultiplyWithCarry(x[3], y, Carry);
end;
function MultiplyWithCarry(x: Longint; y: Longint;
var Carry: Longint): integer;
// Result := LoDWord(x * y + Carry);
// Carry := HiDWord(x * y + Carry);
asm
// EDX:EAX := EAX * EDX; // x * y
mul edx
// Inc(EDX:EAX, Carry);
add eax, [ecx]
adc edx, 0
// Carry := EDX; // High order 32 bits of the result
mov [ecx], edx;
end;
MultiplyWithCarry é muito semelhante a AddWithCarry mas realiza uma
multiplicação ao invés de uma adição, e gera um excesso de 32-bit ao
invés de um bit apenas (a multiplicação de dois valores de 32-bit gera
um valor de 64-bit enquanto sua soma gera um valor de 33-bit).
MultiplyWithCarry primeiramente realiza a multiplicação sem sinal de
"x" (EAX) por "y" (EDX), usando o opcode MUL. O resultado de 64-bit
é um inteiro sem sinal contido em EDX:EAX, ao qual a função soma o
valor do parâmetro Carry. A função retorna os 32 bits mais baixos do
resultado final (localizado em EAX) e os 32 bits mais altos (EDX)
constituem o excesso para a próxima multiplicação, que é armazenado
no parâmetro Carry (passado por referência).
Uma implementação em assembler de HugeMul e HugeMulInt encontra-se no
código em anexo. Por razões de simplificação, nos exemplos acima, as
funções consideram que os números não possuem sinais, mas o código
anexo considera os sinais. O código de HugeMul também não chama
HugeMulInt ou HugeShl e está bastante otimizado.
Ao invés de considerar um inteiro gigante como quatro inteiros de
32-bit, podemos considerá-lo como 128 inteiros de 1-bit multiplicados
por 128 potências de 2:
bit127 * 2^127 + bit126 * 2^126 + ... + bit1 * 2^1 + bit0 * 2^0
Como cada bit só pode ser 0 ou 1, o algoritmo acima pode ser muito
simplificado:
function HugeMul(x: Hugeint; y: Hugeint): Hugeint;
// Result := x * y;
var
i: Longint;
begin
SetZero(Result);
for i := 0 to 127 do
if BitTest(y, i) then
Result := HugeAdd(Result, HugeShl(x, i));
end;
A idéia é somar diferentes potências de 2 de "x", dependendo essas
potências nos bits de "y". Por exemplo, se "y" for 20, os bits 5 e
3 estariam ligados (20 em decimal é 10100 em binário), de modo que
apenas duas adições são realizadas e o resultado é HugeShl(x, 3)
mais HugeShl(x, 5).
Esse algoritmo pode ser codificado de forma bastante eficiente em
assembler mas o primeiro algoritmo será ainda mais rápido. A razão de
mostrá-lo é que facilitará o entendimento do algoritmo que usaremos
para divisões.
Divisão
=======
Vamos primeiro ver o caso da divisão de um Hugeint por um inteiro de
32-bit, que deve ser fácil de entender:
function DivideWithRemainder(x: Longint; y: Longint;
var Remainder: Longint): Longint; forward;
function HugeDivInt(x: Hugeint; y: Longint): Hugeint;
// Result := x div y;
var
Remainder: Longint;
begin
Remainder := 0;
Result[0] := DivideWithRemainder(x[3], y, Remainder);
Result[1] := DivideWithRemainder(x[2], y, Remainder);
Result[2] := DivideWithRemainder(x[1], y, Remainder);
Result[3] := DivideWithRemainder(x[0], y, Remainder);
asm
mov edx, Remainder
end;
end;
function DivideWithRemainder(x: Longint; y: Longint;
var Remainder: Longint): Longint;
// Result := Remainder:x div y;
// Remainder := Remainder:x mod y;
asm
push esi
mov esi, edx // y
mov edx, [ecx] // Remainder
// EAX := EDX:EAX div ESI;
// EDX := EDX:EAX mod ESI;
div esi
// Remainder := EDX;
mov [ecx], edx;
pop esi
end;
HugeDivInt deixa o resto da divisão em EDX, de modo que possa ser usado
em uma função que retorne o resto da divisão:
function HugeModInt(dividend: Hugeint; divisor: Longint): Longint;
// Result := dividend mod divisor;
// Parameters: EAX = @dividend; EDX = @divisor;
asm
sub esp, TYPE(Hugeint) // Abrir espaço na pilha para um Hugeint
mov ecx, esp // com o resultado da divisão
call HugeDivInt // Realizar a divisão
add esp, TYPE(Hugeint) // Restaurar o ponteiro da pilha
mov eax, edx // Result := Remainder;
// o resto foi deixado em EDX
end;
Para o caso de dois inteiros gigantes, temos que pensar no algoritmo que
usaríamos para dividir um número de quatro dígitos decimais no papel.
Mas esse procedimento é complexo e lento demais pois envolve além das
divisões, multiplicações, subtrações, antecipação de etapas, etc. Há
alternativa possível para o algoritmo? Sim:
function HugeDiv(dividend: Hugeint; divisor: Hugeint): Hugeint;
// Result := dividend div divisor;
begin
if HugeIsZero(divisor) then
raise EDivByZero.CreateRes(@sDivByZero);
Result := 0;
while HugeCmp(dividend, divisor) >= 0 do begin
dividend := HugeSub(dividend, divisor);
Result := HugeAdd(Result, IntToHuge(1));
end;
end;
Claro, o algoritmo acaba sendo extremamente lento (se dividirmos
12 milhões por 3, o laço executará 4 milhões de vezes) mas podemos
acelerá-lo se subtrarimos do dividendo o divisor multiplicado por
diferentes potências de 2, da maior para a menor, definindo o bit
correspondente do resultado toda vez que efetuarmos a subtração (o
bit na posição da potência de 2 que foi usado). É o inverso do que
foi feito no caso da multiplicação acima. O processo de divisão seria
reduzido ao máximo de 128 subtrações.
No exemplo a seguir, o dividendo é 20 (10100 em binário) e o divisor
é 3 (11 em binário):
10100 - 11 * 2^2 = 10100 - 1100 = 1000 Result := 100
1000 - 11 * 2^1 = 1000 - 110 = 10 Result := 110
Inicialmente, 11 * 2^2 é o maior valor que é menor ou igual ao dividendo
então subtraímos esse valor do dividendo e definimos o bit 2 do
resultado pois subtraímos o divisor multiplicado por 2^2. Até o momento,
o resto da divisão é 8 (1000 em binário) e 11 * 2^1 é o maior valor que
é menor ou igual ao resto. Então subtraímos esse valor do resto e
definimos o bit 1 do resultado pois subtraímos o divisor multiplicado
por 2^1. O resto agora é 2 (10 em binátio) e como o divisor é maior que
esse valor, a divisão é interrompida. O resto da operação seria 2 (10 em
binário) e, como os bits 2 e 1 do resultado estão marcados, o resultado
é 110 em binário, ou 6 em notação decimal.
function HugeDiv(dividend: Hugeint; divisor: Hugeint): Hugeint;
var
_r_: Hugeint; // remainder
_d_: Hugeint; // divisor
_q_: Hugeint; // quotient
BitPosR, BitPosD, count: integer;
begin
_r_ := dividend;
_d_ := divisor;
HugeSetZero(_q_);
BitPosD := HugeBitScanReverse(_d_);
if BitPosD = -1 then RaiseDivByZero;
BitPosR := HugeBitScanReverse(_r_);
count := BitPosD - BitPosR;
if count > 0 then
_d_ := HugeShl(_d_, count);
repeat
if HugeCmp(_d_, _r_) <= 0 then begin
_r_ := HugeSub(_r_, _d_);
HugeBitSet(_q_, count);
end;
_d_ := HugeShr(_d_, 1);
dec(count);
until count < 0;
Result := _q_;
asm
lea edx, _r_
end;
end;
HugeBitScanReverse é a função que retorna a posição do primeiro bit não
zero, realizando a busca a partir do bit 127 até o bit 0. Se todos os
bits são zero, o resultado é -1. Usamos HugeBitScanReverse para
determinar a primeira potência de dois que devemos multiplicar o divisor
para iniciar a divisão.
A implementação em assembler de HugeDiv no código anexo suporta inteiros
com sinais. É apenas uma primeira aproximação que pode ainda ser muito
melhorada.
A função deixa em EDX o endereço do resto de modo que ele possa ser
usado por uma função que retorna o módulo da divisão:
function HugeMod(dividend: Hugeint; divisor: Hugeint): Hugeint;
// Result := dividend Mod divisor;
// Parameters: EAX = @dividend; EDX = @divisor; ECX = @Result
asm
push ecx // @Result
call HugeDiv // EDX := @remainder;
pop eax // EAX := @Result;
call HugeMov // EAX^ := EDX^;
end;
________________________________________________________________________
Qual foi a última vez que você votou para o Boletim Pascal? Suporte essa
iniciativa votando para o Boletim Pascal no The Programming Top 100!
http://top100borland.com/in.php?who=20
________________________________________________________________________
7. Fóruns / Listas
Para juntar-se a qualquer um de nossos fóruns de discussão, a melhor
forma é assinar através da web, já que dessa forma você poderá acessar
todas as funcionalidades disponíveis no site (como alterar suas opções
de assinatura, visualizar mensagens passadas, baixar arquivos, etc.).
Um ID Yahoo! é necessário para isso e você pode adquirir o seu de forma
gratuita registrando-se como um usuário Yahoo! Mas se você não deseja
registrar-se ou se não tem acesso completo à Internet, você pode fazer
sua assinatura por e-mail (basta ter acesso a uma conta de e-mail).
* Delphi: Todos os usuários de língua portuguesa são bem-vindos ao grupo
de discussão; se você é um novato ou um guru, essa lista é para você.
Essa é a maior e mais bem conceituada lista de discussão Delphi em
língua portuguesa!
http://br.groups.yahoo.com/group/delphi-br/
Assinatura:
http://br.groups.yahoo.com/group/delphi-br/
delphi-br-subscribe@yahoogroups.com
* Kylix (inglês): Programação Kylix.
http://groups.yahoo.com/group/KylixGroup/
Assinatura:
http://groups.yahoo.com/group/KylixGroup/join
KylixGroup-subscribe@yahoogroups.com
* Componentes (inglês): Esse é um fórum para pesquisa/recomendação de
componentes de software (componetes VCL e CLX, objetos ActiveX, DLLs,
SOs, etc.), assim como utilitários, tutoriais, informações, etc.
http://tech.groups.yahoo.com/group/components/
Assinatura:
http://tech.groups.yahoo.com/group/components/join
components-subscribe@yahoogroups.com
* Desenvolvedores de Software (inglês): Esse é um fórum para discussões
sobre o desenvolvimento de software e para a troca de experiências de
trabalho em ambientes profissionais e comerciais. Esse não é um fórum
sobre programação; os assuntos abordados são mais gerais e
independentes de linguagem de programação.
http://tech.groups.yahoo.com/group/software-developers/
Assinatura:
http://tech.groups.yahoo.com/group/software-developers/join
software-developers-subscribe@yahoogroups.com
________________________________________________________________________
Merlin's Delphi Forge
Delphi and Kylix news, FAQ, downloads, links, forums and more.
Accepting uploads and submissions.
http://www.delphifaq.net/
________________________________________________________________________
8. Delphi na Rede
Por Dave Murray <irongut @ vodafone.net>
Sites em português
==================
* Comunidade Delphi de Rio Preto
Portal com componentes, novidades, artigos, links e mais.
http://www.delphirp.com.br/
* Planet Delphi
Site brasileiro especializado em componentes para Delphi. Download
grátis.
http://www.fprass.hpg.ig.com.br/
* Delphi Company
Site do Fernando Gonçalves dedicado ao mundo Delphi
http://www.delphicompany.hpg.ig.com.br/
* IntereSite
Tudo sobre Delphi
http://www.ulbrajp.com.br/~tecnobyte/
* Advanced Developers
Delphi, productos, novidades, consultoria...
http://www.adev.com.br
* Fórum Delphi-BR
http://br.groups.yahoo.com/group/delphi-br/
* Fórum Delphi !!
http://www.qualyinf.com.br/forum/delphi/delphi.html
Componentes, Bibliotecas e Utilitários
======================================
Shareware/Comercial
-------------------
* SMImport v1.75 - by Scalabium Software ($30 standard, $50 with source)
Native VCL suite for importing data into a dataset without external
libraries. Supports import from: Access (using DAO/MS Jet), Excel
(without OLE/DDE), Lotus 123, QuattroPro, text, HTML, XML including
TClientDataset format, Paradox, dBase and any TDataSet descendant.
New in v1.75: visual Expression Builder; import from Word; direct
import for dBase, no BDE required; load BLOB fields for XML; extended
style for wizard dialog; OnCreateStructure event that allows creation
of a dataset with parsed columns before real import; and more.
http://www.scalabium.com/
* SMExport v4.30 - by Scalabium Software ($20 standard, $35 with source)
Native VCL suite for exporting data from different sources (dataset,
grids, decision cube, memory, DevExp trees etc). Supports export into:
MS Excel, MS Access, MS Word, PDF, Text/CSV, HTML, XML, dBase, RTF,
SQL, Lotus 1-2-3, QuattroPro and more.
http://www.scalabium.com/
* Storage Library v3.24 - by DeepSoftware.Ru ($39)
Storage Library - elegant way for application settings management.
Supports working with ini files, registry, xml files, TStream objects.
Provides encryption, unicode support, working with published
properties without programming, saving form position and much more...
http://www.deepsoftware.ru/rsllib/index.html
* Delphi Knowledge Base v1.5 ($29)
A unique collection of Delphi tips and articles where Delphi
programmers can find ideas, solutions and share their experience.
The new version contains these new features: fast article search,
integrated flat type interface, added bookmark system, new filtering,
grouping and sorting features in the article grid, multilingual
interface, generally improved article update tool and much more...
http://www.baltsoft.com/product_dkb.htm
Freeware
--------
* IBUtils v0.9.2.4 - by Ales Kahanek
IBUtils is designed to simplify database design for Interbase and
Firebird databases by showing the links between the tables in your
database visually, like some CASE tools do. It does not allow database
editing, it is a read-only tool. The model is saved to INI-like files
or can be exported as an image to a JPG or BMP file. Uses IBObjects.
http://www.alikiwi.com/ibutils/ibutils.htm
* Key Objects Library v1.72 - by Delphree (with source)
Based on experience aquired on eXtreme Class Library project. Main
purpose is to create smaller programs using Delphi environment.
http://delphree.clexpert.com/pages/app_KOL.htm
* GPU 0.788b - by Delphree (with source)
GPU is a Gnutella client for sharing files and CPU-resources. The
objective is to develop a robust framework for distributed computing
on a peer-to-peer grid.
http://delphree.clexpert.com/pages/app_GPU.htm
* TurboPower SysTools for Kylix v1.01 - by TurboPower (source) (KYLIX)
A library of utility routines and algorithms for Borland Kylix. Among
other things, it supports 1-Dimensional bar codes, date time and
string routines, sorting, a regular expression engine and a run-time
math expression analyzer.
https://sourceforge.net/projects/tpsystoolskylix/
Atualizações do Delphi
----------------------
* Patch: glibc update for Kylix 3 C++ package loading - by John Kaster
Linux distributions using glibc 2.2.x will probably encounter issues
loading the database and SOAP packages for the Kylix 3 IDE for C++.
This patch resolves that issue.
http://community.borland.com/article/0,1410,29968,00.html
Artigos, Dicas e Truques
========================
* Sip from the Firehose: It all starts with Define! - by David I
In the recent BDN 2003 Survey, David I asked members a question about
what drives their development processes and decisions. In this article
he reports the results.
http://community.borland.com/article/0,1410,30043,00.html
* Interview with Jeff Duntemann - by Clay Shannon
Jeff Duntemann tells about his experiences working for Borland,
writing and editing for Coriolis and Visual Developer, a rigged
programming contest he participated in vs. Bill Gates, what he does
everywhere, and what he's been up to lately.
http://community.borland.com/article/0,1410,30012,00.html
* Interview with Steve Teixeira - by Clay Shannon
Interview with Steve Teixeira, co-author of the classic "Delphi X
Developer's Guide". Among other things, Steve tells about his days at
Borland, how the above tome came about, and "geek" practical jokes.
http://community.borland.com/article/0,1410,29925,00.html
* Using Semaphores in Delphi Part 2: The Connection Pool - Cary Jensen
Semaphores are used to coordinate multiple threads and processes. The
ability of semaphore to provide multiple threads with simultaneous
access to a shared resource is highlighted by the TFixedConnectionPool
class described in this article.
http://community.borland.com/delphi/0,1419,1,00.html
* Binary Serialization with the .NET Framework and Delphi for .NET
- by Marcel van Brakel
This article explains binary serialization, complete with Delphi for
.NET and C# source code.
http://community.borland.com/article/0,1410,29787,00.html
* Simple Programming Tip #1 - by Charlie Calvert
This article describes the first of several simple programming tips.
The discussion and code in this article is generic and applies equally
to C++, C#, Delphi or Java. The tip for this article is: Avoid writing
code that does anything substantial inside a visual container, instead
write code inside separate classes designed for a single purpose.
http://community.borland.com/article/0,1410,30011,00.html
* MessageBox on top of "stay on top" forms - by Zarko Gajic
This tip causes "stay on top" forms to allow a MessageBox to appear on
top. After the message box is closed, the topmost forms are restored
so that they continue to float to the top.
http://delphi.about.com/cs/adptips2003/index.htm
* Mouse moving the contents of a ScrollBox - by Zarko Gajic
How to move a TImage object in a ScrollBox with the mouse, like a drag
and drop operation - without the scroll bars.
http://delphi.about.com/library/weekly/aa050603a.htm
* Sorting records in Delphi DBGrid - by Zarko Gajic
How to sort records in Delphi DbGrid by clicking on the column title.
How to change the appearance of the selected column title to reflect
the sort order. How to change the cursor when moving over the DBGrid
column titles.
http://delphi.about.com/library/weekly/aa042203a.htm
* Choosing a ZIP Library for Delphi - by Mark Steinberg
Describes the pros and cons of several ZIP libraries - VCLZip, ZipTv,
ZipForge, Abbrevia and Delphi Zip.
http://www.delphifaq.net/modules.php?name=FAQ&op=view&id=219
* How to encrypt/decrypt files using NTFS API - by m3rlin
http://www.delphifaq.net/modules.php?name=FAQ&op=view&id=220
* Coding DB2 SQL for Performance: The Basics - by Craig S. Mullins
Poorly coded SQL and application code can cause performance problems.
This article is intended to give the basics of good SQL programming to
application developers, particularly for those who are using Borland
Kylix and Delphi RAD tools.
http://www7b.software.ibm.com/dmdd/library/techarticle/0210mullins/
0210mullins.html
* Create a Reusable Component to Connect Delphi 7 to DB2 with dbExpress
- by Bob Swart
How to use IBM DB2 as the backend database for applications written
with Delphi 7 and dbExpress. Specifically, how to connect the seven
dbExpress components to DB2 and use them to build visual forms on top
of database tables.
http://www7b.software.ibm.com/dmdd/library/techarticle/0210swart/
0210swart.html
* Display and Modify DB2 Master-Detail Data in Delphi 7 Apps - Bob Swart
A typical real world application will involve combining and displaying
data from multiple tables in a usable format for reviewing and
editing. This article shows how to add data and create relationships,
manipulate the data from a Delphi application and get ready to move
the entire package to Linux with Kylix.
http://www7b.software.ibm.com/dmdd/library/techarticle/0211swart/
0211swart.html
* The Big Switch: Moving from Windows to Linux with Kylix 3 - Bob Swart
One of the great things about using tools and databases such as Delphi
IBM DB2 is that moving between platforms is only a matter of a few
changes and a recompile. This article shows how to take the big jump
and move a Delphi 7 application running on Windows to a Linux (Intel)
application using Kylix 3.
http://www7b.software.ibm.com/dmdd/library/techarticle/0211swart/
0211swart2.html
* Build DB2 and Delphi 7 Internet Applications with WebSnap - Bob Swart
With Delphi 7 WebSnap technology, you can quickly take data from an
IBM DB2 database and move it to a Web-based application in a snap.
http://www7b.software.ibm.com/dmdd/library/techarticle/0211swart/
0211swart3.html
* Create Distributed DB2 and Delphi Web Apps with DataSnap - Bob Swart
Enter the world of distributed applications, where you split your
application into two different tiers: a thin client and a database
server tier. This article focuses on the server side, as well as the
communication between the client and the middleware server.
http://www7b.software.ibm.com/dmdd/library/techarticle/0212swart/
0212swart.html
* DB2 and Delphi 7: SOAP and Database Web Services - by Bob Swart
Creating a distributed application based on SOAP as the communication
protocol, where the server (DB2) will be turned into a cross-platform
Web Service. As a consequence, you can compile both the server and the
client with Delphi 7 and Kylix 3 and deploy them on either Windows or
Linux; this is a true cross-platform solution.
http://www7b.software.ibm.com/dmdd/library/techarticle/0212swart1/
0212swart1.html
* Data Entry Input Validation With Delphi and Kylix - by Bob Swart
How to build data entry forms on top of IBM DB2 Universal Database as
database tables and records, and how to perform data entry validation
using Delphi Studio and Kylix. Uses dbExpress and DB2 PE v8.1.
http://www7b.software.ibm.com/dmdd/library/techarticle/0303swart/
0303swart.html
* Drill Into DB2 Tables for Decision Support Using Delphi - by Bob Swart
How to build decision-support functionality by drilling into IBM DB2
tables using the Decision Cube component of Delphi. Uses dbExpress to
connect to the DB2 UDB Personal Edition v7.x database.
http://www7b.software.ibm.com/dmdd/library/techarticle/0304swart/
0304swart.html
* DB2 + SOAP: Database Web Services Follow-up with DataSnap - Bob Swart
This extended DataSnap SOAP example covers deployment issues and some
login and authentication details that help increase security for the
DB2 backend database.
http://www7b.software.ibm.com/dmdd/library/techarticle/0305swart/
0305swart.html
* Building a Web Service in Delphi with a DB2 Backend - by Marco Cantù
To help you get started with Web services this article shows you a
practical SOAP Web service example built with Delphi and a test client
that serves up data from an IBM DB2 Universal Database backend.
http://www7b.software.ibm.com/dmdd/library/techarticle/0212cantu/
0212cantu.html
* Check Efficiency of Oracle Caching with this Report - Donald Burleson
One of the most important areas of Oracle tuning is the management of
the RAM data buffers. Not only is it useful to know the contents of
Oracle data buffers, it's also interesting to watch them move about in
the list. Try this report to check up on your caching effectiveness.
http://builder.com.com/article.jhtml?id=u00320030422brl01.htm
* Ensure data integrity with proper database design - by Susan Harkins
Data is the backbone of application development, so data accuracy is
imperative. Take advantage of referential integrity to protect your
database from invalid data.
http://builder.com.com/article.jhtml?id=u00320030507ssh01.htm
* How to List all files in a directory?
http://www.swissdelphicenter.ch/en/showcode.php?id=1725
* How to export a TStringGrid to a MS Word table?
http://www.swissdelphicenter.ch/en/showcode.php?id=1726
* How to export an Excel Table to a TStringgrid?
http://www.swissdelphicenter.ch/en/showcode.php?id=1728
* How to trap mouse events outside of my application?
http://www.swissdelphicenter.ch/en/showcode.php?id=1729
* How to fill in MS Word Form Fields?
http://www.swissdelphicenter.ch/en/showcode.php?id=1731
* How to read a BlobStream with TADOQuery from an AccessDB?
http://www.swissdelphicenter.ch/en/showcode.php?id=1744
* User list on Windows NT - by Serhiy Perevoznyk
http://www.delphi3000.com/articles/article_3637.asp
* Do you want TWAIN? - by Maarten de Haan
Delphi Scanner Support Framework as a component.
http://www.delphi3000.com/articles/article_3638.asp
* How to convert a Grid's Surfer to a Grid's Arcview - by Camila Pinilla
This code is useful to load a raster Grd file from surfer to ArcView
when you want to interpolate data by using Sufer and then loading the
grid by using Raster Arcview.
http://www.delphi3000.com/articles/article_3639.asp
* Component to calculate a Regression Multiple of set data - C Pinilla
This code was used in a mathematical model to calculate a Regression
Multiple in many points of a computational mesh.
http://www.delphi3000.com/articles/article_3640.asp
* An easy procedure to draw a Vector Field - by Camila Pinilla
Useful if you have to draw a velocity field in a two dimensional mesh.
http://www.delphi3000.com/articles/article_3641.asp
* Choosing a ZIP Library for Delphi - by Mark Steinberg
http://www.delphi3000.com/articles/article_3644.asp
* How to create a dynamic PopUpMenu - by Christoph Otto
Have you ever wanted to Create a PopupMenu at a Position you wanted?
E.g. from a button going up. Here's how using TrackPopupMenuEx.
http://www.delphi3000.com/articles/article_3647.asp
* Secure compression component - by Ronald Douson
A discussion on chosing a component for compressing files with strong
encryption.
http://www.delphi3000.com/articles/article_3648.asp
* Fast Sine and Cosine Calculations - by John Pears
How to really speed up sine and cosine calculations (in degrees).
http://www.delphi3000.com/articles/article_3649.asp
* Understanding pointers: for the amateurs - by Martin Strand
Written for all the beginners out there.
http://www.delphi3000.com/articles/article_3650.asp
* WebSnap III: use of Adapter instead of Html Transparent Tags
- by Eber Irigoyen
The use of adapters to manage content in your web pages. Perhaps
easier to use than html transparent tags?
http://www.delphi3000.com/articles/article_3651.asp
* TreeView control DragDrop Operation helper functions - by Wei Bao
Make Treeview dragdrop operation programming simpler: automatic expand
and collapse, move with children nodes, disable drop to child and
self, auto scroll while the cursor near top or bottom of the control.
http://www.delphi3000.com/articles/article_3652.asp
* INI to XML- by Jim McKeeth
INI was the old way to store settings (outside the registry), now
everything is XML. This routine will convert an INI file into an XML
node of a document.
http://www.delphi3000.com/articles/article_3654.asp
* Moving items in a TListBox using the mouse - by Christophe Geers
A quick example on how to move items in a TListBox using the mouse.
http://www.delphi3000.com/articles/article_3655.asp
* A lot of DLLs with forms, Load dynamically into a PageControl of a
Main-Form - by Manfred Suesens
How to put DLL-Forms as Parent to a MainForm-PageControl-TabSheet.
http://www.delphi3000.com/articles/article_3656.asp
* Internet Explorer Automation - by Teun Spaans
How to integrate IE into your application.
http://www.delphi3000.com/articles/article_3657.asp
* Next or Prev working Day - by Andreas Schmidt
How to calculate the next/prev working day starting from a given date.
http://www.delphi3000.com/articles/article_3658.asp
* Creating a Delphi-Expert (Part I) - by Daniel Wischnewski
The simplest way of creating a Delphi-Expert.
http://www.delphi3000.com/articles/article_3661.asp
* Create "Wait.." panel in design time - Miquel Taule
Quick way to create a panel message.
http://www.delphi3000.com/articles/article_3666.asp
* Reading + Writing System-Wide Environment Variables - Richard Winston
How do you set an environment variable that will apply outside the
process that set the variable or those spawned by it?
http://www.delphi3000.com/articles/article_3669.asp
* Automatically start a service after using /Install or /Uninstall
switch - by Brian Gochnauer
Have you ever wished that the service would also start after
installing the service not just install itself.
http://www.delphi3000.com/articles/article_3671.asp
* Captions in the DBNavigator - by Victor Dalvi
http://www.delphi3000.com/articles/article_3672.asp
* Users Take Open Source Databases for a Spin - by John Cox
A growing number of companies are finding that open source databases
are reaching a state where they can become the latest addition to
their inventory of open source tools.
http://www.networkworld.com/news/2003/0428specialfocus.html
* The Art of Enbugging - by Andy Hunt and Dave Thomas
An article from IEEE Software about reducing the errors in your code
through decoupling techniques.
http://www.ccs.neu.edu/research/demeter/related-work/
pragmatic-programmer/jan_03_enbug.pdf
Artigos
-------
* Cross-platform Development with Borland RAD Tools - by Borland
Traditionally, developers create and maintain separate programs for
Windows and Linux platforms. Borland makes it possible to target both
platforms with a single application. This white paper gives you an
overview of what you can do including multi-tier apps, Web apps, and
integration with Web services.
http://dn.codegear.com/article/29139
* Database Application Development Using Borland Kylix and DB2 UDB v7.2
- by Paul Yip (IBM) and Ramesh Theivendran (Borland)
Kylix is a RAD tool that provides a thin, cross-platform, database-
independent, disconnected data-access model that can be used to
quickly develop database applications for Linux and Windows platforms.
By combining Kylix and DB2, you can write applications once and deploy
them to run natively on both Linux and Windows without code changes.
http://www-3.ibm.com/software/data/pubs/papers/kylix/kylix.pdf
Tutoriais
=========
* A Beginner's Guide to Delphi: Chapter 13 - by Zarko Gajic
It's time to learn how to let Delphi help you code faster: start using
code templates, code insight, code completion, shortcut keys, etc.
http://delphi.about.com/od/beginners/a/delphicourse.htm
* Creating Simple User Object Property Dialogs - by Brian Frost
A neat way of creating simple user object property dialogs that avoids
spending ages wiring up controls to object properties.
http://www.thedelphimagazine.com/samples/1614/1614.htm
* Fun With OpenGL - by Dave Jewell
Insights into the OpenGL graphics library and what it can do for your
applications, demonstrating that it's not as difficult as you might
think and it isn't all chocolate teapots, either!
http://www.thedelphimagazine.com/samples/1445/1445.htm
* Relational Databases: Defining Relationships Between Database Tables
- by Susan Harkins
Database normalization is the cornerstone of database theory. Once a
database is normalized, relationships between the data in multiple
tables must be established.
http://builder.com.com/article.jhtml?id=u00320030430ssh01.htm
* How to Program the Lego Mindstorms Robotic Kit - by Geert Barandat
Tutorial of the Lego® Mindstorms® robotics kit and how to program it
with Delphi. Topics include an introduction to ActiveX, PC-RCX
interfacing and building autonomous robots.
http://www.barandat.be/mindstorms/
Outros Links
============
* The Quick Reference Site
The ultimate resource for free IT Quick Reference Cards and e-books.
http://www.digilife.be/quickreferences/indexe.html
Notícias
========
* Borland Janeva
Janeva provides seamless, high-performance interoperability between
the Microsoft .NET Framework applications and the J2EE and CORBA
infrastructures, allowing .NET client- or server-based applications
to access J2EE and CORBA server-side components through the highly
scalable and secure Internet Inter-ORB Protocol (IIOP). Janeva is
tightly integrated with popular development environments for the
Microsoft .NET Framework, including Microsoft Visual Studio for .NET
and Borland C#Builder. Janeva helps accelerate the application
lifecycle at a low total cost of ownership: implementation requires
no expertise with J2EE or CORBA technologies, no change to back-end
systems, and no additional hardware or software investments.
http://www.borland.com/janeva/
Janeva in the news:
- http://www.oreillynet.com/pub/wlg/3167
- http://news.com.com/2100-1012_3-999698.html
- http://zdnet.com.com/2100-1104_2-999698.html
- http://www.businessweek.com/technology/cnet/stories/999698.htm
- http://www.nytimes.com/cnet/CNET_2100-1012_3-999698.html
* Borland C#Builder
The first independent development environment for the .NET Framework.
C#Builder offers a design-driven approach to development that
increases team productivity. C#Builder provides interoperability
between .NET, J2EE and CORBA, so you can integrate different software
systems. It also provides native support for major databases.
http://www.borland.com/csharpbuilder/
* C# Builder box screen shots - by Anders Ohlsson
A first look at the screen shots that are on the product boxes for
Borland's new C# Builder (formerly Project Sidewinder).
http://community.borland.com/article/0,1410,30021,00.html
* Borland Makes .Net 'Life Cycle' Play - by Martin LaMonica
Borland Software will take on software giant Microsoft with a suite
of .Net development tools targeted at companies that program with both
.Net and Java.
http://news.com.com/2100-1012-997684.htm
* Borland: Building Bridges Between Java and .Net - by ZDNet
ZDNet Video interviews Dale Fuller, President and CEO, Borland.
http://zdnet.com.com/1601-2-997475.html
________________________________________________________________________
VOCÊ PODE NOS AJUDAR
Nós precisamos de sua ajuda para manter esse boletim ativo e cada vez
maior. Você pode ajudar indicando o boletim a seus amigos e colegas:
http://www.latiumsoftware.com/br/pascal/index.php
Você também pode votar para nós em um ou todos esses rankings para dar
maior visibilidade a nosso site e assim aumentar o número de assinantes
do boletim:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
São alguns segundos para você que REALMENTE significam muito para nós.
Não esqueça que também precisamos de artigos para os boletins e que
existe um prêmio para um dos autores em cada número (em inglês).
Todos os artigos serão considerados mas nós estamos particularmente
interessados em artigos sobre Kylix já que existe pouco material
disponível online.
* Envie seu artigo em inglês para
pascal-newsletter-owner@yahoogroups.com
* Envie seu artigo em português para
boletim-pascal-owner@yahoogrupos.com.br
________________________________________________________________________
Se você não recebeu o código fonte completo dos exemplos neste número,
você pode obtê-los em http://www.latiumsoftware.com/br/pascal/p0047.zip
________________________________________________________________________
Esse boletim é fornecido "COMO ESTÁ" sem garantias de qualquer tipo. Seu
uso implica na aceitação dos termos de licença e isenção de garantia que
podem ser lidos em http://www.latiumsoftware.com/br/pascal/index.php
Os artigos são propriedade e copyright de seus respectivos autores e
foram reproduzidos aqui com sua permissão. Você pode redistribuir esse
boletim desde que na sua íntegra (incluindo notas de propriedade e
copyright), sem alterações e de forma gratuita.
________________________________________________________________________
Página principal.....: http://www.latiumsoftware.com/br/pascal/index.php
Página do grupo:.....: http://br.groups.yahoo.com/group/boletim-pascal/
Assinar..............: boletim-pascal-subscribe@yahoogrupos.com.br
Cancelar assinatura..: boletim-pascal-unsubscribe@yahoogrupos.com.br
Assinar/cancelar.....: http://groups.yahoo.com/group/boletim-pascal/join
Problemas com sua assinatura? boletim-pascal-owner@yahoogrupos.com.br
________________________________________________________________________
Boletim Pascal http://www.latiumsoftware.com/br/pascal/index.php
Copyright (c) 2003 por Ernesto De Spirito. Todos os direitos reservados.
________________________________________________________________________
|