Boletim Pascal #47
Os exemplos do código fonte desta edição estão disponíveis para download.
![]() |
![]() |
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.ceberus.com/lmd/products/index.php3#P9 ________________________________________________________________________ 6. Assembler Inline em Delphi (IX) - Aritmética Inteira de 128 bits (3) Por Ernesto De Spirito <eds2004 @ 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://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium ________________________________________________________________________ 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://groups.yahoo.com/group/components/ Assinatura: http://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://groups.yahoo.com/group/software-developers/ Assinatura: http://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.nwfusion.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.pragmaticprogrammer.com/articles/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://bdn.borland.com/article/images/29139/ xplatform_with_borland_rad_tools.pdf * 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/library/weekly/aa020202a.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 ________________________________________________________________________ Vote o Boletim Pascal (Pascal Newsletter) em The Delphi Top 200! http://top200.jazarsoft.com/delphi/rank.php3?id=latium ________________________________________________________________________ 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.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium http://news.optimax.com/delphi/links/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://www.top219.org/cgi-bin/vote.cgi?delphi&83 http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80 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. ________________________________________________________________________ |
Os exemplos do código fonte desta edição estão disponíveis para download.
![]() |
Erros? Omissões? Comentários? Por favor contate-nos!






