março 2009
março 2009
Índice
Editorial
Delphi
Zlib - Construíndo um compactador de arquivos no Delphi
Aprimorando o desempenho de um Banco de Dados
Delphi Prism com LINQ
04
.NET
Dicas Delphi
Trabalhando com dynamic Data
Controls
O ASP.NET ultimamente vem revolucionou o desenvolvimento de aplicações para
web oferecendo uma plataforma robusta e
altamente produtiva elevando o potencial dos
desenvolvedores com excelente
recursos como: GridView, DataControls, Validators , WebParts
entre outros.
24
Ativar Auto Run do CD-ROM
Criptografar Strings
Ver se existe Midia no Drive
Ver impressora conectada
Localizar Arquivos no Windows
Mostrar as fontes True Types instaladas no Windows
Intermediário
28
Desafio
The CLub
Legenda
Iniciante
05
10
13
15
DataSnap 2009 - ParteI Introdução
Posso dizer que
a partir do mês de
Agosto do ano passado onde assumi a
direção da revista The
Club Megazine, todas
nossas edições foram
feitas com o objetivo
de levar um
conteúdo
cheio de novidades ...
Teste seus conhecimentos.
Avançado
março 2009
30
03
Bem-vindo
Posso dizer que a partir do mês de Agosto do ano passado onde assumi
a direção da revista The Club Megazine, todas nossas edições foram feitas
com o objetivo de levar um conteúdo cheio de novidades e recursos aplicáveis no dia-a-dia do programador. Este mês nos do The Club ficamos
muito satisfeitos com o resultado desta edição, pois acreditamos que nas
paginas desta edição para qualquer que seja o leitor, com certeza novidades serão encontradas. Assim continuando a seqüência de artigos sobre a
nova ferramenta da Embarcadero, o Delphi Prism, Luiz Alexandre com seu
artigo “Delphi Prism com Linq (Language Integrate Query)”, nos mostras
mais algumas funcionalidades da ferramenta num artigo bastante completo
que apresenta conceitos do Linq, que podem ser aplicados inclusive em
um aplicação C#.
Sabemos da importância de velocidade e performance em nossas aplicações, desta forma o consultor Marco Antonio Armando em seu artigo
“Aprimorando desempenho de banco de dados”, demonstra em dicas simples, mas de grande importância na aplicação, como escrever consultas
SQL visando obter a melhor eficiência do banco de dados.
Entre as muitas novidades apresentadas pela Embarcadero no lançamento do Delphi 2009, encontramos os novos avanços na tecnologia DataSnap
que chamaram bastante a atenção, neste mês trago o artigo “DataSnap
2009 - Introduçao“ onde mostro como ficou simples e funcional criar um
servidor de métodos DataSnap, mostrando o poder de uma tecnologia
que embora lançadas a muito tempo ainda é uma grande caixa preta para
muitos programadores, e que agora após um período de estagnação da
tecnologia, foi remodelada pela Embarcadero sendo lançada nesta nova
versão com novos recursos e independente da tecnologia COM.
Uma necessidade comum nas aplicações é a compactação de arquivo
seja para backup de dados ou envio de arquivo pela internet, assim o
consulto Antonio Spitaleri escreveu o artigo “Zlib Construindo um compactador de Arquivos no Delphi” onde usando a Unit ZLib.pas nativa do
Delphi demonstra como realizar este procedimento sem o uso de nenhum
componente de terceiros.
Ao longo dos anos surgiu no mercado necessidades como a criação de
telas automáticas de cadastro, com o lançamento do Service Pack 1 do .NET
3.5, foi disponibilizando dentro do ASP.NET um novo conjunto de controles
conhecido como Dynamic Data Controls que tem objetivo de montar as
telas para as ações básicas. Assim este mês Fabiano Belmont aborda este
assunto com seu novo artigo “Trabalhando com Dynamic Data Controls”.
Av. Profº Celso Ferreira da Silva, 190
Jd. Europa - Avaré - SP - CEP 18.707-150
Informações: (14) 3732-1529
Suporte: (14) 3733-1588
Internet
http://www.theclub.com.br
Cadastro: [email protected]
Suporte: [email protected]
Informações: [email protected]
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1
theclub_linha2
Copyright The Club Megazine 2008
Diretor Técnico
Marcos César Silva
Diagramação e Arte
Vitor M. Rodrigues
Revisão
Marcos César Silva
Colunistas
Antonio Spitaleri Neto
Fabiano Belmonte
Luís Alexandre de Oliveira
Marco Antonio Armando
Marcos César Silva
Impressão e acabamento:
GRIL - Gráfica e Editora
Rua São Paulo, nº 447
Cep: 18740-00 - Taquarituba-SP
Tel. (14) 3762-1345
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
Megazine” são terminantemente proibidos sem autorização
escrita dos titulares dos direitos autorais.
Que todos tenham uma boa leitura e apreciem os artigos sem moderação.
Marcos César Silva - Editor Chefe
[email protected]
04
março 2009
Delphi é marca registrada da Borland International,
as demais marcas citadas são registradas
pelos seus respectivos proprietários.
Delphi
Parte I
Entre as muitas novidades apresentadas
pela Embarcadero no lançamento do Delphi
2009, encontramos os novos avanços na tecnologia DataSnap que chamaram bastante a
atenção. O DataSnap embora possa parecer
uma tecnologia nova e cheia de mistérios
nasceu juntamente com o lançamento do
Delphi 3, inicialmente conhecida como
tecnologia MIDAS ( “Multi-Tier Distributed
Application Services”), teve seu nome alterado para Datasnap quando no lançamento
do Delphi 6 passou a contar com suporte a
SOAP/XML HTTP.
Um dos principais avanços concebido
nesta nova versão foi à desvinculação do
Datasnap da tecnologia COM, independência esta esperada a logo prazo por muitos
desenvolvedores que ira simplificar em muito
o processo de desenvolvimento. Embora que
vale ressaltar que foi mantida toda compatibilidade com versões anteriores.
N
este artigo ire demonstrar com
criar um servidor de métodos
e uma aplicação cliente que irá
consumir os métodos disponíveis
pelo servidor.
Introdução
Imagem 1 – Criando VCL Forms Applications
Criação do Servidor Datasnap
No RAD Studio Delphi 2009 para criar uma aplicação servidora Datasnap o primeiro passo é criar
uma aplicação VCL Forms Applications comumente
utilizada, para isto vá em New Projects selecione a
opção VCL Forms Applications (Imagem 1).
Será criado a unit principal que salvaremos
com o nome de unServer.pas e o projeto que salvaremos como Server.dpr, iremos também alterar a
propriedade Name do form criado frmServer.
Veja a imagem 1.
março 2009
05
Neste momento irei adicionar os componentes servidor Datasnap, para isto em Tool Palette
selecione a opção ”DataSnap Server” e inseria no
formulário os componente TDSServer, TDSTCPServerTransport e um TDSServerClass1 como pode
ver na Imagem 2.
Imagens 2 – Componentes Inseridos no formulário
Uma vez inserido os componentes é necessário
configurar a propriedade Server dos componentes
DSTCPServerTransport 1 e DSServerClass11 para
DSServer1. Uma dica importante neste momento
é observar a propriedade Port que se encontrada
no componente TDSTCPServerTransport, o numero
da porta deverá ser único por aplicação servidora
para evitar que mais de uma aplicação responda
na mesma Porta.
06
março 2009
Imagem 3 – Criando o Server Module
Criaremos agora o Server Module, que será
nosso DataModule da aplicação DataSnap, ou melhor um TProviderDataModule que ira servir como
um provedor de métodos e dados da aplicação
Servidora. Para criar o Server Module vá em New
Itens e selecione o item Server Module (Imagem
3), e salve-o como unServerModule;
Veja a imagem 3.
Apenas para finalidade de demonstração
irei criar um método que irá retorna a versão do
projeto, para isto no código fonte do TDSServerModule1, na seção public da classe declare a function
PegaVersao e em implementation insira o código
fonte da função como pode ver abaixo:
type
TDSServerModule1 =
class(TDSServerModule)
private
{ Private
declarations }
public
function
PegaVersao:string;
end;
var
Agora voltaremos ao form frmServer e adicione a uses unServerModule com Alt+F11 (Imagem
4) e no componente DSServerClass1, adicione o
evento OnGetClass e insira o código abaixo:
procedure TfrmServer.
DSServerClass1GetCl
ass(DSServerClass:
TDSServerClass;
var PersistentClass:
TPersistentClass);
begin
PersistentClass :=
TDSServerModule1
end;
DSServerModule1:
TDSServerModule1;
implementation
{$R *.dfm}
{ TDSServerModule1 }
function
TDSServerModule1.
PegaVersao: string;
begin
Result := ‘Versão 1.0’;
end;
março 2009
07
e então será executado o método desejado da
classe, que neste caso é o PegaVersao;
implementation
uses unClientClass;
{$R *.dfm}
procedure TfrmClient.
Button1Click(Sender:
TObject);
var
ServerModule:
TDSServerModule1Client;
Imagem 4 - Adicionando a uses unServerModule
Imagem 5 – Propriedades do SQLConnection1
Compile o projeto com a opção Run Without
Debugging Shift+Ctrl+ F9 assim será criado o
executável Server.exe sem a opção de debug, não
“prendendo” a sua execução com a IDE do Delphi,
neste momento apenas minimize o executável do
projeto servidor, pois o mesmo deverá estar em
execução para responder ao projeto cliente que
iremos criar.
Agora Clique com o botão direito no mouse
sobre o componente SQLConnection1 e selecione
a opção Generate DataSnap client classes (Imagem
6), para que seja criado pelo DataSnap proxy generator a unit de classes cliente correspondente
ao métodos disponíveis na aplicação servidora,
salve-a como unClientClass.pas. Outra dica importante, certifique-se que a aplicação servidora
esta “rodando”, caso contrário a classe não será
gerada com sucesso.
begin
ServerModule :=
TDSServerModule1Client.
Create(SQLConnection1.
DBXConnection);
try
Label1.Caption :=
ServerModule.PegaVersao;
finally
ServerModule.Free;
end;
end;
Criação do Cliente DataSnap
O próximo passo antes de criar a aplicação
cliente e salver o grupo de projetos em Project
Manager, para isto clique com o botão direito
do Mouse sobre o Arquivo de Grupo de projetos
e selecione “Save Projet Group As” salve como
DataSnapProjectGroup.groupproj, salvo o arquivo
volte a clicar sobre o Grupo de Projetos e selecione
Add New Project selecione a opção VCL Forms Applications para criarmos a aplicação cliente, salve a
unit como unClient.pas renomeando a propriedade
Name do formulário para frmClient, e salvando o
projeto como Client.dproj.
O próximo passo é adicionar os componentes
de conexão, para isto em Tool Palette selecione o
componente TSQLConnection e adicione no formulário frmClient, assim no SQLConnection1 em
sua propriedade Driver selecione o item Datasnap,
observe que esta propriedade no Object Inspector
tem Subpropriedades , coloque na subpropriedade
HostName o valor localhost e em port 211, e não
esqueça de alterar a propriedade LoginPrompt para
false como pode var na imagem 5
08
março 2009
Variação da Aplicação Cliente DataSnap
Imagem 6 – Criando as classes cliente
Para que possamos testar, adicione no form
frmClient a uses unClientClass (Alt+F11) e coloque
um componente Label para receber o retorno do
método e um Button para disparar a execução, no
evento OnClick do botão adicione o código que
pode ver abaixo, para que desta forma quando for
executado o clique no botão será criado a classe
TDSServerModule1Client gerada na etapa anterior
Para deixarmos mais evidente que a conexão está sendo feita através do driver DBXClient
existindo uma integração direita com DataSnap e
dbExpress, iremos utilizar a mesma função da aplicação Server, só que desta vez sem a declaração da
classe TDSServerModule1Client como foi feito no
processo anterior. Para isto adicione o componente
TSqlServerMethod que se encontra em Tool Palette
-> dbExpress no formulário frmClient, altere a sua
propriedade SQLConnection para SQLConnection1
e em ServerMethodName observe que será listada
todos os métodos da aplicação Server, selecione
assim o item que nos interessa que é o TDSServerModule1.PegaVersao (Imagem 6). Adicione
mais um componente TLabel e outro TButton, no
evento Onclick deste novo botão coloque o código
abaixo responsável por executar o método:
procedure TfrmClient.
Button2Click(Sender:
TObject);
acesso a banco de dados.
begin
SqlServerMethod1.
ExecuteMethod;
Label2.Caption :=
SqlServerMethod1.
ParamByName
(‘ReturnParameter’).
AsString;
end;
Quando selecionamos o ServerMethodName
no componente SqlServerMethod1, automaticamente a propriedade params deste componente
foi preenchida, neste nosso caso existia apenas o
parâmetro de retorno (Result) chamado por padrão
como ReturnParameter, Caso nosso método tivesse
parâmetros de entrada (Imput), estes parâmetros
seriam também adicionados em Params, e deveriam ter uma valor para eles atribuídos antes da
chamada do método ExecuteMethod do componente SqlServerMethod1 da seguinte forma:
SqlServerMethod1.
ParamByName(‘Parametro1’).
AsInteger := 10;
Conclusão
Imagem 7 – Selecionado o método
Vimos como ficou muito mais simples e
prático a criação de aplicação Multicamadas, não
dependendo de nenhuma outra tecnologia para
seu funcionamento. Em nosso próximo encontro
iremos ver como usar a tecnologia Datasnap para
Download:
www.theclub.com.br/revista/rev0309/datasnap2009.rar
Referencia:
http://blogs.embarcadero.com/
andreanolanusse/2008/10/16/exemplos-datasnap-dbexpress-e-outros-recursos-do-delphi2009/
Sobre o autor
Marcos César Silva, Consultor de
Sistemas na consultoria de sistemas DataSmart
e Consultor Técnico do The Club, Bacharel em
Ciência da Computação, MBA em Gestão Empresarial, Certificações MCAD (Microsoft Certified
Application Developer) e MCSD.NET (Microsoft
Certified Solution Developer .NET)
março 2009
09
Entre as inúmeras units presentes no Delphi, sem dúvida uma que poucos conhecem
é a zlib. Essa unit contém classes que tornam
possível a criação de objetos que realizam a
compactação de arquivos.
Nesse artigo, estarei mostrando passo a passo
com construir um compactador de arquivos bem
simples utilizando Delphi e a zlib. Mãos a obra!
Formulário:frmcompactador.
Edits: edtarquivo,edtdestino.
Buttons: btncompacta,btndescompacta,btnse
lecionaarq,btndestino;
Finalizando, insira ao lado das edits edtarquivo
e edtdestino duas labels com as propriedades caption como arquivo e destino respectivamente.
O formulário deverá ficar com a seguinte
aparência:
Veja a Figura 01.
Preparando a Aplicação
Inicie um novo projeto no Delphi, e inclua na
unit do form a unit zlib.
Insiram no formulário os seguintes componentes:
Realizando a codificação
Chegou a hora de inserirmos o código necessário para que o nosso compactador funcione.No
2 edits(palheta standard);
4 buttons(palheta standard);
2 labels(palheta standard);
1 opendialog(palheta dialogs);
Altere as propriedades name dos componentes conforme segue:
Figura 01.
10
março 2009
evento onclick do btnselecionaarq digite:
procedure Tfrmcompactador.
btnselecionaarqClick(Sender:
TObject);
begin
OpenDialog1.Execute;
edtarquivo.
Text:=OpenDialog1.FileName;
end;
Nesse evento estamos abrindo a caixa de diálogo abrir do windows, selecionando um arquivo e
colocando seu caminho na edtarquivo.
No evento onclick do btndestino digite:
procedure Tfrmcompactador.
btndestinoClick(Sender:
TObject);
begin
OpenDialog1.Execute;
edtdestino.Text:=Extra
ctFilePath(OpenDialog1.
FileName);
end;
Aqui estamos selecionando um arquivo e
extraindo através da função extractfilepath seu
caminho já que é apenas o caminho que será utilizado.Esse caminho irá ser exibido na edtdestino.
Agora a parte mais importante, que é a codificação que irá realizar a compactação do arquivo
selecionado.É nessa parte que estaremos utilizando
as classes da zlib que realizam a compactação.
No evento onclick do btncompacta digite:
procedure Tfrmcompactador.
btncompactaClick(Sender:
TObject);
var
FileIni, FileOut:
TFileStream;
Zip: TCompressionStream;
nomearq:string;
begin
try
try
nomearq:=InputBox(‘C
ompactar’,’Digite um nome
para o arquivo’,’’);
FileIni:=TFileStream.
Create(edtarquivo.
Text, fmOpenRead and
fmShareExclusive);
FileOut:=TFileStream.
Create(nomearq+’.
zip’, fmCreate or
fmShareExclusive);
Zip:=TCompressionStream.
Create(clMax, FileOut);
Zip.CopyFrom(FileIni,
FileIni.Size);
except
Raise Exception.
Create(‘Não foi possível
compactar o arquivo’);
abort;
end;
finally
Zip.Free;
FileOut.Free;
FileIni.Free;
end;
end;
Fileini recebe o arquivo a ser compactado no
formato stream para ser processado pelo objeto
zip, que realiza a compressão e coloca o resultado
no objeto fileout, este último também do tipo
tfilestream.
março 2009
11
DeZip:=TDecompressionStream.
Create(FileIni);
repeat
i:=DeZip.Read(Buf,
SizeOf(Buf));
if i <> 0 then
FileOut.
Write(Buf, i);
until i <= 0;
except
raise Exception.
Create(‘Não foi possível
descompactar o arquivo’);
abort;
end;
finally
DeZip.Free;
FileOut.Free;
FileIni.Free;
end;
end;
Repare que essa rotina possui a variável buf,
um array de 1024 bytes onde será escrito o resultado da descompressão.
Repare que caso algum erro ocorra, o processo
de compressão é interrompido e é enviada uma
mensagem ao usuário de que a compressão não
foi possível.
A chamada à função inputbox no início do
evento permite que o usuário escolha o nome desejado para o arquivo depois de compactado.
Os arquivos compactados com a unit zlib possuem a extensão .zip que é uma das extensões de
arquivos compactados mais utilizada atualmente.
O objeto mais importante de nosso aplicativo é o zip, do tipo tcompressionstream.A classe
tcompressionstream da unit zlib é que contém os
códigos que permitem a compressão de arquivos.
Além da classe Tcompressionstream, a zlib
também possui a classe tdecompressionstream,
que como o nome sugere, realiza a descompressão
de arquivos.
Apesar de não ser o foco do artigo, estarei
mostrando um pequeno exemplo de código para
descompactação que pode ser inserido no evento
onclick do btndescompacta:
12
março 2009
procedure Tfrmcompactador.
btndescompactaClick(Sender:
TObject);
var
FileIni, FileOut:
TFileStream;
DeZip:
TDecompressionStream;
i: Integer;
Buf: array[0..1023]of
Byte;
nomearq:string;
begin
try
try
nomearq:=InputBox
(‘Descompactar’,’Digit
e um nome e a extensão do
arquivo,’’);
FileIni:=TFileStream.
Create(edtarquivo.
Text, fmOpenRead and
fmShareExclusive);
FileOut:=TFileStream.
Create(nomearq,fmCreate or
fmShareExclusive);
Na rotina de descompressão, a inputbox deverá ser preenchida com o nome e a extensão do
arquivo. Ex:teste.txt.Diferentemente da compressão onde apenas o nome é necessário.
Como pôde ser observado, com a unit zlib é
possível construir um compactador de arquivos
até com certa facilidade sem a necessidade de
componentes de terceiros.
Espero que tenham gostado e até a
próxima.
Sobre o autor
Antonio Spitaleri Neto
Consultor Técnico The club
[email protected]
APRIMORANDO
O DESEMPENHO
DE UM BANCO DE DADOS
No dia a dia, uma preocupação para
desenvolvedores de bancos de dados, sem
sombra de dúvidas, é a performance final
dos mesmos.
Neste sentido, muitos programadores se
confundem no que tange a diferença entre
um ajuste de banco de dados versus ajuste
de uma instrução SQL.
Assim desmistificando, temos:
•
O ajuste de um banco de dados significa
o processo de ajustar o banco de dados real, ou
seja, fatores como: alocação de memória, uso de
disco, CPU, etc. Não podemos nos esquecer também que o ajuste também compreende a estrutura
do banco de dados, como tabelas e índices.
•
O ajuste de uma instrução SQL, é o processo ajustar uma instrução SQL, como consultas,
inserções, etc., com o objetivo de tirar o máximo
proveito possível em performance e confiabilidade.
Ajuste de uma instrução SQL
O ajuste de uma instrução SQL, visa construir
instruções com excelência, visando obter resultados com eficácia. A formatação de uma instrução
representa um papel crucial na performance
final, neste contexto o ajuste da clausulas FROM
E WHERE são vitais, pois são essas duas clausulas
das quais dependerão a forma em que o servidor
de bancos dados irá processá-la.
Embora possa ser rotineiro em nosso cotidiano, a construção de instruções SQL´s, requer
atenção, e alguns pré requisitos fundamentais, eis
alguns deles:
•
•
•
•
Levar em conta sempre a legibilidade;
Posicionamento das tabelas na cláusula
FROM;
Posicionamento de condições restritivas
na cláusula WHERE;
Posicionamento de condições de JOIN na
cláusula WHERE;
LEGIBILIDADE
Quando se pensa em ajuste de uma instrução
SQL, o primeiro passo a se levar em conta é a legibilidade da mesma, a fim de que fique bem escrita,
e facilite a vida de quem além do desenvolvedor
que a escreveu, possa discerni-la de forma rápida
e segura.
Para isto relacionaremos abaixo algumas
particularidades que tornam uma instrução de
forma legível:
•
Inserir uma cláusula FROM em uma linha separada da cláusula SELECT, e cláusula WHERE
separada da cláusula FROM:
SELECT ID_CODIGO, NOME, CPF
FROM CLIENTES
WHERE NOME = ‘GILSON’
•
O uso de tabulações ou espaços e recomendável quando um argumento de uma cláusula,
excedem uma linha.
março 2009
13
•
Quando da necessidade de utilizar
várias tabelas em uma instrução, o uso de aliases
é indispensável.
SELECT C.ID_CODIGO, C.NOME,
V.ID_CODIGO, V.VALOR
FROM CLIENTES C, VENDAS V
•
Inicie sempre uma nova linha na instrução, caso haja a necessidade de se trabalhar com
várias colunas na instrução SELECT, isto também se
aplica as cláusulas FROM e WHERE.
SELECT C.ID_CODIGO,
C.NOME,
C.CPF,
C.TELEFONE,
V.ID_CODIGO,
V.VALOR,
FROM
CLIENTES C,
VENDAS V
WHERE C.ID_CODIGO =
V.ID_CODIGO
Veremos abaixo, um exemplo clássico de como
muitos desenvolvedores escrevem uma instrução
SQL, onde não se leva em conta a legibilidade:
SELECT C.ID_CODIGO,
C.NOME, C.CPF, C.TELEFONE,
C.CIDADE, P.ID_CODIGO,
P.NUM_PEDIDO, P.VALOR,
P.QTDE
FROM CLIENTES C, PEDIDOS P
WHERE C.ID_CODIGO = P.ID_
CODIGO AND C.CIDADE = ‘SAO
PAULO’ AND P.VALOR > 100
Agora levando em conta os princípios da legibilidade, vamos reescrever a instrução acima:
SELECT C.ID_CODIGO,
C.NOME,
C.CPF,
C.TELEFONE,
C.CIDADE,
P.ID_CODIGO,
P.NUM_PEDIDO,
P.VALOR, P.QTDE
14
março 2009
FROM CLIENTES C,
PEDIDOS P
WHERE C.ID_CODIGO = P.ID_
CODIGO
AND C.CIDADE = ‘SAO PAULO’
AND P.VALOR > 100
Podemos observar que as duas instruções
retornaram o mesmo número de registros, e não
terão nenhuma diferença na sua performance, mas
para quem as lerem, fará uma grande diferença,
principalmente se estivermos desenvolvendo um
projeto de grande porte, que envolvam muitos
desenvolvedores.
ORDEM ADEQUADA DE CONDIÇÕES
DE JUNÇÃO:
Quando trabalhamos com mais de duas tabelas em uma instrução SQL, a tabela base dever
locada no lado direito de uma junção numa cláusula
WHERE, onde a união deverá ser feita sempre primeiramente com a menor tabela e posteriormente
deverá ser efetuada com as maiores, vejamos
melhor no exemplo abaixo:
SELECT <COLUNAS>
FROM TABELA1 (TABELA MENOR)
TABELA2
TABELA3 (TABELA MAIOR)
WHERETABELA1.<COLUNA> =
TABELA3.<COLUNA>
TABELA2.<COLUNA> =
TABELA3.<COLUNA>
BUSCANDO A CONDIÇÃO RESTRITIVA
Buscar a condição mais restritiva é o foco
principal, visando um ótimo desempenho em uma
consulta SQL.
Assim podemos definir uma condição restritiva, como a forma de utilizarmos em uma cláusula
WHERE de uma instrução que retorne uma menor
quantidade de registros.
Para isto é importante saber como o otimizador do banco de dados opera para executar a
instrução, pois alguns banco por exemplo lêem da
parte inferior da cláusula WHERE para cima, assim
devemos colocar a condição mais restritiva por
último, pois é a primeira condição que é lida pelo
otimizador do banco utilizado.
Abaixo vejamos a sintaxe básica:
FROM TABELA1
<TABELA
MENOR>
TABELA2
TABELA3
<TABELA MAIOR>
WHERE TABELA1.<COLUNA>
= TABELA3.<COLUNA> AND
TABELA2.<COLUNA> =
TABELA3.<COLUNA>
AND CONDIÇÃO 1
<MENOS RESTRITIVA>
AND CONDIÇÃO 2
<MAIS RESTRITIVA>
Se por ventura, na implementação utilizada, na
sua documentação, não mencionar como o otimizador funciona quanto a condições de restrição, para
que possamos escrever instruções que interajam
de maneira mais eficiente com o banco de dados,
a melhor forma, seria executar as consultas cronometrando o seu tempo de execução, verificando se
o otimizar lê a cláusula WHERE, de cima para baixo,
ou de baixo para cima.
Posteriormente, devemos organizá-las de
forma que as condições restritivas respondam de
maneira concernente ao otimizador.
É muito comum, no suporte do THE CLUB, os
sócios muitas vezes, apresentarem muita preocupação e dúvidas quanto a conexão a ser escolhida
para desenvolvimento de uma aplicação, isto sem
dúvida requer uma escolha correta, mas nunca não
podemos de nos esquecer que, banco de dados
bem construídos, e instruções SQL´s bem escritas
nos pouparão de muitos problemas, e nos retornarão, um resultado final muito mais proveitoso,
principalmente aos olhos de nossos clientes.
Um abraço e até a próxima.
Sobre o autor
Marco Antonio Armando
Consultor Técnico The club
Todos os aplicativos, exceto os triviais,
precisam processar dados. Historicamente,
a maioria dos aplicativos fornece um lógica
própria para realizar essas operações. Mas
essa estratégia pode fazer o código em um
aplicativo tornar-se excessivamente amarrado
à estrutura dos dados que ele processa. E se
houver mudanças no esquema de banco de
dados, talvez você necessite realizar um
número significativo de alterações no código
que trata os dados. A proposta da LINQ é
abstrair o mecanismo que um aplicativo utiliza para consultar dados a partir do próprio
código do aplicativo.
A LINQ fornece uma sintaxe e semântica muito
semelhantes da SQL, com vantagens parecidas.
Você pode mudar a estrutura dos dados em consulta sem precisar alterar o código que a realiza.
O diagrama acima apresenta uma
visão geral do LINQ , seus provedores e
as fontes de dados acessíveis:
LINQ TO OBJECTS
A LINQ tem como objetivo simplificar consultas a informações em collections, arrays, assim
como informações baseadas em base de dados,
XML e objetos.
Tem como objetivo simplificar consultas a
informações em collections, arrays, assim como
informações baseadas em base de dados, XML
e objetos
Atualmente o LINQ suporta
Atualmente o LINQ suporta:
Linq to objects
Linq to SQL
Linq to xml
LINQ to Objects
LINQ to SQL
LINQ to XML
Delphi Prism suporta LINQ através de :
Sequences e Query Expressions
Lambda Expressions
Expressions Trees
Extension Methods
Anonymous Types
Type Inference
Vamos entender como funciona o LINQ
QUERY EXPRESSIONS
março 2009
15
Permite executar querys em coleção de
objetos.
Vamos contruir um exemplo prático. Vá no
menu File --> New --> Project . No treeview a esquerda escolha Delphi Prism. Selecione o template
Windows Aplication .(Imagem 1)
Clique em ok.
No form Principal adicione um button e um
listbox. Seu layout ficará assim (Imagem 2):
Clique duas vezes no botão do formulário.
Adicione no evento do botão o seguinte trecho de
código (trecho 1)
method MainForm.btnok_
Click(sender: System.
Object; e: System.
EventArgs);
begin
var words :
Array of string
:=[‘ola’,’Delphi Prism’,
‘linq’,’The
Club’,’Alexandre’];
Imagem 1
var shortwords:=
From word in words
where
Word.Length<=5
select Word;
for each word in
shortwords do begin
lstValor.Items.
Add(word);
end;
end;
Trecho1.
Imagem 2
Na edição anterior, abordei algumas caracteristicas da linguagem Oxygene( baseado em Object
Pascal), vale a pena dar uma olhada.
Observe a nova sintaxe de declaração de variáveis. Declarei um array com 5 elementos.
Na variável shortwords (Query Exprressions) fiz
um select dentro do array para trazer as palavras
que contenham até 5 caracteres. Observe que a
variável word receberá os itens consultados. Um
ponto importante é que essa variável não necessita
de uma declaração explicita e a mesma será utilizada no escopo do select. O select word retorna a
instância do tipo array.
16
março 2009
O laço de repetição for each traz o resultado
do Query Expressions.Dê um F5 para debugar e
observe o resultado na figura 3.
LINQ TO SQL
Imagem 3
Permite executar querys em banco de dados,
mapeando tabelas como classes, conhecidas como
Entity classes.
Tem como objetivo mapear tabelas e seus
atributos como classes aproveitando o conheci-
mento em SQL
Vamos efetuar o mapeamento objeto relacional, criar um contexto de dados (DataContext) e
consultar um banco de dados SQL Server com LINQ
To SQL via código .
Mapeando classes para Tabelas
O conceito de mapeamento objeto Relacional
(ORM) não é uma novidade. Um ORM pode ser
visto como um classe (entidade) que possui propriedades ou campos que mapeiam para as colunas
de um banco de dados.
O mapeamento para uma tabela possui dois
elementos básicos:
1. TableAttribute - mapeia a classe para a
tabela no banco de dados;
2. ColumnAttribute - mapeia cada propriedade para uma coluna do banco de dados;
Para mapear a classe para uma tabela usamos
o TableAttribute com argumentos nomeados para
associar a classe com a tabela.
Abra o Visual Studio 2008 e crie um novo
projeto do tipo Windows Application com o nome
ExemploLInq.
Imagem 4
A seguir inclua uma referência ao LINQ To SQL
clicando com o botão direito sobre o nome do
projeto e selecionando Add Reference;
A seguir na janela Add Reference selecione, na
aba .NET, System.Data.Linq e clique no botão OK.
Veja a imagem 4;
Com isso já temos tudo pronto para iniciar
o projeto.
Vamos criar um banco de dados com o Studio
Express. No object Explorer clique duas vezes em
seucomputador\sqlexpress. Com o botão direito
do mouse em DataBase, acesse new DataBase. Em
databaseName coloque Categorias.
Clique em OK e pronto,nosso banco já esta
criado.
Veja a imagem 5.
Imagem 5
março 2009
17
Clique duas vezes em CATEGORIAS e clique
com o botão direito do mouse em tables.
Adicione a primeira tabela conforme imagem
6
Faça o mesmo procedimento para adicionar a
table SUBCATEGORIA.
Veja a imagem 7.
Faça o mesmo procedimento para criar uma
tabela de contatos
Vamos criar o diagrama do banco de dados.
Clique em DataBase Diagrams com o botão direito
do mouse e adicione um novo.
Nosso relacionamento ficará assim:
Veja a imagem 8.
Imagem 6.
Nosso objetivo será efetuar o mapeamento
objeto relacional com as tabelas Contato Categoria
e Subcategoria .
No menu Project | Add New Item selecione o
template Class e informe o nome Categoria.PAS.
Clique em add. Nesta classe iremos definir o mapeamento entre as tabelas do banco de dados.
Abra a classe e inclua a seguinte declaração :
System.Data.linq,
System.Data.Linq.Mapping,
Agora inclua o seguinte código(Listagem1) que
irá criar o mapeamento para as tabelas Categorias
e SubCategorias para os campos definidos:
Imagem 7.
namespace ExemploLInq;
interface
uses
System.Collections.
Generic,
System.Linq,
System.Data.linq,
System.Data.Linq.Mapping,
System.Text;
type
[Table(Name:=
18
março 2009
Imagem 8.
‘CATEGORIAS’)]
Categorias = public class
Public
[Column(IsPrimaryKey:=true,
Name:=’CATEGORIAID’)]
Property
CategoriaID:Integer;
[Column(Name:=’NOME’)]
Property
CatNome:String;
End;
[Table(Name :=
‘SUBCATEGORIAS’)]
Subcategorias = class
Public
[Column(IsPrimaryKey:=true,
Name:=’SUBCATEGORIAID’)]
Property
SubcategoriaID:Integer;
[Column(Name:=’NOME’)]
Property
SubcatNome:String;
[Column(Name:=’CATEGORIAID’)]
property
CategoriaID:Integer;
[Association
(OtherKey:=’CategoriaID’)]
Property Categorias:
EntitySet<Categorias>;
System.Linq,
System.Data.linq,
System.Data.Linq.
Mapping,
System.Text;
type
[Table(Name:=
‘CONTATOS’)]
Contatos = Class
Public
[Column(IsPrimaryKey:=true,
Name:=’CONTATOID’)]
Property
contatoid:Integer;
[Column(Name:=’Nome’)]
Property
ContatoNome:String;
End;
implementation
end.
Na classe principal Main.pas adicione um
DataGridView que se encontra na seção Data
do ToolBox. Adicione também dois buttons e
um textbox que se encontra na seção Common
Controls. O textbox terá o caminho do banco.
Adicione em uses :
End;
implementation
end.
Se trabalharmos com join podemos representá-las através de Associações .
ENTIDADES PODEM ESTAR RELACIONADOS
ATRAVÉS DO ATRIBUTO DE ASSOCIAÇÃO (Joins)
Observe que z classe que verifica a associação
entre Subcategorias e Categorias de um produto.
Vamos mapear a tabela contatos.Crie uma
outra classe Contatos .Listagem 1
namespace ExemploLInq;
interface
uses
System.Collections.
Generic,
System.Linq,
System.Data.Linq,
System.Data.Linq.
Mapping,
O formulário ficará assim:
No evento Clique do botão Query com Joins
adicione o script abaixo:
Adicione em uses System.Data.Linq,
method MainForm.Joins_
Click(sender: System.Object;
e: System.EventArgs);
var
Path :String :=
System.IO.Path.
GetFullPath(tbDataBase.
text);
// inicialização da variável
para pegar o banco de dados
db:DataContext := new
DataContext(path);
cats:Table<Categorias> :=
db.GetTable<Categorias>();
subcats:Table<Sub
categorias>:=db.
GetTable<Subcategorias>();
Begin
Var query:= from cat in cats
join subcat in
subcats
on cat.
CategoriaID equals subcat.
CategoriaID
order by
cat.CatNome
select new
class (cat.CatNome,subcat.
SubcatNome);
dataGridView1.DataSource :=
query;
end;
Temos quatro variáveis,sendo a primeira é
armazenado o caminho do banco e a segunda
armazenda um DataContext que faz a conexão com
o banco . As varíaveis categoria e subcategoria são
do tipo table e através do método getTable elas
referenciam seu tipo genérico.
Em query temos os alias categoria e subcategoria representando as variaveis categorias e
subcategorias respectivamente.
Em “on categoria.CategoriaID equals subcategoria.CategoriaID” é feito o join. Os registros são
ordenados em “order by Categoria.Nome”.
março 2009
19
O resultado é retornado numa nova classe (
select new class (categoria.Nome,subcategoria.
Nome)
Atribuimos o resultado “query” que é um
collection em um DataGridView.
Nota do consultor.
A classe DataContext é uma classe LINQ
to SQL que atua como uma ponte entre o
banco de dados SQL Server e as classes das
entidades LINQ To SQL mapeadas para o
banco de dados. Ela contém a informação e os
métodos para efetuar a conexão com o banco
de dados e manipular os dados.
Da mesma forma , no botão query simples
adicione o código abaixo:
Imagem 9.
LINQ TO XML
method MainForm.Simples_
Click(sender: System.
Object; e: System.
EventArgs);
Var
Path :String :=
System.IO.Path.
GetFullPath(tbDataBase.
text);
// inicialização da
variável para pegar o
banco de dados
db:DataContext := new
DataContext(path);
// Criação do Contexto
begin
Var contato:=
from contato in
db.GetTable<Contatos>()
where
contato.contatonome =
‘JOSE’
select
contato;
dataGridView1.DataSource
:= contato; // atribuo a
collection ao datasource
end;
20
março 2009
O LINQ to XML é um provedor de dados LINQ
que é implementado no namespace System.Xml.
LINQ a partir da versão 3.5 da plataforma .NET. Ele
fornece um modelo de programação que permite
ler, construir e escrever dados XML. Você pode usar
LINQ To XML para realizar consultas LINQ sobre
dados no formato XML que podem ser retornados
do arquivo de sistemas, de uma URL HTTP remota,
de um web service ou partir de qualquer XML em
memória existente.
Observe a hierarquia da classe linq to XML.
Veja a Imagem 9.
As principais classes do link to xml são:
•
XDocument
Atua como um
container para a árvore XML e deve ser usado
somente se necessário. Você pode salvar o documento com um arquivo XML.
•
XElement Permite criar elementos
, modificar o conteúdo dos elementos (incluir,
remover, modificar elementos filhos), modifica os
atributos dos elementos , salvar como um arquivo
XML.
•
XAttributeUsado para criar um par
nome/valor no interior de um elemento do arquivo
XML.
•
XName Representa um nome completo XML consistindo de um objeto XNamespace
e do nome local.
•
XComment
Representa um
comentário XML.
•
XDocumentType
Representa um
documento XML DTD - Document Type Definition.
•
XProcesingInstructionRepresenta o
processamento de uma instrução de um documento XML.
•
XTest
Representa um nó Texto.
•
XDeclaration
Representa uma
declaração XML.
O LINQ TO XML gera arquivos xml diretamente a partir das classes. Isso implica em redução
de linha de código em até 4 vezes. Outro ponto
importante é que o XML até então não tinha boa
integração com as linguagens, sendo necessário
o uso de diversas API’s.
Vamos criar um pequeno exemplo desse
poderoso recurso utilizando um array de livros.
Crie um novo projeto em files->new projet 
windowapplication
Adicione dois textbox e dois buttons. O layout
ficará assim:
Veja a Imagem 10
Para criar documentos completos XML você
deve primeiro instanciar o objeto XDocument e
então incluir o elemento XElement, XAtributte ou
outra entidade que o documento necessita. Clique
no botão gerar XML e adicione o código abaixo
Imagem 10.
Var
xml:System.Xml.Linq.
XElement;
begin
xml:=
new xElement(‘Clientes’,
new xElement(‘Cliente’,
new
xAttribute(‘codigo’,’1’),
New
XElement(‘nome’,
‘Alexandre’),
New
XElement(‘email’,
‘[email protected]’)),
New
XElement(‘cliente’,
New XAttribute(‘codigo’,
‘2’),
O arquivo xml foi atribuido para o textbox1
. Foi utilizado o método toString para conversão
de tipos. Um arquivo teste.xml foi gerado no
diretório raiz.
No botão consultar xml adicione o código
abaixo.
var
xml := XElement.
Load(‘c:\teste.xml’,
LoadOptions.SetBaseUri
or LoadOptions.
SetLineInfo);
begin
var consulta :=
v in xml.Elements
from
where
v.Attribute(‘codigo’).
Value = ‘2’
select v;
New XElement(‘nome’,
‘Antonio’),
For each cons in
consulta do
textBox2.Text:=
cons.ToString;
New XElement(‘email’,
‘[email protected]’)));
end;
textBox1.Text:=
xml.ToString();
xml.Save(‘c:\
teste.xml’);
end;
Na variável xml foi atribuido o conteúdo
do arquivo teste.xml por intermédio da classe
XElement.
O LoadOption possui quatro opções . None :
todas as linhas desnecessárias,linhas em branco e
linhas de informações, do arquivo XML não serão
carregadas. PreserveWhitespace: essa opção define que todas as linhas em branco do arquivo XML
março 2009
21
Imagem 11.
serão preservadas. SetBaseUri : essa opção define
o preenchimento da propriedade BaseUri. SetLineInfo: essa opção habilita o preenchimento da das
informações de linha, essa informações pode ser
recuperadas através da interface IXmlLineInfo.
Na variável consulta atribuímos os elementos
do arquivos onde o atributo código seja igual a 2.
Observe o resultado da consulta.
Veja a imagem 11.
Conclusão
Com esses exemplos dá para se ter uma ídéia
do poder do Linq para manipulação de objetos,
consultas e de arquivos xml. A Linq promete, sobretudo ser uma nova forma de trabalho de dados
em memória.
Sobre o autor
Luís Alexandre de Oliveira é Técnologo em Processamento de Dados ,graduado
pela Faculdade de Técnologia de Sorocaba,
Consultor técnico do The Club.
Docente do curso técnico informática - Etec
de Avaré e do curso Tecnologia em Redes de
Computadores - Fatec Eduvale – Avaré
22
março 2009
Referências:
http://www.microsoft.com/brasil/msdn/Tecnologias/arquitetura/LINQ.mspx
http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx
http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx
http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx
http://blogs.embarcadero.com/pawelglowacki/2005/09/22/21244
http://blogs.teamb.com/craigstuntz/2007/03/28/33565/
http://msdn.microsoft.com/pt-br/library/system.xml.linq.aspx
http://edn.embarcadero.com/br/article/39135
Microsoft Visual C# Passo a Passo - John Sharp
março 2009
23
Trabalhando com Dynamic
Data Controls
O ASP.NET ultimamente vem revolucionou o desenvolvimento de aplicações para
web oferecendo uma plataforma robusta e
altamente produtiva elevando o potencial
dos desenvolvedores com excelente recursos
como: GridView, DataControls, Validators ,
WebParts entre outros.
A
o longo dos anos, outras necessidades foram surgindo no mercado
como a criação de telas automáticas
de cadastro conhecidas atualmente
como Scaffold bastante populares com o Ruby
on Rails.
Já faz algum tempo que a Microsoft vem
investindo em linguagens dinâmicas e agora, com
o lançamento do Service Pack 1 do .NET 3.5, foi
disponibilizando dentro do ASP.NET um novo conjunto de controles conhecido como Dynamic Data
Controls que tem objetivo de montar as telas para
as ações básicas de qualquer CRUD (Create, Read,
Update, Delete).
Logo após instalar o Service Pack 1 do Visual
Studio 2008, vai aparecer, conforme apresentado
na figura abaixo, mais um novo tipo de projeto web
para o .NET 3.5 chamado de “Dynamic Data”
Veja na imagem 1.
Após criar seu novo projeto, verifique nas
referências e vai observar que ele traz as os novos
namespaces System.Web.DynamicData e System.
Web.DynamicData.Design.
A funcionalidade Dynamic Data Controls trabalha em conjunto com o LINQ TO SQL e Entities
FrameWork, pois ele precisa de uma interface de
acesso a dados que será utilizada para gerar as
funcionalidade em tempo de execução.
Imagem 2.
Bem agora para continuarmos com o exemplo
precisamos de uma base de dados e um diagrama
LINQ que será utilizado pela aplicação. Vou utilizar
um banco de dados .mdb so SQLExpress que já
tenho pronto.
Agora vou criar o Diagrama LINQ e adicionar
as tabelas que desejo trabalhar em meu projeto,
para isso basta clicar com o lado direto do mouse
no projeto, selecionar a opção add new item, e
selecionar o DataClasses.dbml do LINQ. Como na
imagem abaixo.
Veja a imagem 2.
Veja a imagem 3.
24
março 2009
Imagem 1.
Imagem 3.
março 2009
25
Imagem 4.
Feito isso, agora vamos arrastar as tabelas que
iremos utilizar no projeto para o diagrama do LINQ.
Como na imagem abaixo.
Agora vem a parte mais simples do projeto
que será a implementação propriamente dita, ou
seja onde colocamos a mão na massa, mais fique
tranqüilo que com esta ferramenta trabalharemos
muito pouco pois a idéia e que tudo seja gerado em
tempo de execução. Para isso temos que configurar
o Dynamic Data para utilizar o LINQ to SQL e gerar
automaticamente as telas de manipulação das
tabelas do diagrama.
O primeiro lugar que vamos alterar e no arquivo global.asax nele devemos localizar o método
RegisterRoutes() e dentro do mesmo modifique a
linha Model.RegisterContext adicionando o nome
do diagrama gerado pelo LINQ que para o nosso
exemplo que foi DataClassesDataContext alterando
o valor de ScaffoldAllTables para true
Veja a Imagem 5.
OBS: Esta linha geralmente vem comentada
dentro do arquivo global.asax devemos descomenta-la e fazer as alterações necessárias
Imagem 5.
Pronto acabamos nosso projeto! Você pode
estar se perguntando, nossa mais não fiz “quase
nada”...
Para ver o resultado basta rodar sua aplicação,
e você verá as paginas de lista, inserção, deleção e
edição prontas para utilização. Como nas imagens
abaixo.
Aqui temos o menu principal com acesso a
todas as paginas do sistema:
Veja a imagem 6.
26
março 2009
Ao Clicar no link de Produtos olha que legal,
teremos um grid com os produtos cadastrados,
onde as colunas do Grid são as mesmas colunas
da Tabela, e o mais interessante e o filtro que foi
gerado automaticamente de acordo com as Chaves
da tabela de Produtos, tem também a paginação
do Grid e tudo isso sem escrever nenhuma linha de
código, temos também links para edição e deleção
do produto e isso acontece para todas as tabelas
relacionadas no diagrama.
Note fizemos esse projeto em 45 min.
Veja a imagem 7.
Imagem 6..
Imagem 7.
Você pode estar se perguntando e o layout
como fica, não gostei desse, esta fora do padrão
da minha empresa ou do meu site, não tem
problema ele e feito todo em cima de CSS, você
poderá customizar tudo, pode também gerar
paginas personalizadas editar somente o GRID de
Produtos, a ferramenta e bem Flexível. Agora você
precisa tomar cuidado para que sua customização
não te leve a fazer tudo do zero ai vale mais apena
fazer de outra maneira. Esta ferramenta trará maior
benefício se tiver pouca customização.
Espero ter ajudado.
Bons Códigos...
Sobre o autor
Fabiano Belmonte
Senior Architect da InfoMoney.com, especialista em aplicações e-Business com larga experiência em
B2B (Submarino.Com e Saraiva.Com). Trabalha há 5 anos com a tecnologia .Net, aplicando conhecimentos
nas diversas áreas: instituições financeiras (sistema SPB), e-Commerce, gerenciamento logístico entre
outras. Trabalhando com Visual Studio desde suas primeiras versões, responsável pela implementação de
uma Metodologia de trabalho e melhoras significativas no resultados e na qualidade do time de Desenvolvimento de muitas empresas por onde passou como (Saraiva.Com) e ferramentas como TFS (Team
Foundation Server).
Foi palestrante em eventos como Codificando. NET 2008 e outros eventos sobre Tecnologia .NET.
março 2009
27
Dicas DELPHI
Ativar Auto Run do CD ROM
// Declare
USES.
Registry
na seção
procedure
SetCDAutoRun(AAutoRun:Boolean);
const
DoAutoRun : array[Boolean] of
Integer = (0,1);
var
Reg:TRegistry;
begin
try
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_
MACHINE;
if Reg.KeyExists(‘System\
CurrentControlSet\Services\Class\
CDROM’) then
begin
if Reg.OpenKey(‘System\
CurrentControlSet\Services\Class\
CDROM’, FALSE) then
begin
Reg.
WriteBinaryData’AutoRun’,
DoAutoRun[AAutoRun], 1);
end;
end;
finally
Reg.Free;
end;
ShowMessage(‘Esta alteração só
será ativada após a reinicialização
do PC.’);
end;
Criptografar Strings
function Criptografar( const Str1:
string): String;
var
Mascara,Str2: String;
PonM, PonS: Byte;
begin
28
março 2009
Mascara := ‘#$%$’#13#12;
Str2 := ‘;
PonM := 1;
for PonS:=1 to length(Str1) do
begin
AppendStr( Str2, Chr(
Ord(Str1[PonS]) Xor
Ord(Mascara[PonM])));
Inc( PonM);
if PonM>Length(Mascara) then
PonM:=1;
end;
Result := Str2;
end;
Ver se existe Midia no Drive
function DiskInDrive(Drive: Char):
Boolean;
var
ErrorMode: word;
begin
Drive: = UpCase(Drive);
if not (Drive in [‘A’..’Z’]) then
raise EConvertError.Create(‘Not a
valid drive ID’);
ErrorMode := SetErrorMode(SEM_
FailCriticalErrors);
try
if DiskSize(Ord(Drive) - $40) = -1
then
DiskInDrive := False
else
DiskInDrive := True;
finally
SetErrorMode(ErrorMode);
end;
end;
Ver Impressora Conectada
Function ImpresConect(Porta:Word):B
oolean;
Const
Portas :Byte = $02;
Var
Res :Byte;
Begin Asm
mov ah,Portas;
mov dx,Porta;
Int $17;
mov Res,ah;
end;
Result := (Res and $80) = $80;
end;
Localizar Arquivos no Windows
TForm1 = class(TForm)
Label1: TLabel;
ListBox1: TListBox;
Button1: TButton;
procedure ListBox1Click(Sender:
TObject);
procedure Button1Click(Sender:
TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
procedure TForm1.
Button1Click(Sender: TObject);
begin
with TDDEClientConv.Create(Self) do
begin
ConnectMode := ddeManual;
ServiceApplication := ‘explorer.
exe’;
SetLink( ‘Folders’,
‘AppProperties’);
OpenLink;
ExecuteMacro(‘[FindFolder(, C:\
Windows)]’, False);
CloseLink;
Free;
end;
end
Mostrar as fontes True Types instaladas no Windows
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics,
Controls, Forms, Dialogs,
StdCtrls;
{$R *.DFM}
// Evento OnClick do componente ListBox
procedure TForm1.ListBox1Click(Sender:
TObject);
begin
// A linha abaixo atribui a propriedade
Caption do
// componente Label o nome da fonte
selecionada no
// componente ListBox
Label1.Caption := ListBox1.
Items[ListBox1.ItemIndex];
// A linha abaixo muda a fonte de letra
de acordo
// com a fonte selecionada no
componente Listbox
Label1.Font.Name :=
ListBox1.Items[ListBox1.ItemIndex];
end;
// Evento OnClick do componente Button
procedure TForm1.Button1Click(Sender:
TObject);
begin
// Carrega as fontes instaladas no
Windows para
// o componente ListBox
ListBox1.Items := Screen.Fonts;
end;
type
março 2009
29
30
março 2009
março 2009
março 2009
Download

Dicas DELPHI