Boletim Pascal #39
Os exemplos do código fonte desta edição estão disponíveis para download.
![]() |
![]() |
Boletim Pascal #39 - 02 DE MARÇO DE 2003 (Original: 13-SEP-2002) ÍNDICE 1. Algumas palavras dos editores 2. Notícias - O Delphi 7 chegou! - Preview do compilador Delphi para .NET - Kylix 3 recebe 5 estrelas do LinuxPlanet 3. Entendendo VisualCLX - O que são os hook-objects numa aplicação QT? 4. Criando Aplicações Middleware de alta performance com Indy 5. Assembler nativo em Delphi (III) - Arrays estáticas 6. Fóruns / listas 7. Delphi na Rede - Sites em português - Componentes, Bibliotecas e Utilidades . Freeware - Artigos, Dicas e Truques - Tutoriais - Outros Links ________________________________________________________________________ 1. Algumas palavras dos editores Editorial da Versão em Português ================================ Novamente eu aqui, pessoal, pedindo desculpas por mais um atraso. Dessa vez extrapolou todos os limites da paciência de vocês, não foi? Bem, então vamos às boas notícias. Finalmente entendi que não posso resolver tudo sozinho e decidi convidar colaboradores para me ajudarem nas traduções dos artigos. Foram vários interessados- fiquei muito feliz com o interesse de todos. Mas, na verdade, como são sempre poucos artigos por número, achei que cinco tradutores seriam suficientes- quatro ativos e um suplente. A partir de agora, as edições devem sair cada vez mais rapidamente até que cheguemos ao ponto ideal- uma semana de atraso em relação à edição em inglês. Bem, então aqui vão meus agradecimentos nominais a todos os que participaram como voluntários ou que de alguma forma demonstraram interesse em ajudar com as traduções: Andrea (não deu sobrenome), Adilson Vahldick, Guilherme A. Mendes, Cristiano de Favari, Frank Alcantara, Ary L. E. Silva, Cristiano Martins, Paulo Henrique Santiago de Maria, Henrique Meira, Joao dos Santos Laimer, Fabio Barreto, Alexandre Augusto Drummond Barroso, Eduardo Souza, Joandre Oliveira Melo, Agostinho Sieczkowski, Carlos Alberto Arrebola, Carlos Longen, J Iuri S Souza, Everton Vargas Agilar Agilar, Kally Cristina, Rubens Kamimura e Daniel (não deu sobrenome). Fiquei imensamente satisfeito com o apoio de todos. Agora, gostaria de dar os parabéns aos colaboradores que, a partir desse número, terão um papel essencial em cada uma de nossas publicações- são nossos tradutores! São eles: Adilson Vahldick Agostinho Sieczkowski Carlos Alberto Arrebola Cristiano de Favari Fabio Barreto 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 ============================= Primeiramente, gostaria de desculpar-me pela demora na publicação desse número, mas estive atolado de trabalho nessas últimas semanas. Espero que o número 40 serja publicado em três semanas. Nesse número, gostaria de agradecer Max Kleiner por contribuir com mais um artigo e fico grato em premiá-lo uma licença do AnyShape Transpack v2.0 for Kylix, o componente cross-platform que facilita a criação de janelas transparentes de todas as formas, vem com um editor WYSIWYG, visualização em tempo de desenvolvimento, arrastamento automático, formulários stay-on-top de verdade e ainda, a possibilidade de combinar regiões. O software é fornecido pela MindBlast Software: http://www.mindblastsoftware.com/?page=transpack&ref=PascalNL A propósito, o autor do próximo artigo Kylix que publicarmos também receberá uma licença do AnyShape Transpack v2.0 para Kylix. Gostaria de agradecer também a Romeo Lefter por seu artigo sobre o Indy e fico igualmente grato em primiá-lo com o DIL CD, CD do Delphi Information Library, um valioso recurso de informação com artigos, dicas, truques, componentes, scripts, imagens, update packs e muito mais, fornecido pelo UK Borland User Group: http://www.richplum.co.uk/html/dil.asp Para o prósimo número, temos os seguintes prêmios à disposição aos colaboradores: * llPDFLib v1.1 - por llionsoft, Shareware ($70, $280 com fontes) llPDFLib é uma biblioteca Object Pascal para a criação de documentos PDF. Não utiliza DLLs ou software externo de terceiros para gerar os PDFs. A biblioteca consiste de um componente TPDFDocument com métodos e propriedades análogos ao TPrinter do Delphi, mas orientados à geração do arquivo PDF. http://www.llion.net/ * Greatis Form Designer v3.4 - por Greatis Software, Shareware ($49.95) Esse é um editor de formulários de tempo de execução que permite ao usuário movimentar e redimensionar qualquer controle do formulário. Não é preciso preparar o formulário para utilizar o Form Designer. Apenas coloque um componente TFormDesigner num formulário, defina a propriedade Active para True e pronto! Para Delphi 4-7 e BCB 3-6. http://www.greatis.com/formdes.htm * Developer Information Library (DIL) CD - por UK Borland User Group Mais de 17,000 dicas, truques, FAQs e artigos técnicos · Atualizações e patches para ferramentas da Borland · Mais de 4000 components e Ferramentas· Mais de 4000 bitmaps prontos para uso e outros 20000 em formato compactado · Mais de 350 scripts javascript prontos para uso · Conjunto completo de How-Tos para Linux · e muito, muito mais... http://www.richplum.co.uk/html/dil.asp Ernesto De Spirito boletim-pascal-owner@yahoogrupos.com.br __________________ Colaborarm nesse número: Dave Murray ________________________________________________________________________ JfControls Library. Multi-language. Multi-appearance. Skins. Privileges. More than 40 integrated and customizable components. Impressive GUI. Centralized resources administration. Multiple programming problems solved. For Delphi 3-6 and C++ Builder 3-5. http://www.jfactivesoft.com/ ________________________________________________________________________ 2. Notícias Tradução: Adilson Vahldick Delphi 7 está aqui! =================== Delphi 7 está entre nós, chamado de Delphi 7 Studio, e é vendido em quatro edições: * Delphi 7 Studio Architect ($3,499 - Atualização do Enterprise: $2,399) http://www.borland.com/delphi/architect/index.html * Delphi 7 Studio Enterprise ($2,999 - Atualização: $1,899) http://www.borland.com/delphi/delphi_enterprise/index.html * Delphi 7 Studio Professional ($999 - Atualização: $399) http://www.borland.com/delphi/delphi_professional/index.html * Delphi 7 Studio Personal ($99 - livre para download) http://www.borland.com/delphi/delphi_personal/index.html A nova edição Architect é muito parecida com a edição Enterprise mas vem com ferramentas adicionais, incluindo o novíssimo Bold for Delphi da BoldSoft, que permite aos desenvolvedores manterem pouco código com verdadeiro MDA. E ainda vem com a tecnologia UML, com suporte integrado para Rational Rose, ModelMaker, importação/exportação de informações do modelo para/de Bold Model Editor e geração automática de database schema usando SQL. DataSnap (formalmente conhecido como MIDAS) vem gratuitamente nas edições Enterprise e Architect e também é incluída na versão Professional. Exceto na versão Professional, todas as edições do Delphi 7 Studio incluem o ambiente Kylix 3 for Delphi (permitindo aos desenvolvedores usarem um único código para sentir a força do desenvolvimento multi- plataforma para o Linux) e o Delphi 7 Studio Migration Kit (para migrar aplicações para Microsoft .NET). Links para o Delhi 7: * Página Principal http://www.borland.com/delphi/architect/index.html * Requisito de sistema http://www.borland.com/delphi/pdf/del7_sysreqs.pdf * FAQ http://www.borland.com/delphi/pdf/del7_faq.pdf * Matriz de Características http://www.borland.com/delphi/pdf/del7_feamatrix.pdf Delphi for .NET compiler preview ===============================- Incluído no Delphi 7, você encontra uma prévia do compilador Delphi para .NET, um utilitário para linha de comando chamado "dccil.exe" que produz aplicações Common Intermediate Language (CIL) que executam em qualquer lugar que o .NET run-time estiver disponível como o gerenciador padrão de aplicações. Isto significa que as aplicações em Delphi podem agora ir além da tradicional plataforma Windows/Intel para qualquer outra plataforma que possua um .NET runtime, como o .NET compact framework disponível nos tablet PCS, telefones e PDAS. * Delphi for .NET compiler preview - By John Kaster Uma prévia das características do compilador Delphi para .NET e a nova sintaxe do Object Pascal http://bdn.borland.com/article/0,1410,28972,00.html * Delphi for .NET Preview: Samples Este site fornece aplicações exemplo para o Delphi for .NET preview compiler. Estes exemplos foram produzidos por membros da comunidade Borland e pelos próprios funcionários. http://dotnet.borland.com * Using Delphi as a script language for ASP.NET - by John Kaster Uma prévia do suporte do Delphi para .NET support dentro do ASP.NET http://bdn.borland.com/article/0,1410,28974,00.html Kylix 3 ganha 5 estrelas do LinuxPlanet ======================================= * Kylix 3: Borland's Linux Delphi e C++ RAD são os vencedores - By Steven J. Vaughan-Nichols Finalmente, atendendo a pedidos dos programadores Linux, o Kylix vem com suporte total ao C++ no mesmo ambiente de desenvolvimento. O resultado é uma ferramenta RAD para Linux que provavelmente se tornará o mais popular ambiente de desenvolvimento integrado (IDE). http://www.linuxplanet.com/linuxplanet/reviews/4427/1/ * Fazendo um test drive com Kylix 3 - By Joe Barr Em resumo, Kylix 3 me permitiu desenvolver uma aplicação simples em interface gráfica com C++ no Linux em poucos dias. Mostrou-me, com a pequena experiência que tenho em desenvolvimento com C++ e Linux, não precisar em momento algum trabalhar com pipes, exceto na linha de comando, e num tempo satisfatório. O Kylix me demonstrou ser digno do selo RAD. http://www.idg.net/go.cgi?id=738304 ________________________________________________________________________ IBAdmin 3.2 - Complete Interbase SQL tool - A powerful DBA/Development tool for managing Interbase servers and databases. IBAdmin provides many capabilities to help with your DB design and management. You can use the Database Designer to visually design the database structure, the Grant Manager to manage users, or the SQL Debugger which can be used to debug stored procedures and triggers. Comfortable SQL code editing with Code- Insight and Code Completion. >>>>>>>>> http://www.sqlly.com/ibadmin2.htm ________________________________________________________________________ 3. Entendendo VisualCLX - O que são os hook-objects numa aplicação QT? Por Max Kleiner <max@kleiner.com> Kleiner Kommunikation http://max.kleiner.com/ Tradução: Adilson Vahldick VisualCLX é a parte da CLX que representa os componentes visuais normalmente descendentes de TWinControl na VCL. O VisualCLX framework é um conjunto de classes que representam os controles visuais que precisam funcionar (se possível) tanto no MS Windows quanto no Linux. Os controles representados pelos componentes da VisualCLX são implementados por uma biblioteca de classes em C++ chamada QT e widgets, de uma companhia norueguesa de desenvolvimento chamada Trolltech. A QT também está disponível no Windows. - A classe TWinControl da VCL é chamada TWidgetControl QT é uma biblioteca de classes C++ que, devido a diferenças de detalhes entre C++ e OP (Object Pascal), um programa OP não consegue manipular diretamente os QT Widgets. Contudo, a VisualCLX faz uso de uma biblioteca adicional, chamada QT Interface Library (libqtintf.so escrita em C++) que exporta todas as funcionalidades do QT de uma maneira que seja acessível ao código OP. A unit de importação para estas interfaces é chamada QT.PAS. Isto significa que qualquer classe declarada descendente das classes QT, utilizará de métodos flat e funções importadas desta biblioteca. Os aqui chamados métodos flat são declarados como subrotinas e funções normais, sem serem atrelados a qualquer classe. Entretanto, como no lado C++ existem realmente estas classes, quase todos estes métodos flat levam um parâmetro extra, que é uma referência ao QT Widget. Você deve estar pensando que isto torna a aplicação lenta, mas o tempo medido não mostrou qualquer diferença no comportamento em tempo execução. Então qual a diferença em termos de arquitetura? Numa aplicação OP, você chama os métodos com a referência dos objetos, por exemplo: myButton.setBounds(15,15,65,35); Transformando este método num método flat, o objeto é passado como referência no primeiro parâmetro e assim o método conhece a instância que o invocou. De acordo com o exemplo anterior, a chamada com um método flat equivalente seria: QButton_SetBounds(myButton, 15,15,65,35) ou em uma manipulacao QT no Kylix: uses QT, QTypes; var Btn:QButtonH; Btn := QButton_Create(Handle, PChar('Btn')); QButton_setGeometry(Btn, 15,15,65,35); É claro que você normalmente não vai precisar escrever este código, pois utilizando-se das classes prontas da CLX, este trabalho já vem todo incorporado dentro da classe TButton. Mas isto serve como um exemplo simples de como os componentes da CLX fazem para usar a CLXDisplayAPI. O que é a CLXDisplayAPI? ------------------------ CLXDisplayAPI é o nome oficial da unit QT.pas que acompanha o Kylix e o Delphi 6 (e posterior). Ela age como uma unit de importação para a biblioteca de widgets QT usado pela VisualCLX. QT é uma biblioteca de classes C++ e o OP não consegue manipular diretamente classes C++. Por causa disto, a Borland escreveu uma biblioteca adicional entre a aplicação CLX e a biblioteca QT. Esta biblioteca extra é chamada libqtintf.so (a QT interface library) e QT.pas é de fato a unidade de importação para esta biblioteca de interfaces. TWidgetControl--->Qt.pas->libintf.so--->Qt_Widget_Classes Entendendo o mecanismo signal/slot ---------------------------------- Um hook object é simplesmente um objeto C++ que existe na biblioteca de interfaces da QT como um intermediário. Assim, se você precisa customizar a reação de um widget, como os tratadores de eventos no Windows, o mecanismo de signal/slot funciona da seguinte forma: - um signal (evento) de um objeto - uma slot (tratador de eventos) responde ao signal Assim nós aprendemos que não é possível ter um slot escrito diretamente em OP, o que significa que a biblioteca de interfaces QT define uma hook Class para cada uma das classes widget. A hook class implementa um slot simples para cada signal da widget, que deve apenas ser chamada pela sua aplicação em Kylix. Mais sobre signal/slot e como o Kylix produz eventos ---------------------------------------------------- Mostramos que as mensagens (callback functions) não são a maneira como a CLX faz as coisas e isto não significa que a CLX não suporte mensagens, mas esta não é a forma como o Kylix trabalha. Nós sugerimos, por exemplo, os movimentos do mouse, que você deixe a CLX responder ao mouse e simplesmente sobrescreva os métodos que a CLX usa para estes eventos. Criado um componente e necessitando interceptar uma mensagem do mouse, você pode utilizar o seguinte método: procedure MouseMove(shift: TShiftState; X, Y: integer); override; A maneira para pensar usando QT, é que os desenvolvedores não respondam diretamente às mensagens (como se fazia no Windows). Então utilize o mecanismo de signal/slot com a seguinte função de conexão: QObject::connect(timer, SIGNAL(timeout()), SLOT(timerSlot())); timer -> start(1000); ou outro exemplo QObject::connect(myslider, SIGNAL(sliderMoved(in)), mylcdNumber, SLOT(display(in))); Não existe nada de especial sobre os métodos de movimento do Slider e de visualização. Apenas os métodos em C++ são marcados como signals e slots, como alguns métodos em Kylix são marcados como virtuais. QObject é uma classe base no QT, como o TObject é a classe base no OP. QObject tem um método de classe (ou estático) chamado connect. Um OP método de classe é o mesmo que um método estático em C++ ou Java. Em particular, podemos chamar um método de classe sem antes criar uma instância do objeto a que ele pertence. E onde está o laço de eventos no Kylix? Aqui está o laço de eventos localizado no centro das aplicações CLX: procedure TApplication.HandleMessage; Avaliando os hooks novamente ---------------------------- Fato: aprendemos que a QT usa um mecanismo de signal e slot e a CLX usa um mecanismo de eventos. Não é tão importante como ambos estão conectados e isto veremos logo a seguir. Mas o que importa no momento é saber que: QT tem um mecanismo signal/slot. CLX tem um mecanismo de eventos. Para traduzir os signals/slots da QT em eventos da CLX, os esenvolvedores do Kylix criaram um mecanismo chamado de hooks. Cada objeto da CLX tem um objeto hook. Este objeto hook converte em eventos da CLX, os eventos de signals e slots de um objeto em particular. Ele então envia estes eventos para o controle CLX apropriado. Em particular, existe um método da CLX do TWidgetControl chamado EventFilter que recebe a maioria destes eventos. Podemos encontrar mais deste tópico no Kylix2 CompanionTool CD: sams_publishing/kdgch07.pdf capítulo 7 "CLX architecture & Visual Development" ou Borland Code Central Entry ID #1679. Abaixo está um trecho extraído: Se você sente um desejo impulsivo de ir além da trivial CLX API, então aqui está um dos métodos que você precisa sobrescrever: function TWidgetControl.EventFilter(Sender: QObjectH; Event: QEventH): Boolean; EventFilter trata a maioria dos eventos lançados pela QT e o Sistema Operacional. Apenas abrindo a unit QControls e dando uma olhada nas mais de 500 linhas que formam a implementação deste método, é o bastante para garantir que qualquer programador lúcido utilize as CLX APIs padrões. Entretando, algumas pessoas gostam de viver no limite. Elas falam que o ar é fraco, mas mais limpo lá fora. function TWidgetControl.MainEventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; var Form: TCustmForm; begin try if csDesigning in ComponentState then begin Form := GetParentForm(Self); if (Form <> nil) and (Form.DesignerHook <> nil) and Form.DesignerHook.IsDesignEvent(Self, Sender, Event) then begin Result := True; Exit; end; end; Result := EventFilter(Sender, Event); except Application.HandleException(Self); Result := False; end; end; __________________ Referência : http://www.delphi3000.com/article.asp?ID=3311 ________________________________________________________________________ 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 ________________________________________________________________________ 4. Criando Aplicações Middleware de alta performance com Indy Por Romeo Lefter <rombest @ hotmail.com> Rombest Software http://www.vreau.com Tradução: Cristiano de Favari Middleware é uma das tecnologias mais legais que estão agora no mercado. Infelizmente, as ferramentas prontas para esta tecnologia custam caro. Esta tecnologia esta associada com banco de dados porque é intensamente utilizada neste campo, mas não está limitada apenas a banco de dados. Usando esta tecnologia, você pode criar uma variedade de aplicações que usam clientes leves. Tipicamente, um framework middleware se parece com a figura abaixo: +-------+ +----------+ +--------+ |Clients| <<-Connection1->> |Middleware| <<-Connection2->> |Database| | | | server | | server | +-------+ +----------+ +--------+ Nesta imagem, os [clientes] representem seus clientes leves, o [middleware server] é seu servidor de aplicação e [Database Server] é o banco de dados. Conforme este modelo, clientes, servidor de aplicação e servidor de banco de dados rodam em máquinas distintas (o banco de dados e o servidor de aplicação podem rodar na mesma máquina). Connection1 e Connection2 são as conexões entre nossas partes. A arquitetura middleware é o melhor jeito de fazer sérias economias. Por exemplo, o MS SQL Server precisa licenças suplementares para cada cliente. Também, precisa alguma coisa chamada "Client Access License" (eu acho). Tudo isso custa dinheiro. Com uma simples licença de cliente (+ Client Access License) você pode construir um servidor middleware e então trabalhar com muitos clientes sem pagar licenças adicionais. E esta solução funciona bem! Relacionado ao middleware, eu quero dizer aqui que não gosto de Midas, COM, DCOM, COM+, etc. Há muitas soluções de middleware no mercado. Uma pequena parte delas representa boas soluções, mas são caras. Há soluções que são fáceis de usar mas, infelizmente, são mais lentas. O problema que eu discutirei aqui é sobre como criar uma aplicação middleware grátis. Isto é possível e, acreditem em mim, são superiores em performance que outros competidores. Primeiro, vamos revisar as ferramentas necessárias para este trabalho. 1. Indy http://www.nevrona.com/indy Você precisa do Indy. Porque é simples de usar e muito fácil. Há outros pacotes comerciais no mercado que são mais rápidos que o Indy mas trabalhar com eles não é tão fácil. Para mim, Indy é um dos melhores pacotes de rede do mercado. 2. KbmMemTable: http://www.onelist.com/community/memtable Esta é a melhor tabela de memória que está agora no mercado. É thread safe, seu conteúdo (registros e estruturas) pode ser salvo em disco ou stream, tem suporte para transações, blobs comprimidos e muito mais. O melhor de tudo, é grátis e vem com o código fonte. => Uma curta descrição sobre o TKbmMemTableFeatures Como eu disse, o modelo Threading do kbmMemTable é um dos melhores. Você tem que ajustar algumas poucas propriedades e sua tabela pode seguramente trabalhar em um ambiente multithreading. A primeira propriedade é AttachedMaxCount. É uma propriedade Integer que armazena o máximo número de memtables que podem ser anexadas a esta tabela. O processo de anexar é legal. Quando você anexa uma tabela de memória (vamos chamá-la de A) em outra tabela (B), todos os dados contidos na tabela B estão disponíveis para a tabela A. Mais do que simplesmente visualizar, a tabela A pode adicionar ou atualizar registros e os resultados são refletidos na tabela B. Em um ambiente multi-threading, este é o melhor modelo. Outra característica de KbmMemTable é a possibilidade de gravar seus dados em streams ou arquivos. Isto é muito bom para o que queremos fazer. Na última versão, TKbmMemTable tem dois componentes facilitadores. kbmBinaryStreamFormat e TkbmCsvStreamFormat nos ajudam a estabelecer uma "linguagem comum de stream" para o servidor e para o cliente. Como você verá, SavetoStreamviaFormat e LoadFromStreamviaFormat são os métodos mais usados em nosso ambiente. É hora agora de discutir o protocolo. Primeiro, por razões de segurança, você precisa de uma parte de autenticação. Então, nós temos que implementar dois comandos: Login e Logoff. O comando login é enviado para o servidor com dois parâmetros: o nome do usuário e sua senha como abaixo: login user pass Se o par (usuário, senha) corresponder aos dados armazenados no servidor, o usuário está apto a trabalhar, senão ele é deconectado. Quando o usuário quer terminar sua sessão, ele envia ao servidor o comando logoff, sem nenhum parâmetro, quando entãio o servidor desconectará o cliente. Para tornar este exemplo simples e portável, trabalharei com tabelas paradox que simularão nosso servidor de banco de dados. Também, para uma fácil portabilidade, usarei queries. Nesta aplicação, usarei a tabela country.db que está em seu alias DBDEMOS. Os clientes que conectarão em nosso servidor middleware serão capazes de: - Adicionar registros na tabela - Trazer a tabela inteira. Para adicionar registros na tabela, nós implementaremos um comando (Add) com cinco parâmetros: Name, Capital, Continent, Area, Population. Então, o comando ficará como o mostrado abaixo: Add p1 p2 p3 p4 p5 Para obter a tabela, precisamos apenas de um comando sem parâmetros (Get). É hora de trabalhar, então vamos começar. Abra um novo projeto, coloque um Memory table e um TIdTcpServer nele. O Memory Table será usado para o processo de login, então você tem que criar dois campos string para isto: user e password. Você tem que implementar algumas procedures para adicionar, apagar e atualizar usuários. Também, nos eventos FormCreate and FormClose você tem que carregar/gravar dados persistentes para esta tabela (usando os métodos LoadFromBinaryFile/LoadFromCsvFile e SaveToBinaryFile/ SaveToCsvFile). Decidi usar memory table para manipular a autenticação do usuário porque é melhor em velocidade e seu mecanismo Thread-safe funciona perfeitamente. Eu decidi ter a seguinte arquitetura: No MainForm: usrs: Um KbmMemTable usado para autenticação (tablea users) Server: Um componente TIdTcpServer, nosso servidor MThread: Um componente TIdThreadMgrPool (usarei para este exemplo um pool threaded com tamanho de pool = 100) Para um entendimento fácil, usarei CommandHandlers habilitado neste projeto, então nós temos que definir 4 comandos: - Login - Logoff - Get - Add A propriedade AttachedMaxCount de AuthTable tem que estar com 100 porque nosso tamanho de pool é 100. Também, para um fácil entendimento, colocamos todos os componentes de "interface de banco de dados" em um DataModule. Então, crie um datamodule e coloque alguns componentes nele, como mostrado abaixo : Query1: Um componente TQuery que fará a interface com o banco de dados. No nosso caso o banco de dados é o DBDEMOS. Session1: Um componente TSession usado para transações seguras. logintable: Um memTable que será anexado a AuthTable para fazer a verificação se o par (usuário, senha) está correto. buffertable: Outro memTable usado para troca de dados. Desabilite o AutoCreateForm do datamodule (em Project|Options). Agora nós olharemos a fundo o modelo de servidor. Como eu disse, o usuário tem que se logar no servidor. Quando o usuário envia o comando LOGIN, o servidor realizará os seguintes passos: 1. Cria o datamodule; 2. Anexa o logintable (do datasource) ao AuthTable (que está no MainForm) 3. Verifica se o par (usuário, senha) é válido 4. Envia de volta ao usuário o resultado da autenticação - Se o número de parâmetros for menor que 2 (isto é, o comando se parece com login meuNome), o servidor envia ('101 - Wrong number of params! Good bye!') e desconecta o usuário; - Se o par (usuário, parâmetro) é válido, o servidor envia uma mensagem como ('201 - Ok, you are now in the system, man!') e o cliente permanecerá conectado - Se o par (usuário, parâmetro) não é válido, o servidor envia uma mensagem como ('102 - Sorry, invalid user or password. Good bye!') e desconecta o usuário. Um pouco de código deixá as coisas mais claras, se você não entendeu o que eu disse. Então, veja abaixo: procedure TForm1.serverCommandHandlers0Command(ASender: TIdCommand); var ClientDataModule:TDatas; loginFlag:boolean; begin // Login command // Format login <<user>> <<password>> if ASender.Params.Count<2 then begin ASender.Thread.Connection.WriteLn( '101 - Wrong number of params! Good bye!'); ASender.Thread.Connection.Disconnect; end; // Create the dataModule.. Its owner is the actual Connection! ClientDataModule:=TDatas.Create(ASender.Thread.Connection); // Assign for the session component an unique name ClientDataModule.Session1.SessionName := 'ClientSession' + Inttostr(ASender.Thread.ThreadID); ClientDataModule.logintable.AttachedTo := usrs; ClientDataModule.logintable.Active := True; ClientDataModule.Query1.SessionName := ClientDataModule.Session1.SessionName; // Ok, now we will verify if the (user,password) is valid if not ClientDataModule.logintable.Locate('User', ASender.Params[0],[]) then loginflag:=false else if ClientDataModule.logintable.FieldByName('Password').AsString = Asender.Params[1] then loginFlag:=true else loginFlag:=false; if loginFlag then Asender.Thread.Connection.WriteLn( '201 - Ok, you are now in the system, man!') else begin Asender.Thread.Connection.WriteLn( '102 - Sorry, invalid user or password. Good bye!'); ASender.Thread.Connection.Disconnect; end; end; À primeira vista, é um pouco "estranho" o modo como criamos o datamodule (no meu projeto, seu nome é Datas). Como você pôde observar, eu o criei usando uma variável local. O problema é "como nós o acessaremos de outras procedures?". E aqui está minha pequena novidade. Usar uma variável global é realmente difícil porque nós não sabemos quantas conexões nós temos no momento. Não se esqueça que o dono (owner) do Datamodule é o Connection. Para cada conexão ativa nós temos um Datamodule criado. É claro, ele é criado apenas se o usuário estiver logado. Se o usuário não estiver logado, o DataModule não existe. Para um fácil entendimento, olhe o cenário abaixo: O cliente conecta no servidor, usando o método connect de TIdTcpClient. Neste momento, o cliente pode enviar qualquer comando para o servidor. Nós precisamos saber que ele está logado e saber também quando ele envia para o servidor um comando como Get ou Add. Usando o modelo que eu descrevi, a verificação de usuário é realmente fácil, porque se para cada conexão cliente um DataModule existe, significa que o cliente está logado, se não, o cliente não está logado. É hora agora de implementar uma função "procura" ("Finder"). Esta função é útil para encontrar se o Datamodule existe para uma conexão. Se o DataModule existe, a função retornará uma referência para o DataModule. Senão, ela retornará nil. function TForm1.FindModule(connection: TIdTCPServerConnection): TDatas; var i: integer; begin Result := nil; for i := 0 to Connection.ComponentCount-1 do if Connection.Components[i] is TDatas then Result := (Connection.Components[i] as TDatas); end; Como eu disse, nós estamos usando um "pool thread model" para nosso servidor. Isto significa que a thread não será destruída quando o usuário desconecta do servidor. Então, nós temos que destruir manualmente o DataModule a cada vez, quando o usuário está desconectado de nosso servidor. procedure TForm1.serverDisconnect(AThread: TIdPeerThread); var AData:TDatas; begin AData := FindModule(AThread.Connection); if AData <> nil then AData.Free; end; Significa que para o comando LogOff nós temos que fazer alguma coisa como: procedure TForm1.serverCommandHandlers1Command(ASender: TIdCommand); begin ASender.Thread.Connection.Disconnect; end; Nós estamos agora no momento da real implementação. Nós temos que trocar dados entre nosso client e o servidor, então nós implementaremos primeiro o comando Get. Para tornar este exemplo simples de entender, este comando não terá nenhum parâmetro. Mas, nós podemos adicionar parâmetros que possam ser usados para fitrar ou para qualquer outra ação. Abaixo, nós temos a implementação do comando: procedure TmainFrm.serverTIdCommandHandler2Command(ASender: TIdCommand); var AData:TDatas; AStream:TStream; begin AData:=FindModule(ASender.Thread.Connection); if Adata=nil then begin ASender.Thread.Connection.WriteLn( '103 - You are not logged in! Good bye!'); Asender.Thread.Connection.Disconnect; end; // Create the stream AStream:=TMemoryStream.Create; // Start the interrogation AData.Query1.sql.Clear; AData.Query1.sql.Add('select * from country'); AData.Query1.Active:=true; // Load the Query's data to buffertable Adata.buffertable.LoadFromDataSet(Adata.Query1,[mtcpostructure]); // Save BufferTable to Astream AData.buffertable.SaveToStreamViaFormat(Astream, adata.kbmBinaryStreamFormat1); // Move Stream to first position Astream.Seek(0, soFromBeginning); ASender.Thread.Connection.WriteLn( '202 - Ok! The stream is comming!'); // Send the Stream to client Application ASender.Thread.Connection.WriteStream(AStream,true,true); // Free the stream AStream.Free; end; Para este comando, o cliente receberá um stream contendo todos o dados da tabela. Este stream pode ser carregado para a TKbmMemTable e a table toda estará visível no cliente. Sem BDE ou qualquer outra "conetividade" de terceiros. O comando Add tem a mesma implementação (você tem que ler os parâmetros e criar a query que insere-os dentro da tabela). Por isto, eu não vou elaborar além deste aspecto. Também, porque a implementação do cliente é realmente fácil, eu não vou descrevê-la. Esta é toda a "tecnologia". É simples de implementar, superior em performance e não custa nada. Há, obviamente, outros aspectos que você tem que pensar. Por exemplo, você pode usar stream comprimidos para reduzir o tráfego entre o servidor e os clientes. Há algumas coisas que você tem que saber antes de começar seu próxima criação do "grande servidor middleware". Antes de você começar, você tem que construir seu protocolo e isto, na minha opinião, é a parte mais importante para o projeto. Um bom protocolo ajudará você no processo de desenvolvimento. Vamos ver o fragmento de código abaixo. Primeiro, você tem que ver que antes de cada string que é enviada para o cliente, há um número. No protocolo de exemplo, eu usei um protocolo numérico combinado a um protocolo de string. Antes de um texto que é enviado ao cliente, eu tenho um código numérico: 1XX representa as ações de erro e 2XX representa as ações de sucesso. Isto ajudará você a desenvolver aplicações clientes. Você pode criar, no lado cliente, uma função de auxílio que extrai este código numérico e, para cada string que é recebida pelo cliente, você saberá se um erro ocorreu ou se "tudo está OK". Outra parte interessante é a sincronização. Quando um servidor manda um stream, você tem que ler o stream no lado do cliente. O mesmo com strings. Se você espera por uma string e a string é enviada, sua aplicação cliente será bloqueada. Isto porque eu inseri a mensagem '202 - Ok! The stream is comming!'. À primeira vista, é desnecessário- mas apenas olhe para o começo da procedure. Se o cliente não está logado, o servidor envia a mensagem '103 - You are not logged in! Good bye!'. Quando nosso cliente envia o comando Get para o servidor, ele primeiro lê uma string porque ele tem que saber se o servidor retorna um erro. Outra parte interessante é sobre como streams são enviadas. A procedure WriteStream tem 3 parâmetros. Primeiro é a stream que será enviada. O segundo parâmetro é um boolean. Se for verdadeiro, o stream será enviado do começo, senão o stream será enviado da posição atual. O terceiro parâmetro é também um boolean. Se verdadeiro, o tamanho do stream será enviado para o cliente, se for falso, este valor não será enviado. Se o último parâmetro é verdadeiro, o tamanho é enviado como um valor inteiro, antes do stream. Então, os fragmentos de código abaixo são os mesmos: 1. => WriteStream com o último parâmetro Falso .... i := MyStream.Size; ASender.Thread.Connection.WriteInteger(i); ASender.Thread.connection.WriteStream(MyStream, true, false); .... é o mesmo com 2. => WriteStream com o último parâmetro true .... ASender.Thread.Connection.WriteStream(MyStream, true, true); .... Um projeto demo está anexado a este artigo. Ele contém um cliente completo e uma implementação do servidor. Divirta-se! __________________ Referência: http://www.delphi3000.com/member.asp?ID=806 ________________________________________________________________________ 5. Assembler nativo no Delphi (II) - Arrays estáticas Por Ernesto De Spirito <eds2004 @ latiumsoftware.com> Tradução: Carlos Alberto Arrebola Passando arrays estáticas como parâmetros ========================================= Parâmetros de arrays estáticas são passados como ponteiros ao primeiro elemento do array, independentemente do parâmetro ser passado por valor ou por referência (como "var" ou como "const"). Dadas as seguintes declarações... const ARRAY_MAX = 5; type TArrayOfInt = packed array [0..ARRAY_MAX] of longint; var a, b: TArrayOfInt; procedure InitializeArray(var a: TArrayOfInt); var i: integer; begin for i := 0 to ARRAY_MAX do a[i] := i; end; ... a chamada à procedure InitializeArray em assembler seria: // Em Object Pascal: // InitializeArray(a); // Em Assembler Inline: asm mov eax, offset a // EAX := @a; call InitializeArray // InitializeArray; end; OFFSET é um operador unário assembler que retorna o endereço de um símbolo. O OFFSET não é aplicável para símbolos locais. Deve-se usar o opcode LEA (veja abaixo), que é mais "universal". Arrays estáticas passadas por valor ----------------------------------- Se o array é passado por valor, é responsabilidade da função chamada preservar o array. Quando a função precisa mudar os valores de um ou mais elementos de um array passado por valor, normalmente ela cria uma cópia local e trabalha com a cópia. O compilador cria uma cópia para nós no "begin" das procedures e funções Pascal, mas em procedures e funções em assembler puro temos de fazer isto nós mesmos. Um modo de se fazer isto seria o seguinte: procedure OperateOnArrayPassedByValue(a: TArrayOfInt); var _a: TArrayOfInt; asm // Copia os elementos de "a" (parâmetro) em "_a" (cópia local) push esi // Salva ESI na pilha push edi // Salva EDI na pilha mov esi, eax // ESI := EAX; // @a lea edi, _a // EDI := @_a; mov eax, edi // EAX := EDI; // @_a mov ecx, type TArrayOfInt // ECX := sizeof(TArrayOfInt); rep movsb // Move(ESI^, EDI^, ECX); pop edi // Restaura EDI da pilha pop esi // Restaura ESI da pilha // Aqui vai o resto da função. Trabalharemos sobre o "_a" (a // cópia local), cujo primeiro elemento está agora apontado por EAX. end; O que encontramos de novo aqui são os opcods LEA e MOVSB, o prefixo REP e o operador TYPE, descritos abaixo: LEA (Load Effective Address) ---------------------------- Move para o primeiro operando o endereço do segundo. Aqui comparamos LEA com MOV: Instrução Traduzida como Efeito ------------------------------------------------------------------- lea eax, localvar lea eax, [ebp-$04] EAX := @localvar; EAX := EBP - $04; mov eax, localvar mov eax, [ebp-$04] EAX := localvar; EAX := (EBP - $04)^; MOVSB (MOVe String Byte) ------------------------ Copia o byte apontado por ESI ao local apontado por EDI, e incrementa ESI e EDI de tal forma que eles apontem para o próximo byte. O trabalho do MOVSB pode ser descrito como segue: ESI^ := EDI^; // Assume que ESI e EDI são do tipo PChar Inc(ESI); Inc(EDI); Notas: * MOVSW e MOVSD são as versões Word (16-bit) e DWord (32-bit) respectivamente (ESI e EDI são incrementadas de 2 e 4 respectivamente). * Os registradores são decrementados se o Direction Flag é setado. REP --- O prefixo REP é usado em operações de string para repetir a operação de decremento ECX até que ECX seja zero. O trabalho do REP poderia ser descrito como segue: // rep string_instruction @@rep: string_instruction loop @@rep Notas: * O REP não é um atalho para um código como o acima. Ele trabalha muito mais rápido. * O valor de ECX não é checado no começo do loop (se ECX fosse zero, a instrução seria repetida 2^32 vezes, mas geraria um extenso AV antes disto, tão logo ESI ou EDI apontassem para uma localição de memória inválida). TYPE ---- O operador TYPE é um operador unário avaliado em tempo de compilação que retorna o tamanho em bytes de um operando, que deve ser um tipo de dados. Por exemplo, TYPE WORD retornará 2 e TYPE INTEGER retornará 4. Acessando os elementos de um array ================================== Para acessar um elemento a[i] precisamos dos valores "@a[0]" e "i" nos registradores (como EDX e ECX, por exemplo) para então podermos usar o endereçamento de memória como segue: lea edx, a // EDX := @a; mov ecx, i // ECX := i; mov ax, [edx+ecx*type integer] // AX := EDX[ECX]; // a[i]; // PWord(EDX + ECX * SizeOf(integer))^ No exemplo, presumimos que os elementos têm 2 bytes (movemos o valor de a[i] para AX, um registrador de 16 bits), que a array não é agrupada (cada elemento realmente ocupa 4 bytes, o tamanho de um inteiro, logo este valor foi usado para calcular a posição do elemento) e que o array não começa pelo elemento 0, ou seja, não é um array "zero-based". Por exemplo: var a: array [0..N] of word = (1, 2, 3, 6, ...); +------ EDX = @a | v +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-- | 1 | 0 | | | 2 | 0 | | | 3 | 0 | | | 6 | 0 | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-- a[0] a[1] a[2] a[3] [edx] [edx+04] [edx+08] [edx+12] Se o array não é zero-based, temos que ajustar o valor do índice para torná-lo zero-based antes de endereçarmos o elemento. Exemplos: // a[1..100] : mov ecx, i // ECX := i; dec ecx // Dec(ECX); // Ajusta ECX : // a[-10..10] : mov ecx, i // ECX := i; add ecx, 10 // Inc(ECX, 10); // Ajusta ECX : A procedure InitializeArray (apresentada acima) pode ser implementada em assembler do seguinte modo: procedure InitializeArray(var a: TArrayOfInt); asm // EAX = PByte(@a[0]); xor ecx, ecx // ECX := 0; @@loop: mov [eax+ecx*type integer], ecx // PInteger(EAX+ECX*4)^ := ECX; // ...or EAX[ECX] := ECX; inc ecx // ECX := ECX + 1; cmp ecx, ARRAY_MAX // if ECX <= ARRAY_MAX then jle @@loop // goto @@loop; end; Ou assim: procedure InitializeArray(var a: TArrayOfInt); asm // EAX = @a[0]; xor ecx, ecx // ECX := 0; @@loop: mov [eax], ecx // EAX^ := ECX; inc ecx // Inc(ECX); add eax, type integer // Inc(EAX); // Aponta para o próximo elemento cmp ecx, ARRAY_MAX // if ECX <= ARRAY_MAX then jle @@loop // goto @@loop; end; Valores de retorno de arrays ============================ As funções que retornam arrays recebem um último parâmetro adicional que é o ponteiro para a locação de memória onde deveam colocar seu valor de retorno (a memória é alocada e liberada se necessário por quem acessou). Por exemplo, consideremos a seguinte função: function ReverseArray(const a: TArrayOfInt): TArrayOfInt; var i: integer; begin for i := 0 to ARRAY_MAX do Result[i] := a[ARRAY_MAX-i]; end; A função recebe dois parâmetros: 1) EAX = endereço do primeiro elemento da array "a" 2) EDX = endereço do primeiro elemento de Result A função pode ser reescrita em assembler como segue: function ReverseArray(const a: TArrayOfInt): TArrayOfInt; asm // EAX = @a[0]; EDX = @Result[0]; push ebx // Save EBX mov ebx, eax // EBX := EAX; xor ecx, ecx // ECX := 0; @@loop: mov eax, ARRAY_MAX sub eax, ecx // EAX := ARRAY_MAX-ECX; mov eax, [ebx+eax*type integer] // EAX := EBX[EAX]; mov [edx+ecx*type integer], eax // EDX[ECX] := EAX; inc ecx // ECX := ECX + 1; cmp ecx, ARRAY_MAX // if ECX <= ARRAY_MAX then jle @@loop // goto @@loop; pop ebx // Restore EBX end; Bem, isto é tudo por enquanto. No próximo artigo veremos como trabalhar com registros. ________________________________________________________________________ 6. 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: Participe da lista de discussão do Grupo Delphi-BR e faça parte da mais profissional lista Delphi do Brasil. Essa lista tem como objetivo a troca de informações entre os diversos programadores Delphi em lingua portuguesa. Aqui você encontrará grandes programadores brasileiros dando suas contribuições para a comunidade e mantendo uma via de comunicação entre todos os programadores Delphi brasileiros. http://br.groups.yahoo.com/group/delphi-br/ Assinatura: http://br.groups.yahoo.com/group/delphi-br/join delphi-br-subscribe@yahoogrupos.com.br * 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 ________________________________________________________________________ 7. 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 ====================================== Freeware -------- * Kylix 3 Open Edition available for download It's a whopping 300+ MB download, but worth every nibble! http://community.borland.com/article/0,1410,29010,00.html * Explorer Drop v1.1, FREEWARE with source - by Simon Grossenbacher TExplorerDrop component enables Drag&Drop with the Windows Explorer for all controls inherited from TWinControl. http://www.torry.net/vcl/system/draganddrop/swissexplorerdrop.zip * KACDO Proffesional v1.0, FREEWARE - by Kiril Antonov Delphi implementation of Microsoft's CDO for Win2k -a set of functions for composing and sending mail. Works only on Win2k/XP machines. Set of 3 powerful components: Message - Message, SMTP, NNTP, Encoding + Decoding Component; Manager - manages IIS SMTP Folders; TreeView - displays + modifies structure of complex messages. http://www.torry.net/vcl/internet/email/kacdopro.zip * TAdvFTP, FREEWARE with source - by Vadim Winebrand (KYLIX) An advanced FTP client component which supports resumes and gives the download rate every few seconds. Includes socks server support. http://www.torry.net/kylix/clxinternet/itools.zip Artigos, Dicas e Truques ======================== * TJpegImage lets you transform BMPs to JPEGs - by Bob Swart Dr Bob shares a trick for transforming BMPs to JPEGs and vice versa. Thanks to a hidden component, it's not as hard as you might think. http://builder.com.com/article.jhtml?id=u00220020913swa01.htm * Using Delphi objects to store config information - by Sebastián Mayorá This article explains how to use objects as a substitute for INI files (and other similar techniques) to store configuration information. http://delphi.about.com/library/bluc/text/uc090302a.htm * Back to School with more Delphi knowledge - by Zarko Gajic Whether you're parent, student or teacher here are the topics you need to enhance your knowledge of Delphi programming. Go back to school in style with the right tutorials, code samples and Delphi quizzes. http://delphi.about.com/library/weekly/aa082702a.htm * ModelMaker tutorials - by Anders Ohlsson ModelMaker is included in D7 Enterprise & Architect - here are some tutorials to get you started. http://bdn.borland.com/article/0,1410,29006,00.html * How to install and uninstall fonts www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=169 * How to check if a string is a number www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=170 * How to get second title bar color www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=171 * BDE error list www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=173 * How to get the CPU speed www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=174 * How to write a correct date in SQL www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=175 * How to get around TQuery.Refresh if it doesn't work - by m3Rlin Sometimes TQuery.Refresh will not refresh as it's supposed to... www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=176 * How to read the serial number of an Audio CD - by m3Rlin Audio CDs, like almost every computer drive/media have a serial number too. Some programs use this number to recognize CDs. www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=177 * How to check is a character is a letter - by m3Rlin www.delphifaq.net/modules.php?op=modload&name=FAQ&op=view&id=178 * How to export a StringGrid to an Excel-File? http://www.swissdelphicenter.ch/en/showcode.php?id=379 * How to turn on/off Caps/Num/Scroll Lock? http://www.swissdelphicenter.ch/en/showcode.php?id=926 * How to synchronize DBGrid title alignments with field alignments? http://www.swissdelphicenter.ch/en/showcode.php?id=1074 * How to save memory with duplicate strings? http://www.swissdelphicenter.ch/en/showcode.php?id=1110 * How to draw a gradient on a canvas with an arbitrary number of colors? http://www.swissdelphicenter.ch/en/showcode.php?id=1162 * How to retrieve information about the TWebBrowser control? http://www.swissdelphicenter.ch/en/showcode.php?id=1191 * How to retrieve the network card addresses? http://www.swissdelphicenter.ch/en/showcode.php?id=1206 * How to convert C Types to Object Pascal Types? http://www.swissdelphicenter.ch/en/showcode.php?id=1217 * How to get an inverse color value to a color? http://www.swissdelphicenter.ch/en/showcode.php?id=1222 * How to show values in a hexadecimal representation? http://www.swissdelphicenter.ch/en/showcode.php?id=1312 * How to show values in binary representation? http://www.swissdelphicenter.ch/en/showcode.php?id=1313 * How to get the start command for a installed Mail-Client? http://www.swissdelphicenter.ch/en/showcode.php?id=1320 * How to execute a document and wait for it to finish? http://www.swissdelphicenter.ch/en/showcode.php?id=1333 * How to do bit-wise manipulation? http://www.swissdelphicenter.ch/en/showcode.php?id=1341 * How to Draw on a Form's Caption bar? http://www.swissdelphicenter.ch/en/showcode.php?id=1345 * How to access Paradox tables on CD or read-only drives? http://www.swissdelphicenter.ch/en/showcode.php?id=1351 * How to define BDE aliases in code? http://www.swissdelphicenter.ch/en/showcode.php?id=1353 * How to multiply big integer values? http://www.swissdelphicenter.ch/en/showcode.php?id=1363 * How to calculate the logarithm for a variable base? http://www.swissdelphicenter.ch/en/showcode.php?id=1371 * How to auto hide IDE windows when coding/designing? http://www.swissdelphicenter.ch/en/showcode.php?id=1382 * How to get the length of wav file (in second)? http://www.swissdelphicenter.ch/en/showcode.php?id=1383 * How to Clone the Controls Properties? http://www.swissdelphicenter.ch/en/showcode.php?id=1392 * How to set system evrionment variable? http://www.swissdelphicenter.ch/en/showcode.php?id=1394 * How to Set a new Index to TToolButton of a TToolbar? http://www.swissdelphicenter.ch/en/showcode.php?id=1395 * How to include the mouse-cursor in a screen shot? http://www.swissdelphicenter.ch/en/showcode.php?id=1396 * How to send data to another program by auto-drag&drop? http://www.swissdelphicenter.ch/en/showcode.php?id=1398 * How to empty all StringGrid cells? http://www.swissdelphicenter.ch/en/showcode.php?id=1399 * How to get the width and height of a Gif-File? http://www.swissdelphicenter.ch/en/showcode.php?id=1400 * How to transition the system to the standby/ hibernate state? http://www.swissdelphicenter.ch/en/showcode.php?id=1401 * How to know if the form is modal? http://www.swissdelphicenter.ch/en/showcode.php?id=1402 * How to prevent copy/paste/cut in TEdit? http://www.swissdelphicenter.ch/en/showcode.php?id=1403 * How to use regular expressions in Delphi? http://www.swissdelphicenter.ch/en/showcode.php?id=1406 * How to save a QuickReport to stream? http://www.swissdelphicenter.ch/en/showcode.php?id=1410 * How to build a Multi Screen Emulator? http://www.swissdelphicenter.ch/en/showcode.php?id=1418 * How to use the DrawAnimatedRects API? http://www.swissdelphicenter.ch/en/showcode.php?id=1419 * How to get the caret-position systemwide? http://www.swissdelphicenter.ch/en/showcode.php?id=1420 * How to invoke the 'find' dialog in a TWebBrowser? http://www.swissdelphicenter.ch/en/showcode.php?id=1421 * How to determine if the current session is remotely controlled? http://www.swissdelphicenter.ch/en/showcode.php?id=1424 * How to translate a virtual-key to ASCII code? http://www.swissdelphicenter.ch/en/showcode.php?id=1425 * How to convert a bitmap to RTF code? http://www.swissdelphicenter.ch/en/showcode.php?id=1426 * How to export a TDBGrid to excel without OLE? http://www.swissdelphicenter.ch/en/showcode.php?id=1427 * How to read a REG_MULTI_SZ value From the Registry? http://www.swissdelphicenter.ch/en/showcode.php?id=1431 * How to restore the default positions of the IDE Toolbars? http://www.swissdelphicenter.ch/en/showcode.php?id=1432 * How to retrieve all database tables with ADO? http://www.swissdelphicenter.ch/en/showcode.php?id=1433 * How to add items to the Application's Windows System Menu? http://www.swissdelphicenter.ch/en/showcode.php?id=1435 * How to get the number of Files in the Recycle Bin + their total size? http://www.swissdelphicenter.ch/en/showcode.php?id=1436 * How to change Background Color in TRichEdit for selected characters? http://www.swissdelphicenter.ch/en/showcode.php?id=1438 * How to show/hide the ActiveDesktop? http://www.swissdelphicenter.ch/en/showcode.php?id=1439 * How to copy formated Rtf-Text from one TRichedit to an other? http://www.swissdelphicenter.ch/en/showcode.php?id=1440 * How to use different underline styles for Text in TRichEdit? http://www.swissdelphicenter.ch/en/showcode.php?id=1441 * How to put the TWebbrowser into Edit Mode? http://www.swissdelphicenter.ch/en/showcode.php?id=1442 * How to set the paragraph line spacing in a TRichedit? http://www.swissdelphicenter.ch/en/showcode.php?id=1444 * Speed up connection to Oracle 8i - by Mark Halter http://www.delphi3000.com/articles/article_3344.asp * How do we store Graphics/Shapes like an Object? - max kleiner Designing a diagram editor or a graphic-tool raises the problem of storing all the painted shapes in a file without get lost in too much overhead. http://www.delphi3000.com/articles/article_3348.asp * Simulate a Web Form POST Request - by Clever Components Discusses the automation of the upload process via HTTP protocol by the POST method using the components from Clever Internet Suite. http://www.delphi3000.com/articles/article_3351.asp * Threaded Brute Forcing Class - by Stewart Moss http://www.delphi3000.com/articles/article_3352.asp * Simple useful Irc routines - by Stewart Moss http://www.delphi3000.com/articles/article_3353.asp * Generic File Importer Base Class - by Stewart Moss Here is a useful base class to create derived classes to import data from any flat file format you can think of. http://www.delphi3000.com/articles/article_3354.asp * ADO Dataset -> CSV file How to export a ADO Dataset to a Comma Separated Values file with a few lines of code. http://www.delphi3000.com/articles/article_3355.asp * Send E-Mails with Indy Components (Easy) http://www.delphi3000.com/articles/article_3356.asp * Show message in OnEnter event Do you ever needed to display a message using the OnEnter event? This example shows how to correctly display a message by using the ShowMessage (or an equivalent function) in OnEnter event. http://www.delphi3000.com/articles/article_3357.asp * EventLog change notification in real-time I needed a way to be notified in real-time when someone acceded my computer inside an intranet. After doing some research, the solution would pass by using the Security event log that is used when you activate any audit option. http://www.delphi3000.com/articles/article_3358.asp * SQL-DMO part 1: The SQL-DMO API This is the first part of a serie of articles about the SQL Distributed Management Objects known as SQL-DMO API. In this first article I'll talk about SQL-DMO, whats the purpose of it and what you'll gain if you use it. I will also show how to install it, so you can use it within our Delphi projects http://www.delphi3000.com/articles/article_3359.asp * Multi Column ListBox with Column Sorting and Resizing This is a VCL that allows multiple columns in a list box. The columns may be sorted (if the AllowSorting property is set to true) by clicking on the column header title. The column headers are set up in the Sections property. They are of type THeaderSections from the THeader component and thus may also display images from an associated image list. The items in the ListBox are semi-colon delimited fields. The fields are lined up in accordance to the Section headers and may be resized by the user at run-time. http://www.delphi3000.com/articles/article_3360.asp * Capture Output of a Console Application - Revised How do you start a DOS or Console Application and capture the output while it is running ? For example, how do you capture the output of the FileCompare (FC) Command ? http://www.delphi3000.com/articles/article_3361.asp * Retrieve Multiple Recordsets from ORACLE 8i Stored Procedure A faster and more resource efficient way to get data from the Database server (in this case - Oracle) http://www.delphi3000.com/articles/article_3363.asp Tutoriais ========= * Defining a ClientDataSet's Structure Using TFields - by Cary Jensen This article demonstrates how to define a ClientDataSet's structure at both design-time and runtime using TFields. How to create virtual and nested dataset fields is also demonstrated. http://community.borland.com/article/0,1410,29001,00.html * Understanding ClientDataSet Indexes - by Cary Jensen A ClientDataSet does not obtain its indexes from the data it loads. Indexes, if you want them, must be explicitly defined. This article shows you how to do this at design-time or runtime. http://community.borland.com/article/0,1410,29056,00.html * Improve application design with Prototyping, Modeling, + Storyboarding - by Ronald Anthony Lewis Meeting client expectations is the number-one goal of application development. Here's how one developer uses three approaches to handle different aspects of this critical objective. http://builder.com.com/article.jhtml?id=u00320020909RAL01.htm * An introduction to XML grammar - by Philip Page Document Type Definitions (DTDs) are an optional but useful part of XML. This article shows you how to declare a grammar in a DTD. http://builder.com.com/article.jhtml?id=u00320020906ppg01.htm * Unified Modeling Language simplifies software design - by Shelley Doll UML is the industry standard for modeling software architecture. It combines best practices, platform independence, and extensibility into a common language for describing solutions. This overview of UML describes why it's useful and outlines the major concepts. http://builder.com.com/article.jhtml?id=u00420020903dol01.htm * To be or not to be normal: That is the database question - Eric Roland There are advantages + disadvantages to normalizing database schemas. This article provides specific examples of when and why you should normalize or denormalize your final database design based on performance requirements. http://builder.com.com/article.jhtml?id=u00320020819ero01.htm * Transition from Logical to Physical Data Model - S Harkins + A Fuller Moving from a logical to physical design is not as straightforward as it appears. Use these tips to make the process as smooth as possible. http://builder.com.com/article.jhtml?id=u00320020826gcn01.htm Outros Links ============ * Delphi Fireworks Component Contest Basically, you have to make a self-contained Delphi visual component. There are no prizes, but you will receive awe and recognition from your peers, just for entering. Also it makes a great resume entry. http://chuckr.freeshell.org/index.php * ModelMaker is available for Delphi 7 Professional - by John Kaster Borland provides a license to ModelMaker for Delphi 7 Professional. http://community.borland.com/article/0,1410,29090,00.html * Borland to wield tools against Microsoft - by Wylie Wong After nearly being knocked out for good by Microsoft, software maker Borland is back on its feet and eager for a rematch. http://news.com.com/2100-1001-954958.html * Borland has a bead on Visual Studio - By Mark Driver (from Gartner) Borland plans to offer an alternative to Microsoft's Visual Studio .NET development environment. Such a product could suit application developers that want to leverage .NET and the best applications from many vendors. techupdate.zdnet.com/techupdate/stories/main/0,14179,2879601,00.html * Now all we need are celebrity endorsements - by Lamont Adams Humourous article about the possibility of celebrity endorsements in programming. Use the official IDE of the World Cup! http://builder.com.com/article.jhtml?id=u00220020904adm01.htm * SharpDevelop lets you jump into C# Programming for FREE! - Tony Patton You're dying to start programming in C#, but Visual Studio .NET is just too expensive. Help is on the way with this free .NET IDE. http://builder.com.com/article.jhtml?id=u00220020821ton01.htm ________________________________________________________________________ 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/p0039.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 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!






