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/dil/index.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/dil/index.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://linux.sys-con.com/read/32782.htm
________________________________________________________________________
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/
________________________________________________________________________
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://top100borland.com/in.php?who=20
________________________________________________________________________
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.indyproject.org
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 <eds2008 @ 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://tech.groups.yahoo.com/group/components/
Assinatura:
http://tech.groups.yahoo.com/group/components/join
components-subscribe@yahoogroups.com
* Desenvolvedores de Software (inglês): Esse é um fórum para discussões
sobre o desenvolvimento de software e para a troca de experiências de
trabalho em ambientes profissionais e comerciais. Esse não é um fórum
sobre programação; os assuntos abordados são mais gerais e
independentes de linguagem de programação.
http://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/kacdo30.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/clx/internet/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://articles.techrepublic.com.com/5100-10878_11-1050841.html
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.cnet.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://articles.techrepublic.com.com/5100-10878_11-1050148.html
* 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://articles.techrepublic.com.com/5100-10878_11-1050213.html
________________________________________________________________________
VOCÊ PODE NOS AJUDAR
Nós precisamos de sua ajuda para manter esse boletim ativo e cada vez
maior. Você pode ajudar indicando o boletim a seus amigos e colegas:
http://www.latiumsoftware.com/br/pascal/index.php
Você também pode votar para nós em um ou todos esses rankings para dar
maior visibilidade a nosso site e assim aumentar o número de assinantes
do boletim:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
São alguns segundos para você que REALMENTE significam muito para nós.
Não esqueça que também precisamos de artigos para os boletins e que
existe um prêmio para um dos autores em cada número (em inglês).
Todos os artigos serão considerados mas nós estamos particularmente
interessados em artigos sobre Kylix já que existe pouco material
disponível online.
* Envie seu artigo em inglês para
pascal-newsletter-owner@yahoogroups.com
* Envie seu artigo em português para
boletim-pascal-owner@yahoogrupos.com.br
________________________________________________________________________
Se você não recebeu o código fonte completo dos exemplos neste número,
você pode obtê-los em http://www.latiumsoftware.com/br/pascal/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.
________________________________________________________________________
|