Revista The Club Megazine - 08/2003
A utilização, reprodução, apropriação, armazenamento em banco de dados,
sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais
em cada publicação da revista “The Club” são terminantemente proibidos
sem autorização escrita dos titulares dos direitos autorais.
Copyright© The Club® 2003
EDITORIAL
Editorial
THE CLUB
Av. Celso Ferreira da Silva, 190
Jd. Europa - Avaré - SP - CEP 18.707-150
Informações: (0xx14) 3732-3689
Suporte: (0xx14) 3733-1588 - Fax: (0xx14) 3732-0987
Internet
http://www.theclub.com.br
Cadastro: [email protected]
Suporte: [email protected]
Informações: [email protected]
Dúvidas
Correspondência ou fax com dúvidas devem ser
enviados ao - THE CLUB, indicando "Suporte".
Opinião
Se você quer dar a sua opinião sobre o clube em
geral, mande a sua correspondência para a seção
"Tire sua dúvida".
Reprodução
A utilização, reprodução, apropriação,
armazenamento em banco de dados, sob qualquer
forma ou meio, de textos, fotos e outras criações
intelectuais em cada publicação da Revista
“The Club” são terminantemente proibidos sem
autorização escrita dos titulares dos direitos
autorais.
Olá amigos, aqui estamos com mais uma edição da The Club Megazine, trazendo até
você informações que com certeza tornam o dia-a-dia do programador Delphi um pouco
mais fácil!
Começamos apresentando o mais recente lançamento da Borland, o C#Builder, que é
a primeira IDE da Borland para desenvolvimento de aplicações para a plataforma Microsoft
.Net e fizemos uma pequena análise da ferramenta, a qual nos deixou ainda mais anciosos
para a nova versão do Delphi que está por vir, vamos aguardar.
No mês passado, publicamos uma entrevista exclusiva com Jason Wharton, o criador
do IBObjects e neste mês estamos dando continuidade ao assunto, demonstrando como
instalar esta ótima suíte de componentes.
Um assunto que tem sido bastante solicitado ao suporte técnico, é referente a
relacionamentos master/detalhe no dbExpress, e mediante isso, estamos publicamos um
artigo completo a respeito deste assunto, procurando assim sanar todas ou pelo menos as
principais dúvidas que têm chegado até nós.
Nosso artigo de capa deste mês, com certeza irá resolver um problema comum entre
muitos programadores! Você acha complicado gerar instalações para distribuir sua
aplicação? Bem, neste artigo estamos apresentando a ferramenta Inno Setup, a qual é
muito poderosa, gratuíta e simples de utilizar. Através dela você poderá gerar instalações,
inclusive embutindo seu banco de dados, vale a pena conferir!
Como mencionei no início, temos muita coisa interessante este mês! Confira ainda um
artigo que mostra como controlar a ociosidade da aplicação, permitindo chamar uma tela
de login após o aplicativo ficar inativo por um certo tempo. Outro assunto que estamos
abordando, é a atualização de versão de aplicativos em rede, sendo este tema, também
muito solicitado aos nossos técnicos. E finalizando, não poderia faltar nossa consagrada
sessão Dicas & Truques, que dispensa comentários.
Bom leitura e até a próxima,
Copyright© The Club® 2003
Impressão e acabamento:
Celso Jefferson Paganelli
Presidente - The Club
Impressos Gril - Gril Gráfica e Repr. Ind. Ltda.
Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259
Rua São Paulo, 447 - Cep 18.740-000
Taquarituba - SP
Tiragem: 5.000 exemplares
Diretor - Presidente
Celso Jefferson M. Paganelli
Diretor Técnico
Mauro Sant’Anna
Delphi é marca registrada da Borland International, as
demais marcas citadas são registradas pelos seus
respectivos proprietários.
Editorial ............................................................................ 03
C#Builder - A primeira IDE da Borland para .NET ............... 04
Como instalar e utilizar o IBObjects ................................... 06
DBEXPRESS - Criando um relacionamento Master/Detalhe 11
Criando Instalações personalizadas com o Inno Setup ....... 16
TimeOut - Controlando a ociosidade da aplicação ............. 22
Criando aplicativos Auto-Atualizáveis ............................... 25
Dicas & Truques ................................................................. 28
MeGAZINE
3
NEWS
C# Builder
A primeira IDE da Borland para desenvolvimento .NET
Equipe de suporte do The Club - [email protected]
Recentemete a Borland lançou o C#Builder, sendo esta a sua
primeira IDE de desenvolvimento para a plataforma Microsoft
.Net.
Nós do The Club já estamos trabalhando com a plataforma
Microsoft .Net há um bom tempo, mais precisamente a partir do
final do ano 2000, utilizando o Microsoft Visual Studio .Net, com
enfoque na linguagem C#.
Estivemos analisando o C#Builder e achamos a IDE bastante
atrativa (não poderia ser diferente, visto essa característica ser
marca registrada das ferramentas Borland), o compilador
bastante rápido e sem contar nas semelhanças com a IDE do
Delphi, o que nos fez sentir-se em casa.
O C#Builder pode ser encontrado em quatro versões, sendo a
Personal, a Professional, a Enterprise e a Architect.
Nas versões Enterprise e Architect existem drivers nativos
para acesso aos principais bancos de dados do mercado, sendo
Oracle, SQLServer, DB2 e Interbase.
Um detalhe importante é que a versão Personal está
disponível gratuitamente para download no site da Borland,
desde que utilizada para fins não comerciais e é uma boa
alternativa para que está querendo apenas conhecer ou começar
a estudar C#/.Net. Para maiores informações acesse http://
www.borland.com/csharpbuilder/.
No C#Builder temos suporte ao desenvolvimento de
aplicações baseadas em WinForms (formulários windows,
semelhantes aos que trabalhamos atualmente no Delphi) e
WebForms/ASP.Net (na realidade, são páginas web, tratadas
como formulários), WebServices e criação de classes e controles
Conclusão
Podemos apenas ter certeza de que temos mais uma ótima
ferramenta para desenvolvimento .Net no mercado e ficamos
ainda mais anciosos aguardando a nova versão do Delphi com
IDE para .Net, o qual promete bastante!
Figura 1 – Menu do C#Builder
4
MeGAZINE
NEWS
Figura 2 – IDE C#Builder –
projeto WinForms.
Figura 3 – IDE
C#Builder –projeto
WebForm/Asp.Net
MeGAZINE
5
DELPHI
Como instalar e utilizar o
IBObjects
Por Claudinei Rodrigues – [email protected]
No mês passado eu publiquei a entrevista com o nosso amigo
Jason Wharton, falando um pouco sobre o IBObjects. Neste mês
vou continuar a falar deste componente e a melhor maneira é
mostrar a vocês como se instalar o componente. Não que sua
instalação seja complicada, mas nada melhor do que começar a
conhecer um componente, como fazendo a sua instalação. Eu sei
que isto pode ser maçante para alguns programadores mais
experientes, mas também existem programadores que estão
conhecendo o Delphi agora. Antes, porém, você pode fazer o
download deste componente a partir da página do The Club. Para
fazer o download é muito simples, acesse a nossa home page,
www.theclub.com.br, clique no ícone Área de download e depois no
ícone Pesquisar arquivos. No campo Digite a informação a ser pesquisada
informe IBObjects e depois no campo Selecione o filtro desejado
informe a versão do Delphi que você está utilizando. Agora clique
no botão Pesquisar, fazendo isto você terá acesso ao arquivo e basta
clicar sobre o seu nome e fazer o download. Caso você não queira
baixar o arquivo através da nossa página, você poderá acessar
diretamente a página do fabricante no endereço
www.IBObjects.com.
Como já foi dito na edição anterior desta revista, a licença
para utilização do IBObjects é Trustware. Isso significa que você
pode utilizar o componente sem precisar a principio pagar por ele.
Eu digo a principio porque o autor do componente diz que você
poderá pagar pelo componente a partir do momento que você
começar a ganhar algum dinheiro com o software que você
desenvolveu utilizando o IBObjects.
6
Instalando o IBObjects
O arquivo IBO4.zip contém quase uma instalação completa
do IBObjects versão 4, incluindo muitos componentes com código
fonte, pacotes com todas as versões e vários exemplos e também
códigos com boas contribuições que foram enviadas por membros
da comunidade IBO.
Além deste arquivo você tem um outro arquivo para cada
versão do Delphi, que lhe dará uma instalação completa sem
limite de tempo. Os arquivo estão nomeados como Dn_DCU.zip,
onde n é a versão do Delphi. Por exemplo, para o Delphi 7 o
arquivo é D7_DCU.zip.
Antes de instalar o componente você deve seguir alguns
passos:
1 – Desinstale qualquer versão do IBObjects anterior a esta
versão.
2 – Delete todos os arquivos .BPL do IBObjects desta versão
mais antiga.
3 – Delete o diretório onde você descompactou a versão mais
antiga do IBObjects.
Pronto, agora você já pode descompactar o arquivo .ZIP da
nova versão do IBObjects. Para facilitar a instalação é
recomendado que você crie um diretório chamado IBO4 a partir
da raiz do seu drive desejado. Aqui nós vamos criar no drive C.
Então ficará assim, C:\IBO4. Você deve também descompactar o
MeGAZINE
Delphi
outro arquivo baixado de acordo com a versão do seu Delphi e
copiar o seu conteúdo para o diretório C:\IBO4.
Ordem dos pacotes
Uma observação para os usuários do Delphi 7. Os arquivos
.DPK do Delphi 7 estão sem o sufixo _D7, por ser a versão mais
recente do Delphi. Os pacotes do Delphi 7 estão nomeados como
“IBO40*RT.dpk” e “IBO40*DT.dpk”.
Veja abaixo a lista de pacotes na ordem que eles foram
construídos. O “n” representa o numero da versão do seu Delphi,
exceto nos pacotes do Delphi 7.
Runtime packages:
*
*
*
*
*
*
*
IBO40CRT_Dn.dpk (Delphi 7 IBO40CRT.dpk)
IBO40TRT_Dn.dpk
IBO40VRT_Dn.dpk
IBO40FRT_Dn.dpk
IBO40XRT_Dn.dpk
IBO40WRT_Dn.dpk
IBO40WXRT_Dn.dpk
Design-time packages:
*
*
*
*
*
*
*
*
*
IBO40CDT_Dn.dpk (Delphi 7 IBO40CDT.dpk)
IBO40ADT_Dn.dpk
IBO40TDT_Dn.dpk
IBO40VDT_Dn.dpk
IBO40FDT_Dn.dpk
IBO40XDT_Dn.dpk
IBO40WDT_Dn.dpk
IBO40WXDT_Dn.dpk
IBO40EDT_Dn.dpk
definiu outro caminho, então os arquivos compilados serão
gerados neste caminho que você definiu.
Você deve informar ao Delphi onde estão localizados os
arquivos fontes e as bibliotecas do IBObjects. Para isto então, vá
até o menu do Delphi na opção Tools | Environment Options,
clique na pasta Library. Informe o diretório nos campos Library
Path e Browsing Path. Caso contrário você não conseguirá
compilar as suas aplicações utilizando o IBObjects.
Instalando no Delphi 3
1 – Feche todos os arquivos que estejam abertos na IDE do
Delphi.
2 – Abra cada arquivo .DPK. Para isto vá até o menu do
Delphi, clique em File | Open. Clique sobre o primeiro arquivo
mencionado na lista anterior e clique no botão Compile para
compilar o pacote e depois clique no botão Install para instalar o
componente.
Usando o arquivo .BPG
A partir da versão do Delphi 4 surgiram os arquivos .BPG
(Grupo de projeto) que são os arquivos IBO40_Dn.bpg ou
IBO40_Cn.bpg. O arquivo .BPG lhe auxilia a compilar todos os
pacotes de uma só vez.
1 - Vá até o menu do Delphi e clique em File | Open.
Selecione o arquivo IBO40_Dn.bpg. Lembrando sempre que você
deve substituir o n pela versão do seu Delphi, exceto para o Delphi
7.
2 – Volte ao menu do Delphi e clique em View | Project
Manager.
3 – Clique com o botão direito do mouse sobre qualquer
arquivo .BPL e selecione a opção Open.
Runtime and Design time packages:
4 – Agora volte ao menu do Delphi clique em Project | Build
All Projects. Isto fará com que todos os pacotes sejam
recompilados.
* IBO40RPL_Dn.dpk
* IBO40FTS_Dn.dpk
Não tente instalar nenhum pacote que não faça parte da
versão do seu Delphi.
Instalando os pacotes
No diretório onde você descompactou os arquivos você
encontrará alguns arquivos .BPG ( Grupo de projetos ) que
instalarão os pacotes compilados no diretório
$(DELPHI)\Projects\BPL\ a menos que você tenha definido
outro caminho de saída para os arquivos compilados. Se você
5 – Agora clique com botão direito do mouse em cada pacote
que termine com as letras DT e clique em Install.
6 – Agora faça o mesmo passo anterior para os arquivos que
terminam com as letras FTS e RPL. Não há necessidade de fazer
isto com os arquivos terminados com RT, pois estes arquivos
devem ser apenas compilados e isto nós já fizemos no passo 4.
MeGAZINE
Aviso importante aos usuários do Delphi 4.
Um erro pode ocorrer na etapa de instalação. Os arquivos
7
Delphi
.BPL podem não serem encontrados a menos que você informe o
caminho. Caso isto aconteça faça o seguinte:
1 – Vá até o menu do Delphi em Components | Install
Packages.
4 – Salve o arquivo. Agora você deverá encontrar o Service
Application Framework pronto para ser utilizado em suas
aplicações.
5 – Use como qualquer outro objeto que você cria no Delphi
usando File | New ....
2 – Para cada pacote faça o seguinte:
Pronto, agora o seu componente já está instalado.
2.a – Clique no botão Add
2.b – Vá até o arquivo onde estão os arquivos .BPL. (o
padrão é
$(DELPHI)\Projects\bpl) e selecione cada pacote
individualmente, (IBO4_*DT_D4.bpl).
Agora nós vamos ver algumas informações básicas sobre os
vários componentes incluídos no IBObjects. O objetivo agora é dar
uma introdução em algumas propriedades comuns e as
configurações necessárias para se utilizar este componente.
Estes passos deverão instalar o componente para você.
Componentes de Acesso a Dados
Mais uma dica para os usuários do Delphi 4.
Se você ainda estiver com problemas na instalação deste
componente no Delphi 4, tente copiar os arquivos .BPL para o
diretório de sistema do Windows, por exemplo
C:\Windows\System32.
Você pode instalar o Service Application Framework
(ibs_base.pas) no repositório do Delphi.
Para fazer isto, siga os passos:
1 – No diretório onde foi instalado o seu Delphi você
encontrará o subdiretório ..\Bin. Neste diretório você encontrará
o arquivo delphi32.dro. Abra este arquivo utilizando o NotePad.
2 – Vá até o final do arquivo e acrescente o seguinte:
[C:\IBO4\IBS_BASE] <- ou onde você instalou o arquivo
ibs_base.pas
Type=FormTemplate
Name=IB Service Base Module
Page=IB Objects
Icon=C:\IBO4\IB_SVCAPP.ICO // ou onde você instalou o
IBO
Description=Base module for IB/Firebird Service apps
Author=Jason Wharton
DefaultMainForm=0
DefaultNewForm=0
Ancestor=
3 – Agora volte ao inicio do arquivo e adicione uma entrada
para [Repository Pages]:
IB Objects=
Alguns conceitos básicos do IBObjects
Os componentes de acesso a dados do IBO trabalham mais ou
menos da mesma forma que os componentes básicos de acesso a
dados do Delphi. Tradicionalmente utilizasse um banco de dados,
um dataset e um datasource. No IBO é a mesma coisa. Porém,
com bancos SQL, como Interbase/FireBird existe também um
fator adicional que devemos considerar que são as Transações.
Antes toda a referência a transações ficava dentro do
componente TDatabase do BDE. Ele usa uma conexão e uma
transação envolvidas em uma única relação. Mas o InterBase/
FireBird não está limitado a apenas uma única transação por
conexão. Por causa do Interbase/Firebird ter a capacidade de ter
múltiplas transações simultâneas em cada conexão, o IBO foi
desenhado para implementar transações em um componente
separado. Desta forma, ele é capaz de ter um componente de
conexão e vários componentes de transação ligados a ele ao
mesmo tempo. Outra característica significante do Interbase/
Firebird é que ele suporta que uma única transação utilize mais
de um banco de dados. Portanto foi necessário projetar o IBO
para controlar o caso onde uma transação se referencia a
múltiplas conexões simultaneamente. Com o IBO você tira
proveito disto de uma maneira muito fácil, basta utilizar as
propriedades IB_Connection1 e IB_Connection2 do componente
TIB_Transaction. Se você tiver mais de três transações, será
necessário então utilizar o método AddConnection() para
adicionar quantas conexões forem necessárias.
Portanto, um dataset não referencia a apenas um database
com o IBO. Ele deve também fazer referência a uma transação.
Isto é que determina o contexto de dados que são lidos e escritos.
Tanto uma instrução quanto um dataset no IBO possuem as
propriedades Database e Transaction. Elas são IB_Connection e
IB_Transaction. O objetivo é tornar as coisas mais flexíveis.
Conexão Padrão
Se uma referência da conexão não for fornecida em uma
8
MeGAZINE
Delphi
instrução ou em um dataset então ele verificará com a sessão
default e verá se existe uma conexão default presente. Se existir
então alinha automaticamente a essa conexão. Isto é tipicamente
o primeiro componente da conexão criado na aplicação. Se existir
apenas uma única conexão para a aplicação inteira não é
necessário prestar muita atenção nisto visto que o IBO
automaticamente configura isto para você.
Transação Padrão
Se uma referência da transação não for fornecida em uma
instrução ou em um dataset então uma transação interna será
gerada automaticamente. Isto dá uma isolação que permite que
você veja o estado “Committed” da base de dados em todas as
vezes e o auto-commit será executado em todas as mudanças que
forem postadas. Desta forma, se você projetar uma aplicação sem
usar a camada de transação ela irá funcionar da mesma forma.
Os datasets se comportam como se não existisse o conceito de
transações.
Modo Normal
Uma instrução ou Query normalmente aponta suas
propriedades IB_Connection e IB_Transaction para os
componentes correspondentes. A propriedade IB_Connection pode
conectar a um componente TIB_Connection, TIB_Database,
TIBODatabase ou qualquer outra subclasse derivada deles. A
propriedade IB_Transaction conecta ao componente
TIB_Transaction ou qualquer outro de sua subclasse.
TIB_DataSource que funcionasse quase igual ao TDataSource.
Ele se referencia a um TIB_Dataset que poderia ser um
componente TIB_Cursor ou TIB_Query.
Se você quer saber o porque disto, é porque o IBO foi iniciado
muito tempo antes do Delphi 3 e da classe virtual TDataset
introduzida por ele. Portanto a única forma foi construir a
funcionalidade necessária para tirar todo o proveito do InterBase/
FireBird. Sendo assim foi escrita uma camada de acesso a dados
própria e também controles baseados nas APIs do InterBase e
nas classes TComponent, TWinControl, TCustomEdit, etc.
Classes TIBO* para compatibilidade com a VCL
Desde que o Delphi 3 introduziu a classe virtual TDataset, foi
necessário escrever os componentes TIBODatabase, TIBOTable,
TIBOQuery e TIBOStoredProc para se igualarem aos
componentes de acesso a dados padrões do Delphi e assim ter
compatibilidade para todos os controles padrões da VCL. Isso foi
possível escrevendo uma camada derivada de TDataset que faz a
ligação com uma instância interna do TIB_Query. Isto dá
habilidade ao IBO para ser usado com geradores de relatórios
como Report Printer Pro, Quick Report e outros.
Os controle que acompanham o IBO não são compatíveis com
os controles padrões da VCL. Para continuar a usar os controles
da VCL e controles de terceiros que são compatíveis com a VCL,
escolha os componentes de acesso a dados iniciados com TIBO* e
o TDataSource padrão do Delphi.
Emulando o BDE
As Classes TIB_*
O componente TIBODatabase foi projetado para fazer o que o
componente TDatabase do BDE faz. Ele combina a conexão com
uma transação interna e por default faz com que todas as
instruções e datasets a ele ligados compartilhem da mesma
transação. Ele ainda permite que você arraste para o seu form
um componente TIBOTransaction e configure-o se desejado. Isto
faz a emulação e ao mesmo tempo as transações adicionais
podem explicitamente ser introduzidas.
Obs: Os componentes TIB_Database e TIBODatabase
trabalham muito bem quando cached update é o seu principal
modo de operação.
Conectando controles Data-Aware
O IBO permite o mesmo tipo de conectividade a seus controles
visuais que a encontrada nos controles padrões do Delphi. Cada
controle terá uma propriedade DataSource e uma DataField, se
for o caso.
Por causa dos controles IBO não serem compatíveis aos
controles padrões do Delphi, foi necessário criar um componente
Os controles nativos do IBO podem ser usados apenas com
componentes de acesso a dados também nativos do IBO, como por
exemplo: TIB_DataSource, TIB_Cursor, TIB_Query e
TIB_StoredProc.
As Classes TIB_xxxxxSource
Os componentes StatementSource, ConnectionSource e
TransactionSource foram desenvolvidos com o propósito de fazer
os formulários ou outros controles cientes de instruções, conexões
ou transações específicadas, respectivamente. Você pode observar
esses componentes em funcionamento olhando os controles
TIB_StatementBar, TIB_ConnectionBar ou
TIB_TransactionBar.
Você pode desenvolver formulários sem dependência de
conexões ou transações. Em run-time você pode fazer uma
linkagem rápida a um contexto de transação e conexão
simplesmente se referenciando aos componentes
ConnectionSource e TransactionSource no formulário. Nos
eventos AfterAssignment você tem uma rotina que replica essa
referência a todos os datasets no formulário.
MeGAZINE
9
Delphi
Focando o Controle Global
Todos os controles de acesso a dados nativos do IBO são
coordenados com um outro componente de sessão, ao qual
pertencem. Uma rede de eventos fica monitorando
constantemente quem tem o foco atual, juntamente com qual
declaração SQL, Dataset, Datasource, Transação e Conexão que
estão ligados a ele. Isso permite os controles como as barras de
botões possam ficar escutando essa rede de eventos e esperando
por eventos que decidam qual o Dataset tem o foco no momento.
O mesmo acontece para Transações e Conexões.
Isso é possível configurando as propriedades AnnounceFocus
e AllowFocus do componente TIB_DataSource e a propriedade
ReceiveFocus de vários controles que podem ter foco. Os exemplos
disto são as várias barras com controles, como por exemplo, o
TIB_Navigator e a TIB_SearchBar.
Resumindo
aplicação. Por acessar os objetos IB_Connection e IB_Transaction
através das propriedades encontradas no TIBODataset, é possível
utilizar a mesma conexão e transação em aplicações híbridas.
Isso se torna especialmente útil quando você está fazendo uma
migração de um aplicativo baseado na BDE para um baseado em
controles nativos do IBO.
Finalizando
Você poderá encontrar diversos exemplos documentados no
subdiretório ..\Samples onde você instalou o seu componente que
mostram como utilizar os diversos componentes do IBObjetcs.
Todo o texto desta matéria foi traduzido e adaptado a partir
das informações disponíveis no site do fabricante,
www.ibobjects.com.
Sobre o autor
Sintam-se a vontade para fazer uma mistura de
componentes como por exemplo utilizar o TIBO* mais os controles
VCL e os TIB_* mais controles nativos do IBO na mesma
10
Claudinei Rodrigues, Consultor Técnico do The
Club - [email protected]
MeGAZINE
Delphi
por André Colavite – Suporte THE CLUB
[email protected]
Nesta matéria iremos indicar os passos para criar um
relacionamento Master/Detail com DBExpress usando o banco de
dados FireBird/Interbase.
DESCRICAO VARCHAR (20) CHARACTER SET WIN1252 COLLATE
PXW_INTL850, VALOR NUMERIC (18, 2));
ALTER TABLE DETALHE ADD CONSTRAINT PK_DETALHE
PRIMARY KEY (CODDETALHE);
Para montar o relacionamento Master/Detail primeiramente
iremos verificar a estrutura de nossas tabelas, criadas dentro do
banco GDB.
ALTER TABLE DETALHE ADD CONSTRAINT FK_DETALHE
FOREIGN KEY (CODMASTER) REFERENCES MASTER
(CODMASTER) ON DELETE CASCADE;
A tabela pai chamaremos de MASTER e será composta pela
seguinte estrutura:
CREATE TRIGGER AI_DETALHE_CODDETALHE FOR DETALHE
ACTIVE
BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.CODDETALHE IS NULL) THEN
NEW.CODDETALHE =
GEN_ID(DETALHE_CODDETALHE_GEN, 1);
END
CREATE TABLE MASTER (
CODMASTER INTEGER NOT NULL,
NOME VARCHAR (20) CHARACTER SET WIN1252 COLLATE
PXW_INTL850);
ALTER TABLE MASTER ADD CONSTRAINT PK_MASTER PRIMARY
KEY (CODMASTER);
CREATE TRIGGER AI_MASTER_CODMASTER FOR MASTER ACTIVE
BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.CODMASTER IS NULL) THEN
NEW.CODMASTER = GEN_ID(MASTER_CODMASTER_GEN, 1);
END
A tabela filha chamaremos de DETALHE e será composta
pela seguinte estrutura:
CREATE TABLE DETALHE (
CODDETALHE INTEGER NOT NULL,
CODMASTER INTEGER,
Conhecendo a estrutura das tabelas podemos começar a criar
o projeto com o
relacionamento, e para isso Dica importante:
começaremos pela
A definição do nome dos campos
visualização da tabela
idênticos nas duas tabelas foi
Master.
Visualizando os
registros da tabela
Master
Primeiramente vamos
criar um novo projeto,
contendo um form e um
MeGAZINE
11
feito para que possamos utilizar
um recurso do DBExpress ao qual
no momento da inclusão do
registro Detalhe o código da
tabela Master será enviado
automaticamente para o campo da
tabela Detalhe, e o DBExpress
envia para o campo que tenha o
mesmo nome.
Delphi
Veja que na instrução de SELECT coloquei uma cláusula de
WHERE com um parâmetro ao qual será utilizada para fazer o
relacionamento com a tabela Master, sendo assim esse parâmetro
deve ter o mesmo nome do campo da tabela
Dica importante:
Master.
datamodule e neste datamodule colocaremos o componente
SQLConnection. Neste componente faça a conexão normal ao
banco de dados FireBird/Interbase.
Coloque um novo componente do tipo
SQLDataSet e na sua propriedade Name
especifique o nome SQLMaster, logo em
seguida ligue-o com o componente
SQLConnection através da sua propriedade
SQLConnection.
Na propriedade CommandText deste
componente SQLMaster iremos especificar
a instrução de SELECT que permitirá
visualizar os dados da tabela Master. Veja a
instrução de SELECT que usaremos:
SELECT * FROM MASTER
Evite usar um Select trazendo todos os
registros, pois quanto mais registros
você trouxer na visualização mais lento
ficará a abertura da tabela. Portanto
recomendamos que sempre utilize uma
clausula de Where para filtrar os dados
a serem visualizados, podendo até na
abertura do form fazer uma clausula de
where com o campo código IS NULL,
pois assim não irá visualizar registros,
deixando o processo bastante rápido.
O Select da tabela Master com essa
clausula de Where ficará da seguinte
forma:
SELECT * FROM MASTER
WHERE CODMASTER IS NULL
O próximo componente que iremos
colocar é o DataSetProvider, aba Data Access, com o nome
DataSetProvider1 ao qual será ligado ao componente SQLMaster
através de sua propriedade DataSet.
E para finalizar a visualização dos dados da tabela Master
iremos colocar o componente ClientDataSet, aba Data Access, ao
qual ligaremos ao DataSetProvider1 através da sua propriedade
ProviderName. A esse ClientDataSet daremos o nome de
CDSMaster.
Pronto, até aqui criamos uma
visualização de dados simples usando o
DBExpress, a partir desse momento
começaremos a criar o relacionamento
Master/Detail e agora mudará um pouco a
forma de trabalhar.
Visualizando os registros da
tabela Detalhe
Em seguida temos que ligar esse
SQLDetalhe ao SQLMaster e faremos isso
através da propriedade DataSource do
componente SQLDetalhe, portanto temos que
colocar no datamodule um componente
DataSource, ao qual daremos o nome de
DSMaster, e em sua propriedade DataSet
ligaremos o componente SQLMaster. Agora
podemos indicar na propriedade DataSource
do componente SQLDetalhe o componente
DSMaster que acabamos de configurar.
Um fato importante na visualização dos
dados da tabela Detalhe é que não usaremos
um novo componente DataSetProvider, pois os dados serão
controlados diretamente pelo provider da tabela Master. Sendo
assim voltaremos o foco para os componentes SQLMaster e
CDSMaster para preparar essa visualização dos dados da
Detalhe.
Mais adiante explicaremos com detalhes a utilização da
propriedade ProviderFlags.
Neste componente SQLMaster iremos criar a lista de tFields,
para isso dê duplo click sobre o componente, onde será aberta
uma lista em branco, pressione o botão direito
do mouse sobre essa lista e selecione a opção
Dica importante:
Add All fields. Faça o mesmo para o
Adicionamos os TFields no SQLMaster
componente CDSMaster
pois quando o Provider montar a
instrução de Insert, Update ou Delete,
a ser enviada ao banco de dados, ele
pega as configurações dos TFields do
SQLDataSet para saber quais campos
serão usados na instrução. E assim
podemos controlar a criação dessas
instruções através da propriedade
ProviderFlags de cada tField.
Mais adiante explicaremos com
detalhes a utilização da propriedade
ProviderFlags.
Para visualizar os dados do Detalhe
usaremos um novo componente
SQLDataSet e daremos o nome de
SQLDetalhe, A esse componente ligaremos o
componente SQLConnection1 através da
sua propriedade SQLConnection. Em sua propriedade
CommandText coloque a instrução de Select para visualizar os
dados da tabela Detalhe, ficando a instrução da seguinte forma:
SELECT * FROM DETALHE WHERE DETALHE.CODMASTER =
:CODMASTER
12
Ao adicionar os TFields no CDSMaster
podemos verificar que foi criado o campo do
tipo DataSetField, com o nome SQLDetalhe.
Esse campo irá trazer as informações da
tabela Detalhe, por esse motivo que não
utilizaremos um componente
DataSetProvider para a tabela DETALHE.
Em seguida colocaremos um componente
do tipo ClientDataSet para visualizar os dados do Detalhe e em
sua propriedade Name coloque o nome CDSDetalhe.
Como não utilizaremos um DataSetProvider para a Detalhe
então a ligação do CDSDetalhe será feita através da sua
propriedade DataSetField, ao qual selecionaremos o tField
SQLDetalhe, criado no CDSMaster. O nome apresentado na
MeGAZINE
Delphi
ligação da propriedade DataSetField deve ser parecido com
CDSMasterSQLDetalhe.
Reconcile Error Dialog, conforme figura 2, e em seguida
pressione Ok.
No próximo passo devemos adicionar os Tfields nos
componentes SQLDetalhe e CDSDetalhe, sendo assim dê duplo
click sobre o componente SQLDetalhe, pressione o botão direito do
mouse sobre a lista e selecione a opção Add All fields. Faça o
mesmo para o componente CDSDetalhe.
Agora, dentro do evento onReconcileError do CDSMaster
escreva a instrução, conforme o exemplo a seguir:
procedure TDM.CDSMasterReconcileError(DataSet:
TCustomClientDataSet;
E: EReconcileError; UpdateKind: TUpdateKind;
var Action: TReconcileAction);
begin
Action := HandleReconcileError(DataSet,
UpdateKind, E);
end;
Para finalizar as instruções do DataModule, criaremos o
evento onReconcilieError do CDSMaster pois através deste
evento iremos tratar os erros gerados no banco de dados durante
a atualização dos dados. Para tratarmos este erro iremos utilizar
um form padrão do Delphi e para criá-lo faça os seguintes passos:
No menu do Delphi selecione a opção File / New depois a opção
Other, onde será aberto o form New Items do Delphi. Neste form
selecione a aba Dialogs e dentro dessa aba selecione a opção
Em outra ocasião explicaremos com detalhes o tratamento de
erro utilizado com o ClientDataSet.
Pronto, neste momento já estamos com o
relacionamento Master/Detail concluido, basta agora
visualizar os registros no form, e para isso
colocaremos dois componentes Datasources,
DataSource1 e DataSource2 e ligaremos esses dois
componentes aos ClientDataSets, CDSMaster e
CDSDetalhe respectivamente.
O DataModule ao final das configurações dos
componentes ficará conforme a figura 1.
Criando o Form para apresentação dos dados
Esta parte do projeto é bastante simples, basta
criarmos o forms para visualizar os dados e para isso
colocaremos os DBEdits para visualizar os campos da
tabela Master e um DBGrid para visualizar os
registros da tabela Detalhe. Não se esqueça de colocar
o DBNavigator para controlar os registros tanto da
tabela Master quando da Detalhe.
Figura 2: Criando o form ReconcileErrorForm no projeto
Como último detalhe do form, colocaremos um
componente Button ao qual será utilizado para
executar a instrução de ApllyUpdates do
ClientDataSet, pois como já sabemos toda atualização
de dados realizada no ClientDataSet ficam em sua
memória e somente será enviada ao banco de dados
após executarmos o método ApplyUpdates. No evento
onclick do Button colocaremos a instrução do
ApplyUpdates com o parametro 0, pois assim
qualquer erro ocorrido todo o processo será cancelado
e nenhum registro será gravado no banco. Veja o
Figura 1: DataModule
MeGAZINE
13
Delphi
exemplo a seguir:
procedure TForm1.Btn_GravaClick(Sender: TObject);
begin
DM.CDSMaster.ApplyUpdates(0);
end;
Em outra oportunidade explicaremos melhor a utilização do
ApplyUpdates.
DataSetProvider. Pois essas duas propriedades em conjunto
fornecem informações ao Provider para a geração das instruções
de Insert, Update e Delete a serem enviadas para o banco de
dados.
Essas instruções são geradas automaticamente no momento
que executarmos a instrução de ApplyUpdates no ClientDataSet.
A propriedade ProviderFlags contém os valores pfInUpdate,
pfInWhere, pfInKey e pfHidden.
A propriedade UpdateMode indica a forma
como serão pesquisados os registros no momento
da atualização dos dados e contêm os valores
upWhereAll, upWhereChanged e
upWhereKeyOnly.
A seguir iremos verificar como utilizar os
valores dessas duas propriedades, ProviderFlags
e UpdateMode:
pfInUpdate : Indica se o campo poderá
enviar valores para o banco de dados, através do
Insert e Update;
pfInWhere : Indica se o campo será utilizado
na cláusula Where para encontrar o registro
que está sendo atualizado, isso quando o
UpdateMode estiver com o valor upWhereAll ou
upWhereChanged.
Figura 3: Form de visualização dos dados da tabela Master e da
tabela Detalhe
Controlando a atualização dos dados no
DBExpress
pfInKey : Indica que o campo é um campo
chave primária e será utilizado para encontrar o registro que
está sendo atualizado, isso quando o UpdateMode estiver com o
valor upWhereKeyOnly.
pfHidden : Indica que a coluna será utilizada somente para a
localização dos registros.
Essas configurações que iremos realizar agora são muito
importantes, pois serão utilizadas em qualquer situação com o
DBExpress, tanto numa conexão a uma simples tabela quanto
para a utilização num relacionamento Master/Detail.
A configuração que normalmente utilizo é com a propriedade
UpdateMode igual a upWhereKeyOnly, e como o ProviderFlags é
configurado em cada tField a seguir vou especificar como ficarão
todos os campos do projeto de exemplo.
Através dessas configurações iremos controlar quais campos
serão atualizados dentro do Delphi e quais campos serão
indicados na cláusula Where das instruções de Update e Delete
enviadas para o banco de dados.
Componente SQLMaster:
Campo CODMASTER - deixe como True somente o pfInKey
Campo NOME - deixe como True somente o pfInUpdate
A nossa configuração será feita na propriedade ProviderFlags
de cada tField do SQLDataSet e na propriedade UpdateMode do
Componente SQLDetalhe:
Campo CODDETALHE - deixe como True somente o valor
14
MeGAZINE
Delphi
pode ser gravado em branco, mas esse campo é incremental e seu
valor é gerado pelo Generator através de uma Trigger.
Sendo assim não permitiremos que o usuário digite qualquer
valor neste campo CODMASTER.
Portanto a solução para resolver este pequeno detalhe é abrir
a lista de Tfields dos componentes SQLMaster e CDSMaster,
selecionar o campo CODMASTER e configurar a sua propriedade
Required com o valor FALSE, para que assim não seja
obrigatório o seu preenchimento.
Esse mesmo detalhe deverá ser observado para o campo
CODDETALHE da tabela Detalhe e sua solução também é a
mesma, mas deverá ser feita nos componentes SQLDetalhe e
CDSDetalhe.
Conclusão
Neste artigo podemos observar os passos para montar um
relacionamente Master/Detail com o DBExpress bem como
configurar a propriedade ProviderFlags de cada campo.
Figura 4: Configurando ProviderFlags do SQLMaster
pfInKey
Campo CODMASTER - deixe como True somente o valor
pfInUpdate
Campo DESCRICAO - deixe como True somente o valor
pfInUpdate
Campo VALOR - deixe como True somente o valor
pfInUpdate
Espero ter lhes ajudado e caso tenham alguma dúvida sobre
a matéria ou sugestão sobre outras matérias a serem publicadas
favor enviá-las ao suporte THE CLUB. Um grande abraço a
todos.
O projeto de exemplo referente a essa matéria está disponível
em nosso site:
http://www.theclub.com.br/revista/download/
DBXMasterDetail.zip
Veja na Figura 4 a configuração do ProviderFlags do
SQLMaster.
Dica importante:
O ProviderFlags dos tFields serão
configurados somente no componente
SQLDataSet (SQLMaster e
SQLDetalhe), pois o Provider busca
informações somente desses tFields.
O ProviderFlags existente nos tFields
do ClientDataSet não são utilizados
pelo Provider.
Com essas configurações as instruções de Update e Delete
geradas pelo Provider conterão em sua cláusula WHERE
somente o campo indicado como chave primária, isso é, o campo
CODMASTER para a tabela Master e CODDETALHE para a
tabela Detalhe. E os demais campos somente mandarão os
valores para o banco de dados.
Uma última configuração nos tFields do projeto
Se executarmos o projeto agora ele irá funcionar
corretamente, mas ao incluir um registro apresentará uma
mensagem de que o campo CODMASTER é obrigatório e não
MeGAZINE
Sobre o autor
André Colavite, Consultor Técnico do The Club [email protected]
15
Delphi
Criando Instalações
Personalizadas com Inno Setup
Instalando sua aplicação com o banco de dados embutido
por Alessandro Ferreira, [email protected]
Introdução
A distribuição de aplicações é uma tarefa as vezes não muito
simples devido a complexidade e falta de versatilidade de muitas
ferramentas existentes no mercado. Porém, estamos aqui para
apresentar-lhes uma ferramenta muito legal para criar
instalações personalizadas e contanto ainda com uma grande
vantagem entre as demais: “É gratuíta!”.
Estou falando do Inno Setup, que foi desenvolvido por Jordan
Russel e está disponível para download em www.innosetup.com,
onde atualmente está na versão 4.0.5 beta, porém, neste artigo
utilizamos a versão 3.0.6.
no decorrer deste aplicativo, onde iremos demonstrar a instalação
de uma aplicação desenvolvida em Delphi, acessando banco de
dados Firebird via dbExpress.
Criando nossa primeira instalação
Bom, estando com o Inno Setup previamente instalado,
vamos criar nossa primeira instalação.
Abra o Inno Setup e será apresentada uma tela semelhante a
Figura 1, na qual poderá selecionar um wizard para criar nossa
instalação.
Como funciona?
O Inno Setup é baseado em scripts com uma estrutura que
lembra arquivos INI, possuindo sessões e dentro das sessões
chaves que irão receber e fornecer valores para gerar a instação.
Veja um pequeno exemplo na Listagem 1:
[Files]
Source: C:\Projetos\SisMed.exe; DestDir: {app}\Exec;
Flags: confirmoverwrite
Source: C:\Projetos\DADOS\DEFAULT.DAT; DestDir:
{app}\Dados
Listagem 1
Tudo é feito com base em scripts como mostrado na Listagem 1.
Não pense que pela forma simples de trabalhar, o Inno Setup
deixe algo a desejar em relação aos demais instaladores, e sim,
muito pelo contrário! Você pode criar instalações para
praticamente qualquer aplicativo que desejar, como poderá ver
16
Figura 1 – Tela inicial do Inno Setup.
MeGAZINE
Delphi
Dando continuidade, você irá
deparar-se com uma tela
semelhante a Figura 2, na qual
deverá preencher as opções
apresentadas.
Neste primeiro exemplo,
estamos configurando as opções
para o NotePad, mas você poderá
adicionar informações do seu
aplicativo.
O próximo passo é informar
onde nosso aplicativo deverá ser
instalado, bastando aceitar a opção
sugerida “Program Files directory”,
que corresponde a pasta “Arquivos
de Programas”.
Em “Application directory
name” você poderá definir o nome
Figura 2 – Opções requisitadas pelo wizard.
da pasta (dentro de Arquivos de
Programas) que será criada para
disponibilizar os arquivos de sua
aplicação e ainda permitir ou não
ao usuário alterar estas
configurações, através da opção
“Allow user to change the application directory”, veja a Figura 3.
Após definido onde os arquivos
de nossa aplicação serão
disponibilizados, iremos selecionar
os arquivos que deverão ser
embutidos em nossa instalação,
como exemplo o EXE de nosso
aplicativo, as DLLs necessárias
para a distribuição do dbExpress,
nosso banco de dados, enfim, tudo
que for necessário para nosso
aplicativo rodar na máquina do
cliente, conforme mostrado na
Figura 4. (página seguinte)
Figura 3 – Configuração da pasta para instalação.
MeGAZINE
17
Delphi
Figura 4 – Arquivos necessários
Figura 7 – Configuração dos textos de licença.
Dica: Você pode definir os locais onde os arquivos deverão ser instalados,
bastando para isso clicar no botão “Edit” e configurar, como mostra a
Figura 5:
O próximo passo será a definição das configurações do atalho
para nosso aplicativo, onde podemos configurar algumas ações
que o usuário terá acesso, como exemplo, permitir criar ícone no
desktop, veja a Figura 6:
Figura 5 –
Configuração
de localização
de arquivos.
E finalizando, temos ainda a opção de adicionar arquivos de
licença (arquivos texto) contendo o texto que será apresentado ao
usuário no momento da instalação, bastando para isso selecionar
o arquivo no disco que o mesmo será embutido na instalação,
Figura 7.
Bem, agora bastará finalizar e salvar nosso projeto de
instalação e o resultado final deverá ser parecido com o exibido na
Listagem 2:
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING
; INNO SETUP SCRIPT FILES!
[Setup]
AppName=NotePad
AppVerName=NotePad XP
AppPublisher=Microsoft
AppPublisherURL=http://www.microsoft.com
AppSupportURL=http://www.microsoft.com
AppUpdatesURL=http://www.microsoft.com
DefaultDirName={pf}\NotePad
DefaultGroupName=NotePad
LicenseFile=C:\leiame.txt
InfoBeforeFile=C:\leiame.txt
InfoAfterFile=C:\leiame.txt
[Tasks]
Figura 6 – Configurações de atalho.
18
MeGAZINE
Delphi
a apresentada na Figura 8:
Name: “desktopicon”; Description: “Create a
&desktop icon”; GroupDescription:
“Additional icons:”
[Files]
Source: “C:\WINDOWS\system32\notepad.exe”;
DestDir: “{app}”; Flags: ignoreversion
Source: “C:\Program Files\Borland\
Delphi7\Bin\dbexpint.dll”;
DestDir: “{app}”; Flags: ignoreversion
Source: “C:\WINDOWS\system32\midas.dll”;
DestDir: “{sys}”; Flags: ignoreversion
; NOTE: Don’t use “Flags: ignoreversion”
; on any shared system files
[Icons]
Name: “{group}\NotePad”; Filename:
“{app}\notepad.exe”
Name: “{userdesktop}\NotePad”; Filename:
“{app}\notepad.exe”; Tasks: desktopicon
Figura 8 – script aberto via IsTool
[Run]
Filename: “{app}\notepad.exe”; Description: “Launch
NotePad”; Flags: nowait postinstall skipifsilent
Listagem 2 – Script gerado em nossa primeira instalação.
Para concluir a instalação, você deverá agora compilar o
script afim de gerar o arquivo de instalação “Setup.exe”, que
geralmente é gerado em uma sub-pasta \Output, dentro da
pasta onde você salvou o script. Pronto, agora você já poderá
testar a instalação, bastando executar o setup gerado.
Ferramentas adicionais
Como você pode observar, utilizando o wizard do Inno Setup,
é bastante simples criar uma instalação, porém, algumas
manutenções futuras talvez exijam que você altere diretamente o
script, o que para alguns usuários pode ser incômodo, além de ser
menos produtivo e intuitivo. Felizmente, alguém já pensou nisso
e criou uma ferramenta chamada IsTool, a qual tem a finalidade
de gerar scripts para o Inno Setup, porém, através de uma
interface gráfica bastante simples e intuitiva, o irá permite
aproveitar melhor todos os recursos que o Inno Setup oferece. A
IsTool, assim como o Inno Setup também é uma ferramenta
gratuíta e poderá ser encontrada em http://www.istool.org/ e um
detalhe interessante é que esta ferramenta permite a escolha do
idioma no momento da instalação, tendo suporte ao português.
Para testar a IsTool, você poderá abrir o script (.iss) que geramos
anteriormente via Inno Setup, e verá uma interface semelhante
Traduzindo a instalação
Como você pode ver, a instalação gerada é em inglês, porém,
isso é um incoveniente, visto a maioria dos usuários finais não
estarem habituados a trabalhar neste idioma. Contudo, você
poderá baixar um script traduzido para português no seguinte
endereço: http://www.jrsoftware.org/files/istrans/. Certifique-se de
baixar a versão correspondente a versão do Inno Setup que você
possui instalado em sua máquina. Após baixar o arquivo, para
traduzir o Inno Setup para português, coloque o arquivo baixado
na pasta do programa e renomeie-o para Default.isl (tomando o
cuidado de fazer um backup do original), e pronto, as instalações
serão geradas em português.
Embutindo o Firebird na instalação
Um grande problema quando trabalhamos como bancos de
dados Client/Server, é que necessitamos fazer a instalação e
configuração dos mesmos, o que em muitos casos exige deslocar
um profissional apenas para isso. Neste exemplo, vamos
demonstrar como embutir o Firebird 1.0.3 (www.ibphoenix.com)
juntamente com nosso aplicativo, fazendo a instalação, o registro
e a inicialização do mesmo na máquina do cliente... Abra o IsTool
e mãos a obra.
Primeiramente, crie um novo projeto de instalação e
salve o mesmo. Após isso, clique na opção “Options” no IsTool e
faça as configurações de nosso aplicativo exemplo, preenchendo
MeGAZINE
19
Delphi
as solicitações, semelhante ao que
já fizemos no início deste artigo.
Após isso, vamos para as
definições de pastas e arquivos
necessários para nosso aplicativo e
o Firebird serem instalados
corretamente, veja na Figura 9:
Figura 9 – Pastas para
a instalação da aplicação
e do Firebird.
Dica: Para criar pastas, apenas clique com o botão direito e
selecione “Criar Diretório”, veja a Figura 10:
Figura 10 – Opções.
Figura 11 - Arquivos
Crie as seguintes pastas (Listagem 3):
[Dirs]
Name: {app}\Exec
Name: {app}\Dados
Name: {pf}\Firebird\bin
Name: {pf}\Firebird\intl
Name: {pf}\Firebird\udf
Listagem 3 – Pastas.
Observe que existem constantes que identificam as pastas
padrões, tanto para a aplicação, quanto para as pastas do
Windows, sendo:
{app} = pasta padrão onde a aplicação será instalada
{pf} = program files ou arquivos de programas
Agora vamos selecionar os arquivos à serem instalados,
bastando para isso clicar com o botão direito e selecionar a opção
“Inserir Arquivos”. Confira os arquivos na Figura 11:
20
Observe que na coluna DestDir está configurado “onde” os
arquivos deverão ser instalados. No caso do Firebird, é
importante manter estes paths, visto existirem chaves no
registro do Windows que irá buscar estes arquivos.
Bem, após selecionar os arquivos, vamos criar o grupo e o
ícone de nosso aplicativo exemplo, para isso estando na sessão
“Ícones”, com o botão direito selecione “Novo ‘Item” e configure,
como mostra a Listagem 4:
Name: {group}\TheClub\Exemplo;
Filename: {app}\Exec\Exemplo.exe;
WorkingDir: {app};
MeGAZINE
Delphi
piler” ative a opção “Ativar Divisão”, com isso, serão gerados
arquivos de até 1.44MB, os quais poderão ser copiados para
disquetes.
IconFilename: {app}\Exec\Exemplo.exe;
Comment: Exemplo de Instalação.;
Flags: createonlyiffileexists runmaximized;
IconIndex: 0
Conclusão
Listagem 4 – Configuração do grupo e ícone.
Agora vamos para as configurações no registro do Windows,
sendo esta, uma configuração muito importante para que o
Firebird possa rodar após nossa instalação.
Teremos as seguintes entradas no registro do Windows,
Figura 12.
Com sabem, o Interbase/Firebird utiliza como porta padrão
de comunicação, a porta 3050 e após finalizamos a instalação
temos que setar esta configuração no arquivo SERVICES (do
Windows), registrar a instalação e inicializar o Firebird. Para
isso, na sessão “Executar na instalação” defina as configurações
apresentadas na Figura 13
Existem outras configurações que podem ser feitas, como por
exemplo, criar grupos de instalação “Completa”, “Personalizada”,
“Mínima”, etc, contudo não iremos nos aprofundar nestes tópicos,
pois nosso intuito neste artigo é apenas o de apresentar a
ferramenta e mostrar do que ela é capaz, mas volto afirmar,
apesar de sua aparência simples, é uma poderosa aliada na
distribuição e atualização de aplicativos, bastando explorar sua
criatividade e necessidades.
Até a próxima...
Downloads
Os exemplos utilizados neste artigo estão disponíveis para
download no endereço:
Nossa instalação está pronta! Agora, apenas clique no botão
“Compilar” e se tudo estiver configurado corretamente, seu
“Setup”sera gerado e bastará você testar nossa instalação.
http://www.theclub.com.br/revista/download/innoexemplos.zip
Para saber mais
Escolha da mídia para distribuição
Você pode observar nos dois exemplos acima, que não nos
preocupamos com o tamanho final da instalação, visto hoje ser
muito comum a distribuição de aplicativos em CDs, pelo seu
baixo custo, tamanho e facilidade de distribuição.
Contudo, caso seja necessário distribuir o aplicativo em
disquetes de 1.44MB, acesse o botão “Options” e na aba “Com-
No site do fabricante você poderá encontrar
informações e ferramentas adicionais para o Inno
Setup, http://www.jrsoftware.org/is3rdparty.php.
No endereço http://ibinstall.defined.net poderão
ser encontrados scripts e informações sobre a
instalação do Interbase e Firebird.
Figura 12 – Chaves no registro do Windows.
Sobre o autor
Alessandro Ferreira, Consultor
Técnico do The Club [email protected]
Figura 13 – Executar após instalação
MeGAZINE
21
Delphi
TimeOut
Controlando a ociosidade da aplicação.
por Alessandro Ferreira, [email protected]
Introdução
Em nossa aplicação, iremos estar verificando as seguintes
mensagens:
Uma funcionalidade bastante interessante no Windows e
mesmo em alguns aplicativos que conheço, é a possibilidade de
tratar a ociosidade do sistema, ou seja, verificar se o aplicativo
não está sendo utilizando e assim, fechá-lo ou solicitar ao usuário
que efetue o login novamente, questão esta até mesmo de
segurança, pois um usuário pode logar-se na aplicação, sair para
tomar um café ou visitar um cliente e por esquecimento não
efetuar um logoff na aplicação, deixando-o assim aberto para
qualquer pessoa ter acesso ao sistema através do usuário logado
atualmente. Mediante isso, neste pequeno artigo iremos
demonstrar como implementar um controle simples e eficaz,
mãos a obra.
Como identificar ociosidade?
Mensagem do Windows
Finalidade
WM_MOUSEMOVE
Qualquer movimentação do
mouse na aplicação.
WM_KEYDOWN
Qualquer tecla pressionada
em nossa aplicação.
WM_LBUTTONDOWN
Click do botão esquerdo do
mouse em nossa aplicação.
WM_RBUTTONDOWN
Click do botão direito do
mouse em nossa aplicação.
WM_SYSKEYDOWN
Como sabem, praticamente tudo no Windows gera
mensagens que podemos facilmente capturar e tratar de acordo
com nossas necessidades. Um simples movimento ou clique do
mouse, uma tecla pressionada, enfim, qualquer execução dispara
diversas mensagens indicando o evento realizado, o que pode ser
tratado de forma bastante simples em nossa aplicação. Caso
tenha curiosidade, abra a unit Windows, e encontrará diversas
constantes declaradas com o prefixo “WM_” que significa
“Windows Message”, que nada mais são do que uma nomeação
para facilitar nosso trabalhado, como exemplo a constante
“WM_MOUSEMOVE”, que indica uma mensagem de movimento
do mouse.
22
Qualquer tecla de sistema
(Windows) pressionada em
nossa aplicação.
Figura 1 – Mensagens do Windows.
No objeto TApplication temos um evento chamado OnMessage o
qual iremos utilizar para fazer o tratamento das mensagens
apresentadas na Figura 1. Vamos iniciar nossa implementação.
Na sessão private do formulário, faça as seguintes declarações:
type
TMainForm = class(TForm)
private
MeGAZINE
Delphi
ligação da mesma ao evento OnMessage.
{ Private declarations }
T: integer;
procedure Mensagem(var Msg: TMsg;
var Handled: Boolean);
public
{ Public declarations }
End;
Observe que o código da procedure Mensagem é bastante
simples, onde basicamente, enquanto houver “operação” no
sistema, vamos atualizando a variável T com o tempo de execução
que o aplicativo está sendo “operado” pelo usuário. Se por algum
motivo, o sistema ficar inativo, esta variável ficará desatualizada,
e se o valor da variável, subtraído do tempo atual de “operação”
for maior que o tempo definido como TimeOut (na constante
cTimeOut, declarada na Listagem 1), iremos chamar o formulário
de login, para que o usuário entre novamente com sua senha,
isso caso o formulário de login não esteja em evidência. Em
seguida, ligamos nossa procedure ao evento OnMessage do objeto
TApplication no evento OnCreate de nosso formulário.
const
cTimeOut = 5000;
// Tempo para acionar a tela de senha.
cChamaSenha: Boolean = True;
// ativação do Form de senha.
Listagem 1 – Declaração da procedure, constantes e variáveis
de controle.
Declaramos uma váriavel chamada T que irá ser utilizando
para guardar o tempo de execução da aplicação. Após declarar a
procedure Mensagem, tecle Ctrl+Shift+C, com isso a
Delphi irá criar a procedure, onde iremos fazer
as implementações mostradas na Listagem 2:
procedure TMainForm.Mensagem
(var Msg: TMsg; var Handled:
Boolean);
begin
if (Msg.message = WM_MOUSEMOVE) or
(Msg.message = WM_KEYDOWN) or
(Msg.message = WM_LBUTTONDOWN) or
(Msg.message = WM_RBUTTONDOWN) or
(Msg.message = WM_SYSKEYDOWN)
then
begin
T := GetTickCount;
end;
Bem, antes de continuar nossas implementações no
formulário principal, vamos criar um simples form para solicitar
a senha ao usuário. Para isso, vá o menu File | New | Other |
Dialogs e selecione “Password Dialog”, como mostra a Figura 2:
Figura 2 – Criação do formulário de senha.
if ((GetTickCount - T) > cTimeOut) and
(PasswordDlg=Nil) then
begin
cChamaSenha := True;
Activate;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
Application.OnMessage := Mensagem;
end;
Com isso, será criado um formulário semelhante ao que
pode ser visto na Figura 3:
Listagem 2 – Implementação da procedure Mensagem e
MeGAZINE
Figura 3 – Formulário de senha
23
Delphi
Neste exemplo, não estamos nos preocupando em fazer
tratamento da senha digitada, pois neste artigo nosso foco
principal é o controle de ociosidade da aplicação.
um componente TTimer (palheta System), no qual
obrigatoriamente teremos que ativar seu evento OnTimer, mesmo
que sem nenhuma programação, veja a Listagem 4:
Caso deseje mais detalhes sobre implementação de controle de
acesso de usuários na aplicação, poderá consultar o artigo “Acesso:
Identificando e controlando usuários no sistema” em nossa revista de
Junho/2003.
Bem, vamos voltar às nossas implementações no formulário
principal, partindo agora para o evento OnActivate do mesmo,
inserindo o código demonstrado na Listagem 3:
procedure TMainForm.FormActivate(Sender: TObject);
begin
T := GetTickCount;
if cChamaSenha then
begin
PasswordDlg := tPasswordDlg.Create(Self);
PasswordDlg.ShowModal;
FreeAndNil(PasswordDlg);
cChamaSenha := False;
end;
end;
Listagem 4 – Evento OnTimer do componente Timer.
Neste exemplo, configuramos a constante cTimeOut
com 5000, que correspondem a cinco segundos.
Compile e execute esta aplicação de exemplo, digite um valor
qualquer no formulário de login, tecle OK e deixe a aplicação
ociosa (sem mexer no mouse e teclado) que dentro de cinco
segundos o login será solicitado novamente!
Conclusão
Vimos neste pequeno artigo um artifício bastante
interessante que será mais um diferencial em sua aplicação.
Pequenas implementações como estas, vão dando um toque
ainda mais profissional ao seu produto e com sua criatividade
poderão ser utilizadas para outras finalidade, como exemplo,
fechar a aplicação após algum tempo de ociosidade.
Listagem 3 – Implementação do evento OnActivate do
formulário principal.
Neste evento, estamos utilizando a API GetTickCount que
retorna o tempo decorrido de execução do Windows, o qual
guardamos na variável T.
Caso tenha alguma sugestão ou comentário, sinta-se a
vontade em nos enviar.
Após isso, se a constante cChamaSenha estiver com valor
igual a True, iremos fazer a chamada do formulário de login, e
atribuir False para a constante.
Estamos trabalhando com esta constante, devido ao fato do
evento OnActivate ser acionado toda vez que o referido formulário
recebe foco (A partir do Delphi 6, para que seja possível atribuir valores à uma
constante, será necessário habilitar esta opção declarando a seguinte constante
{$J+}).
Lembre-se de declarar a unit referente ao formulário de
senha na lista de uses do formulário principal.
Forte abraço, e até a próxima.
Download
O projeto de exemplo referente este artigo está disponível em:
www.theclub.com.br/revista/download/TimeOutLogin.zip
Sobre o autor
Um detalhe bastante importante, é que iremos necessitar de
24
procedure TMainForm.tmrControleTimer(Sender:
TObject);
begin
// Evento OnTimer do nosso componente Timer.
end;
Alessandro Ferreira, Consultor Técnico do The
Club - [email protected]
MeGAZINE
Delphi
Criando Aplicativos
Auto-Atualizáveis
Aprenda a criar um EXE para verificação de versão na rede
por Alessandro Ferreira ([email protected])
Introdução
É muito comum os desenvolvedores
disponibilizarem uma cópia de seu aplicativo
(EXE) em cada estação da rede para vários
motivos, como por exemplo, evitar a elevação do
tráfego em rede no momento da carga da
aplicação. Isso é interessante, contudo, pode
trazer alguns efeitos colaterais, sendo o mais
grave, ter versões diferentes do mesmo
aplicativo rodando na rede.
Temos recebido diversas solicitações de nossos associados
buscando uma solução para este problema, e, pensando nisso
estamos publicando este artigo, o qual esperamos que venha a
atender ou pelo servir como parâmetro para resolver este
problema!
Figura 1 – Formulário Principal do Projeto Atualiza.
Agora, crie o evento OnShow para este Form, pois é neste
evento que iremos concentrar nossa programação, conforme
poderá conferir na Listagem 1:
A Lógica
Em nosso exemplo, iremos criar duas aplicações, sendo a
primeira, um aplicativo que iremos chamar de “Atualiza” que
recebe dois parâmetros, sendo o caminho da atualização
(geralmente no Servidor) e o caminho local do aplicativo (EXE na
estação). A segundo projeto, será a aplicação propriamente dita, a
qual em sua inicialização irá comparar sua data com a data do
arquivo no servidor e caso seja inferior, irá executar a
atualização.
O projeto “Atualiza”
Este projeto é bastante simples, porém muito importante e
poderá ser utilizado para atualizar um ou várias aplicações,
devido ao fato dele não fazer referência direta as EXEs que
deverão ser autualizados. Bom, chega de papo e mãos a obra.
Abra o Delphi, e crie um novo projeto e salve-o como “Atualiza”.
Poderá ajustar o Form principal como mostra a Figura1:
MeGAZINE
procedure TMainForm.FormShow(Sender: TObject);
var
Origem, Destino: string;
begin
(* Verifica passagem de parâmetros... *)
if ParamCount < 2 then
Exception.Create
(‘Erro na passagem de parâmetros, verifique!’);
(* Pega valores dos parâmetros *)
Origem := ParamStr(1);
Destino := ParamStr(2);
(* Check dos arquivos *)
if not FileExists(Origem) then
Exception.Create
(‘Arquivo de origem não existe!’);
if not FileExists(Destino) then
25
Delphi
efetuamos a chamada do novo EXE (aplicativo já atualizado) e
para finalizar, iremos fechar o “Atualiza”.
Exception.Create(‘Arquivo de destino não
existe!’);
(* Copia novo EXE para a pasta do aplicativo *)
CopyFile(PChar(Origem), PChar(Destino), False);
(* Chama aplicativo já com o novo EXE *)
WinExec(PChar(Destino), sw_ShowNormal);
(* Fecha este aplicativo *)
PostMessage(Handle, wm_Quit, 0, 0);
end;
Aplicação Exemplo
Agora, vamos criar uma aplicação de exemplo que iremos
chamar de “auto-atualizável”, bastante simples, porém funcional,
onde você poderá entender como a verificação e atualização irão
acontecer. Mãos a obra! Crie um novo projeto, e como sugestão de
tela, veja a Figura 2.
Salve o projeto e acesse o código fonte do projeto (para isso, vá
ao menu Project | View Source), pois é diretamente neste
arquivo de projeto que iremos codificar nossa lógica de
atualização. Primeiramente, declare as seguintes Units na sessão
Uses, como poderá visualizar na Listagem 3.
Listagem 2 – Evento OnShow do projeto Atualiza.
Bem, este é todo o código que iremos necessitar neste projeto.
Como pode observar, primeiramente verificamos a quantidade
de parâmetros recebidos pela aplicação e se estiverem dentro do
número esperado, capturamos os parâmetros para duas
variáveis, como apresentado no Quadro 1
Quadro 1 – Parâmetros do aplicativo Atualiza.
Depois verificamos se ambos os arquivos informados
existem e caso positivo, iremos efetuar a atualização (cópia do
arquivo do Servidor para a Estação). Após efetuada a cópia,
program TheClub;
uses
Dialogs,
Windows,
SysUtils,
IniFiles,
Forms,
unPrincipal in ‘unPrincipal.pas’ {Form1};
{$R *.res}
(* Variáveis para Controle da Atualização *)
var
PathUpdate, Command: String;
TSI: TStartupInfo;
TPI: TProcessInformation;
Ini: TIniFile;
Listagem 3 – Units e variáveis no
projeto.
Continuando, você irá
perceber que verificamos o
caminho da atualização em
um arquivo INI (que
chamamos de version.ini) que
deverá estar junto como o
EXE (na estação), o qual tem
a seguinte estrutura:
[ATUALIZACAO]
PATH=\\Servidor\Atualizacoes\
THECLUB.EXE
Figura 2 – Formulário principal do projeto Auto-Atualizável
26
Na Listagem 4 estamos
apresentando o código restante de nosso projeto.
MeGAZINE
Ori
De
Delphi
(* Segue carga da aplicação *)
Application.CreateForm(TForm1, Form1);
Application.Run;
begin
Application.Initialize;
(* Verifica path da atualização *)
end.
Ini := TIniFile.Create(ExtractFilePath
(ParamStr(0))+’version.ini’);
try
PathUpdate := Ini.ReadString
Listagem 4 – Código restante do projeto.
(‘ATUALIZACAO’, ‘PATH’, ‘’);
finally
Ini.Free;
end;
Vamos analisar o código da Listagem 4. Começamos criando
um objeto TIniFile o qual irá ler as configurações do arquivo INI
citado anteriormente. Após isso, verificamos se existe arquivo de
atualização referente ao caminho contido no arquivo INI e caso
(* Verifica se a atualização existe *)
if FileExists(PathUpdate) then
begin
(* Compara pela Data do Arquivo. Se a data do
exista, comparamos se a data do arquivo de atualização (no
servidor) é maior que a data do aplicativo corrente e caso seja,
executamos o aplicativo “Atualiza” passando como parâmetros o
caminho e arquivo de origem (servidor) e o caminho e arquivo de
EXE existente na pasta de atualização for > do que
este EXE... *)
if FileAge(PathUpdate) > FileAge(ParamStr(0))
then
begin
(* Caminho do atualizador *)
Command := ExtractFilePath(PathUpdate) +
‘Atualiza.Exe ‘ + PathUpdate
destino (aplicativo corrente na estação), fazendo a execução
através da criação de um processo no Windows.
Após efetuar a cópia e se esta for bem sucedida, inibimos a
apresentação do MainForm da aplicação corrente (apenas para
evitar o efeito de “piscar” o Form) e finalizamos a aplicação
corrente, isso porque a aplicação “Atualiza” irá fazer a chamada
(conforme explicado anteriormente) através da API WinExec e
+ ‘ ‘ + ParamStr(0);
FillChar(TSI, SizeOf(TSI), 0);
TSI.CB := SizeOf(TSI);
(* Cria processo para atualização *)
com isso, colocar a nova versão para rodar.
if not CreateProcess(nil, PChar(Command),
nil, nil, False, CREATE_SHARED_WOW_VDM,
nil, nil, TSI, TPI) then
begin
simples, porém, nos vários testes que efetuamos em nosso
laboratório obtivemos ótimos resultados com esta abordagem,
reduzindo bastante os problemas de atualização e diferença de
versão. Esperamos estar contribuindo para tornar seus
MessageBeep(0);
Exception.Create(‘Problemas
na atualização da versão!’);
end;
aplicativos cada vez mais profissionais e caso tenha alguma
sugestão ou comentário, sinta-se a vontade para entrar em
contato conosco, até a próxima.
(* Não deixa mostrar o MainForm *)
Application.ShowMainForm := False;
(* Encerra aplicação para chamar nova versão
do Executável *)
Download
O projeto de exemplo referente este artigo está disponível para
download em:
Conclusão
Como mencionei no início deste artigo, a idéia é bastante
http://www.theclub.com.br/revista/download/atualizador.zip
Application.Terminate;
(* Não executa daqui para baixo... *)
Exit;
end;
Sobre o autor
Alessandro Ferreira, Consultor Técnico do The
Club - [email protected]
end;
MeGAZINE
27
Dicas & TTruques
ruques
Rave Reports – Como fazer cálculo (Campo1*
Campo2/100) linha a linha
Somente essas propriedades serão ligadas, e neste momento
montamos a fórmula para fazer Campo1 * Campo2.
Para fazer esse cálculo dentro do Rave Report iremos utilizar
as seguintes configurações:
Agora coloque um segundo componente CalcOp, chamado
CalcOp2, onde completaremos a fórmula dividindo o resulto do
CalcOp1 anterior por 100.
Selecione o componente chamado CalcOp da aba REPORT e
depois clique sobre a banda onde estão sendo impressos os dados;
(Esse componente não ficará visível na banda somente é utilizado
para fazer os cálculos entre os campos.
Para trabalhar com esse componente selecione-o através do
treeview existente ao lado do design do relatório.)
Neste componente CalcOp, chamado CalcOp1 iremos
configurar as seguintes propriedades:
Operator
:
Src1CalcVar :
Src2Value :
DestPIVar :
relatório)
coDiv
CalcOp1
100,000
vCalculo
(nome da variável criada no
Essa variável vCalculo deve ser criada da seguinte maneira:
Operator
: coMul (Indica que será feita
multiplicação)
Src1DataView
: indique o dataview que contém o
primeiro campo do cálculo
Src1DataField : indique o primeiro campo do cálculo
Src2DataView
: indique o dataview que contém o
segundo campo do cálculo
Src2DataField : indique o segundo campo do cálculo
DisplayFormat : indique a mascara, pode ser
###,##0.00
28
No CalcOp2 configure as seguintes propriedades:
Selecione o relatório no Treeview, logo abaixo da opção Report
Library, agora na propriedade PIVars escreva o nome da variável
desejada, no caso vCalculo, e pronto está criada a variável que
receberá o resultado do cálculo.
Para finalizar este cálculo, precisamos somente mostrar o
valor que está na variável, no relatório e para isso iremos colocar
um componente chamado DataText da aba Report. Neste
componente na propriedade DataField pressione o botão com
reticências (...). Agora na tela Data Text Editor selecione no
MeGAZINE
Dicas & TTruques
ruques
combo “Post Initialize Variables” a variável que guardamos o
resultado do cálculo, pressione o botão “Insert_PIVar” e depois
pressione o botão Ok. Pronto o resultado do cálculo armazenado
na variável será impresso no relatório.
3.Certifique-se de que a DLL “libmysql.dll” esteja em um
path acessível (como exemplo, \Windows\System)
Continuando,
1.insira um componente sqlConnection
2.dê um duplo clique sobre o mesmo
3.Adicione uma conexão do tipo MySQL
4.Configure host com o IP ou se for local = localhost
5.Configure usuário e senha, como exemplo root e 123456
6.Configure DataBase com o nome de seu banco de dados;
Rave Report – Passando parâmetros para o
relatório
Para criar um parâmetro dentro do Rave faça o seguinte:
Selecione a página do relatório e acesse a propriedade
Parameters, dentro desta propriedade escreva o nome do seu
parâmetro, exemplo PAnoMes.
Depois coloque um componente DataText e na propriedade
DataField clique no botão (...). Agora no combo Project Parameters selecione o parâmetro que foi criado e pressione o botão
“Insert Parameter”. Pronto o parâmetro será impresso neste
componente DataText.
Para passar o valor do Delphi para o Rave utilize o seguinte
comando:
Rpt_Projeto.Open;
{
Passa parametro para o relatório para imprimir no
DataText do cabeçalho
}
Rpt_Projeto.SetParam(‘PAnoMes’, Mes.Text+’/
’+Ano.Text);
Rpt_Projeto.ExecuteReport(‘RelFat’);
Rpt_Projeto.Close;
Feito isso, bastará ligar um sqlDataSet ao sqlConnection, um
DataSetProvider ao sqlDataSet, um ClientDataSet e fazer as
edições via ClientDataSet.
Veja como criar atalhos no menu iniciar do
Windows
Neste exemplo, iremos demonstrar uma forma bastante
simples para criar:
- Grupos de programas
- Items de programas
- Atalhos para programas
Em nossa abordagem, não iremos utilizar a criação via
interface DDE por alguns questões de parametrização e sim,
demonstraremos a partir da criação direta de “folders” na pasta
“Programs” do Windows.
Primeiramente, vamos criar uma procedure para criação de
atalhos:
MySQL – Conectando MySQL via dbExpress
O acesso ao MySQL via dbExpress é bastante simples,
contudo, primeiro recomendamos atualizar seu Delphi (caso
esteja utilizando Delphi 6) com o “Update Pack#2” que pode ser
encontrado no site da Borland:
http://www.borland.com/delphi
Após isso, faça a seguinte alteração:
1.Abra o arquivo dbxdrivers.ini, pasta: “/Program Files/
Common Files/Borland Shared/DBExpress”
2.Onde está escrito “dbexpmys.dll”, altere para
“dbexpmysql.dll”
MeGAZINE
implementation
uses ShlObj, ActiveX, ComObj;
{$R *.dfm}
procedure CriaShortCut(aNome, aFileName, aPathGroup:
string; aLocation: integer);
var
IObject
: IUnknown;
ISLink
: IShellLink;
IPFile
: IPersistFile;
PIDL
: PItemIDList;
InFolder
: array[0..MAX_PATH] of Char;
TargetName : String;
LinkName,s : WideString;
29
Perguntas & Respostas
Observe que esta procedure recebe como parâmetro o nome
do grupo (que na realidade será o nome de um “Folder” e a
localização, ou seja, onde ele deverá ser criado.
begin
TargetName := aFileName;
IObject := CreateComObject(CLSID_ShellLink);
ISLink := IObject as IShellLink;
IPFile := IObject as IPersistFile;
Exemplo de utilização:
with ISLink do
begin
SetPath(pChar(TargetName));
SetWorkingDirectory(pChar(ExtractFilePath(TargetName)));
end;
SHGetSpecialFolderLocation(0, aLocation, PIDL);
SHGetPathFromIDList(PIDL, InFolder);
s := InFolder;
LinkName := s + ‘\’ + aPathGroup + ‘\’ +
aNome + ‘.LNK’;
IPFile.Save(PWChar(LinkName), false);
end;
Esta procedure recebe como parâmetro o Nome do atalho a
ser apresentado, o caminho e nome do aplicativo a ser executado,
e por último o grupo ao qual ele irá pertencer no menu Iniciar do
Windows.
Agora vamos para a procedure responsável em criar o Grupo
e o Ítem de Programa:
function CreateFolder(Foldername: string; aLocation:
integer): boolean;
var
pIdl: PItemIDList;
hPath: PChar;
begin
Result := False;
if SUCCEEDED(SHGetSpecialFolderLocation(0,
aLocation, pidl)) then
begin
hPath := StrAlloc(max_path);
SHGetPathFromIDList(pIdl, hPath);
SetLastError(0);
if ForceDirectories(PChar(hPath + ‘\\’ +
Foldername)) then
Result := true;
StrDispose(hPath);
end;
end;
30
procedure TForm1.Button1Click(Sender: TObject);
begin
// cria Grupo principal.
CreateFolder(‘The Club’, CSIDL_PROGRAMS);
// cria sub-grupo dentro do “The Club”
CreateFolder(‘The Club\Grupo 1’, CSIDL_PROGRAMS);
// cria sub-grupo dentro do “The Club”
CreateFolder(‘The Club\Grupo 2’, CSIDL_PROGRAMS);
// cria sub-grupo dentro do “The Club”
CreateFolder(‘The Club\Grupo 3’, CSIDL_PROGRAMS);
// cria sub-grupo dentro do “The Club\Grupo 1”
CreateFolder(‘The Club\Grupo 1\Sub Grupo 1’,
CSIDL_PROGRAMS);
// cria sub-grupo dentro do “The Club\Grupo 2”
CreateFolder(‘The Club\Grupo 2\Sub Grupo 1’,
CSIDL_PROGRAMS);
// cria sub-grupo dentro do “The Club\Grupo 3”
CreateFolder(‘The Club\Grupo 3\Sub Grupo 4’,
CSIDL_PROGRAMS);
// cria atalho para os programas
CriaShortCut(‘Calculadora’,
‘c:\windows\system32\calc.exe’
, ‘The Club\Grupo
1’, CSIDL_PROGRAMS);
CriaShortCut(‘Bloco de Notas’,
‘c:\windows\system32\notepad.exe’, ‘The Club\Grupo
2’, CSIDL_PROGRAMS);
CriaShortCut(‘WordPad’, ‘C:\Program Files\Windows
NT\Accessories\wordpad.exe’, ‘The Club\Grupo 3’,
CSIDL_PROGRAMS);
end;
Dica: A constante CSIDL_PROGRAMS indica a pasta padrão
onde os ítens do menu iniciar do Windows ficam armazenados.
Trabalhando com esta constante, independente da versão e
linguagem do Windows, a pasta irá ser criada no local correto.
Observe que primeiramente criamos um grupo principal,
chamado “The Club”. Seguindo, dentro de “The Club” criamos
sub-grupos e dentro dos sub-grupos os atalhos que irão chamar
os aplicativos em questão.
Este exemplo está disponível para download em nosso site no
endereço:
http://www.theclub.com.br/revista/download/
CriaGrupoAtalho.zip
MeGAZINE
Download

Delphi - The Club