Você está na página 1de 2112

ENTRAR

Publicidade

Quer anunciar aqui? Clique Aqui


Apoio:
Apresenta

850 Dicas de Programação Delphi


Programador:

José J. Carvalho Júnior

<= Lloyd Dickinson =>

HP:http://lloydsoft.no-
ip.com

E-
Mail:lloydsoft@yahoo.com.br
Última Atualização:
14/02/2005

Made in Riachuelo - Sergipe


- BR
Se quiser aprender mais sobre
programação
Clique Aqui
Agradecimentos
The Programmer - dprogrammer_br@yahoo.com.br
Membros da comunidade “Delphi” que colaboraram:
- Adriano
- Alex Mazaron - Apucarana - Paraná. -
www.mazaron.hpg.ig.com.br;
- Alexandre de Andrade Gonçalves;
- André Luiz dos Reis - Londrina - Paraná;
- andrepbol@bol.com.br
- André Fisher - Bacharel em Ciências da Computação e apaixonado
pelo Delphi
- Antonio Carvalho - Portugal;
- Bruno Martins Stuani
- Carlos Naves
- Carlos Hegeto Junior
- Daniel P. Guimarães - IntereSite -
www.ulbrajp.com.br/~tecnobyte;
- David
- Douglas Junior Ferreira - Joinville - SC - Brasil
- Ederson Rutz Fischer - desenvolvedor - VB 6 - Oracle 8 - Delphi
6 - Access 2000
- Elionai
- eltonsilva@sinos.net
- Fábio André Campos da Cruz
- Fábio K. Salviano
- Fábio Macedo Garcia
- Fabio Tinti
- Felipe
- Francisco Rosemberg - São B. do Campo - SP -
www.comunidadedelphi.hpg.ig.com.br;
- Gelson Luiz
- Guilherme
- Gladson J. Reis Vieira - Belo Horizonte - MG - Brasil
- Hélton Ribeiro Nunes - Tubarão-SC - Brasil;
- Henrique Meira - Grupo Delphi-BR -
www.pedgih.hpg.ig.com.br
- Heverton Luiz Fornazari
- Israel Calheiros - Rio de Janeiro - RJ - Brasil;
- Jacks Paciornick
- Jackson Pires de O. S. Júnior - Téc. em Informática -
Paulo Afonso - BA - Brasil;
- Jason Lopes G Silva
- Jasoni Corrêa - Enviou uma dica usando o formulário do site
- Jefferson Hilgert - Toledo - PR - Brasil -
www.bestreader.com;
- Joubert Rinaldi
- José Amparo Soares - Belo Horizonte - MG - Brasil
- Jucicleia Castro - Macapá- Amapá - Brasil;
- Klebyu Boy - Tangara da Serra - MT
- Lucas Augusto Deters - ITAPIRANGA - SANTA
CATARINA
- Luis Felipe Cipriani
- Luis Henrique - Analista de Sistemas;
- Márcio William - Rio de Janeiro - RJ - Brasil;
- Marcus Vitoratti
- Marco Barki Algranti - Diretor Técnico - Wisys Produtos
Inteligentes
- Marcio Souza
- MuriloSH
- Pablo Gomes Mariano - Enviou uma dica usando o formulário do site
- Paulo Henrique de F. Martins
- Ricardo C. Figueiredo
- Rodrigo Jacobowski - Enviou uma dica usando o formulário do site
- Ronald Reis
- Silvio Guedes dos Santos - Programador - João Pessoa - PB -
Brasil
- Sinomar P de Morais (Pedro) - Brasília - DF - Brasil;
- Themys Tadeu Macedo Carvalho Neres - DBA -
Analista de Sistemas
- Thiago Ribeiro da Silva
- Tiago Santos - Lisboa - Portugal.
- William Zonta Mendonça
Colaboradores da DTDelphi 2.7
A. Varaschin
Adriano Santos
Amilton Maciel
Carlos Alberto Ribeiro
Carlos Karol
Aldebaran Beloli Martini
Andréa Santos Figueiredo
Antônio Carlos
Bizarro
Claudemiro Freitas
Cleiton S. Goulart
Clériston Martinelo
Clóvis Vigari Vento
Daniel Arantes de Oliveira
Daniel Fabiano Correia
Diorgenes C. Tavares
Flávio Rafael de Oliveira
Gefirson Plínio Duarte
Hildeberto Melo
Jackson Pires de O. S. Júnior
José do Amparo Soares
José Roberto F. de Araújo Junior
José Roberto Marque
Luciano Henrique
Marcelo Otone Aguiar
Marcos das Neves
Mauricio de Lima
Renato Arcon Gaio
Rogério Corrêa Magro
Rulio Vangellis
Snake_Ice

Gostaria de avisar a todos os companheiros que o


objetivo desta lista de dicas e truques que criei é facilitar
o uso do Delphi.
Espero que todos contribuam para aumentar esta lista.
Envie qualquer dica ou truque, sugestões ou críticas
para lloydsoft@yahoo.com.br
Está autorizado a qualquer pessoa que quiser
disponibilizar esta lista em seus sites.
Passe para seus colegas, Vamos juntos desvendar
este genioso programa!!!!
Visite a minha HP e fique atualizado sobre novas
versões!!!
http://lloydsoft.no-ip.com
Obrigado,

Lloyd Dickinson
Atualizações
Dicas Dicas
Versão
Adicionadas Modificadas
1.0 - 50 dicas 50 0
1.1 - 78 dicas 28 0
1.2 - 115 dicas 37 0
1.3 - 145 dicas 30 0
1.4 - 179 dicas 34 0
1.5 - 208 dicas 19 0
1.6 - 229 dicas 21 0
1.7 - 300 dicas 71 0
1.8 - 350 dicas 50 0
1.9 - 400 dicas 50 1
2.0 - 500 dicas 100 1
2.1 - 550 dicas 50 6
2.2 - 600 dicas 50 2
2.3 - 650 dicas 50 4
2.4 - 700 dicas 50 4
2.5 - 750 dicas 50 12
2.6 - 800 dicas 50 26
2.7 - 850 dicas 50 10
Obs.: Muitos usuários me perguntam o porque
da demora para atualizar a DTDelphi! É Simples!
Só atualizo quando há novas dicas suficientes
para dar um acréscimo significativo a lista, ou
seja, quando consigo encontrar 50 novas dicas,
atualizo! Por isso que é muito importante a
contribuição de todos que a utilizam!
Vamos lá!! Estamos quase chegando a 1000!!

Para Atualizar o DTDelphi


Clique Aqui
Lista de Discussão
Algum tempo atrás alguns usuários da DTDelphi
sugeriram a criação de um grupo de discussão para a
mesma. Não achei assim tão interessante só que hoje o
número de usuários da DTDelphi está tão grande que
me vi forçado a criar um grupo de discussão exclusivo
para DTDelphi.
Neste grupo os participantes podem tirar dúvidas sobre
as dicas e discutirem alterações na dicas e muito mais!
Se você quer participar do Grupo da DTDelphi mande
um e-mail para:
DTDelphi-subscribe@yahoogrupos.com.br
O objetivo desse grupo é auxiliar no crescimento da
DTDelphi e manter um contato direto com todos os
usuários da DTDelphi assim como obter ajudar referente
a alguma dica como também receber informações sobre
atualização da mesma. Entre outros poderão facilmente
entrar em contato comigo!
Depois de inscrito basta enviar email´s para:
DTDelphi@yahoogrupos.com.br
Aviso
Antes de começar a utilizar estas dicas tenha em
atenção que pode perder ou danificar
informação no seu computador, por isso eu desde
já aviso que não sou responsável pelos danos
causados.
Lista de Discussão
Algum tempo atrás alguns usuários da DTDelphi
sugeriram a criação de um grupo de discussão para a
mesma. Não achei assim tão interessante só que hoje o
número de usuários da DTDelphi está tão grande que
me vi forçado a criar um grupo de discussão exclusivo
para DTDelphi.
Neste grupo os participantes podem tirar dúvidas sobre
as dicas e discutirem alterações na dicas e muito mais!
Se você quer participar do Grupo da DTDelphi mande
um e-mail para:
DTDelphi-subscribe@yahoogrupos.com.br
O objetivo desse grupo é auxiliar no crescimento da
DTDelphi e manter um contato direto com todos os
usuários da DTDelphi assim como obter ajudar referente
a alguma dica como também receber informações sobre
atualização da mesma. Entre outros poderão facilmente
entrar em contato comigo!
Depois de inscrito basta enviar email´s para:
DTDelphi@yahoogrupos.com.br
Lloyd Dickinson
Deletar Registro
{Button.click}
if MessageDlg(‘Tem Certeza Que deseja
Excluir Este Registro?’, mtConfirmation,
[mbYes, mbNo], 0) = mrYes then
begin
Table1.Delete;
end;
Enter To Tab
{TForm1.FormKeyPress}
if key= #13 then
begin
Perform (CM_DialogKey, VK_TAB, 0);
key:=#0;
end;
Esc Para Sair
{TForm1.FormKeyDown}
case key of
vk_Escape: entrada.close;
end;
begin
case key of
vk_Escape: Table1.cancel;
end;
end;
Ponto Por Virgula
{TForm1.FormKeyPress}
if key= ‘.’ then
key:=’,’;
Tudo Maiusculo
{FormKeyPress:=True}
procedure TForm1.Memo1KeyPress(Sender:
TObject; var Key: Char);
begin
Key := AnsiUpperCase(Key)[Length(Key)];
end;
{“A dica acima foi modificada pelo
Anderson Biz”
- Valeu pela colaboração!!}
Identar
Ctrl + Shift + I para identar
Ctrl + Shift + U para desidentar
Curiosidades
Para você ver a versão do seu DELPHI entre no
menu Help opção About… Quando aparecer o form
AboutDelphi digite VERSION com o <alt> da
esquerda pressionado.
Para você conhecer a equipe que trabalhou no
desenvolvimento do DELPHI entre no menu Help
opção About… Quando aparecer o form
AboutDelphi digite DEVELOPERS com o <alt> da
esquerda pressionado.
tente também CHUCK com o <alt> da esquerda
pressionado.
tente também QUALITY com o <alt> da esquerda
pressionado.
tente também TEAM com o <alt> da esquerda
pressionado.
Como desabilitar a tela de abertura
do Delphi
No Windows, a partir do atalho para o programa, entre
em Propriedades e inclua -ns ao final da linha de
comando.
Como evitar que o Delphi abra um
projeto padrão
No Windows, a partir do atalho para o programa, entre
em Propriedades e inclua -np ao final da linha de
comando.
A Origem do Nome Delphi
“Delphi” começou como codinome de um projeto
altamente secreto na Borland: uma nova geração de
ambiente de desenvolvimento visual para Windows,
baseado na linguem de programação Object Pascal.
Este codinome foi lançado em meados de 1993, após a
equipe de desenvolvimento ter passado 6 meses de
pesquisas, testes e análise de marketing. Integrantes da
equipe de desenvolvimento Pascal ficavam se reunindo
no escritório do Gerente de desenvolvimento Gary
Whizin, para debater possíveis nomes para o novo
produto. Não era um escritório muito grande, mas a
equipe não era tão grande também - cerca de 10
pessoas entre gerentes, analistas, marketing.
Era comum ver Anders Heilsberg, Chuck Jazdzewski,
Allen Bauer, Zack Urlocker, Richard Nelson, eu, e
diversas outras pessoas batendo papo na sala do Gary.
Nas sessões de discussão sobre o codinome havia
gente se espremendo nos corredores.
A Borland tem uma longa tradição em criar codinomes
“diferentes”, alguns como slogans “inteligentes” ou
imagem que o relacionava ao marketing e ao foco do
produto. Um codinome, como é chamado o nome do
produto beta, não deve ter nenhuma relação óbvia com
o produto, para que caso algum espião ouça o seu
nome numa conversa não fique tão óbvio qual produto
estão discutindo.
Nós estavamos sempre sentados no escritório do Gary
sugerindo estranhos e esquisitos codinomes para o
produto. A decisão estratégica de tornar as ferramentas
de banco de dados e a conectividade parte central do
novo produto Pascal, tinha sido feita apenas alguns dias
antes. Então Gary estava ansioso para ter um codinome
que indicasse o novo “foco” de banco de dados. O tema
banco de dados não foi passageiro - eu me lembro de
ser relutante em “poluir” as ferramentas Pascal com este
tema. Foi um passo arriscado para a Borland, mas tudo
foi muito planejado e implementado. Por outro lado,
tornar o Delphi um produto para banco de dados era
exatamente o que faltava para impulsionar as
ferramentas Pascal da Borland sobre o mercado
“fechado” do Visual Basic e C++, e colocar o Delphi em
destaque entre as tradicionais ferramentas de
desenvolvimento para Windows.
Gary insistia no codinome “Oracle”, referindo-se a
conectividade com os servidores de banco de dados.
Entretanto, este nome não agradou ao grupo. Além da
confusão óbvia com a empresa Oracle e produtos para
servidores, este nome obrigava o Delphi a ter recursos
de servidor, enquanto, o produto que estavamos
desenvolvendo era uma ferramenta de criação de
programas para o cliente, simplesmente um método se
se comunicar com o Oracle e outros servidores de
banco de dados.
Como você conversa com um “oracle” ? “The Oracle at
Delphi” foi a associação de frase que surgiu na minha
cabeça. Então, eu sugeri “Delphi”: Se você quer
conversar como o Oracle, então vá para o Delphi.
A sugestão não “pegou” de primeira. Esse era um nome
velho, um lugar antigo, um templo pagão nas ruinas de
uma civilização extinta. Não era exatamente uma
brilhante associação para um novo produto! Apesar
disso tudo, o codinome “Delphi” ainda era bem melhor
do que os nomes absurdos que eram criados naquela
sala. O Pascal é uma linguagem de programação
clássica, o que combina direito com a clássica figura
Grega. E como os mitologistas Gregos dizem, o templo
de Delphi era o menos incestuoso, assassino e polêmico
da história Grega.
Nós passamos por diversos codinomes durante o
desenvolvimento da versão 1.0, apresentando diferentes
codinomes a cada apresentação corporativa ou
entrevistas do produto beta. Esta era uma estrategia de
limitar os rumores e identificar os possíveis furos de
informações. A última coisa que gostaríamos era que,
você sabe quem!, obter informações do que estavamos
fazendo. Após todos estes codinomes, o nome Delphi
“embalou”. No final da etapa de desenvolvimento, o
departamento de marketing começou a utilizar o
codinome Delphi em todas as apresentação a imprensa
e empresas, e também como codinome para as versões
betas finais. Isto despertou diversos rumores entre as
pessoas, e a industria de software só falava no projeto
secreto da Borland de codinome “Delphi”. J.D.
Hildebrand escreveu um editorial inteiro na revista
Windows Tech Journal sobre o “Efeito Delphi”, meses
antes do software ser lançado no mercado. Ele dizia:
“Não posso dizer o que é, mas posso dizer isto: o Delphi
irá transformar nossas vidas.”.
Quando chegou a hora de escolher um nome definitivo
para o produto, os nomes possíveis eram menos
inspiradores do que “Delphi”. O nome “funcional”, ou
seja, um nome que descreva o que o produto realmente
faz e, por sua vez, é muito mais fácil de divulgar, seria
“AppBuilder”. Esse nome ainda aparece em classes
internas do código do IDE, como por exemplo o nome
da classe da janela principal. Mas o nome AppBuilder
não animava as pessoas. Não funcionava bem para
outros países - somente era “funcional” na língua
inglesa.
Ainda bem que alguns meses antes do Delphi ser
lançado, a Novell criou um produto chamado Visual
AppBuilder. Pelo menos essa opção estava fora do
páreo. Sem um nome “funcional”, muitas pessoas
sugeriram manter o codinome Delphi para o nome final
do produto.
O nome Delphi ainda não estava definido. O chefe do
departamento de marketing tinha ínumeras
preocupações com o esforço extra que seria necessário
para a divulgação, no mercado, de um nome não-
funcional. Então ele pediu que fosse feita uma votação
entre os desenvolvedores. Somente teve um voto contra
(Advinhe de quem?). Mas alguém chegou a conclusão
que a equipe de desenvolvimento não possuia uma
visão estratégica de mercado, e organizaram uma
pesquisa com os usuários betas. Quando esta pesquisa
não produziu o resultado que gostaria, ela foi estendida
para as subsidiárias internacionais da Borland, analistas
de mercado, imprensa, consultores de empresas,
revendas, e provavelmente alguns clientes do K-Mart.
Isto virou uma comédia: quanto mais as pessoas
queriam abolir o nome “Delphi”, mais ele ganhava apoio.
“Delphi” tem uma imagem clássica. Possui uma
associação consistente em diferentes idiomas. Não
significa palavrões em nenhuma outra língua (que eu
saiba). Além de tudo, o pessoal do departamento de
marketing realizou um excelente trabalho de pre-
divulgação sobre o Delphi. O mercado foi abençoado
pelo nome “Delphi”.
E foi assim que o Delphi ganhou um nome.
by Danny Thorpe Senior Engineer, Delphi R&D Inprise
Corp
André Fischer
Texto enviado por SERAC 5
Links
Programação (Especialmente Delphi)
Active Delphi
Torry’s Delphi Pages.
Acrópole Delphi® - Cultura on line
THE CLUB - O maior clube de programadores do
Brasil!
Guia do Delphi
.. DelphiBR ..
IE & Delphi
Klibrary&webdesign
Boletim Pascal - Publicação gratuita
VCL Components - Delphi and C++ Builder
Components
Dr. Delphi - www.drdelphi.com.br
iMasters - Treinamento e Conteúdo
www.CodigoAberto.Net
Delphi Super Page
Walter Chagas - WebSite
Themys Delphi Page
Freecode .. A liberdade do Conhecimento.
INFOSQUAD.NET O seu portal de Tecnologia e
Informação
delphi3000.com - The Platform for all Delphi-
Developers
User Control Package for Delphi
Ivan Mecenas
BABOO 2003
ThaiDephiCC Update pack
br.geocities.com/fabiano_lh/index.html
www.fprass.hpg.com.br
www.edudelphipage.com.br
www.elivaldo.com.br
www.ramosdainformatica.com.br
Interbase & FireBird
Comunidade Firebird de Língua Portuguesa
Firebase
FIBPlus Download Components
OFF Topic
- Como zerar informações do setup
(incluindo a senha do mesmo).
No Prompt do DOS Digite DEBUG, no Prompt do
DEBUG digite:
o 70 2e (pressione enter)
o 71 ff (enter)
q (enter)
- Cabo CrossOver
O cabo CrossOver serve para interligar dois
computadores via cabo par trançado sem a necessidade
de HUB.
é só fazer um cado crossover e ligar nas 2 placas de
rede…
para fazer o cabo faça o seguinte:
SEQUÊNCIA 1
1 = Branco-Verde
2 = Verde
3 = Branco-Laranja
4 = Azul
5 = Branco-Azul
6 = Laranja
7 = Branco-Marrom
8 = Marrom

SEQUÊNCIA 2

1 = Branco-Laranja
2 = Laranja
3 = Branco-Verde
4 = Azul
5 = Branco-Azul
6 = Verde
7 = Branco-Marrom
8 = Marrom

* Cabo normal monta-se as 2 pontas c/ a seqüência 1


* Cabo CrossOver monta-se 1 ponta com cada
sequência
A pinagem começa da direita para esquerda estando o
conector com a aste voltada para cima.
- Compartilhamento invisível
dica legal. Coloque o sinal de $ no final do
compartilhamento. Ex: \servidor\c\dados$ Com isto ele
fica INVISÍVEL. Como só vc sabe o nome (e o seu
sistema, claro!) só será acessado por vc.
Tabela ASCII
Dec Hex Char Dec Hex Char Dec Hex Char Dec Hex Char

0 0 NUL 32 20 64 40 @ 96 60 `

1 1 SOH 33 21 ! 65 41 A 97 61 a

2 2 STX 34 22 “ 66 42 B 98 62 b

3 3 ETX 35 23 # 67 43 C 99 63 c

4 4 EOT 36 24 $ 68 44 D 100 64 d

5 5 ENQ 37 25 % 69 45 E 101 65 e

6 6 ACK 38 26 & 70 46 F 102 66 f

7 7 BEL 39 27 ‘ 71 47 G 103 67 g

8 8 BS 40 28 ( 72 48 H 104 68 h

9 9 TAB 41 29 ) 73 49 I 105 69 i

10 A LF 42 2A * 74 4A J 106 6A j

11 B VT 43 2B + 75 4B K 107 6B k

12 C FF 44 2C , 76 4C L 108 6C l

13 D CR 45 2D - 77 4D M 109 6D m

14 E SO 46 2E . 78 4E N 110 6E n

15 F SI 47 2F / 79 4F O 111 6F o

16 10 DLE 48 30 0 80 50 P 112 70 p

17 11 DC1 49 31 1 81 51 Q 113 71 q

18 12 DC2 50 32 2 82 52 R 114 72 r
19 13 DC3 51 33 3 83 53 S 115 73 s

20 14 DC4 52 34 4 84 54 T 116 74 t

21 15 NAK 53 35 5 85 55 U 117 75 u

22 16 SYN 54 36 6 86 56 V 118 76 v

23 17 ETB 55 37 7 87 57 W 119 77 w

24 18 CAN 56 38 8 88 58 X 120 78 x

25 19 EM 57 39 9 89 59 Y 121 79 y

26 1A SUB 58 3A : 90 5A Z 122 7A z

27 1B ESC 59 3B ; 91 5B [ 123 7B {

28 1C FS 60 3C < 92 5C \ 124 7C |

29 1D GS 61 3D = 93 5D ] 125 7D }

30 1E RS 62 3E > 94 5E ^ 126 7E ~

31 1F US 63 3F ? 95 5F _ 127 7F DEL
Caracteres Especiais
Código ASCII na Fonte Courier New
Ascii 0 {Nulo, Sem Som}
Ascii 1
Ascii 2
Ascii 3
Ascii 4
Ascii 5
Ascii 6
Ascii 7
Ascii 8 {BackSpace}
Ascii 9 {Tab}
Ascii 10
Ascii 11
Ascii 12
Ascii 13 {Enter}
Ascii 14
Ascii 15
Ascii 16 {Shift}
Ascii 17 {CTRL}
Ascii 18 {ALT}
Ascii 19
Ascii 20 {CapsLock}
Ascii 21
Ascii 22
Ascii 23
Ascii 24
Ascii 25
Ascii 26
Ascii 27
Ascii 28
Ascii 29
- Ascii 30
- Ascii 31
Ascii 32 {Espaço}
! Ascii 33
” Ascii 34
# Ascii 35
$ Ascii 36
% Ascii 37
& Ascii 38
‘ Ascii 39
( Ascii 40
) Ascii 41
* Ascii 42
+ Ascii 43
, Ascii 44
- Ascii 45
. Ascii 46
/ Ascii 47
0 Ascii 48
1 Ascii 49
2 Ascii 50
3 Ascii 51
4 Ascii 52
5 Ascii 53
6 Ascii 54
7 Ascii 55
8 Ascii 56
9 Ascii 57
: Ascii 58
; Ascii 59
< Ascii 60
= Ascii 61
> Ascii 62
? Ascii 63
@ Ascii 64
A Ascii 65
B Ascii 66
C Ascii 67
D Ascii 68
E Ascii 69
F Ascii 70
G Ascii 71
H Ascii 72
I Ascii 73
J Ascii 74
K Ascii 75
L Ascii 76
M Ascii 77
N Ascii 78
O Ascii 79
P Ascii 80
Q Ascii 81
R Ascii 82
S Ascii 83
T Ascii 84
U Ascii 85
V Ascii 86
W Ascii 87
X Ascii 88
Y Ascii 89
Z Ascii 90
[ Ascii 91
\ Ascii 92
] Ascii 93
^ Ascii 94
_ Ascii 95
` Ascii 96
a Ascii 97
b Ascii 98
c Ascii 99
d Ascii 100
e Ascii 101
f Ascii 102
g Ascii 103
h Ascii 104
i Ascii 105
j Ascii 106
k Ascii 107
l Ascii 108
m Ascii 109
n Ascii 110
o Ascii 111
p Ascii 112
q Ascii 113
r Ascii 114
s Ascii 115
t Ascii 116
u Ascii 117
v Ascii 118
w Ascii 119
x Ascii 120
y Ascii 121
z Ascii 122
{ Ascii 123
| Ascii 124
} Ascii 125
~ Ascii 126
Ascii 127
¬ Ascii 128
Ascii 129
Ascii 130
’ Ascii 131
Ascii 132
&ldots; Ascii 133
Ascii 134
! Ascii 135
Æ Ascii 136
0 Ascii 137
` Ascii 138
9 Ascii 139
R Ascii 140
Ascii 141
Ž Ascii 142
Ascii 143
Ascii 144
‘ Ascii 145
‘ Ascii 146
” Ascii 147
” Ascii 148
o Ascii 149
- Ascii 150
- Ascii 151
Ü Ascii 152
” Ascii 153
a Ascii 154
: Ascii 155
S Ascii 156
Ascii 157
~ Ascii 158
x Ascii 159
Ascii 160
¡ Ascii 161
¢ Ascii 162
£ Ascii 163
¤ Ascii 164
¥ Ascii 165
¦ Ascii 166
§ Ascii 167
¨ Ascii 168
© Ascii 169
ª Ascii 170
« Ascii 171
Ascii 172
Ascii 173
® Ascii 174
¯ Ascii 175
° Ascii 176
± Ascii 177
² Ascii 178
³ Ascii 179
´ Ascii 180
µ Ascii 181
Ascii 182
· Ascii 183
¸ Ascii 184
¹ Ascii 185
º Ascii 186
» Ascii 187
¼ Ascii 188
½ Ascii 189
¾ Ascii 190
¿ Ascii 191
À Ascii 192
Á Ascii 193
 Ascii 194
à Ascii 195
Ä Ascii 196
Å Ascii 197
Æ Ascii 198
Ç Ascii 199
È Ascii 200
É Ascii 201
Ê Ascii 202
Ë Ascii 203
Ì Ascii 204
Í Ascii 205
Î Ascii 206
Ï Ascii 207
Ð Ascii 208
Ñ Ascii 209
Ò Ascii 210
Ó Ascii 211
Ô Ascii 212
Õ Ascii 213
Ö Ascii 214
× Ascii 215
Ø Ascii 216
Ù Ascii 217
Ú Ascii 218
Û Ascii 219
Ü Ascii 220
Ý Ascii 221
Þ Ascii 222
ß Ascii 223
à Ascii 224
á Ascii 225
â Ascii 226
ã Ascii 227
ä Ascii 228
å Ascii 229
æ Ascii 230
ç Ascii 231
è Ascii 232
é Ascii 233
ê Ascii 234
ë Ascii 235
ì Ascii 236
í Ascii 237
î Ascii 238
ï Ascii 239
ð Ascii 240
ñ Ascii 241
ò Ascii 242
ó Ascii 243
ô Ascii 244
õ Ascii 245
ö Ascii 246
÷ Ascii 247
ø Ascii 248
ù Ascii 249
ú Ascii 250
û Ascii 251
ü Ascii 252
ý Ascii 253
þ Ascii 254
ÿ Ascii 255
Lista Geral
1. Como Fazer um Protetor de Tela no Delphi
2. Linkar um OBJ ao executavel
3. Alterar o LOCAL SHARE via programação
4. Verificando se o Delphi esta Aberto
5. Criando Formulários
6. Criado Alias via programação
7. Desabilitar Teclas Alt+Ctrl+Del
8. Splash Screen
9. Para Saber Somente o Path da Aplicação
10. Como Saber se o aplicativo ja foi aberto
11. Impressão Com o TPrinter
12. Imprimir Direto Para Impressora
13. Definir o tamanho do papel em Tprinter
14. Como Criar Forms Em Tempo de Execução
15. Adaptando para resoluções de video
diferentes
16. Executar um programa do DOS
17. Como posso rolar um form com PgUp e PgDn
18. Tocando Sons WAV
19. Colocando funções em uma DLL
20. Compactando Tabelas
21. Verifica Validade de CGC e CPF
22. Gera número por extenso
23. Preenche com quantidade determinada de
zeros o lado esquerdo de uma string
24. Ponto Decimal
25. FindNearest numa Query
26. Relatórios em HTML
27. Desligando Windows via programação
28. Como saber se o CD está no drive
29. Tradução de Mensagens
30. Função que devolve tempo decorrido em uma
string
31. Criando uma rotina para pegar todos os erros
do programa
32. Capturando conteúdo do desktop
33. Obtendo número do registro atual
34. Enviando um arquivo para a lixeira
35. Carregar um cursor animado
36. Modificando a posição do cursor em um
Memo
37. Traduzindo a mensagem Delete Record ?
38. Pegando o Nome do usuário e a Empresa do
Windows
39. Escrevendo um Texto na Diagonal usando o
Canvas
40. Fundo do texto transparente
41. Formatação de Casas Decimais
42. Escondendo/Mostrando o botão Iniciar
43. Esconde/Mostra a Barra de Tarefas
44. Detectando o Numero Serial do HD
45. Como Limpar Todos os Edit’s de um Form de
uma só vez?
46. Marcando um pedaço do código
47. Alterar o papel de parede 1
48. Alterando cor de linha de um DBGrid
49. Diretório de instalação do windows
50. Exclusividade para o programa
51. Substituindo TAB pelo ENTER
52. Copiando arquivos
53. Criando tabela em tempo de execução
54. Armazenando BMP’s em arquivos RES
55. QR armazenado num Blop
56. Deletando um arquivo
57. Diretório Windows e System
58. Alterar o papel de parede 2
59. AutoExecução do Programa via Registro
60. Como fazer um Hot Link
61. Como saber se o disquete está no drive
62. Formatar disquete
63. Como detectar as teclas de seta
64. Caps Lock e Num Lock
65. BDE em 1 disquete
66. Cor de fundo do hint
67. Margem para RichText
68. Mostrando progresso de uma SQL
69. Código usados pelas impressoras HP
70. Verificando atributo do arquivo
71. Um Contador de letras
72. Obtendo o diretório de uma Alias
73. Como Finalizar o Windows sem Avisar?
74. Como impedir de apagar um registro em um
DBGRID através de CTRL+DEL?
75. Backup e Restauração
76. Executar um programa DOS
77. Trabalhando com horas
78. Para colocarmos um .bmp como figura de
fundo
79. Escondendo o Programa de Ctrl+Alt+Del
80. Formulário Transparente
81. Mover Formulário em todas as partes
82. Filtrando registros com o Quickreport
83. Como executar programas externos
84. Alterando Idapi32.Cfg Via Programa
85. Trocando a cor da fonte num DBGrid
86. Pegando a linha e coluna atuais de um memo
87. Pegar nome do usuário na rede
88. Criando tabelas
89. Gerenciando mais de uma linha selecionada
num DBGrid
90. Traduzindo o preview padrão do Quickreport
91. Extraindo o ano, mês ou dia de uma data via
SQL
92. Data por extenso no Quickreport
93. Imprimindo um campo memo via Canvas
94. Procura e substituição de string num campo
memo
95. Testando drives
96. Como saber o estado das teclas Num lock,
Caps lock e Scroll lock
97. Como compartilhar uma pasta de um outro
micro e mapear com uma letra
98. Como extrair o ícone de um executável
99. Aguardar um determinado número de
segundos
100. Como extrair o número de cores do modo de
vídeo corrente do Windows95
101. Verificando a memória
102. Trocando a cor de uma célula num DBGrid
103. Exponenciação
104. Como manipular arquivos INI
105. Como extrair o tamanho de um arquivo
106. Como alterar a data e a hora do sistema
107. Como obrigar a digitação de caracteres
maiúsculos num campo memo
108. Como validar a entrada em um TEdit
109. Como conectar uma unidade de rede
110. Inserindo um Combobox num DBGrid
111. Definido o tamanho mínimo e máximo de um
formulário
112. Chaves do Registro
113. Posicionando o cursor numa linha de um
Memo ou RichEdit
114. Como verificar se um arquivo existe?
115. Evitando Perdas de Dados
116. StrToIntDef
117. Quebra de String
118. Inserindo zeros no inicio de um inteiro
119. Para dar a senha de uma tabela Paradox no
programa
120. Pegando o registro do windows
121. Fechar outro programa
122. Como Manipular arquivos .INI 2
123. Pegando a data de um arquivo
124. Compactar tabelas
125. Criando diretório
126. Reindexando índices
127. Verificando se a impressora está ativa
128. Interceptando as teclas de função no seu
programa
129. Copiando arquivos via programação
130. Função que retorna o nome do Computador
131. Escondendo janelas filhas minimizadas
132. Executando uma única cópia do aplicativo
133. Alterar as cores do título de um DBGrid em
tempo execução
134. Como fazer para o computador soar o beep
135. Como mostrar o mouse como uma ampulheta
136. Como controlar o pressionamento da tecla
Enter
137. Como varrer uma tabela inteira
138. Como Copiar os valores de campos de uma
tabela para outra
139. Como verificar se um campo inteiro é par ou
ímpar
140. Como verificar se uma string contém um
inteiro
141. Como subtrair datas
142. Principais Procedimentos e Funções Pré
definidas
143. Definindo Atributo de um arquivo
144. Executável com parâmetros
145. Funções Aritméticas suportadas pelo Pascal
146. Formatando Strings
147. Como controlar o fechamento de um
formulário
148. Método de procura em tabela indexada
149. Como evitar repetição em uma lista de
ComboBox
150. Caracteres Especiais que compõem uma
MaskEdit
151. Exemplo de Arraste
152. Convertendo a primeira letra de um EditBox
para maiúsculas
153. Criando janelas não retangulares
154. Detectando a finalização do Windows
155. Alinhando itens do menu principal à direita
156. Usando funções externas (de DLLs)
157. Manipulando Application
158. Executando ações padrão de um Ole
Container
159. Verificando se há uma cópia em execução
160. Alterando o glyph dos botões do DbNavigator
161. Paradox em Rede
162. Hint Com Quebra De Linha
163. AutoOcultar a barra de tarefas
164. Como mover um componente em Run-time
165. Executar um AVI no Form
166. Colocar zeros a esquerda no componente Edit
167. Mostrar o HINT num Panel
168. Configuração do BDE para ambiente de rede
169. Verificando o seu endereço IP
170. Verificando se já estou conectado na Internet
171. Desabilitar o botão fechar o form
172. Chamar um site utilizando o seu browse
padrão
173. Localizar Arquivos do Windows
174. Criar um documento no Word
175. Ativar a proteção de tela
176. Desligar e Ligar monitor
177. Abrir e fechar o drive de CD-ROM
178. Copiar registros de tabela para o Clipboard
179. Personalizar a mensagem de erro do Delphi
180. Colocar uma ProgressBar da StatusBar
181. Verificar se uma string contém uma hora
válida
182. Verificar se uma string contém um valor
numérico válido
183. Mudar a resolução do vídeo via programação
184. Simular um CharCase no DBGrid
185. Verificar se uma string é uma data válida
186. Limpar um campo tipo data via programação
187. Obter o endereço IP do Dial-Up
188. Exibir a caixa de solicitação de senha do
banco de dados
189. Truncar valores reais para apenas n casas
decimais
190. Excluir todos os registros de uma tabela
191. Saber se o sistema está usando 4 dígitos
para o ano
192. Imprimir caracteres acentuados diretamente
para a impressora
193. Imprimir texto justificado na impressora
Epson LX-300
194. Descobrir o código ASCII de uma tecla
195. Usar eventos de som do Windows
196. Trabalhar com Filter de forma mais prática
197. Reproduzir um arquivo WAV
198. Copiar arquivos usando curingas (*.*)
199. Excluir arquivos usando curingas (*.*)
200. Definir a quantidade de registros a ser
impressa
201. OnGetEditMask, OnGetEditText e
OnSetEditText do TStringGrid
202. Fazer a barra de título ficar intermitente
203. Posicionar o cursor do mouse em um controle
204. Mostrar o Hint para cada coluna do StringGrid
205. Alterar o papel de parede 3
206. Arquivos AVI e WAV em tabelas
207. Copiar registros de uma tabela incluindo
valores NULL
208. Jogar uma imagem direto para um campo da
tabela
209. Retornar a coluna ativa do DBGrid
210. Imprimir em impressora matricial em modo
caracter
211. Gravar imagem JPG em tabela Paradox
212. Ler imagem JPG da tabela Paradox
213. Como saber quantos dias tem no mes
214. Como saber se o ano é bisexto
215. Colocar o mes por extenso
216. Chamar um e-mail pelo Delphi
217. Imprimir em impressora matricial em modo
caracter via Rede
218. Link para WEB
219. Configurar o Delphi para acessar tabelas do
Acess
220. Emular o pressionamento de uma tecla
221. Procurar arquivos
222. Ligar/desligar a tecla Caps Lock
223. Verificar se uma determinada tecla está
pressionada
224. Fazer pesquisa incremental
225. Implementar rotinas assembly em Pascal
226. Alterar o nome de volume (Label) de um
disco
227. Evitar a proteção de tela durante seu
programa
228. Validar datas
229. Formatar CEP
230. Quantas Segundas tem num mês
231. Retorna a quantidade de dias uteis entre
duas datas
232. Como registrar um OCX
233. Como usar recursos do word
234. Bloqueio de palavras
235. Esconder o icone da Barra de Tarefas
236. Texto Rotativo
237. Enviando caracteres para outra aplicação
238. Limitando a região de movimentação do
mouse
239. Executar Internet Explorer
240. Enviar um email
241. Listbox
242. Capturar ecrã
243. String Grid Colorido
244. Utilizar o MessageBox com parâmetros
245. Cor em DbGrid
246. Todos os programas que estão em execução
247. Evitando o erro de Key Violation
248. Conferindo se o processador da máquina é
386, 486 ou Pentium
249. Apagar um subdiretório
250. Abrir arquivos com aplicativo associado
251. Inserindo uma Imagem no Formulário
252. Número de cores suportadas pelo seu Monitor
253. Verificando se uma determinada fonte esta
instalada
254. Listando os campos da tabela num Memo
255. Imprimindo o conteúdo de um Memo
256. Verificando o tipo de Drive
257. Como tocar sons no auto-falante interno do
PC
258. Apagando todos os registros da tabela
259. Como desenhar um Bitmap num form
260. Evitando caracteres com acento
261. Executando uma chamada para a Conexão
Dial-Up
262. Capturar informações do ambiente DOS
263. Capturar a data da BIOS do computador
264. Manda o Form para frente
265. Form com um furo da pra ve atraz
266. Abrir as configurações do Vídeo do Painel de
Controle
267. Simular o pressionamento de uma
combinação de teclas
268. Alterar o ícone do botão iniciar do Windows
269. Inverter os botões do mouse
270. Clicar com o mouse
271. Executar algo antes de minimizar
272. Esconder icones do desktop
273. Senha em tabelas
274. Rodar videos em um panel
275. Sql por campo edit pesquisando pelo nome
276. Sql relacionada com a primeira letra
277. Fazer um campo memo ocupar 2 páginas
278. Procura com mais de um Banco de Dados
279. Senhas Aleatórias
280. Configurações internacionais
281. Desenhando com tipos diferentes de linhas
282. Desabilitando o Splash Screen do Report
Smith
283. Verificar se o registro está travado
284. Cursor customizado
285. Dica impressora matricial
286. Retorna a cor de um componente no formato
string
287. Retornar o nome do usuário que esta com a
tabela Exclusiva
288. Mostrar as fontes TrueType Instaladas
289. Como criar um contador de página no QR
290. Como retornar a uma lista os campos
indexados de um tabela
291. Como definir seu próprio hotkey
292. Transformando ícone em um bitmap
293. Transferindo o conteúdo de um memo para
um memofield
294. Mudar o foco do campo em um Dbgrid
295. Como tirar os espaços no início e no final de
uma string
296. Como colocar uma coluna do DBGrid em
maiuscula
297. Simular Print Screen
298. Resolvendo Problemas do Print-Setup do
QuickReport
299. Caption do BitBtn com várias linhas
300. Alterar fonte do hint
301. Ocultar/Mostrar o Relógio na Barra de Tarefas
302. Caixa Mista
303. Justificar Texto
304. Código gerador de senha
305. Espaço maior no RichEdit
306. Como criar novas tabela a partir de consulta
sql
307. Código sequencial automático
308. Encriptar/Desencriptar strings
309. Encriptar/Desencriptar arquivos
310. Colocar os bitmaps na dll
311. Teclas mágicas para trabalhar mais rápido
312. Procurar Strings numa ListBox
313. DbGrid Zebrado
314. Enviar relatório do Quickreport para TXT
315. Como retornar a cor de um pixel de uma
imagem
316. Criando uma barra de status
317. Abreviando Nomes
318. Acessando Membros Protegidos de um Objeto
319. Alterando a fonte de determinado registro em
um DBGrid
320. Apagar arquivos via MS-DOS
321. Armazenado num Blop
322. Array de Edit boxes
323. Arredondando valores
324. Centralizando uma string
325. Chamando Help
326. Colocando bitmaps num ComboBox
327. Colocando uma barra de progresso para o
batchmove
328. Colocar Senha em tabelas Paradox
329. Como evitar a mensagem de erro Key
Violation
330. Como Trocar o Cursor do Mouse
331. Configurando a Rede em Win95/Win98 com
Delphi
332. Configurando RedeNovell NetWare com Delphi
333. Convertendo nomes longos para nomes
curtos
334. Adicionando a soma de Fields no
QRExpression do QuickReport
335. Criando e apagando TFields em Run-Time
336. Alterando parcialmente o conteúdo da
prop.SQL de uma Query
337. Como fazer uma unit como biblioteca
338. Como imprimir com codigo fonte
339. Dicas de DbGrid
340. Para colocar um back ground nos forms
341. Como indexar um vetor
342. Como formatar data para exibição por
extenso
343. Como converter DBF para Paradox e Acess
paar Paradox
344. Como acrescentar caracteristicas em um
objeto
345. Como acessar pelo Delphi, tabelas no Acess
346. Extrair palavra que está sob o cursor
347. Como extrair o primeiro nome de uma pessoa
348. Criar atalho no desktop
349. Imprimir com precisão milimétrica
350. Como alterar o caption da janela de preview
do quickreport
351. Como Instalar RXLIB no Delphi 5
352. Verificação de PIS
353. Imprimindo com o Bloco de Notas
354. Estado de uma tabela
355. Adicionando uma nova fonte no Windows
356. Alternando Bitmaps no Fundo de um Form
357. Atualizando as informações em ambiente de
rede
358. BookMarks
359. Centralizando um formulário
360. Colocando BMP’s em StringGrids
361. Consultando entre datas utilizando SQL
362. Convertendo PCHAR para STRING
363. Convertendo valor Hexadecimal para Inteiro
364. Convertendo valores de Campos
365. Copiando arquivos de diretório para diretório
366. Copiando arquivos usando o Shell do
Windows
367. Criando Alias de Banco de Dados no código
368. Criando componentes em tempo de execução
369. Criando cores personalizadas
370. Criando uma barra de status completa
371. Deletando um Diretório
372. Descobrindo se há impressora instalada
373. Descobrindo se o aplicativo está minimizado
374. Descobrindo se um form já está criado
375. Descobrindo se um form já está criado 2
376. Descobrindo se um objeto tem uma
determinada propriedade
377. Descobrindo se uma janela está maximizada
378. Detectando e Finalizando o screen saver
379. Exibindo solicitação de senha do banco dados
personalizada
380. Exibindo corretamente o conteúdo dos
campos boolean
381. Exibindo o diálogo About do Windows
382. Exibindo ou compararando data de arquivos
383. Exportando Relatório do QuickReport para
HTML, DOC, TXT ou XLS
384. Fazendo cálculo de horas
385. Fazendo sua aplicação executar sem
apresentar o form principal
386. Fazendo um Pack em arquivos PARADOX
387. Fazendo uma impressão direta
388. Fazendo uma janela filha de outra sem usar
MDI
389. Finalizando todas as tarefas
390. Como incrementar 1 mês numa data
391. Como obter informações do S.O.
392. Unit com varias funções de datas
393. Consulta SQL que usa a data do sistema
394. Imprimindo Forms
395. O Enigma da propriedade filter do Ttable
396. Permitir cancelar processo demorado
397. Descobrir se uma data é fim do mês
398. Obter o tipo de dado de um valor no Registro
do Windows
399. Programar meu aplicativo para abrir arquivos
a partir do Windows Explorer
400. Consultar por mês de um campo data
401. Criando tabelas via SQL
402. Obter nomes dos campos de uma tabela
403. Nomeando um relatório no spool de
impressão do Windows
404. Impedir que o form seja arrastado para fora
das margens da tela
405. Mostrar mensagem mesmo que esteja no
Prompt do DOS
406. Criar sub-diretório no diretório do EXE
407. Enviar comandos de rolagem vertical para um
TMemo
408. Criar form sem título que possa ser arrastado
409. Definir data/hora de um arquivo
410. Ocultar/exibir o cursor do mouse
411. Executar um programa e aguardar sua
finalização antes de continuar
412. Adicionar o evento OnClick do DBGrid
413. Criar caixas de diálogo em tempo de
execução
414. Fechar um aplicativo com uma mensagem de
erro fatal
415. Criar um EXE que seja executado apenas
através de outro EXE criado por mim
416. Resolver “Internal error near: IBCheck” do
Interbase 5.1.1 Server no NT
417. Obtendo uma data acrescida de xMeses
418. Separar (filtrar) caracteres de uma string
419. Trabalhar com cores no formato string
420. Verificar se determinado programa está em
execução (Word, Delphi, etc)
421. Gerar uma tabela no Word através do Delphi
422. Obter a quantidade de registros total e visível
de uma tabela
423. Salvar/restaurar o tamanho e posição de
Form’s
424. Criando um campo lookup em tempo de
execução
425. Mostrar um Form de LogOn antes do Form
principal
426. Saber se a impressora atual possui
determinada fonte
427. Saber se determinada Font está instalada no
Windows
428. Como importar dados de um arquivo texto
para uma Tabela
429. Como Imprimir um arquivo direto para a
Impressora
430. Como Usar ASSEMBLER com Delphi
431. Como Retornar Várias informações Sobre a
BIOS
432. Quando der problema na instalação do
componente
433. Digito Verificador
434. O Delphi faz alguma coisa em C++.
435. Como enviar dados do Delphi para o Excel
436. Virtual keys
437. Validando número de cartão de crédito
438. Utilizando o registro do Windows
439. Usando TList e Record como Array
440. Usando o objeto Sender internamente
441. Tratando erros no banco de dados
442. Tirando os botões Load e Save do Preview do
QuickReport
443. Substituindo os botões do DBNavigator
444. Significados dos componentes da RXLIB
445. Selecionando um formulário coberto por um
componente
446. Selecionando registros órfãos via SQL
447. Salvando e Restaurando uma Tstringgrid
448. Retirando acentos de uma string
449. Removendo a barra de rolagem vertical do
DBGrid
450. Como reduzir o tempo e carga de um
programa
451. Obtendo o próximo dia útil
452. Obtendo o último dia útil
453. Obtendo o nº de ocorrências de uma string
‘T’ dentro de outra ‘S’
454. Obtendo o nome das tabelas de um
determinado alias
455. Obtendo o indice de um componente em
tempo de execução
456. Obtendo o extenso do mês passado por
parâmetro
457. Obtendo o extenso de uma data informada
458. Obtendo data do primeiro dia util do mês
459. Obtendo a versão e outras informações do
BDE
460. Obtendo a versão da tabela
461. Obtendo a próxima palavra após os espaços
determinados por ‘BlankToSkip’
462. Obtendo a Posição Inicial da Próxima palavra
após o caracter indicado por ‘InitPos’
463. Obtendo a posição da enésima ocorrência da
string ‘T’ na string ‘S’
464. Obtendo a maior data anterior a uma data
inválida
465. Obtendo a lista de Aliases disponíveis
466. Obtendo a data do último dia do mês, ou
último dia útil, de uma data informada
467. Mudando o foco para o próximo controle
468. Mudando a fonte de um menu
469. Movimentando o ponteiro do mouse sem a
intervenção do usuário
470. Mostrando um formulário Modal usando Show
471. Mostrando a lista de último acesso dos
arquivos aberto ultimamente
472. Montando um Banco de Dados
Cliente/Servidor
473. Lendo e gravando arquivos de texto
474. Lendo e Escrevendo dados binários no
Registro do Windows
475. Invertendo uma string
476. Instalando componentes
477. Imprimir no Delphi como no DOS “a mesma
fonte”
478. Imprimindo um bitmap utilizando TPrinter
479. Fazendo um Web Browser
480. Exibindo caixa de diálogo personalizada de
solicitação de senha do banco dados
481. Evitando que o Form seja redimensionado
482. Enviando combinação de teclas para o buffer
do teclado
483. Como criar uma figura do tipo marca d’ água
484. Bloqueando um arquivo em ambiente de rede
485. Recuperar a Velocidade da CPU
486. Utilizando o Dblookupcombobox
487. Adicionar horas
488. Checa se o Simbolo da UF é Valido
489. Testa se seu processador pentium tem o Bug
fatal
490. Como verificar se falta algum edit para
preencher
491. Como gerar um clone de um programa
492. Como criar um arquivo de Backup muito feio
mais eficiente
493. Como ler código de barras
494. Como desenhar figuras no desktop
495. Para você mudar as imagens do DbNavigator
496. Quantas Palavras existem?
497. Exporta uma imagem para o formato WMF
498. Converte hora (formato HH:MM) para
minutos
499. Como Visualizar arquivos ARJ
500. Visualizar aruqivos compactados CAB
501. Replace Str
502. Abrir tableas paradox protegidas por senha
503. Drag e Drop com o Windows Explorer
504. Mudandp o texto de um edit no evento
OnChange
505. Desabilitando um RadioButton Num
RadioGroup
506. Obter o tipo de um drive
507. Executar um arquivo com extenção *.lnk
508. Gravando e reproduzindo as teclas digitadas
no delphi
509. Tipo de Conexão
510. Sender - Objeto
511. Deletar com QUERY
512. Criar labels em tempo de execução
513. Insert em duas tabelas
514. Vetor Dinamico
515. Tipos de Array
516. Biblioteca para operações com DiskDrives
517. Biblioteca para Operações com Mouse
518. Biblioteca para Operações com Strings
519. Biblioteca para Operações com o Sistema
520. Atribuindo a uma coluna do StringGrid como
só de leitura
521. Chamar um programa e esperar a finalização
522. Colocar o cursor no final do TEdit ao receber
o foco
523. Convertendo um número real para string com
2 casas
524. Como acrescentar dias uteis a uma data
525. Como converter de decimal para binario
526. Como converter decimal para base
especificada
527. Como converter decimal para romanos
528. Como desconectar unidade de rede
529. Diferença entre duas horas
530. Tamanho de um Diretorio
531. Eliminar Caracteres de Strings
532. Verificar se variavel está vazia
533. Executar o Windows Explorer com parametros
534. Como Esvaziar uma Tabela
535. Pegar informações de Executavel
536. Verifica tipo de arquivo
537. Converter qualquer variavel em string
538. Calcular percentual de Valor
539. Retorna Path de Browser Padrão
540. Resgate de variaveis do ambiente DOS
541. Tipo de Executável
542. Path de Aplicativo associado a uma extensão
543. Nome do Host da Conexão
544. Clone Monocromático de BitMap
545. Quantos fins de semana já se passaram no
corrente ano
546. Testa se a hora é antes de Meio dia
547. Habilita o Autorun para CD-Rom
548. Reindexando Indices
549. Como achar um Modem e sua porta
550. Nome da Impressora Padrão
551. Verificar se Impressora esta Conectada
552. Exibindo as propriedades do arquivo
553. Dicas Práticas
554. Criar Dll´s
555. Criando um componente Skin
556. Armazanando sons, vídeos em bancos de
dados
557. Usuario logado
558. Paradox X Interbase
559. Executando sons no PC-Speaker
560. Troca de tamanho do papel
561. Testa se determinada tecla está pressionada
562. Como evitar efeito de maximização
563. Como usar as teclas de função F1, F2, etc?
564. Rotina genérica para tratamento de erros na
aplicação - BDE
565. Como usar o Install Shield
566. Como limpar o conteudo de um
LookupComboBox?
567. Como fazer para o sistema nao pedir o Login
(Password) Banco de Dados
568. Dicas QuickReport
569. Biblioteca com funções para Strings
570. Função de potenciação - Juros
571. Lista de erros BDE
572. Como utilizar strings de recurso em suas
aplicações
573. Desvendando a programação “Client/Server”
574. Como inserir um registro com o componente
UpDateSQL
575. Como saber qual o objeto que esta com o
foco no form
576. Como utilizar o form Sobre padrão do
Windows
577. Como evitar as mensagens de Warning do
Compilador (Variavel não inicializada)
578. Como diminuir o tempo de abertura do Table
e Query
579. Caixas de mensagens da aplicação
580. Retorna que tipo de variavel é
581. Retorna o último acesso de um arquivo
582. Retorna a versão do aplicativo
583. Converte um arquivo JPEG em BMP
584. Retorna a idade atual de uma pessoa
585. Transferência de som em um CHAT
586. Como alterar o driver de acesso do access no
bde automaticamente
587. Emissao de NF e boleto
588. Gerando um arquivo HTML
589. Cuidado quando gravar arquivos binarios
590. Cuidados quando criar procedimentos e
funções com parametros
591. Como atribuir um valor inicial para uma
variável global
592. Como criar um form completo com botões
dinamicamente
593. Problemas Delphi X Imp. Xerox
594. Sublinhando no Canvas
595. Como fazer para alterar a largura do dbgrid
automaticamente
596. Exemplo de como pegar o nome de um
objeto ou janela
597. Instalando os componentes RXLIB 2.40 no
Delphi 3
598. Instalando os componentes RXLIB
2.50/2.60/2.75 no Delphi 4
599. Passando variáveis para o ReportSmith
600. Adiciona a barra invertida a um texto
selecionado
601. Como abrir um TComboBox sem clicá-lo
602. Como Calcular Digito Verificador de CNPJ e
CPF
603. Criando uma base de dados MS Access pelo
Delphi
604. Desenhando texto 3D no form com Canvas
605. Como saber há quanto tempo o WINDOWS
foi inicializado
606. Como alterar o tamanho do papel na
impressão
607. Como filtrar registros de uma tabela pelo mês
de um campo data
608. Otimizações SQL
609. Excluindo registros de uma tabela
610. Selecionando registros de uma tabela que
não existam em outra tabela
611. Uso da cláusula HAVING
612. Bloco PL/SQL para inserção de dados
613. Como selecionar um item de um listbox
614. Executa uma Url a partir do Netscape mesmo
que ele não seje o Browser padrão
615. Retorna a hora da criação de um diretório
616. Como fazer para que o ComboBox abra na
direcao desejada
617. função captura a tela e salva-a em um
Bitmap
618. Copia ou move arquivos usando a API do
Windows
619. converte o equivalente decimal para horas
620. Retorna um Stringlist com todas as
informações da tabela
621. Bloqueia uma Tabela paradox
622. Testa se a tabela esta bloqueada ou nao
623. Retorna o IP de sua máquina no momento
em que você está conectado
624. Remove caracteres de uma string deixando
apenas numeros
625. Transformar literal em extenso
626. Rotina para apagamento da senha do setup
627. Imprime o conteúdo de um TRichEdit
628. Como saber se estou conectado à internet
629. Acessando o banco de dados Oracle a partir
do Delphi
630. Como pegar a URL ativa no Browser
631. Compara dois arquivos textos
632. Procurando um arquivo em todo o HD
633. Como desabilitar o menu pop-up do
windows(Na area de trabalho)
634. Como inserir um item em um TreeView em
Run Time
635. Como chamar a pasta impressoras
636. Mudar Impressora padrão pelo nome
637. Função para gerar Log de Erros
638. Protegendo o seu programa e o seu bolso
639. MessageBox com o NÃO como default
640. Como verificar que sua aplicação não está
sendo utilizada
641. Como enviar mensagem para todos que estão
conectados na REDE WinNT
642. Criando um arquivo de texto
643. Problema com Null no Delphi 6
644. Foto no InterBase
645. Comandos para Threads
646. A melhor maneira de liberar um form da
memoria
647. Para ocultar em tempo de execução uma
coluna de um stringgrid
648. Como colocar uma unica linha de uma
stringgrid editavel
649. Como gravar as alterações feitas no DBGrid
em tempo de execução
650. Efeito legal no caption do form
651. Enter funcionando como Tab em toda a
aplicação
652. Mudando a cor dos componentes assim que
receber o foco
653. Como Instalar no Delphi o ActiveX do Flash
654. Como evitar que apareçam numeros
negativos na consulta
655. Como colocar imagens numa StatusBar
656. Como pegar o diretorio de uma ALIAS
657. Como trocar a cor do componente focado
658. Como instalar componentes 3
659. Não aparecer na barra e tb como não
aparecer no ctr+alt+del.
660. Impressão apartir de Consult
661. Procedimentos com parâmetros opcionais:
662. Exemplos de path via registro
663. Executar um programa do Windows
664. Como descobrir se você está conectado com
a Internet?
665. Como desabilitar as teclas Alt + F4
666. Para trocar as cores dos botoes do radiogroup
667. Como usar um frame em sua aplicação
668. Como trocar a cor do texto de uma coluna do
dbgrid
669. Deixando o EXE menor e mais rápido
670. Usando MessageBox
671. Efeito legal no Caption do Form 2
672. Criando tabela em tempo de execução 2
673. Criando tabelas em tempo de execução 2
674. Usando o Registro do Windows
675. Usando o Registro do Windows 2
676. Tabelas DBase acentudas em DOS, como
corrigir?
677. Nomes dos arquivos que estão sendo
executados:
678. Como usar a cláusula UNION em um Query:
679. Alterando o NetDir via programação:
680. Cuidados ao usar o OnExit (Parte I):
681. Cuidados ao usar o OnExit (Parte II):
682. Zerar Campo AutoIncremento:
683. Manipulando o Internet Explorer
684. Como posso saber a coluna que estou
posicionado no DBGrid?
685. Transformar inteiro em romanos
686. Como tabular um ListBox
687. Pesquisa incremental em uma listbox
688. Eliminando os hints de uma treeview
689. Retorna o dia da semana em formato string
690. Pega o path de um arquivo arrastado do
explorer
691. Como pegar a lista de favoritos do Internet
Explorer
692. Como fechar um arquivo de Help quando
encerro minha Aplicação
693. Como mudar a cor de uma regiao de Texto
RichEdit
694. Como utilizar código de barras no meu
sistema
695. Como copiar tabelas Paradox para Texto ou
DBase e vice-versa
696. Deletar um diretório inteiro de uma vez
697. Habilitar e desabiliar a senha do protetor de
tela
698. Sobrescrevendo um evento
699. Clicando um componente sem clicar nele
700. O Dilema do envio de e-mail
701. Como fazer para ajustar o tamanho da lista
de um combobox?
702. Como descobrir o código de uma tecla
pressionada?
703. Como Reindexar um Banco M$Access 2000?
704. Como alterar a Página Inicial do IE via
Programação
705. Sistemas Numéricos
706. Construindo Threads com Delphi
707. Validando formato de e-mail
708. Como pegar a posição do mouse na tela
709. Como tranformar de inteiro (Milisegundos)
em formato Timer
710. Obter a célula de um StringGrid que está sob
o cursor do mouse
711. Fechando todas as tabelas de um aplicativo
712. Retorna quantos dias tem um referido mes do
ano
713. Retorna a diferenca de dias entre duas datas
714. Converte um certo número de segundos em
horas já formatado
715. Como colocar um componente ComboBox em
um componente StringGrid
716. Colocar senha geral em um banco de dados
Access
717. Procedimento para pedir uma senha antes de
abrir o FormPrincipal
718. Corrigir Erros de campo AutoIncremento
719. Label escrita letra a letra
720. Função Split
721. Função que arredonda valores
722. Como vazar um form usando letras
723. Pesquisa de um string mudando o texto
724. Função para Abrir e Fechar Query
725. Código de Erros do BDE
726. 20 motivos alguns motivos para você adotar
o InterBase em sua empresa
727. 10 Passos para fazer o Interbase
728. Interrompendo o desligamento do Windows
729. Opções de Projeto
730. Melhorando a aparência do seu Hint
731. Criando e Distribuindo Aplicações Shareware
732. Os limites do InterBase
733. Alinha o título da barra de títulos a direita
734. Carrega os dados, salvos em um arquivo, em
um StringGrid
735. Executando o comando ARJ em um aplicativo
Delphi
736. Trabalhando com Strings
737. Atalhos de Teclado da IDE do Delphi
738. Lock de Registro
739. Como mudar o foco após digitar toda a data
740. 13 Pequenas modificações no Delphi
741. Macro no rxQuery
742. Como anda a lista de processos do windows
NT
743. Como adicionar uma linha formatada (cor,
negrito, etc) num RichEdit
744. Criando fontes no Delphi
745. Como colocar BitButton no messagedlg
746. Teclas de funções no Dbgrid
747. Detectando o tipo de Conexão com a internet
748. Comandos para Dial-up com Delphi
749. Como usar os arquivos QRP criados com
QuickReport
750. Como incrementar a Barra de Status
751. Função para Desligar o Windows 2000
752. Como fazer para um executavel se Auto-
Deletar
753. Funções de CRC
754. Funções para detectar o SoftIce
755. Como apagar uma imagem de um TImage
756. Baixando arquivos da internet
757. Criptografando Imagens
758. Compilar *.pas fora do Delphi
759. Validando Titulo de Eleitor
760. Função que retorna texto entre caracteres
761. Mover Timage sem que ele pisque
762. Como colocar Captions no DBNavigator
763. Como separar termos de uma string
764. Como arredondar um valor do tipo Float /
Double
765. Como transformar de uma Classe para outra
766. Selecionando vários objetos dentro de um
outro
767. Como colocar imagens em um TStatusBar
768. Validando CEP
769. Como obter uma string entre outras duas
770. Como passar parâmetros entre 2 forms
771. Transforma a imagem em negativo de
fotografia
772. Função para obter os termos de uma string
773. Função que deleta vários items de um listbox
774. Como ir para o final de um texto com o
Richedit
775. Como retornar quantidade de dias meses e
anos entre duas datas
776. Para chamar um HTMLHelp (.chm) a partir da
aplicação Delphi
777. Como adicionar items de menu
dinâmicamente
778. Mostrar todas as unidades mapeadas na
máquina.
779. Clonando um Form
780. Como formatar um TMemo ou TRichEdit em
formato HTML
781. Animando a abertura de um form
782. Alterando a cor dos TabSheet de um
PageControll
783. Como reduzir expressões if then else
784. Como saber quantas paginas vão ser
impressas com Quickrep
785. Rotina para criptografia mais absoluta
786. Exportando uma Tabela ou uma Query para
uma página HTML
787. Criando drivers ODBC através do Delphi
788. Tabela de Máscaras
789. Como evitar as mensagens de Warning do
Compilador
790. Selecionar todo o conteúdo de um Memo ou
RichEdit com as teclas Ctrl+A
791. Criar Código de Barras 2x5i
792. Exibindo imagens em caixas de mensagens
de Aplicações CLX
793. Como gerar numeros randomicos para
loterias
794. Função para Criar Subescrito e Sobrecrito
795. Como trocar o Glyph de um BitButton em
tempo de execução
796. Validar Inscrições Estaduais
797. InputBox para entrada de Senhas (com
caracter *)
798. Coloração Gradiente no Form
799. Como alterar a coluna Description do
IBConsole
800. Converter DBGrig em Html
801. Criar um programa para transferencia via ftp

802. Gera um Thumbnail


803. Quebra de String Versão 2 melhorada
804. Adicionar Fonte no Windows
805. Criando um menu Janela e listando nele as
janelas abertas em tempo de execução
806. Envio de E-Mail com Indy
807. Copiando um arquivo com um gauge
808. Como verificar se uma porta serial está em
uso
809. Como imprimir escolhendo uma faixa de
Paginas no QR
810. Como Bloquear Mouse e Teclado
811. Como colorir os itens de um TCheckListBox

812. Usando as APIs para Procurar e Mover janelas


do Windows
813. Imprimir na Vertical no QuickReport
814. Alinhar Panel ao centro do Formulário
815. Como desenhar uma linha na diagonal
usando Canvas
816. Gerar Código de Barras EAN13
817. Alinhar Texto do Edit à Direita
818. Como Abrir Sempre o Mesmo Tabsheet
Dentro de Um Pagecontrol
819. Gravando Sons do Microfone Com o Delphi
820. Chamar a Lista de Tarefas e Menu Iniciar
821. Como alterar uma imagem desenhada na
StatusBar
822. Como alterar o volume do som do
computador com o Delphi
823. Executando sons contidos num ListBox
através de chamadas MCI
824. Desenhando em Delphi via programação
825. Enviando Caracter Aleatório à uma Janela

826. Como chamar o formulario de setup para


impressão de Gráficos
827. Desenhar um ícone (bitmap) em células do
DBGrid
828. Checar se a URL existe
829. Verificar registros deletados no BDE/Paradox

830. Contar todos os itens e subintem de um


menu
831. Download com Thread
832. Obtendo o nome das tabelas no
ACCESS(ADO)
833. Obtendo o nome dos campos de uma tabela
no ACCESS(ADO)
834. Exportando ADO tables em vários formatos

835. Escrever para um DB Access usando ADO /


SQL
836. Colocando um barra Horizontal em um
ListBox
837. Simulando CheckBox em DBGrid
838. Tratamento de Erro do Banco Interbase (com
componente IBX)
839. Converter Binario para Inteiro
840. Listar Arquivos de um Diretório
841. Cria um MainMenu via BD automaticamente
842. Como Salvar o Relatório do QR em imagens
JPG ou BMP
843. Compilando a aplicação pelo MS-DOS
844. Capturar Erros e Enviar por E-mail
845. Como Resolver o Erro “QRStandPreview
Already Exists”
846. Utilizando Threads
847. Criando Log básico para qualquer aplicação
Delphi
848. Tabela para texto (CSV) num piscar de olhos

849. Mudando o IP da máquina via API do


Windows
850. Texto na diagonal e girando
Exercícios
1.Faça um Form, com um Edit e botões para passar o
texto do Edit para maiúsculas, minúsculas e apagar
todos os espaços.
2.Crie um Form com dois Edits, um botão para verificar
se os dois textos são iguais sem levar em consideração
o caso, um botão para inserir o texto do primeiro Edit no
meio do segundo e outro botão para verificar se o texto
do primeiro Edit está dentro do texto do segundo.
3.Crie um projeto com um Form de múltiplas páginas,
onde possa ser feita uma analise de balanço. Na
primeira guia, devem ser informados o patrimônio líquido
da empresa, os valores circulante, realizável a longo
prazo e permanente. Na Segunda guia mostre uma
análise vertical, tome o patrimônio líquido como 100% e
mostre o percentual de cada um dos outros valores
informados. Na terceira guia, mostre um gráfico com
panels representando cada um dos percentuais
mostrados na segunda guia.
4.Faça um programa que sugira que o usuário pare de
trabalhar quando o relógio do sistema não estiver em
horário comercial.
5.Sabendo que M e N são inteiros, o que podemos
concluir desses números se a expressão M div N * N =
M retornar true e qual outra expressão poderia ser
usada para testar a mesma condição?
6.Sendo I um número inteiro, R um real e S uma string
com um texto numérico como encontrar o resultado da
soma dos 3 valores, e de que tipo será esse resultado?
7.Como poderíamos mandar o texto de um Edit
chamado Edit1 para uma caixa de mensagem do tipo
MessageBox, que recebe parâmetros do tipo PChar?
8.Faça um programa para encontrar as raízes de uma
equação de 2º grau cujos coeficientes sejam informados
pelo usuário. Para relembrar, a fórmula é ax2 + bx + c =
0, o delta é D = b2 - 4ac e as raízes são dadas como x1
= (- b + RAIZ(D ))/2a e x2 = (- b - RAIZ(D ))/2a.
9.Qual expressão podemos usar para encontrar a média
aritmética entre M e N, sabendo que M é uma string
numérica e N é um caractere numérico?
10.Sabendo que no SENAC a média mínima é 7,0 e a
tolerância de faltas é 15 % da carga horária do curso,
faça um programa que peça as informações necessárias
e informe a situação do usuário.
11.Faça uma função que retorne o número de
caracteres numéricos que existem em uma string.
12.Faça uma função que defina se o ano é bissexto ou
não. Sabendo que para ser bissexto, o ano precisa ser
divisível por 4 e, além disso, não ser divisível por 100.
Se for divisível por 100 o ano tem que ser divi’sivel por
400 para ser bissexto.
13.Sabendo que a chamada de função Pos(Str1, Str2)
retorna a posição da string Str1 dentro de Str2, que
Delete(S, 4, 6) remove 6 caracteres da string S a partir
do caractere 4, e que Lenght(S) retorna o número de
caracteres da string S, crie um procedimento chamado
Remover que remova as ocorrências de uma string
dentro de outra.
14.Crie uma função que retorne a string enviada como
parâmetro de trás para frente.
15.Usando a função anterior crie um Form com dois
Edits, onde ao digitar um texto no primeiro Edit, esse
texto apareça invertido no segundo.
16.Usando a função anterior faça uma função que
receba como parâmetro uma data e retorne quantos
dias há no mês e ano dessa data. Como fazer com que
um Edit só aceite que sejam digitados caracteres
numéricos em seu interior?
17.Faça um programa onde o usuário informe 2 datas e
seja mostrado o número de anos, meses e dias entre
elas.
18.Faça um programa que peça a data de nascimento
do usuário, converta o texto dessa data para uma forma
de ano com 4 dígitos e mostre a idade do usuário.
19.Digamos que peso ideal de uma pessoa em quilos
seja sua altura menos 1,15 m. Faça um programa que
peça a altura e o peso do usuário e informe quanto ele
precisa engordar ou emagrecer.
20.Faça um programa que mostre quantos caracteres
numéricos e quantos alfabéticos existem em um Memo
Exercício 2
Criar uma aplicação em DELPHI que permita cadastrar
Nome, Endereço, Sexo, Cidade, Estado, Idade e Data
de Admissão de funcionários. Além disto, dado o Salário
Bruto do funcionário, calcule o seu Salário Líquido.
Considere que os descontos podem ser o Vale
Transporte (2%), Vale Alimentação (5%) e Plano de
Saúde (10%).

1.Mudar a propriedade Name e Caption do Form.


Observar as propriedades BorderIcons, FormStyle,
Position e WindowState.
2. Colocar MainMenu (paleta Standard) com as opções
Arquivo, Cadastro, Sobre. Observar o uso do &.
3.Em Arquivo colocar a opção Sair. Observar ShortCut.
4.Colocar Barra de Status (Win95).
5.Colocar Painel (Standard) onde ficarão os botões.
Observar propriedades name e caption do Painel.
Observar propriedades Top, Left, Width, Height e Align,
BevellInner E BevellOuter.
6.Dentro do Painel, colocar dois outros painéis alinhados
alRight.
7.Colocar um botão (Standard ou Additional) dentro de
cada painel: um com nome Cadastro e outro com nome
Sair. Observar propriedades Kind, Glyph, Hint
ModalResult e ShowHint.
8.Na opção Sair, do Menu, feche o formulário.
9.No evento OnClose do Form colocar uma mensagem
para confirmar o encerramento da aplicação.
10.Abrir um novo formulário observando sua
propriedade Name.
11.Voltar ao formulário Principal e colocar o comando
para abrir o novo formulário no botão e no menu.
12.Gravar a aplicação. Observe o diretório.
Executar e testar a aplicação.
13.Abrir o formulário de Cadastro.
14.Colocar um Painel (Standard) alinhado alBottom.
15.Dentro do Painel, colocar outro Painel (Standard)
alinhado alRight.
16.Dentro deste último Painel colocar um botão
(Additional) de Retornar.
17.Colocar um componente PageControl (Win95)
alinhado alClient. Clicar com o botão da direita sobre o
componente e em New Page criar duas páginas.
18.Clicar dentro do componente PageControl e em cada
página mudar as propriedades Caption para Funcionário
e Salário.
19.Dentro da pasta Funcionário colocar sete Labels
(Standard), mudando suas propriedades Caption e
Name para os textos definidos no enunciado: Nome,
Endereço, … Observar as propriedades Font.
20.À frente dos Labels Nome, Endereço e Cidade
colocar componentes Edit (Standard). Observar a
propriedade Text.
21.À frente do Label Sexo colocar um RadioGroup
(Standard). Observar as propriedades Caption, Items e
ItemIndex. Exclua o Label Sexo.
22.À frente do Label Estado colocar um ComboBox
(Standard). Observar as propredades Items Style, Text.
23.À frente do componente Data de Admissão colocar
um Mask Edit (Additional). Observar a propriedade
EditMask.
24.À frente do componente Idade colocar um SpinEdit
(Samples). Observar as propriedades Increment,
MaxValue, MinValue e Value.
Executar e testar a aplicação.
25.Dentro da pasta Salário colocar três Labels: Salário
Bruto, Descontos e Salário Líquido.
26.À frente dos Labels colocar três Edits. Observar a
propriedade ReadOnly.
27.Ainda dentro da pasta Salário colocar um GroupBox
(Standard). Observar a propriedade Caption.
28.Dentro do GroupBox colcar três componentes
CheckBox (Standard) colocando os tipos de descontos.
Observar as propriedades Checked e Caption.
29.Dentro da pasta Salário colocar o botão Calcular.
30.No botão calcular, realizar o cálculo do salário. A
partir do Salário Bruto digitado deve-se calcular os
Descontos e o Salário Líquido.
Executar e testar a aplicação.
31.Fazer o cálculo do salário no evento OnChange do
Edit do Salário Bruto e dos CheckBox. Elimine o botão
Calcular.
Executar e testar a aplicação.
32.Voltar ao form principal e dividir a Barra de Status
através da propriedade Panels.
33.Colocar um componente Timer.
34.No evento OnTimer colocar a data e a hora no
Painel.
Executar e testar a aplicação.
35.Clique no menu principal do DELPHI em File | New.
Selecione a pasta Forms.
36.Na pasta Forms selecione a opção AboutBox e clique
em OK.
37.Verifique/altere a imagem na propriedade Picture.
38.No form Principal, na opção Sobre coloque o
comando para abrir o formulário Sobre.
39.Colocar Hint no painel.
Exercício 3
Fazer um editor que leia e armazene um arquivo texto.
O editor deve permitir formatação de caracteres
(Negrito, Itálico e Sublinhado), formatação de fontes
(tipo e tamanho) e formatação de parágrafos (Esquerda,
Direita, Centralizado).

1.Coloque um componente MainMenu (Standard) com


as opções Arquivo e Formatar. Em Arquivo coloque as
opções Novo, Abrir, Salvar, Imprimir e Sair e em
Formatar coloque a opção Fonte.
2.Coloque um Painel (Standard) e o alinhe alTop.
(Sugestão de Nome para o Painel: pnFormatos)
3.Coloque outro Painel e o alinhe alClient. (pnTexto).
4.Dentro do Painel pnTexto coloque um componente
RichEdit (Win95) alinhado alClient. Observe as
propriedades Lines e ScrollBars. (reTexto).
5.Dentro do Painel pnFormatos coloque outro Painel
denominado de pnEstilos.
6.No Painel pnEstilos coloque três componentes
SpeedButton (Additional) representando-os como botões
de Negrito, Itálico e Sublinhado. Observe as
propriedades AllowAlUp, Caption, Down, Font, Glyph,
GroupIndex, Hint e ShowHint. (spNegrito, spItálico e
spSublinhado).
7.Faça com que o clique no botão (sbNegrito, sbItálico
ou sbSublinhado), coloque o texto no estilo
correspondente. (método SelAttributes).
8.Repita os passos de 5 a 7 definindo um Painel para
formatar parágrafos. (sbEsquerda, sbDireita e
sbCentralizado). (método Paragraph).
9.Faça com que, ao flutuar sobre um texto, os botões
assumam a configuração do texto.
10.Insira um diálogo SaveDialog (Dialogs), associando à
opção Salvar do menu Arquivo, para gravar o texto em
um arquivo. Observe as propriedades DefaultExt,
FileName, Filter, InitialDir, Options e Title.
(SalvarArquivo).
11.Faça a opção Novo do menu Arquivo, eliminado todo
o texto da tela.
12.Insira um diálogo OpenDialog (Dialogs), associado à
opção Abrir do menu Arquivo, para ler o texto de um
arquivo. (AbrirArquivo).
13.Insira um diálogo FontDialog (Dialogs), associado à
opção Fonte do menu Formatar, para formatar o texto
selecionado. Observar as propriedades Device e
Options. (Formatar Fonte).
14.Insira um novo Painel no pnFormatos, alinhado
alLeft, inserindo uma ComboBox para formatar o tipo da
fonte e outra para formatar o tamanho. (pnFonte,
cbTipo, cbTamanho).
15.Insira um diálogo PrinterDialog (Dialogs), associado à
opção Imprimir do menuArquivo, para imprimir o arquivo.
Observar a propriedade Options. (ImprimrArquivo).
Exercício Figuras Geométricas
Fazer um sistema que permita o desenho de figuras
geométricas (Quadrado, Círculo, Triângulo e Retângulo)
utilizando conceitos de programação orientada a
objetos. O sistema deverá permitir Desenhar, Colorir e
Apagar as figuras desenhadas.
1.Crie uma nova aplicação.
2.Crie uma nova unit, implementando a classe TFigura,
definindo seus atributos e métodos.
3.Crie uma nova unit, implementando a classe TCirculo,
definindo seus atributos e métodos.
4.Crie uma nova unit, implementando a classe
TTriângulo, definindo seus atributos e métodos.
5.Crie uma nova unit, implementando a classe
TRetângulo, definindo seus atributos e métodos.
6.Crie uma nova unit, implementando a classe
TQuadrado, definindo seus atributos e métodos.
7.Crie uma nova unit, implementando a classe TLista,
definindo seus atributos e métodos, esta classe depois
de instanciada vai ser útil para armazenar as figuras
desenhadas.
8.Colocar um RadioGroup no Form Principal com os
items relacionadados com cada figura possível
(Triângulo, Quadrado, Círculo e Retângulo).
9.Inserir 4 components Edit no form principal para a
leitura dos atributos necessários para desenhar cada
figura geométrica (CoordenadaX, CoordenadaY, Base,
Altura, Raio, Lado, etc).
10. Inserir um componente Image no form para
desenhar as figuras desejadas.
11.Colocar um ColorDialog para selecionar o atributo
“cor” das figuras.
12.Adicionar um botão colorir, que aciona o ColorDialog
e atribui a cor ao atributo cor do objeto
13.Adicionar um botão desenhar, que aciona o método
“desenha em” do objeto corrente.
14.Crie outro form, para colocar o componente ListBox
que vai conter a lista de figuras que foram desenhadas e
assim poderão ser apagadas.
15.Adicione um botão apagar, para viabilizar a seleção
da figura a ser apagada e após a mesma selecionada,
disparar o método da classe TLista instanciada,
responsável pela remoção da figura da lista de figuras.
Algumas Dicas Para Perder Menos
Tempo Na Hora de Programar
Alinhando um bloco de código.

Selecione o bloco (Setas e o Shift pressionado, ou Ctrl K B e Ctrl


K K.
Alinhe para frente com Ctrl K I .
Alinhe para trás com Ctrl K U

Ajuste fino na posição dos componentes

Selecione o componente (ou Grupo).


Utilize as Setas com a tecla Ctrl pressionada.

Selecionando mais de um Componente

Selecione os componentes com a tecla Shift pressionada ou


pressione o Botão esquerdo do mouse, arraste e solte com a tecla
Ctrl pressionada.

Verificando mais de um pedaço de código de um mesmo


programa (unit) simultaneamente.

Utilize a opção de menu View / New Edit Window ou pressione o


Botão direito do mouse sobre a unit e selecione a opção New Edit
Window.

Selecionando um componente pai encoberto por um filho.


Selecione o componente filho e pressione a tecla Esc.

Bookmarks na Unit.

Para marcar o código pressione Ctrl K n (com n variando de 0 a


9).
Para retornar ao código marcado pressione Ctrl Q n (com n
variando de 0 a 9).
Para desmarcar o Bookmarks pressione novamente Ctrl K n.

Localizando um BreakPoint.

Para visualizar os breakpoints, utilize as opções de menu View /


Debug Windows / Breakpoints.
Pressione Ctrl Alt B

Convertendo Dfm em Txt e Txt em Dfm.

No prompt do Dos:

Convert nome_do_form.dfm *.txt

Ou

Convert nome_do_form.txt *.dfm

Dica: Se não funcionar, altere as propriedades de Path de seu


Windows.

Hiperlinks

Posicione o mouse sobre a função ou variável desejada.


Pressione o Ctrl para aparecer o Hiperlink.
Pressione o botão esquerdo do mouse para ir até a definição da
função ou variável.

Localizando o parênteses correspondente

Posicione o cursor na posição anterior do parênteses desejado.


Pressione Alt .
O cursor irá para a posição imediatamente anterior ao parênteses
procurado.

Selecionando Colunas de Texto

Posicione o cursor sobre o inicio da coluna desejada.


Pressione Alt Shift e setas para definir o bloco.
O bloco marcado poderá ser manipulado com os comandos
normais de bloco.

Executando uma macro no IDE.

Inicie a gravação da macro com o pressionar das teclas Ctrl Shift


R (Linha de Status – Recording).
Faz-se as operações desejadas.
Para encerrar a macro pressione novamente Ctrl Shift R.
Para executar a macro pressione Ctrl Shift P.

Incluindo diversos componentes iguais no form.

Pressione a tecla Shifr ao selecionar o componente.


Cada vez que se clicar no form um novo componente será
inserido.
Para encerrar a inserção pressione o ícone da seta na paleta.
Alterando de maiúscula para minúscula e vice-versa

Marque o bloco desejado.


Pressione Ctrl K F para passar para Maiúscula.
Pressione Ctrl K E para passar para Minúscula.

Para inverter a caixa do bloco pressione Ctrl O U.

Localizando uma linha específica na unit.

Pressione Ctrl O G e informe o número da linha.

Copiando propriedades de um componente

Selecione o Objeto que possui a propriedade a ser copiada.


Pressione Ctrl ou Shift e selecione os componentes que receberão
a propriedade.
Selecione a propriedade em questão.
Pressione a tecla Esc.
Bancos de Dados
Conceitos Importantes
O gerenciamento de bancos de dados é essencial para o
desenvolvimento comercial, e para criar um banco de dados
eficiente é necessário o conhecimento prévio de modelagem
de bancos de dados relacionais. Conceitos como banco de
dados, tabelas, campos, registros, índices, chaves,
relacionamentos, normalização, dentre outros são pré-
requisitos básicos para o desenvolvimento desse conteúdo.
Modelo de Dados
É essencial planejar o banco de dados antes de implementar.
Um dos métodos que você pode utilizar é o DER, como no
exemplo não normalizado mostrado logo abaixo.
Borland Database Engine
A BDE fornece a capacidade de acesso padronizado a banco
de dados para Delphi, C++ Builder e outros ambientes de
programação da Borland, oferecendo um grande conjunto de
funções para auxiliar no desenvolvimento de aplicações
Desktop e Cliente/Servidor.
Os controladores da BDE podem ser usados para acessar
bases de dados dBase, Paradox, Access, FoxPro, Interbase,
Oracle, Sybase e MS-SQL Server, DB2, Informix, além de um
controlador de acesso a arquivos texto. Você também pode
utilizar fontes de dados ODBC, podendo acessar qualquer
base de dados compatível.
As funções que compõe uma API da BDE são usadas
internamente pelos componentes de acesso a dados do
Delphi e muito raramente você teria que usá-las diretamente,
mas isso é totalmente possível. A referência completa das
funções da BDE, com exemplos em Delphi, está no BDE API
Help na pasta do Delphi no Menu Iniciar.
Arquitetura de Acesso
O acesso e manipulação de um banco de dados por um
programa Delphi é realizado como mostrado abaixo, note que
a aplicação não acessa os dados diretamente, mas usa
sempre a BDE.

Assim, para uma aplicação de bancos de dados funcionar, é


preciso que a BDE esteja instalada na máquina, não
bastando apenas o arquivo executável.
Criação do Banco de Dados
Para criar um banco de dados novo, normalmente, é
necessário dispor de alguma ferramenta do próprio banco de
dados, como o Access, mas se a base de dados for Paradox,
ou dBase, você pode usar o Database Desktop, um utilitário
que vem com o Delphi e permite a criação desses tipos de
bancos de dados.
Database Desktop
Fornece uma interface simples e completa para configuração,
definição e manipulação de tabelas de bancos de dados
Paradox e dBase. Além disso na Opção Tools/Alias Manager
você pode configurar seu banco de dados, como será
lembrado logo adiante.

Tabelas Paradox
Para criar tabelas Paradox, siga os passos abaixo. Você deve
salvar as tabelas de um mesmo banco de dados na mesma
pasta, pois o Paradox trata a pasta onde estão as tabelas
como sendo o banco de dados.

Clique em File/New/Table
Escolha o tipo da nova tabela, Paradox 7
Aparece uma janela para que você defina a estrutura de
campos, índices e demais opções necessárias na criação
da tabela
Em Field Name, você escolhe o nome do campo, com
até 25 caracteres
Em Type, o Tipo do campo, com a barra de espaço ou o
botão direito do mouse você pode escolher o tipo a partir
de uma lista
Size é o tamanho do campo, usado somente em alguns
tipos de campos
Key especifica os campos que farão parte da chave
primária, que não pode se repetir e deve ser composta
pelos primeiros campos da tabela

Table Properties
Em Table Properties você define os vários aspectos de
configuração da tabela. Muitas dessas opções podem ser
implementadas no Delphi e vários programadores preferem
não usá-las no Database Desktop.

Opção Descrição
Validity Validações para os campos, como obrigatoriedade,
Checks valor mínimo e máximo
Table Lookup Indica que o valor atribuído a um determinado campo
tem que estar gravado em outra tabela
Secondary Cria índices secundários
Indexes
Referential Cria integridade referencial, geralmente utilizada em
Integrity relacionamentos de 1 para N.
Password Permite a criação de senhas, protegendo a tabela de
Security acesso não autorizado
Table Especificar o driver de língua utilizado pela tabela,
Language geralmente é o Pdox ANSI Intl850
Dependent Mostra todas as tabela dependentes através da
Tables integridade referencial

Tipos de Campos
Os principais tipos de campos são mostrados abaixo, mas
existem outros além desses. Os tamanhos marcados com
asterisco indicam que o campo pode guardar tamanhos
maiores que os informados, o que ultrapassar o tamanho será
guardado em um arquivo externo com a extensão MB.

Tipo Descrição Faixa Tamanho


A Alfanumérico - 1-255
N Numérico ± 10 308 -
$ Monetário -
S Short Integer ± 32767 -
I Long Integer ± 2147483648 -
D Data - -
T Hora - -
@ Data e Hora de - -
modificação
M Memo - 1-240*
G Gráfico - 1-240*
L Lógico True/False -
+ Autoincremental 1-2147483648 -
Configuração
Para configurar o acesso a um banco de dados, você tem
várias opções, criar um Alias, usar o componente TDatabase
ou os dois juntos.

Aliases
Um Alias é um nome lógico, um atalho para um banco de
dados. Todo o trabalho do Delphi com um banco de dados
pode ser feito baseado no Alias, de forma que para mudar de
banco de dados, só é necessário mudar o Alias. Para criar um
Alias você pode usar Database Explorer, o BDE Administrator
ou o próprio Database Desktop.

Database Explorer
Pode aparecer com os nomes Database Explorer ou SQL
Explorer. Nele você pode manipular os Aliases, navegar pelas
estruturas dos bancos de dados, alterar os dados das tabelas
e executar comandos SQL.
Para criar um Alias selecione o item Databases, clique em
Object/New, escolha o tipo do banco de dados, ou Standard
para dBase, Paradox e arquivos texto, depois digite um nome
do Alias, esse nome será usado pelo Delphi quando você
quiser acessar o banco de dados, finalmente defina as
propriedades do banco de dados na seção Definition, cada
banco de dados terá suas próprias definições.

BDE Administrator
Com o BDE Administrator você pode alterar a configuração
da BDE, por exemplo em Configuration/System/Init você tem
a propriedade Local Share que deve ser setada para True,
quando você quiser que a base de dados seja compartilhada
em uma rede. Além disso, você pode criar Aliases, como no
Database Explorer.
TDatabase
Esse componente permite a manipulação de um banco de
dados, através de um Alias da BDE ou a criação de um Alias
local, somente visível dentro da aplicação, esse componente
também permite o gerenciamento de transações, garantindo
uma integridade maior no projeto. Por essas e outras razões
o uso do componente Database é altamente recomendado
como opção para criação de Aliases.

Propriedades Descrição
AliasName Nome do Alias do banco de dados, usado quando
você criar um Alias da BDE
Connected Define se a conexão com o banco de dados está
ativa
DatabaseName Nome do Alias local a ser usado pelos outros
componentes do Delphi
DataSetCount Número de DataSets (Tabelas) abertos no banco de
dados
DataSets Lista com os DataSets abertos
DriverName Driver usado para criar um Alias local,
automaticamente cancela a propriedade AliasName
InTransaction Define se o Database está em transação
KeepConnectionDefine se a conexão com o banco de dados será
mantida, mesmo sem DataSets abertos
LoginPrompt Define se será mostrado o quadro de login padrão
da BDE
Params Parâmetros do banco de dados, com itens
semelhantes à seção Definition do Database
Explorer
TransIsolation Nível de isolamento da transação, define como uma
transação irá enxergar outra
Métodos Descrição
Close Encerra a conexão com o banco de dados, todos os
DataSets serão fechados
CloseDataSets Fecha todos os DataSets abertos, mas a conexão
não é encerrada
Commit Grava alterações feitas durante a transação
Open Abre a conexão com o banco de dados
Rollback Anula todas as alterações feitas durante a transação
StartTransaction Inicia uma transação
Eventos Descrição
OnLogin Evento usado quando você quiser escrever seu
próprio método de conexão com o banco de dados
Para acessar uma base de dados Access, você poderia usar
os valores mostrados na descrição textual a seguir.
AliasName = ‘Northwind’
DatabaseName = ‘Dados’
LoginPrompt = False
KeepConnection = True
Params.Strings = (
‘DATABASE NAME=C:\Meus Documentos\NorthWind.mdb’
‘USER NAME=paulo’
‘OPEN MODE=READ/WRITE’
‘LANGDRIVER=intl850’
‘PASSWORD=elvis’)
Para ajudar a preencher os parâmetros de um Database,
clique duas vezes sobre o componente e clique em Defaults,
todos os parâmetros defaults serão apresentados.
Para acessar uma base Paradox, use as propriedades
abaixo, note que para o Paradox, a única informação
realmente significante é o Path, a pasta onde estão as
tabelas.
AliasName = ‘DBDEMOS’
DatabaseName = ‘Dados’
LoginPrompt = False
KeepConnection = True
Params.Strings = (
‘PATH=d:\Borland\Delphi 3\Demos\Data’
‘ENABLE BCD=FALSE’
‘DEFAULT DRIVER=PARADOX’)
Após a criação do Alias da BDE ou do Alias local, usando o
componente TDatabase, o banco de dados está configurado
e pronto para ser usado.
Database Form Wizard
Após a configuração do banco de dados, a maneira mais
rápida, de se fazer uma janela de manutenção de dados é
através do Form Wizard no menu Database. Ao chegar no
Wizard são feitas uma série de perguntas que podem resultar
em uma janela simples ou Mestre/Detalhe. O acesso ao
banco de dados pode ser feito através de componentes
TTable ou através de SQL, com o componente TQuery,
usaremos o componente TTable. Todos os campos
selecionados aparecem na janela permitindo entrada de
dados através de componentes do tipo TDBEdit. Cada DBEdit
recebe um Label baseado no nome do campo na tabela
selecionada. Na Janela é incluído também um componente
para permitir a navegação e a manutenção dos dados, um
DBNavigator. O componente utilizado para fazer a ligação
entre os componentes visuais e o TTable é um TDataSource.
Geralmente os componentes TTable e TDataSource são
inseridos em DataModules, que são a base para a criação de
classes de dados. Sempre Após usar o Wizard, lembre-se de
mudar os nomes dos componentes, para que fiquem mais
claros.

Form Passo a Passo


O diagrama abaixo mostra como o Wizard fez a ligação entre
os componentes, onde os quadrados são componentes e as
elipses, propriedades.

Para concluir, acompanhe abaixo os passos realizados pelo


Wizard e tente você mesmo criar seu próprio Form.

Inclua um novo DataModule


Adicione ao DataModule um Table e um DataSource
No Table Coloque em DatabaseName o nome do Alias
criado pela propriedade DatabaseName do Database e
em TableName, o nome da tabela
No evento OnCreate do DataModule, chame o método
Open do componente Table
No DataSource coloque em DataSet o nome do
componente TTable
No Form, para definir a interface com o usuário, use os
componentes de controle de dados que estão na página
DataControls, basicamente DBEdit e DBNavigator
Para poder acessar os dados, coloque a Unit onde está o
DataModule no uses da Unit do Form
Em todos os componentes DataControls, escolha na
propriedade DataSource, o componente DataSource
criado no DataModule
Em alguns controles, como no DBEdit, deve ser
especificado também o campo da tabela, na propriedade
DataField

Seguindo esses passos, o Form estará pronto para usar. Mais


adiante, veremos uma forma mais rápida de se criar um Form
de manutenção, mas o mais importante é compreender os
passos mostrados acima, com todos os componentes e
propriedades envolvidas. Vamos detalhar agora cada um dos
componentes envolvidos nesse processo, para
compreendermos melhor o que está acontecendo.
TDataModule
Um DataModule é como se fosse um Form invisível, onde
iremos inserir os componentes de acesso a dados, como o
Table e o Datasource. Por serem também classes, os
DataModules permitem a fácil implementação de modelos de
objetos, permitindo herança, criação de métodos, dentre
outros aspectos. Para inserir um DataModule em um projeto,
escolha New DataModule do menu File. Os DataModules não
gastam recursos do sistema, servem apenas para conter os
componentes de acesso a dados e criar, assim, uma classe
persistente.
TTable
Componente usado para acessar uma tabela em um banco
de dados. Esse componente é o mais importante quando
acessamos bases de dados Desktop. Muitas dos itens
mostrados abaixo estão definidos na classe TDataSet,
ancestral do TTable.

Propriedades Descrição
Active Define se a tabela esta aberta ou fechada
BOF Informa se está no início da tabela
CanModify Define se a aplicação pode inserir, deletar ou alterar
registros
DatabaseName Nome do banco de dados onde está a tabela, deve
ser escolhido um Alias, que pode ser local
EOF Informa se está no fim da tabela
Exclusive Define se a tabela pode ser compartilhada por outro
usuário
FieldCount Número de campos da tabela
FieldDefs Lista com a Definição dos campos da tabela
Fields Lista de objetos do tipo TField, que representam os
campos da tabela
Filter String com uma condição de filtragem
Filtered Define se a tabela é filtrada
IndexFieldNamesNome dos campo de índice, usados para ordenar
os registros da tabela
IndexName Nome do índice atual, vazia quando o índice for a
chave primária
IndexDefs Lista com a definição dos índices
MasterFields Campos usados no relacionamento com a tabela
mestre
MasterSource DataSource da tabela mestre em uma relação
Mestre/Detalhe
Modified Define se o registro atual foi modificado
ReadOnly Define se a tabela é somente para leitura
RecNo Número do registro atual
RecordCount Número de registros
State Estado da tabela
TableName Nome da tabela
TableType Tipo da tabela
Método Descrição
AddIndex Cria um novo índice, a tabela deve ser exclusiva
Append Entra em modo de inserção e, ao gravar, o registro
será colocado no fim do arquivo
AppendRecord Insere um registro no final do arquivo através de
código
Cancel Cancela as alterações feitas no registro atual
Close Fecha a tabela
CreateTable Cria uma tabela, depende de FieldDefs e IndexDefs
Delete Exclui o registro corrente
DeleteIndex Exclui um índice
DeleteTable Exclui a tabela
DisableControls Desabilita a atualização dos controles visuais
Edit Permite a alteração dos campos do registro atual
EmptyTable Apaga todos os registro da tabela, para isso a
tabela não pode esta sendo compartilhada
EnableControls Habilita os controles visuais
FieldByName Acessa um campo, do tipo TField, pelo nome
FindKey Procura o registro com os valores exatos aos dos
parâmetros nos campos do índice atual
FindNearest Procura o registro com os valores mais
aproximados aos dos parâmetros nos índices
First Move para o primeiro registro
Insert Entra em modo de inserção de um novo registro na
posição atual
InsertRecord Adiciona um novo registro, já com os dados, na
posição atual
IsEmpty Define se a tabela está vazia
Last Move para o último registro
Locate Procura um registro, usando ou não índices, de
acordo com a disponibilidade
LockTable Trava a tabela
Lookup Procura um registro e retorna valores dos campos
deste
MoveBy Move um número específico de registros
Next Move para o próximo registro
Open Abre a tabela
Post Grava as alterações no registro atual
Prior Move para o primeiro registro
Refresh Atualiza a tabela com os dados já gravados
RenameTable Renomeia a tabela
UnlockTable Destrava a tabela
Evento Descrição
AfterCancel Após do método Cancel
AfterClose Após o fechamento da tabela
AfterDelete Após do método Delete
AfterEdit Após do método Edit
AfterInsert Após do método Insert
AfterOpen Após do método Open
AfterPost Após do método Post
AfterScroll Após mudar de registro
BeforeCancel Antes do método Cancel
BeforeClose Antes do fechamento da tabela
BeforeDelete Antes do método Delete
BeforeEdit Antes do método Edit
BeforeInsert Antes do método Insert
BeforeOpen Antes do método Open
BeforePost Antes do método Post
BeforeScroll Antes de mudar o registro
OnCalcFields Evento usado para calcular os valores dos campos
calculados
OnDeleteError Quando ocorre um erro ao chamar o método Delete
OnEditError Quando ocorre um erro ao chamar o método Edit
OnFilterRecord Evento usado com filtragem variável
OnNewRecord Quando a tabela entra em modo de inserção, não
deixa Modified igual a True
OnPostError Quando ocorre um erro ao chamar o método Post

Filtros
Usando o Filter, você pode filtrar os registro de uma tabela
usando uma expressão lógica, como nos exemplos abaixo.
Para tornar um filtro ativo, basta colocar Filtered igual a True.
Data = ‘20/04/1998’
(Data = ‘20/04/1998’) AND (Vendedor = ‘Gilherme Augusto da
Fonseca’)
(Nome > ‘A’) AND (Nome < ‘B’)
Contudo, se a condição de filtragem for muito variável, é
preferível usar um código como o mostrado abaixo no evento
OnFilterRecord da Table, para fazer uma filtragem dinâmica,
com a propriedade Filter vazia e Filtered igual a True.
Accept := TblData.Value = Date;
Ao filtrar uma tabela, a propriedade RecordCount da Table, só
mostra o número de registros que satisfazem ao filtro, como
se os outros registros nao existissem.
Alterando Registros
Para alterar registros em código, colocamos a tabela em
modo de edição, alteramos o valor dos campos e gravamos
as alterações, se for necessário.
with DtmPedidos do
begin
Tbl.Edit;
TblData.Value := Date;
TblHora.Value := Time;
Tbl.Post;
end;

Inserindo Registros
Para inserir registros em código você pode usar os métodos
AppendRecord e InsertRecord, caso você não precise de
algum campo, mesmo assim ele deve ser informado com o
valor Null.
DtmProd.Tbl.AppendRecord([Null,
EdtDescricao.Text, EdtPreco.Text]);

Localizando Registros
Para localizar registros você pode usar vários métodos, mas o
melhor deles é o Locate, no exemplo abaixo é feita uma
pesquisa exata.
if not DtmCli.Tbl.Locate(‘CodCli’, Edt.Text,
[]) then
ShowMessage(‘Cliente não encontrado.’);
Você também pode fazer uma pesquisa parcial e/ou sem
sensitividade de caso usando o terceiro parâmetro, que é um
conjunto de opções.
DtmCli.Tbl.Locate(‘Nome’, Edt.Text,
[loPartialKey, loCaseInsensitive]);
Se você precisar fazer uma pesquisa por mais de um campo,
separe os nomes dos campos por ponto e vírgula e use a
função VarArrayOf para criar um array com os valores que
você quer procurar.
if not DtmPed.Tbl.Locate(‘Vendedor;Data’,
VarArrayOf([EdtVendedor.Text, EdtData.Text]),
[loCaseInsensitive]) then ShowMessage(‘O
vendedor não realizou nenhuma venda nessa
data’);
Caso os campos pesquisados sejam indexados, a pesquisa
será muito mais eficiente, senão será criado um filtro
temporário da BDE para localizar os registros

Indexação
A indexação é usada para ordenar os registros da tabela,
para isso você deve escolher os campos pelos quais você
quer ordenar na propriedade IndexFieldNames, inclusive em
código, como mostrado abaixo, todos campos devem ser
indexados e separados por ponto e vírgula.
DtmCli.Tbl.IndexFieldNames := ‘Nomcli’;
DtmPed.Tbl.IndexFieldNames := ‘Data, Vendedor’;

Estados da Tabela
A propriedade State determina o estado das tabelas, os
principais estados são demonstrados abaixo, veja como os
métodos mudam o estado.

Verificando Alterações
Onde for necessário a verificação de alterações feitas em
uma Tabela, por exemplo no evento OnClose de um Form de
manutenção, você pode usar a propriedade Modified, como
mostrado no exemplo abaixo.
if DtmCli.Tbl.Modified then
if Application.MessageBox(‘Gravar
alterações?’, ‘Dados Alterados’,
MB_ICONQUESTION
+ MB_YESNO) = IDYES then
DtmCli.Tbl.Post
else
DtmCli.Tbl.Cancel;

Valores Default
Caso você queira especificar valores Default para os campos
de uma tabela, use o evento OnNewRecord, pois nesse
evento o registro não é marcado como modificado.
TblData.Value := Date;

Percorrendo uma Tabela


Utilize um código semelhante ao mostrado abaixo para
percorrer uma tabela do início ao fim.
Tbl.DisableControls;
Total := 0;
Tbl.First;
while not Tbl.EOF do
begin
Total := Total + TblValor.Value;
Tbl.Next;
end;
Tbl.EnableControls;

Forms Modais de Inclusão/Alteração


Para mostrar Forms Modais de inclusão ou alteração de
registros utilize comandos como os mostrados abaixo.
TblCli.Insert;
if FormInsCli.ShowModal = mrOk then
TblCli.Post
else
TblCli.Cancel;
Mestre/Detalhe
Nos relacionamentos de 1 para N, uma tabela pode estar
ligada a outra em uma relação Mestre/Detalhe, nesse tipo de
relação os registros da tabela de ordem N são filtrados pelo
campo de relacionamento com a tabela de ordem 1. Por
exemplo, se o relacionamento de Clientes com Pedidos for
mestre/detalhe, só serão acessados em pedidos, os registros
cujo campo CodCli seja igual ao CodCli da tabela de Clientes.
Para fazer esse tipo de relacionamento, siga os passos
abaixo.

No uses da Unit detalhe, Pedidos, inclua a Unit da tabela


mestre, Clientes
Na Table detalhe, Pedidos, Coloque em MasterSource o
DataSource da tabela mestre, Clientes
Em MasterFields, chame o Fields Links Designer e
escolha os campos de ligação das tabelas, no caso,
CodCli para as duas tabelas
Fields Editor
Para criar objetos para os campos de uma tabela clique duas
vezes no componente TTable ou escolha Fields Editor no seu
menu de contexto, na janela do Fields Editor, clique com o
botão direito do mouse e escolha Add, na janela Add Fields,
escolha os campos que você vai querer usar e clique em Ok.
No Fields Editor podemos também remover os campos
criados, alterar sua ordem de apresentação e usar suas
propriedades e eventos no Object Inspector. Para cada
campo é criado um objeto de um tipo descendente de TField,
como TStringField, TIntegerField, TFloatField. As principais
propriedades dos objetos TField estão listadas na tabela
abaixo.
Se você não criar nenhum objeto TField, todos os campos da
tabela estarão disponíveis, mas caso você crie algum,
somente os campos que você criar estarão disponíveis.
Se você selecionar os campos no Fields Editor e arrastar para
o Form, serão criados os controles visuais para esses
campos, Label, DBEdit e outros, mas antes coloque a
descrição dos campos na propriedade DisplayLabel.
TField
A classe TField é usada como ancestral para todos as
classes dos campos. Geralmente iremos usar objetos de
classes descendentes de TField, mas em todos eles podemos
encontrar os itens mostrados abaixo.

Propriedades Descrição
Alignment Alinhamento do texto do campo nos
controles visuais
AsBoolean Valor do campo convertido para Boolean
AsCurrency Valor do campo convertido para Currency
AsDateTime Valor do campo convertido para DataTime
AsFloat Valor do campo convertido para Double
AsInteger Valor do campo convertido para Integer
AsString Valor do campo convertido para string
AsVariant Valor do campo convertido para Variant
Calculated Indica se o campo é calculado em tempo de
execução
CanModify Indica se um campo pode ser modificado
ConstraintErrorMessageMensagem de erro se a condição de
CustomConstraint não for satisfeita
CustomConstraint Condição de validação do campo
DataSet DataSet onde está o campo
DataSize Tamanho do campo, em Bytes
DataType Propriedade do tipo TFieldType, que indica o
tipo do campo
DefaultExpression Expressão com valor Default do campo para
novos registros
DisplayLabel Título a ser exibido para o campo
DisplayText Texto exibido nos controles visuais
associados ao campo
DisplayWidth Número de caracteres que deve ser usado
para mostrar o campo no controles visuais
EditMask Máscara de edição do campo
FieldKind Propriedade do tipo TFieldKind que indica o
tipo do campo, como Calculado ou Lookup
FieldName Nome do campo na tabela
FieldNo Posição física do campo na tabela
Index Posição do campo nos controles visuais
IsIndexField Indica se um campo é válido para ser usado
como índice
IsNull Indica se o campo está vazio
KeyFields Campo chave da tabela no relacionamento
com LookupDataSet, usado em campos
Lookup
Lookup Indica se um campo é Lookup
LookupCache Define se será usado cache para campos
Lookup
LookupDataSet DataSet onde está definido o valor do campo
Lookup
LookupKeyFields Campo chave do relacionamento em
LookupDataSet
LookupResultField Valor do campo, que será mostrado nos
controles visuais
ReadOnly Define se um campo é somente para leitura
Required Define se o campo é obrigatório
Size Tamanho físico do campo
Text Texto de edição do campo
Value Acesso direto ao valor do campo
Visible Define se um campo é visível
Eventos Descrição
OnChange Chamado quando o valor do campo é
mudado
OnSetText Chamado pelos controles visuais para
atribuir o texto digitado pelo usuário ao
campo
OnGetText Chamado para formatar o texto de exibição
do campo
OnValidate Validação do valor atribuído ao campo, caso
o valor não seja válido, gere uma exceção
Método Descrição
Assign Atribui um valor de um campo a outro,
inclusive nulo
FocusControl Seta o foco para o controle visual ligado ao
campo nos Forms
Clear Limpa o conteúdo do campo
Estão listadas abaixo algumas classes que realmente iremos
manipular no tratamento dos campos de uma tabela, são
classes descendentes de TField.
TStringField TBlobField TTimeField
TSmallintField TIntegerField TBytesField
TFloatField TWordField TVarBytesField
TCurrencyField TAutoIncField TGraphicField
TBooleanField TBCDField TMemoField
TDateField TDateTimeField
Em alguns desses campos você pode encontrar as
propriedades mostradas abaixo, que não estão presentes em
TField.

Propriedades Descrição
MaxValue Valor máximo para o campo
MinValue Valor mínimo para campo
DisplayFormat Formato de apresentação do campo, como ,0.00”
%” ou ,0.##” Km”
EditFormat Formato de edição do campo
Currency Define se um campo é monetário
DisplayValues Usado com campos Boolean, define o texto para
True e False, como Sim;Não
Métodos Descrição
LoadFromFile Carrega o conteúdo do campo de um arquivo
SaveToFile Salva o conteúdo do campo para um arquivo
Para acessar os campo de uma tabela, existem várias
abordagens, como mostrado abaixo..

Usando o objeto TField ligado ao campo.

TblDescricao.Value := TblVendedor.Value + ‘ em
‘ + TblData.AsString;

Usando a notação de colchetes. Se você não especificar


nenhuma propriedade, é assumida a propriedade Value
por padrão.

Tbl[‘Descricao’] := Tbl[‘Vendedor’] + ‘ em ‘ +
Tbl[‘Data’].AsString;

Através do método FieldByName

Tbl.FieldByName(‘Descricao’).Value :=
Tbl.FieldByName(‘Vendedor’).Value + ‘ em ‘ +
Tbl.FieldByName(‘Data’).AsString;

Usando a lista Fields do TTable

Tbl.Fields[5].Value := Tbl.Fields[3].Value + ‘
em ‘ + Tbl.Fields[4].AsString;
Conversão de Tipos
A conversão de tipo de um campo pode ser feita através as
propriedades tipo As…, como AsString.
DtmPed.TblData.AsString := EdtData.Text;

Validação
Para validar os valores de um campo, você pode usar a
propriedade CustomConstraint, por exemplo para garantir que
a quantidade de um item seja maior que zero, use em
CustomConstraint Quantidade > 0, e em CustomConstraint
coloque a mensagem para o usuário caso a condição seja
falsa. Outra forma, mais flexível, é usando o evento
OnValidate, com um código como abaixo, onde é gerada uma
exceção para cancelar a atribuição do valor ao campo.
if TblQuantidade.Value <= 0 then
raise Exception.Create(‘Quantidade deve ser
maior que zero.’);

Formatação Personalizada
Caso queira fazer uma formatação personalizada do campo,
pode usar os eventos OnGetText e OnSetText. Por exemplo,
se tiver um campo Estado, e quiser que quando o valor do
campo for C fosse mostrado Casado e S, Solteiro, no evento
OnGetText use um código como o abaixo.
if TblEstado.Value = ‘C’ then
Text := ‘Casado’
else if TblEstado.Value = ‘S’ then
Text := ‘Solteiro’;
Como controle visual para o usuário escolher o valor do
campo, você poderia usar o DBComboBox, com Solteiro e
Casado na propriedade Items, e no evento OnGetText do
campo o código mostrado abaixo.
if Text = ‘Casado’ then
TblEstado.Value := ‘C’
else if Text := ‘Solteiro’ then
TblEstado.Value = ‘S’;

Campos Calculados
Para criar campos calculados, clique com o direito no Fields
Editor e escolha New Field, no quadro NewField, digite o
nome do campo, o nome do objeto será automaticamente
informado, o tipo do campo, seu tamanho e escolha
Calculated em Field type.
Para colocar um valor nesse campo usaremos o evento
OnCalcFields do componente TTable, em nenhuma outra
parte os valores desses campos podem ser alterados.
O código do evento OnCalcFields deve ser enxuto, pois este
é chamado várias vezes durante a edição de um registro e
um procedimento pesado pode comprometer a performance
do sistema.
procedure TDtmAluno.TblCalcFields(DataSet:
TDataSet);
begin
if TblFaltas.Value >
DtmTurma.TblMaxFaltas.Value then
TblSituacao.Value := ‘Evadido’
bTblNota.Value >= 7 then
TblSituacao.Value := ‘Aprovado’
else
TblSituacao.Value := ‘Retido’
end;

Campos Lookup
Para fazer um relacionamento, às vezes precisamos criar um
campo de descrição, por exemplo em uma biblioteca, na
tabela de empréstimos, temos o código do Livro, mas
gostaríamos de mostrar o Título, esses campos são
chamados de campos Lookup.
Para criar um campo Lookup, siga os passos abaixo,
tomando como exemplo o caso do livro no empréstimo.
Abra o Fields Editor do Table desejado, Empréstimos
Clique com o direito e escolha New Field
No quadro New Field, escolha as propriedades do
campo como descrito em campos calculados, mas em
Field type, escolha Lookup
Em Key Fields escolha o campo da tabela que faz parte
do relacionamento, CodLivro
DataSet é a tabela onde está a descrição, Livros
Em Lookup Keys, escolha o campo de DataSet que faz
parte do relacionamento, CodLivro
Finalmente, escolha em Result field o campo de DataSet
que vai ser mostrado para o usuário, Título

Essas opções correspondem a algumas propriedades do


objeto TField gerado, que podem ser alteradas no Object
Inspector, KeyFields, LookupDataSet, LookupKeyFields,
LookupDataSet e LookupResultField.
Quando esses campo são exibidos em um DBGrid, por
padrão é criado um botão de lookup que mostrará os valores
da outra tabela uma lista. Para colocar esses campos em um
Form, devemos usar o DBLookupComboBox, apenas com as
propriedades padrão, DataSource e DataField, onde deve ser
escolhido o campo Lookup, quando você arrastar o campo
para o Form isso será feito automaticamente.
TDataSource
Componente usado para fazer a ligação entre um DataSet e
os componentes visuais.

Propriedade Descrição
AutoEdit Define se a tabela entrará em modo de edição assim
que o usuário digitar novos valores nos controles
DataSet DataSet ao qual o TDataSource faz referência
Evento Descrição
OnDataChange Ocorre quando o DataSet é alterado, ao mudar de
registro ou mudar os valores dos campos
OnStateChangeOcorre quando o estado do DataSet é alterado
OnUpdateData Ocorre antes de uma atualização

Botões de Navegação Personalizados


O DBNavigator tem os principais botões necessários para a
navegação por uma tabela, contudo se você quiser criar seus
próprios botões de navegação, o que não é recomendado, no
evento OnClick desses botões deve ser chamados os
métodos de navegação, como indicado abaixo.
DtmCli.Tbl.Next;
Para controlar a habilitação dos botões de navegação use o
evento OnDataChange do DataSource correspondente como
indicado abaixo.
BtnProx.Enabled := not DtmCli.Tbl.EOF;
Para criar botões de controle, como inclusão e exclusão, use
o evento OnStateChange do DataSource como indicado
abaixo para controlar a habilitação.
BtnAlterar.Enabled := DtmCli.Tbl.State =
dsBrowse;
Data Controls
Controles usados na interface com o usuário. Todos esses
componentes tem uma propriedade DataSource, que deve ter
o DataSource do Table ao qual estão ligados.
TDBNavigator
O DBNavigator permite que o usuário realize operações
padrão de controle de dados. Cada um dos botões do
DBNavigator chama um método do Componente Table ao
qual está ligado.

Podemos personalizar o DBNavigator usando as suas


propriedades e eventos, mas se quisermos mudar a figura
dos botões teremos que editar diretamente o arquivo
LIB\DBCTRLS.RES, na pasta do Delphi.

Propriedades Descrição
VisibleButtons Define os botões que serão visíveis
Hints Hints exibidos pelos botões
ConfirmDelete Define se será solicitado uma confirmação antes da
exclusão
Eventos Descrição
BeforeAction Quando um botão do Navigator é pressionado, antes
da ação ser executada
OnClick Quando um botão do Navigator é pressionado,
depois da ação ser executada
TDBGrid
Mostra os registros de uma tabela em forma de grade, cada
coluna é um campo e cada registro, uma linha.

Propriedades Descrição
Columns Lista do tipo TDBGridColumns, com as colunas da
Grid, cada item da lista é do tipo TColumn
Fields Lista de objetos TField mostrados nas colunas
Options Set com as opções da Grid, como ConfirmDelete,
MultiSelect, ColumnResize
SelectedField Campo da coluna selecionada
SelectedIndex Índice da coluna selecionada
SelectedRows Lista do tipo TBookmarkList, com os registros
selecionados em uma Grid com MultiSelect
TitleFont Fonte do título das colunas
FixedColor Cor Fixa, usada nas colunas e indicadores
Eventos Descrição
OnCellClick Ao clicar em uma célula da Grid
OnColEnter Quando uma célula de alguma coluna da Grid
recebe o foco
OnColExit Quando uma célula de alguma coluna da Grid
perde o foco
OnColumnMoved Quando o usuário mover uma coluna
OnDrawDataCell Evento usado para personalizar a forma de
desenhar os dados que são apresentados na Grid
OnEditButtonClick Ao clicar no botão de edição de uma célula,
mostrado pela propriedade ButtonStyle da coluna
OnTitleClick Ao clicar no título das colunas

TColumn
Item de uma lista TDBGridColumns, usada na propriedade
Columns da Grid, objetos desse tipo representam uma coluna
da Grid. Às vezes as propriedades definidas para o campo
sobrepõem as propriedades

Propriedades Descrição
ButtonStyle Botão mostrado ao editar as células da coluna
Field Objeto TField ligado à coluna
FieldName Nome do campo ligado à coluna
PickList TStrings com os itens da lista DropDown usada nas
células da coluna
Title Propriedade do tipo TColumnTitle com as opções do
título da coluna
TDBText, TDBEdit, TDBMemo,
TDBListBox, TDBComboBox,
TDBImage, TDBRichEdit
Controles genéricos ligados a um campo de uma tabela.

Propriedades Descrição
DataField Campo ao qual o controle está ligado
TDBCheckBox
Usado em campos que podem receber apenas dois valores,
como campos lógicos.

Propriedades Descrição
ValueChecked Valor a ser armazenado quando está selecionado
ValueUncheckedValor a ser armazenado quando não está
selecionado
TDBRadioGroup
Mostra algumas opções para o preenchimento de um campo.

Propriedades Descrição
Values Valor a ser armazenado para cada botão de rádio
TDBLookupListBox,
TDBLookupComboBox
Preenche um campo com dados contidos em outra tabela. Se
o campo mostrado nesses componentes for um campo
Lookup, você não precisa especificar nenhuma das
propriedades abaixo, apenas DataSource e DataField.

Propriedades Descrição
ListSource DataSource que contém os valores a serem exibidos
na lista
ListField Campo de ListSource que será exibido
KeyField Campo de ListSource usado no relacionamento
Exercícios
1. Crie uma aplicação que cadastre os Clientes de uma
empresa e as Compras feitas por estes Clientes, permita
inclusão, alteração, exclusão e consulta aos dados
cadastrados. Na janela principal fica o cadastro de Clientes,
com a grade de visualização de suas Compras, crie também
uma Janela para localizar Clientes por Nome.
A tabela de clientes deve ter Nome, Endereço, Bairro, Cidade,
Estado, CEP e Telefone, defina também índices para
melhorar a localização de clientes por Nome. Na tabela de
Compras, deseja-se saber a Data, Produtos e Valor, assuma
que cada compra tem um Produto apenas. Como foi
mencionado, as compras serão cadastradas pelo cliente
atual, crie a relação Mestre/Detalhe entre Clientes e
Compras.
O Form de localização de Clientes deve permitir pesquisa
Nome, da mesma forma da questão anterior.
2. Uma academia de ginástica deseja manter um controle
maior sobre seus Alunos, para isso ela organizou os clientes
em turmas. Os dados de uma Turma são Número de alunos,
Horário da aula, Duração da aula, Data inicial, Data final e
Instrutor. Deve ser feita também uma tabela de instrutores
para evitar a digitação repetitiva do Nome. Os dados dos
Alunos são Matrícula, Data de Matrícula, Nome, Endereço,
Bairro, Cidade, Estado, Telefone, Data de nascimento, Altura
e Peso. Crie um banco de dados, normalizado, para guardar
essas informações.
No cadastro de Turmas, o Horário de aulas deve ser entre
7:00 e 18:00, a Duração não pode ser maior que 2 horas e a
Data Final tem que ser, no mínimo 5 dias após a Inicial. Esse
cadastro deve ser ordenado primeiro pela Data Final, em
ordem decrescente e depois pelo Horário, em ordem
crescente. As turmas já encerradas não devem ser mostradas
no cadastro, mas crie um arquivo morto com as turmas já
encerradas, onde os dados não possam ser alterados. Deve
ser possível também procurar o Instrutor pelo Nome, usando
um ComboBox, com os registros da tabela de Instrutores.
No cadastro de Alunos, a matrícula é Auto-incremental, a
Data de Matrícula deve ser, obrigatoriamente, a Data do
sistema e deve ser criado um campo calculado com o peso
ideal do cliente, altura menos 1,15.
Comandos de Consulta ao Esquema
Devemos ressaltar que a linguagem SQL é utilizada
tanto pelos profissionais responsáveis pelos dados,
onde é ressaltada a figura do Administrador do Banco
de Dados e dos Analistas de Dados, como também
pelos desenvolvedores de Aplicações. Enquanto
àqueles estão preocupados com o desempenho,
integridade do Banco de Dados e utilizam toda gama de
recusos disponíveis no SQL, estes estão preocupados
apenas em “transformar dados em informações”,
portanto para os desenvolvedores costuma-se dizer que
conhecer o “select” já basta. Em nosso curso
enfatizaremos a importância de TODOS os comandos
do SQL, mas sabemos de antemão que os professores
responsáveis pelas linguagens IDEO, VB e Delphi,
ressaltarão a preponderância da instrução “select”, que
será apresentada a seguir e não no final do curso de
SQL como geralmente acontece, pelo fato de que
diversas disciplinas necessitam especificamente deste
comando, que passaremos a apresentar:
1) Seleção de todas os campos (ou colunas) da
tabela de Departamentos.
Resp:
SELECT * FROM DEPT;
O exemplo utiliza o coringa “*” para selecionar as
colunas na ordem em que foram criadas. A instrução
Select, como pudemos observar seleciona um grupo de
registros de uma (ou mais) tabela(s). No caso a
instrução From nos indica a necessidade de
pesquisarmos tais dados apenas na tabela Dept.
 Where como base das Restrição de
tuplas.
A cláusula “where” corresponde ao operador restrição
da álgebra relacional. Contém a condição que as tuplas
devem obedecer a fim de serem listadas. Ela pode
comparar valores em colunas, literais, expressões
aritméticas ou funções.
A seguir apresentamos operadores lógicos e
complementares a serem utilizados nas expressões
apresentadas em where.
 Operadores lógicos
Operador Significado
= Igual a
> Maior que
>= Maior que ou igual a
< Menor que
<= Menor que ou igual a

Exemplos:
SELECT EMPNOME, EMPSERV
FROM EMP
WHERE DEPNUME > 10;
SELECT EMPNOME, EMPSERV
FROM EMP
WHERE EMPSERV = ‘GERENTE’;
O conjunto de caracteres ou datas devem estar entre
apóstrofes (‘) na cláusula “where”.
2) Selecione todos os departamentos cujo
orçamento mensal seja maior que 100000. Apresente
o Nome de tal departamento e seu orçamento anual,
que será obtido multiplicando-se o orçamento
mensal por 12.
Resp: Neste problema precisamos de uma expressão
que é a combinação de um ou mais valores, operadores
ou funções que resultarão em um valor. Esta expressão
poderá conter nomes de colunas, valores numéricos,
constantes e operadores aritméticos.
SELECT DEPNOME, DEPORCA * 12
FROM DEPT
WHERE DEPORCA > 100000;
3) Apresente a instrução anterior porém ao invés
dos “feios” DepNome e DepOrca, os Títulos
Departamento e Orçamento.
Resp: Neste exemplo deveremos denominar colunas por
apelidos. Os nomes das colunas mostradas por uma
consulta, são geralmente os nomes existentes no
Dicionário de Dado, porém geralmente estão
armazenados na forma do mais puro “informatiquês”,
onde “todo mundo” sabe que CliCodi significa Código do
Cliente. É possível (e provável) que o usuário
desconheça estes símbolos, portanto devemos os
apresentar dando apelidos às colunas “contaminadas”
pelo informatiquês, que apesar de fundamental para os
analistas, somente são vistos como enigmas para os
usuários.
SELECT DEPNOME “DEPARTAMENTO”, DEPORCA *
12 “ORCAMENTO ANUAL”
FROM DEPT
WHERE DEPORCA > 100000;
4) Apresente todos os salários existentes na
empresa, porém omita eventuais duplicidades.
Resp: A cláusula Distinct elimina duplicidades,
significando que somente relações distintas serão
apresentadas como resultado de uma pesquisa.
SELECT DISTINCT EMPSERV
FROM EMP;
5) Apresente todos os dados dos empregados,
considerando sua existência física diferente de sua
existência lógica (ou seja devidamente inicializado).
Resp: Desejamos um tratamento diferenciado para
valores nulos. Qualquer coluna de uma tupla que não
contenha informações é denominada de nula, portanto
informação não existente. Isto não é o mesmo que
“zero”, pois zero é um número como outro qualquer,
enquanto que um valor nulo utiliza um “byte” de
armazenagem interna e são tratados de forma
diferenciada pelo SQL.
SELECT EMPNOME, EMPSALA + EMPCOMI
FROM EMP;
SELECT EMPNOME, NVL(EMPSALA,0) +
NVL(EMPCOMI,0)
FROM EMP;
Obs: a função “NVL” é utilizada para converter valores
nulos em zeros.
6) Apresente os nomes e funções da cada
funcionário contidos na tabela empresa, porém
classificados alfabeticamente (A..Z) e depois
alfabeticamente invertido (Z..A).
Resp: A cláusula Order By modificará a ordem de
apresentação do resultado da pesquisa (ascendente ou
descendente).
SELECT EMPNOME, EMPSERV
FROM EMP
ORDER BY EMPNOME;
SELECT EMPNOME, EMPSERV
FROM EMP
ORDER BY EMPPNOME DESC;
Nota: Também é possível fazer com que o resultado da
pesquisa venha classificado por várias colunas. Sem a
claúsula “order by” as linhas serão exibidas na
sequência que o SGBD determinar.
7) Selecione os Nomes dos Departamentos que
estejam na fábrica.
Resp:
SELECT DEPNOME
FROM DEPT
WHERE DEPLOCA = “SAO PAULO”;
O exemplo exigiu uma restrição (São Paulo) que nos
obrigou a utilizar da instrução Where. Alguns analistas
costumam afirmar em tom jocoso que SQL não passa
de
“Selecione algo De algum lugar Onde se verificam tais
relações”
Acreditamos que esta brincadeira pode ser útil ao
estudante, na medida em que facilita sua compreensão
dos objetivos elementares do SQL.
Demais Operadores
Operador Significado
between…and… entre dois valores (inclusive)
in (….) lista de valores
like com um padrão de caracteres
is null é um valor nulo

Exemplos:
SELECT EMPNOME, EMPSALA
FROM EMP
WHERE EMPSALA BETWEEN 500 AND 1000;
SELECT EMPNOME, DEPNUME
FROM EMP
WHERE DEPNUME IN (10,30);
SELECT EMPNOME, EMPSERV
FROM EMP
WHERE EMPNOME LIKE ‘F%’;
SELECT EMPNOME, EMPSERV
FROM EMP
WHERE EMPCOMI IS NULL;
O símbolo “%” pode ser usado para construir a pesquisa
(“%” = qualquer sequência de nenhum até vários
caracteres).
Operadores Negativos
Operador Significado
<> diferente
not diferente da coluna
nome_coluna =
not não maior que
nome_coluna >
not between não entre dois valores informados
not in não existente numa dada lista de valores
not like diferente do padrão de caracteres informado
is not null não é um valor nulo

8) Selecione os Empregados cujos salários sejam


menores que 1000 ou maiores que 3500.
Resp: Necessitaremos aqui a utilização de expressão
negativas. A seguir apresentamos operadores
negativos.
SELECT EMPNOME, EMPSALA
FROM EMP
WHERE EMPSALA NOT BETWEEN 1000 AND 3500;
9) Apresente todos os funcionários com salários
entre 200 e 700 e que sejam Vendedores.
Resp: Necessitaremos de consultas com condições
múltiplas.
Operadores “AND” (E) e “OR” (OU).
SELECT EMPNOME, EMPSALA, EMPSERV
FROM EMP
WHERE EMPSALA BETWEEN 200 AND 700
AND EMPSERV = ‘VENDEDOR’;
10) Apresente todos os funcionários com salários
entre 200 e 700 ou que sejam Vendedores.
Resp:
SELECT EMPNOME, EMPSALA, EMPSERV
FROM EMP
WHERE EMPSALA BETWEEN 200 AND 700
OR EMPSERV = ‘VENDEDOR’;
11) Apresente todos os funcionários com salários
entre 200 e 700 e que sejam Vendedores ou
Balconistas.
Resp:
SELECT EMPNOME, EMPSALA, EMPSERV
FROM EMP
WHERE EMPSALA BETWEEN 200 AND 700
AND ( EMPSERV = ‘BALCONISTA’ OR EMPSERV =
‘VENDEDOR’ );
Funções de Caracteres
Função Significado
Lower força caracteres maiúsculos aparecerem
em minúsculos.v
Upper força caracteres minúsculos aparecerem
em maiúsculos.
Concat(x,y) concatena a string “x” com a string “y”.
Substring(x,y,str) extrai um substring da string “str”,
começando em “x”, e termina em “y”.
To_Char(num) converte um valor numérico para uma string
de caracteres.
To_Date(char,fmt) converte uma string caracter em uma data.
^Q converte data para o formato apresentado.

12) Apresente o nome de todos os empregados em


letras minúsculas.
Resp:
SELECT LOWER( EMPNOME )
FROM EMP;
13) Apresente o nome de todos os empregados
(somente as 10 primeiras letras).
Resp:
SELECT SUBSTRING (1,10,EMPNOME)
FROM EMP;
14) Apresente o nome de todos os empregados
admitidos em 01/01/80.
Resp:
SELECT *
FROM EMP
WHERE EMPADMI = ^Q”DD-AAA-YYYY”(“01-JAN-
1980”);
ou
SELECT *
FROM EMP
WHERE EMPADMI = ^Q(“01-JAN-1980”);
Funções Agregadas (ou de
Agrupamento)
Função Retorno
avg(n) média do valor n, ignorando nulos
count(expr) vezes que o número da expr avalia para algo
nao nulo
max(expr) maior valor da expr
min(expr) menor valor da expr
sum(n) soma dos valores de n, ignorando nulos

15) Apresente a Média, o Maior, o Menor e também a


Somatória dos Salários pagos aos empregados.
Resp:
SELECT AVG(EMPSALA) FROM EMP;
SELECT MIN(EMPSALA) FROM EMP;
SELECT MAX(EMPSALA) FROM EMP;
SELECT SUM(EMPSALA) FROM EMP;
Agrupamentos
As funções de grupo operam sobre grupos de
tuplas(linhas). Retornam resultados baseados em
grupos de tuplas em vez de resultados de funções por
tupla individual. A claúsula “group by” do comando
“select” é utilizada para dividir tuplas em grupos
menores.
A cláusula “GROUP BY” pode ser usada para dividir as
tuplas de uma tabela em grupos menores. As funções
de grupo devolvem uma informação sumarizada para
cada grupo.
16) Apresente a média de salário pagos por
departamento.
Resp:
SELECT DUPNUME, AVG(EMPSALA)
FROM EMP
GROUP BY DEPNUME;
Obs.: Qualquer coluna ou expressão na lista de seleção,
que não for uma função agregada, deverá constar da
claúsula “group by”. Portanto é errado tentar impor uma
“restrição” do tipo agregada na cláusula Where.
 Having
A cláusula “HAVING” pode ser utilizada para especificar
quais grupos deverão ser exibidos, portanto
restringindo-os.
17) Retome o problema anterior, porém apresente
resposta apenas para departamentos com mais de
10 empregados.
Resp:
SELECT DEPNUME, AVG(EMPSALA)
FROM EMP
GROUP BY DEPNUME
HAVING COUNT(*) > 3;
Obs.: A claúsula “group by” deve ser colocada antes da
“having”, pois os grupos são formados e as funções de
grupos são calculadas antes de se resolver a cláusula
“having”.
A cláusula “where” não pode ser utilizada para restringir
grupos que deverão ser exibidos.
Exemplificando ERRO típico - Restringindo Média Maior
que 1000:
SELECT DEPNUME, AVG(EMPSALA)
FROM EMP
WHERE AVG(SALARIO) > 1000
GROUP BY DEPNUME;
( Esta seleção está ERRADA! )
SELECT DEPNUME, AVG(EMPSALA)
FROM EMP
GROUP BY DEPNUME
HAVING AVG(EMPSALA) > 1000;
( Seleção Adequada )
Seqüência no comando “Select”:
SELECT ;coluna(s)
FROM ;tabela(s)
WHERE ;condição(ões) da(s) tupla(s)
GROUP BY ;condição(ões) do(s) grupo(s) de tupla(s)
HAVING ;condição(ões) do(s) grupo(s) de tupla(s)
ORDER BY ;coluna(s);
A “sql” fará a seguinte avaliação:
a) WHERE, para estabelecer tuplas individuais
candidatas (não pode conter funções de grupo)
b) GROUP BY, para fixar grupos.
c) HAVING, para selecionar grupos para exibiçao.
Equi-Junção ( Junção por igualdade
)
O relacionamento existente entre tabelas é chamado de
equi-junção, pois os valores de colunas das duas
tabelas são iguais. A Equi-junção é possível apenas
quando tivermos definido de forma adequada a chave
estrangeira de uma tabela e sua referência a chave
primária da tabela precedente. Apesar de admitir-se em
alguns casos, a equi-junção de tabelas, sem a
correspondência Chave Primária-Chave Estrangeira,
recomendamos fortemente ao estudante não utilizar
este tipo de construção, pois certamente em nenhum
momento nos exemplos propostos em nossa disciplina
ou nas disciplinas de Análise e Projeto de Sistemas,
serão necessárias tais junções.
18) Listar Nomes de Empregados, Cargos e Nome do
Departamento onde o empregado trabalha.
Resp: Observemos que dois dos três dados solicitados
estão na Tabela Emp, enquanto o outro dado está na
Tabela Dept. Deveremos então acessar os dados
restringindo convenientemente as relações existentes
entre as tabelas. De fato sabemos que DEPNUME é
chave primária da tabela de Departamentos e também é
chave estrangeira da Tabela de Empregados. Portanto,
este campo será o responsável pela equi-junção.
SELECT A.EMPNOME, A.EMPSERV, B.DEPNOME
;FROM EMP A, DEPT B
WHERE A.DEPNUME = B.DEPNUME;
Obs.: Note que as tabelas quando contém colunas com
o mesmo nome, usa-se um apelido “alias” para substituir
o nome da tabela associado a coluna. Imagine que
alguém tivesse definido NOME para ser o Nome do
Empregado na Tabela de Empregados e também NOME
para ser o Nome do Departamento na Tabela de
Departamentos. Tudo funcionaria de forma adequada,
pois o aliás se encarregaria de evitar que uma
ambiqüidade fosse verificada. Embora SQL resolva de
forma muito elegante o problema da nomenclatura
idêntica para campos de tabelas, recomendamos que o
estudante fortemente evite tal forma de nomear os
campos. O SQL nunca confundirá um A.NOME com um
B.NOME, porém podemos afirmar o mesmo de nós
mesmos?
19) Liste os Códigos do Cada Funcionário, seus
Nomes, seus Cargos e o nome do Gerente ao qual
este se relaciona.
Resp: Precisamos criar um auto-relacionamento, ou
seja, juntar uma tabela a ela própria. É possível
juntarmos uma tabela a ela mesma com a utilização de
apelidos, permitindo juntar tuplas da tabela a outra
tuplas da mesma tabela.
SELECT A.EMPNUME, A.EMPNOME, A.EMPSERV,
B.EMPNOME
FROM EMP A, EMP B
WHERE A.EMPGERE = B.EMPNUME;
As Sub-Consultas
Uma sub-consulta é um comando “select” que é
aninhado dentro de outro “select” e que devolve
resultados intermediários.
20) Relacione todos os nomes de funcionários e
seus respectivos cargos, desde que o orçamento do
departamento seja igual a 300000.
Resp:
SELECT EMPNOME, EMPSERV
FROM EMP A
WHERE 300000 IN ( SELECT DEPORCA
FROM DEPT
WHERE DEPT.DEPNUME = A.DEPNUME );
Nota: Observe que a cláusula IN torna-se verdadeira
quando o atributo indicado está presente no conjunto
obtido através da subconsulta.

21) Relacione todos os departamentos que possuem


empregados com remuneração maior que 3500.
Resp:
SELECT DEPNOME
FROM DEPT A
WHERE EXISTS (SELECT *
FROM EMP
WHERE EMPSALA > 3500 AND EMP.DEPNUME =
A.DEPNUME’);
Nota: Observe que a cláusula EXISTS indica se o
resultado de uma pesquisa contém ou não tuplas.
Observe também que poderemos verficar a não
existência (NOT EXISTS) caso esta alternativa seja
mais conveniente.
Uniões
Podemos eventualmente unir duas linhas de consultas
simplesmente utilizando a palavra reservada UNION.
22) Liste todos os empregados que tenham códigos
> 10 ou Funcionários que trabalhem em
departamentos com código maior que 10.
Resp: Poderíamos resolver esta pesquisa com um único
Select, porém devido ao fato de estarmos trabalhando
em nosso exemplo com apenas duas tabelas não
consiguimos criar um exemplo muito adequado para
utilização deste recurso.
(Select *
From Emp
Where EmpNume > 10)
Union
(Select *
From Emp
Where DepNume > 10);
Inserções, Alterações e Exclusões
Uma linguagem direcionada a extração de informações
de um conjunto de dados, em tese não deveria
incorporar comandos de manipulação dos dados.
Devemos observar contudo que a mera existência de
uma linguagem padronizada para acesso aos dados
“convidava” os desenvolvedores a aderirem a uma
linguagem “padrão” de manipulação de tabelas.
Naturalmente cada desenvolvedor coloca “um algo
mais” em seu SQL (SQL PLUS, SQL *, ISQL, e toda
sorte de nomenclaturas), por um lado desvirtuando os
objetivos da linguagem (padronização absoluta), mas
em contrapartida otimiza os acessos ao seu banco de
dados e por maior que sejam estas mudanças, jamais
são tão importantes que impeçam que um programador
versado em SQL tenha grandes dificuldades em se
adaptar ao padrão de determinada implementação. De
fato as diferenças entre o SQL da Sybase, Oracle,
Microsoft, são muito menores dos que as existentes
entre o C, o BASIC e o Pascal, que são chamadas de
linguagens “irmãs”, pois todas originam-se
conceitualmente no FORTRAN. Podemos observar que
todas as três linguagens mencionadas possuem
estruturas de controle tipo “para” (for), “enquanto” (while)
e repita (do..while, repeat..until). Todas trabalham com
blocos de instrução, todas tem regras semelhantes para
declaração de variáveis e todas usam comandos de
tomada decisão baseadas em instruções do tipo “se” ou
“caso”, porém apesar de tantas semelhanças (sic), é
praticamente impossível que um programador excelente
em uma linguagem consiga rapidamente ser excelente
em outra linguagem do grupo. Poderíamos arriscar a
dizer que um excelente programador C que utilize a
implementação da Symantech terá que passar por um
breve período de adaptação para adaptar-se ao C da
Microsoft.
O que ocorreria então se este programador tiver que
adaptar-se ao Delphi (Pascal) da Borland?
De forma alguma o mesmo ocorrerá com o especialista
em SQL ao ter que migrar do Banco de Dados X para o
Banco de Dados Y. Naturalmente existirá a necessidade
de aprendizado, mas este programador poderá ir
adaptando-se aos poucos sem precisar ser retreinado, o
que é um aspecto extremamente vantajoso para as
empresas.
Inserir (Insert)
INSERT INTO <tabela> [<campos>] [VALUES
<valores>]
Ex:
INSERT INTO DEPT;
Possibilita a inserção de registros de forma interativa.
INSERT INTO DEPT
(DEPNUME,DEPNOME,DEPLOCA) VALUES
(70,“PRODUCAO”,“RIO DE JANEIRO”);
Possibilita a inserção de registros em tabelas sem
digitação dos dados.
Atualizar (Update)
UPDATE <tabela> SET <campo> = <expressão>
[WHERE <condição>];
Ex:
UPDATE EMP SET EMPSALA = EMPSALA* 1.2
WHERE EMPSALA< 1000;
Excluir (Delete)
DELETE FROM <tabela> [WHERE <condição>];
Ex:
DELETE FROM emp WHERE EMPSALA > 5000;
Transações
Muitas vezes gostaríamos que determinado processo,
caso fosse abortado por qualquer motivo, pudesse ser
inteiramente cancelado. Imaginemos por exemplo um
usuário digitando um pedido. Imaginemos ainda que o
sistema possa reservar cada item solicitado de maneira
“on line”, ou seja ao mesmo tempo em que estou
digitando a quantidade o sistema já “empenhe” uma
quantidade equivalente no estoque. Imaginemos ainda
que o sistema deve cancelar todas as operações se
apenas um dos itens não puder ser atendido. Grande
problema, caso não pudéssemos anular todos os
processos a partir de determinada condição.
Vamos simular tal ocorrência com nosso banco de
dados EMP. Imaginemos que ao invés de digitarmos
DELETE FROM emp WHERE salario > 5000;
tivéssemos digitado DELETE FROM emp WHERE
salario > 500; Ao invés de eliminarmos 2 registros,
praticamente teríamos eliminado o banco de dados todo.
Para evitarmos que um erro de digitação, ou um
processo iniciado porém sem condição de ser
completado integralmente comprometa todos nossos
dados podemos criar uma transação que nos
assegurará que nossos testes sejam bem sucedidos ou
cancelados sem comprometer nossos dados.
begin transaction;
delete from emp where salario > 500;
if SQL_RECORDCOUNT > 20 THEN;
ROLLBACK TRASACTION;
else
COMMIT;
endif;
end transaction;
Visões
Uma visão consiste basicamente de uma tabela
derivada de outras tabelas. Considerando o exemplo
TRABALHO, poderíamos criar uma visão baseada na
Tabela de Empregados (EMP) e na Tabela de
Departamentos (DEPT) onde tivéssemos somente os
Nomes dos Funcionários e os Departamenos nos quais
estes trabalhassem. Teríamos algo assemelhado ao
abaixo representado
CREATE VIEW EMP_DEP
AS SELECT E.EMPNOME, D.DEPNOME
FROM EMP E, DEPT D
WHERE E.DEPNUME = D.DEPNUME;

Devemos observar que:

1- Uma visão definida sobre uma única tabela


somente será atualizável se os atributos da tal visão
contiverem a chave primária de tal tabela.
2- Visões sobre várias tabelas não são passíveis de
atualizações.
3- Visões que se utilizam de funções de
agrupamentos, também não poderão ser
atualizadas.
PARTE III - Relatórios
Comando:
REPORT DISTINCT / UNIQUE
[ atributo(s) ]
REPORTTOP
PAGETOP
TOP
DETAIL
NONE
BOTTOM
PAGEBOTTOM
REPORTBOTTOM
FROM [ tabela(s) ]
[ WHERE clausula-where ]
[ GROUP BY clausula-grupo ]
[ ORDER BY clausula-order by ];
Como exemplo converteremos um simples Select
em um Report, temos:
SELECT EMPNOME
FROM EMP
WHERE DEPNUME = 1000;
REPORT
DETAIL EMPNOME
WHERE DEPNUME = 1000;

Podemos direcionar a saida de um relatório tanto


para um arquivo como para uma impressora.
Para um arquivo:
;REPORT ON “RELAT.DAT” …
Para uma impressora:
REPORT ON LP:” …

Agora incrementando um report temos:


REPORT
REPORTTOP COL 10, “*** RELATORIO DE
FUNCIONARIOS *** “,
TODAY %Q”DD/MM/YY”, SKIP,
COL 10,
“=================================”, SKIP
2
DETAIL COL 10, NOME %C22, SALARIO %FS,
ADMISSAO %Q”DD/MM/YY”
REPORTBOTTOM COL 10,
“=================================”, SKIP,
COL 20, “TOTAL:”, TOTAL(SALARIO)
FROM EMP
ORDER BY NOME;

Onde:
REPORTTOP - O que sera impresso no topo do
relatório.
PAGETOP - Impresso em cada topo de pagina.
TOP - Impresso em cada Topo do Sort-Grupo do
relatório.
DETAIL - O que sera impresso em cada linha.
NONE - Se não tiver resultado o select, não sera
impresso o relatório.
BOTTOM - Impresso em cada Bottom do Sort-
Grupo do relatório
PAGEBOTTOM - O que sera impresso no rodapé
de cada pagina.
REPORTBOTTOM - O que sera impresso no
rodape do relatório.
Formatos:
%C - caracter
%D - data
y - ano,
n - mes numérico,
a - mes alfanumérico,
d - dia,
j - dia e ano juliano
Exemplo: %D”dd/mm/yy”
%I - inteiro
%F - ponto flutuante
%FSZ onde: S - separador de 3 digitos e decimal
point
Z - zeros serão suprimidos
%Q - data
%J - Hora
h - hora, m - minutos, s - segundos
%T - hora
E temos as funções: TOTAL, AVERAGE,
MAXIMUM, MINIMUM.
Texto Para Iniciantes
Introdução à Programação
Caso você já tenha uma base de programação pode
pular esta parte, ou pode lê-la caso se sinta inseguro
quanto ao seu conhecimento.
Bem, em primeiro lugar, o que este guia exige é uma
noção de comandos básicos que todo (ou quase todo)
tipo de linguagem exige.
Note que os exemplos serão baseados na programação
Delphi, e não qualquer linguagem.
Variáveis
Variável é um nome conhecido por qualquer
programador (ou pelo menos deveria ser), este nome
significa um endereço na memória onde um certo valor
fica guardado. Vejamos um exemplo: se você declara a
variável i:
var i:integer;
(“var” é nome usado para declarar uma variável em
Delphi, “integer” é o tipo de informação que ela deverá
armazenar) daí você pode estabelecer um valor para i:
i := 12;

este valor vai ficar “guardado na memória” para você


poder usa-lo mais tarde, por exemplo, para fazer uma
conta:
i := 4 * i;
Agora i vale 4 vezes 12 (48).
Loops
Se você já fez algum programa em uma linguagem
qualquer deve se lembrar dos famosos FOR e WHILE
(loop), caso contrário, vamos a uma introdução a estes
comandos:
Em uma linguagem de programação, loop é um
comando que faz com que um certo código seja
executado enquanto uma certa condição for atendida,
um exemplo o ajudará a entender melhor:
var i:integer; //(declara a variável i)
for i := 1 to 30 do
ShowMessage (‘O VALOR DE “I” É: ‘ +
IntToStr(I));

Este comando fará com que “PARA” (FOR) I = 1, ou


seja, o valor inicial de i é 1, “ATÉ” (TO) 30 (inclusive)
exiba uma mensagem (SHOWMESSAGE, é o comando
de exibir mensagens) escrevendo o valor de i. Portanto
serão exibidas 30 mensagens. O valor de i e
incrementado automaticamente ao fim do loop. Veja:
for i := 1 to 30 do (i=1) => ShowMessage(…) =>
(retorna a origem) for i := 1 to 30 do (i=2) =>
ShowMessage (…) =>
(…)
for i := 1 to 30 do (i=30) => ShowMessage (…) => Fim
do loop.
O comando While é semelhante, veja um exemplo de
seu uso:
var k:integer; //(declara a variável k).
k := 0 //(define o valor de k como “0”.
while k < 10 do
ShowMessage (‘k é menor que 10’);
“QUANDO” (WHILE) k é menor que 10 exibe a
mensagem “k é menor que 10” (a mensagem em Delphi
realmente deve estar entre apóstrofos (aspas simples) e
não aspas duplas (como em muitas linguagens)). No
entanto este loop não deve ser usado desta forma, pois,
ao contrário de “for”, while NÃO incrementa
automaticamente o número, portanto o loop nunca
acabará, pois k é 0 e sempre será 0 (foi definido esse
valor em “k := 0”). Portanto seria melhor fazer:
var k:integer; //(declara a variável k).
begin
k := 0 //(define o valor de k como “0”.
while k < 10 do
begin
ShowMessage (‘k é menor que 10);
k := k + 1;
end;

Agora o valor de k será incrementado de 1 toda a vez


que o loop “retornar”, portanto depois de 10 mensagens
o loop acabará (k vai de 0 até 9). Não se importe com o
“begin” e “end” eles serão discutidos mais adiante.
Introdução a linguagem e migrando
para Delphi
Variáveis
Talvez programadores oriundos de outras linguagens
tenham certa dificuldade para se acostumar com os
padrões delphi. A declaração de variáveis e seu uso,
provavelmente parecerá chato para programadores
Visual Basic. Vamos a algumas regras práticas:

1. Não é possível declarar variáveis em qualquer


lugar, apenas no início do procedimento.
2. Os tipos de dados Delphi não são compatíveis
(como no VB), por exemplo, você não pode
multiplicar a string “X” pela string “Y”, mas sim
transformá-las em números inteiros e depois
multiplica-los, veja: Z := StrToInt(X) * StrToInt(Y);.

Nem mesmo números inteiros são compatíveis com


reais.
Sinal de igual
Não use o sinal de igual para atribuir valores (como em
grande parte das linguagens) mas sim “:=” como na
linha abaixo:
i := 0;

O sinal de igual é usado apenas para comparação


como em comandos “If”, veja:
If i = 0 then
ShowMessage(‘O valor de i é 0’);
else
ShowMessage(‘O valor de i não é 0’;
Note que não se usa o EndIf como no caso do Visual
Basic, por exemplo… Mas pode-se usar o begin e end
para determinar o início e o fim como em:
if i = 0 then
begin
ShowMessage(‘O valor de i é 0’);
ShowMessage(‘Foi usado Begin e End porque
foram utilizadas duas linhas’);
end
else
ShowMessage(‘O valor de i não é 0’;
Quando se usa uma única linha não há necessidade de
usar Begin e End.
IMPORTANTE
Você deve ter notado que em Delphi não se usam aspas
duplas (“), mas aspas simples (‘), ou apóstrofo, como
preferir. Também é usado ponto e vírgula (;) no final de
cada comando (mas não nos que terminam com
comandos como If. Mas lembre-se que NÃO se deve
usar ponto e vírgula antes de else.
Outro motivo pelo qual no final de cada declaração usa-
se o ponto e vírgula é para mostrar que acabou. Por
esta razão pode-se continuar o comando na linha de
baixo (menos partir strings ao meio), veja:
Estaria CORRETO:
MessageDlg (‘Esta é uma mensagem!’,
mtinformation, [mbok], 0);
Mas estaria INCORRETO:
MessageDlg (‘Esta é uma
mensagem!’, mtinformation, [mbok], 0);
Se for necessário use:
MessageDlg (‘Esta é uma’ +
+ ‘ mensagem!’, mtinformation, [mbok], 0);
Isso é correto.
Comentários
Os comentários podem estar entre chaves:
{Este é um comentário que pode estar
em mais de uma linha}
entre sinais de parênteses e asterisco, como o
mostrado abaixo:
(* este é um comentário
que pode estar em mais de uma linha
até que seja colocado o sinal de asterisco
e fecha parênteses *)
Ou pode estar depois de duas barras, para comentários
rápidos de apenas uma linha, veja:
// Este comentário não pode passar de uma
linha…
Operadores
Eles são:
* - Multiplicação aritmética.
/ - Divisão de números que obtém um número
real (exemplo: 5/2 = 2.5).
div - Divisão de números que obtém um
número inteiro (exemplo: 5/2 = 2).
+ - Adição.
- - Subtração.
= - Igual.
<> - Diferente.
> - Maior.
>= - Maior ou igual.
< - Menor.
<= - Menor ou igual.
 Exemplo:
Form1.Canvas.TextOut (1, 1, IntToStr((2 * 5) div
3));

Form1: Nome do formulário;


Canvas: Propriedade (não apenas do formulário)
relacionada com desenho. Neste caso ela é usada para
escrever no formulário (com o TextOut), algo como o
print do Visual Basic. Sua cor de fundo padrão é
branca, mas é possível mudá-la acessando a
propriedade brush. O primeiro parâmetro é o left, o
segundo é o top e o terceiro é o texto a ser escrito.
IntToStr: Transforma um inteiro em caracteres (como já
foi dito anteriormente, o Delphi não possui
compatibilidade entre Integers e Strings, a não ser que
sejam usadas Variants).
 Iniciantes:
Para quem ainda não está integrado com programação
aqui vão alguns conceitos:
Parâmetros: São “valores extras”, colocados entre
parênteses para fornecer outras informações ao método
(function ou procedure). No exemplo mostrado, a função
precisa dos parâmetros inteiros (que foram determinado
como 1 neste caso) para saber a que distância da
margem esquerda e o topo, respectivamente;
Left: Valor inteiro que diz a distância até o canto
esquerdo de um objeto;
Top: Valor inteiro que diz a distância até o topo de um
objeto;
Dicas…
Usando funções externas (de
DLLs)…
Usar funções externas, de uma ou mais DLLs é muito
simples, basta declara-las da seguinte forma:
function NomeDaFuncao(Parâmetros: Tipo):
TipoRetorno; stdcall; external
‘NomeDaDLL’;
Você pode ver o nome de uma função da DLL na
Visualização Rápida do Windows (se esta estiver sido
instalada), para isso encontre o arquivo DLL, clique nele
com o botão direito do mouse e escolha visualização
rápida.
Manipulando “Application”…
A classe TApplication proporciona muitas manipulações
úteis do aplicativo como um todo. Por exemplo, caso
você queira que quando um aplicativo for minimizado
apareça a hora atual no título da barra de tarefas, e
quando ele for restaurado não apareça, use o seguinte
código no evento OnLoad do formulário, por exemplo:
Application.OnMinimize := ShowDate;
Application.OnRestore := NShowDate;

procedure ShowDate;
begin
TForm1.Timer1Timer(Sender);
Timer1.Enabled := True;
end;

procedure NShowDate;
begin
Timer1.Enabled := False;
Application.Title := ‘Título do
Aplicativo’;
end;
Este exemplo considera que o aplicativo possua um
relógio que atualiza de tempos em tempos (a cada 250
milésimos de segundo por exemplo). Este é desabilitado
quando o formulário é restaurado.
Undo na caixa de texto (Memo)…
Use o seguinte código para Desfazer a última ação em
uma caixa de Texto (Memo):
Memo1.Perform(EM_UNDO, 0, 0);
o valor retornado de Memo1.Perform(EM_CANUNDO,
0, 0) será diferente de zero se o comando de Desfazer
estiver disponível.
Pegando a posição do cursor…
Use o seguinte código para ver a posição do cursor na
tela, ele é muito útil quando o evento usado não possui
como parâmetros “X” e “Y”:
procedure GetPosition (var X; var Y);
var CPos: TPoint;
begin
GetCursorPos(CPos);
X := CPos.X;
Y := CPos.Y;
end;

Se quiser aprender mais sobre programaçã

Clique aqui para ver as novidades!!!


Fundamentos do Object Pascal
Conceitos de Programação Orientada a
Objetos
Antes de partir para a linguagem propriamente dita,
vamos revisar alguns conceitos básicos de
Programação Orientada a Objetos.
Classe: Definição de tipo dos objetos, modelo de objeto.
Objeto: Instância de classe, variável cujo tipo é uma
classe.
Atributos: Variáveis de instância, são os dados de um
objeto.
Métodos: Funções e procedimentos de um objeto.
Propriedades: Apelido usado para evitar o acesso
direto aos atributos de um objeto, onde podemos
especificar métodos que serão usados para ler e atribuir
seus valores a esses atributos.
Mensagens: Chamada de métodos, leitura e atribuição
de propriedades.
Encapsulamento: Conjunto de técnicas usadas para
limitar o acesso aos atributos e métodos internos de um
objeto.
Herança: Possibilidade de criar uma classe
descendente de outra, aproveitando seus métodos,
atributos e propriedades.
Ancestral: Super classe ou classe de base, a partir da
qual outras classes podem ser criadas.
Descendente: Subclasse.
Hierarquia de Classes: Conjunto de classes ancestrais
e descendentes, geralmente representadas em uma
árvore hierárquica.
Polimorfismo: Capacidade de redefinir métodos e
propriedades de uma classe em seus descendentes.
1.0 Estrutura de Units
Vamos examinar o código gerado para um novo Form,
identificando as principais seções de uma Unit típica.
Crie uma nova aplicação e observe na Unit principal as
seguintes cláusulas.
Unit: A primeira declaração de uma unit é seu
identificador, que é igual ao nome do arquivo.
Interface: Seção interface, onde ficam declarações que
podem ser usadas por outras Units.
Uses: Na cláusula uses fica a Lista de Units usadas.
Type: Na cláusula type fica a definição de tipos, aqui
temos a declaração da classe do Form.
Var: Na cláusula var são declaradas as variáveis, aqui
temos a declaração da instância do Form.
Implementation: Na seção implementation ficam as
definições dos métodos.
End: Toda Unit termina com um end a partir de onde
qualquer texto é ignorado.
2.0 Variáveis
No Delphi, toda variável tem que ser declarada antes de
ser utilizada. As declarações podem ser feitas após a
palavra reservada var, onde são indicados o nome e o
tipo da variável. Os nomes de variáveis não podem ter
acentos, espaços ou caracteres especiais como &, $ ou
% e o primeiro caractere de um nome de variável tem
que ser uma letra ou um sublinhado. O delphi ignora se a
variável é maiúscula ou minúscula, não fazendo diferença na hora de
acessa-las.

.
Variáveis Globais
As variáveis abaixo são globais, declaradas da Interface
da Unit. Podem ser acessadas por qualquer Unit
usuária.
var
I: Integer;
Usuario: string;
A, B, Soma: Double;
Ok: Boolean;
Variáveis Locais
As variáveis abaixo são locais ao método, ou seja elas
só existem dentro do método, não podem ser acessadas
de fora, mesmo que seja na mesma Unit. Na verdade
essas variáveis são criadas quando o método é
chamado e destruídas quando ele é encerrado, seu
valor não é persistente.
procedure
TFrmExemplo.BtnTrocarClick(Sender:
TObject);
var
Aux: string;
begin
Aux := EdtA.Text;
EdtA.Text := EdtB.Text;
EdtB.Text := Aux;
end;
3.0 Atributos
Os atributos são variáveis de instância. Para declarar
um atributo em uma classe basta definir o identificador e
o tipo do atributo na declaração da classe, feita na
seção type da Interface da Unit, como abaixo.
type
TFrmSomar = class(TForm)
private
{ Private declarations }
A, B: Double;
public
{ Public declarations }
Soma: Double;
end;
4.0 Encapsulamento
Os principais níveis de visibilidade dos atributos e
métodos de uma classe são mostrados abaixo.

Nivel Visibilidade
Os itens declarados nesse nível só podem ser acessados na
Private mesma unit.

Public Nesse nível, qualquer unit usuária poderá acessar o item.

Os itens só poderão ser acessados em outra unit se for em


Protected uma classe descendente
É o nível default, igual ao Public, mas define propriedades e
Published eventos usados em tempo de projeto

5.0 Classes
Classes são tipos de objetos, uma classe é declarada na
cláusula type da seção interface e os métodos são
definidos na seção implementation. Examine o código
de um Form para identificar os elementos de sua classe.
interface
type
TFrmSomar = class(TForm)
EdtA: TEdit;
EdtB: TEdit;
BtnSoma: TButton;
procedure BtnSomaClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
implementation
procedure TFrmSoma.BtnSomaClick(Sender:
TObject);
begin
ShowMessage(EdtA.Text + EditB.Text);
end;
6.0 Objetos
Um Objeto é tratado como uma variável cujo tipo é uma
classe. A declaração de objetos é igual à declaração de
uma variável simples, tendo no lugar do tipo a classe do
objeto.
var
FrmSomar: TFrmSomar;
7.0 Literais
Valores literais são valores usados em atribuições e
expressões. Cada tipo tem uma sintaxe diferente.

Tipo Definição
Seqüência de dígitos decimais (0 a 9),
Inteiro
sinalizados ou não
Inteiro Seqüência de dígitos hexadecimais (0 a F),
Hexadecimal precedidos por um sifrão ($)
Igual ao tipo Inteiro, mas pode usar
Real
separador decimal e notação científica
Letra entre apóstrofos ou o caracter #
Caractere seguido de um número inteiro entre 0 e
255 (ASCII)
Seqüência de caracteres delimitado por
String
apóstrofos

8.0 Constantes
São declaradas na seção const, podem ser usadas
como variáveis, mas não podem ser alteradas.
Geralmente o nome das constantes é escrito em letras
maiúsculas e na declaração dessas constantes não é
indicado o tipo.
const
G = 3.94851265E-19;
NUM_CHARS = ‘0123456789’;
CR = #13;
SPACE = ‘ ‘;
MAX_VALUE = $FFFFFFFF;
Constantes Tipadas
Na verdade, constantes tipadas são variáveis
inicializadas com valor persistente, que podem ser
alteradas normalmente, como qualquer variável. A única
diferença de sintaxe entre constantes tipadas e simples
é que o tipo da constante é indicado explicitamente na
declaração. Se uma constante tipada for declarada
localmente, ela não será destruída quando o método for
encerrado. Para diferenciar das constantes normais,
costuma-se declarar estas com letras de caso variável,
como abaixo.
const
Cont: Integer = 1;
Peso: Double = 50.5;
Empresa: string = ‘SENAC’;
9.0 Instruções
Os programas são compostos por instruções, que são
linhas de código executável. Exemplos de instruções
simples são atribuições, mensagens entre objetos,
chamadas de procedimentos, funções e métodos, como
mostradas abaixo. As instruções podem ser divididas
em várias linhas, o que indica o fim de uma instrução é o
ponto e vírgula no final. Quando uma instrução é
quebrada, costuma-se dar dois espaços antes das
próximas linhas, para melhorar a leitura do código.
Caption := ‘Gabba Gabba Hey!’;
Form2.ShowModal;
Application.MessageBox(‘Você executou uma
operação ilegal, o programa será
finalizado.’,
‘Falha geral’, MB_ICONERROR);
Você pode usar várias instruções agrupadas em uma
instrução composta, como se fosse uma só instrução.
Uma instrução composta delimitada pelas palavras
reservadas begin e end. Toda instrução, simples ou
composta, é terminada com um ponto-e-vírgula.
if CheckBox1.Checked then
begin
ShowMessage(‘O CheckBox será
desmarcado.’);
CheckBox1.Checked := False;
end;
Estilo de Codificação
As instruções e todo o código de uma Unit devem ser
distribuídos para facilitar o máximo a leitura. Para isso,
podemos usar a indentação, geralmente de dois
espaços para indicar os níveis de código. Procure criar
um estilo próprio, que melhor se molde à sua realidade.
Se for desenvolver em grupo, é melhor que todos usem
o mesmo estilo para evitar confusões.
10.0 Comentários
Existem 3 estilos de comentário no Delphi, como
mostrado abaixo.
(* Comentário do Pascal Padrão *)
{ Comentário do Turbo Pascal }
// Comentário de linha do C++
Cuidado com as diretivas de compilação, pois elas são
delimitadas por chaves e podem ser confundidas com
comentários. A diretiva de compilação mostrada abaixo
é incluída em todas as Units de Forms.
{$R*.DFM}
11.0 Tipos de Dados Padrão
O Delphi trata vários tipos de dados padrão, segue uma
descrição sucinta desses tipos.
Tipos Inteiros
São tipos numéricos exatos, sem casas decimais. O tipo
Integer é o tipo inteiro padrão.

Tipo Tamanho em Valor Mínimo Valor Máximo


Bytes
ShortInt 1 -128 127
SmallInt 2 -32768 32767
Longint 4 -2.147.483.648 2.147.483.647
Byte 1 0 255
Word 2 0 65535
Integer 4 -2.147.483.648 2.147.483.647
Cardinal 4 0 2.147.483.647

Tipos Reais
São tipos numéricos com casas decimais. O tipo Double
é o tipo real padrão.

Tipo Tamanho Valor Valor Dígitos


em Bytes Mínimo Máximo Significativos
Real 6 10-39 1038 11-12

Single 4 10-45 1038 7-8

Double 8 10-324 10308 15-16

Extended 10 10-4932 104932 19-20

Comp 8 -1018 1018 19-20

Currency 8 -1012 1012 19-20

Tipos Texto
Os tipos texto podem operar com caracteres simples ou
grupos de caracteres. O tipo texto padrão é o tipo string.

Tipo Descrição
Char Um único caractere ASCII
Texto alocado dinamicamente, pode ser limitado a
String
255 caracteres conforme configuração
String terminada em nulo (#0), usada geralmente
PChar
nas funções da API do Windows

O operador + pode ser usado para concatenar strings e


você pode usar uma variável do tipo string como uma
lista de caracteres.
ShowMessage(‘5ª letra do título da janela:
‘ + Caption[5]);
Label1.Text := ‘2ª letra do Edit: ‘ +
Edit1.Text[2];
Existem várias funções de manipulação de strings, veja
algumas das mais importantes mostradas abaixo.

Função Descrição
Compara 2 strings sem sensitividade
AnsiCompareText
de maiúsculas/minúsculas
Converte todas as letras de uma
AnsiLowerCase
string para minúsculas
Converte todas as letras de uma
AnsiUpperCase
string para maiúsculas
Copy Retorna parte de uma string
Delete Apaga parte de uma string
Insert Insere uma string em outra
Length Número de caracteres de uma string
Pos Posição de uma string em outra
Remove todos os espaços de uma
Trim
string
Remove os espaços à esquerda de
TrimLeft
uma string
Remove os espaços à direita de uma
TrimRight
string
Format Formata uma string com uma série de
argumentos de vários tipos

Por exemplo, para comparar o texto de dois Edits,


poderíamos usar a função AnsiCompareText.
if AnsiCompareText(EdtA.Text, EdtB.Text) =
0 then
ShowMessage(‘O texto dos dois Edits são
iguais.’);
A função Format é especialmente útil na formatação de
strings, veja alguns exemplos.
ShowMessage(Format(‘O número %d é a parte
inteira do número %f.’, [10, 10.5]));
ShowMessage(Format(‘Este texto%sfoi
formatado%susando o caractere #%d.’, [#13,
#13, 13]));
ShowMessage(Format(‘O preço do livro %s é
%m.’, [‘Como Programar em Delphi’,
50.7]));
Um detalhe que deve ser observado é que as
propriedades dos objetos não podem ser usadas como
variáveis em funções. Veja a declaração do
procedimento Delete no help.
procedure Delete(var S: string; Index,
Count:Integer);
Digamos que você deseje apagar as 5 primeiras letras
de um Edit, como a string do Delete é variável, não
poderia usar o código abaixo.
Delete(Edit1.Text, 1, 5);
Para você poder fazer a operação desejada, teria que
usar uma variável como variável auxiliar.
var
S: string;
begin
S := Edit1.Text;
Delete(S, 1, 5);
Edit1.Text := S;
end;
Tipos Ordinais
Tipos ordinais são tipos que tem uma seqüência
incremental, ou seja, você sempre pode dizer qual o
próximo valor ou qual o valor anterior a um determinado
valor desses tipos. São tipos ordinais o Char, os tipos
inteiros, o Boolean e os tipos enumerados. Algumas
rotinas para ordinais são mostradas abaixo.

Função Descrição
Dec Decrementa variável ordinal
Inc Incrementa variável ordinal
Odd Testa se um ordinal é ímpar
Pred Predecessor do ordinal
Succ Sucessor do ordinal
Ordem de um valor na faixa de valores de
Ord
um tipo ordinal
Low Valor mais baixo na faixa de valores
High Valor mais alto na faixa de valores

Por exemplo, use o código abaixo no evento


OnKeyPress de um Edit e veja o resultado.
Inc(Key);
Boolean
Variáveis do tipo Boolean podem receber os valores
lógicos True ou False, verdadeiro ou falso. Uma variável
Boolean ocupa 1 byte de memória.
TDateTime
O tipo TDateTime guarda data e hora em uma estrutura
interna igual ao tipo Double, onde a parte inteira é o
número de dias desde 31/12/1899 e a parte decimal
guarda a hora, minuto, segundo e milissegundo. As
datas podem ser somadas ou subtraídas normalmente.
Existem várias rotinas de manipulação de datas e horas,
usadas com o tipo TDateTime, veja algumas abaixo.

Rotina Descrição
Date Retorna a data do sistema
Now Retorna a data e hora do sistema
Time Retorna a hora do sistema
Retorna o dia da semana de uma data
DayOfWeek
especificada
Decodifica um valor TDateTime em Words
DecodeDate
de dia, mês e ano
Decodifica um valor TDateTime em Words
DecodeTime
de hora, minuto, segundo e milissegundos
Retorna um TDateTime a partir de Words
EncodeDate
de dia, mês e ano
Retorna um TDateTime a partir de Words
EncodeTime
de hora, minuto, segundo e milissegundos

No help de cada uma das funções acima você vai


encontrar alguns exemplos, veja os colocados abaixo.
if DayOfWeek(Date) = 1 then
ShowMessage(‘Hoje é Domingo, pé de
cachimbo!’)
else
ShowMessage(‘Hoje não é Domingo, pé de
cachimbo!’);
var
A, M, D: Word;
begin
DecodeDate(Date, A, M, D);
ShowMessage(Format(‘Dia %.2d do mês %.2d
de %d.’, [D, M, A]));
end;
Variant
Tipo genérico, que pode atribuir e receber valores de
qualquer outro tipo. Evite usar variáveis do tipo Variant,
pois o uso dessas variáveis podem prejudicar a
performance do programa, além de diminuir a
legibilidade do código fonte e a integridade do
executável, veja o trecho de código abaixo e note como
esse tipo de variável tem um comportamento estranho.
var
V1, V2, V3: Variant;
begin
V1 := True;
V2 := 1234.5678;
V3 := Date;
ShowMessage(V1 + V2 + V3);
end;
12.0 Conversões de Tipo
Freqüentemente você vai precisar converter um tipo de
dado em outro, como um número em uma string. Para
essas conversões você pode usar duas técnicas, o
TypeCasting e as rotinas de conversão de tipos.
TypeCasting
TypeCast é uma conversão direta de tipo, usando o
identificador do tipo destino como se fosse uma função.
Como o Delphi não faz nenhuma verificação se a
conversão é válida, você deve tomar um certo cuidado
ao usar um TypeCast para não criar programas
instáveis.
var
I: Integer;
C: Char;
B: Boolean;
begin
I := Integer(‘A’);
C := Char(48);
B := Boolean(0);
Application.MessageBox(PChar(‘Linguagem de
Programação’ + #13 + ‘Delphi 3’), ‘SENAC’,
MB_ICONEXCLAMATION);
end;
Rotinas de Conversão
As principais rotinas de conversão estão listadas na
tabela abaixo. Caso você tente usar uma dessas rotinas
em uma conversão inválida, pode ser gerada uma
exceção.

Rotina Descrição
Chr Byte em Char
StrToInt String em Integer
IntToStr Integer em String
String em Integer, com um valor default
StrToIntDef
caso haja erro
IntToHex Número em String Hexadecimal
Arredonda um número real em um
Round
Integer
Trunc Trunca um número real em um Integer
StrToFloat String em Real
FloatToStr Real em string
Número real em string usando uma
FormatFloat
string de formato
TDateTime em string de data, de
DateToStr acordo com as opções do Painel de
Controle
StrToDate String de data em TDateTime
TimeToStr TDateTime em Strind de Hora
StrToTime String de hora em TDateTime
DateTimeToStr TDateTime em string de data e hora
StrToDateTime String de data e hora em TDateTime
FormatDateTime TDateTime em string usando uma
string de formato
Qualquer tipo em outro usando
VarCast
argumentos do tipo Variant
VarAsType Variante em qualquer tipo
Val String em número, real ou inteiro
Str Número, real ou inteiro, em String

Veja alguns exemplos de como usar essas rotinas.


Conversão de dados é uma operação muito comum na
programação em Object Pascal, seeria interessante dar
uma olhada no help de cada uma das funções acima.
var
I: Integer;
D: Double;
S1, S2: string;
begin
D := 10.5;
I := Trunc(D);
S1 := FloatToStr(D);
S2 := IntToStr(I);
ShowMessage(S1 + #13 + S2);
end;

var
A, B, Soma: Bouble;
begin
A := StrToFloat(EdtA.Text);
B := StrToFloat(EdtB.Text);
Soma := A + B;
ShowMessage(Format(‘%f + %f = %f’, [A, B,
Soma]);
end;
13.0 Expressões
Uma expressão é qualquer combinação de operadores,
variáveis, constantes, valores literais e chamadas de
funções que resultem em um valor de determinado tipo.
Uma expressão é usada sempre que precisamos de
uma valor que possa ser obtido por uma expressão.
A + 12 * C
Date - 4
StrToInt(Edit1.Text + Edit2.Text)
StrToDate(Edit2.Text) -
StrToDate(Edit1.Text)
12 * A / 100
A < B
14.0 Operadores
Os operadores são usados em expressões e a ordem
em que as expressões são executadas depende da
precedência desses operadores. Veja abaixo a lista de
operadores em ordem descendente de precedência.

Operador Descrição
Operadores Unários
@ Endereço
not Não booleano ou bit voltado para não
Operadores Multiplicativos e de direção de Bit
* Multiplicação ou interseção de conjuntos
/ Divisão de Real
div Divisão de Inteiro
mod Resto de divisão de Inteiros
as TypeCast seguro quanto ao tipo (RTTI)
E booleano ou bit voltado para e
and
shl Deslocamento de bits à esquerda
shr Deslocamento de bits à direita
Operadores Aditivos
+ Adição ou união de conjuntos
- Subtração ou diferença de conjuntos
or Ou booleano ou bit voltado para ou
xor Ou exclusivo booleano ou bit voltado para ou
exclusivo
Operadores Relacionais
= Igual
<> Diferente
< Menor
> Maoir
<= Menor ou igual
>= Maior ou igual
in Pertinência a conjuntos
is Compatibilidade de tipos (RTTI)

Para forçar uma expressão de menor precedência a ser


executada antes, você pode usar os parênteses, como
mostrado abaixo.
(5 - 2) * 3;
(A > B) and (A < C)
Para fazer potenciação, use a função Power, abaixo
temos que A é igual a A elevado a 4.
A := Power(A, 4);
15.0 Estruturas de Decisão
If
O if é uma estrutura de decisão usada para realizar
instruções em determinadas condições. O if é
considerado uma só instrução, por isso, só encontramos
o ponto-e-vírgula no final. O else é opcional.
if Opn.Execute then
Img.Picture.LoadFromFile(Opn.FileName);
if Nota < 5 then
ShowMessage(‘Reprovado’)
else
ShowMessage(‘Aprovado’);
Case
Permite que o fluxo da execução seja desviado em
função de várias condições de acordo com o valor do
argumento, que tem que ser ordinal, caso o valor do
argumento não corresponda a nenhum dos valores
listados, podemos incluir um else.
case Ch of
‘ ‘: ShowMessage(‘Espaço’);
‘0’..‘9’: ShowMessage(‘Dígito’);
‘+’, ‘-‘, ‘*’, ‘/’:
ShowMessage(‘Operador’);
else
ShowMessage(‘Caractere especial’);
end;
case CbbBorda.ItemIndex of
0: BorderStyle := bsDialog;
1: BorderStyle := bsSingle;
2: BorderStyle := bsSizeable;
end;
16.0 Estruturas de Repetição
While
O laço while executa uma instrução até que uma
condição seja falsa.
I := 10;
while I >= 0 do
begin
ShowMessage(IntToStr(I));
Dec(I);
end;
For
O laço for executa uma instrução um número
determinado de vezes, incrementando uma variável de
controle automaticamente a cada iteração. Caso seja
preciso que a contagem seja decremental, pode-se usar
downto em vez de to.
for I := 1 to ComponentCount do
ShowMessage(‘O ‘ + IntToStr(I) + ‘º
Componente é ‘ + Components[I - 1].Name);
for I := Length(Edit1.Text) downto 1 do
ShowMessage(Edit1.Text[I]);
Repeat
O laço repeat executa instruções até que uma condição
seja verdadeira.
I := 1;
repeat
S := InputBox(‘Acesso’, ‘Digite a senha’,
”);
Inc(I);
if I > 3 then
Halt;
until S = ‘flamengo’;
Quebras de Laço
Em qualquer um dos laços mostrados podemos usar o
procedimento Break para cancelar a repetição e sair do
laço, podemos também forçar a próxima iteração com o
procedimento Continue.
I := 1;
while true do
begin
Inc(I);
if I < 10000000 then
Continue;
ShowMessage(‘Chegamos a dez milhões’);
Break;
end;
17.0 Tipos Definidos Pelo Usuário
O usuário também pode declarar tipos não definidos
pelo Delphi. Essas declarações são feitas na seção
type, da interface ou implementation, sendo que na
implementation esses tipos não poderão ser usados em
outras Units.
Dificilmente você terá que definir tipos, a não ser
classes, pois os tipos padrão do Delphi são o bastante
para a maioria das aplicações.
Strings Limitadas
Caso se deseje limitar o número de caracteres que uma
string pode receber, podemos criar um tipo de string
limitada.
TNome = string[40];
TEstado = string[2];
Tipo Sub-Faixa
É um subconjunto de um tipo ordinal e possui as
mesmas propriedades do tipo original.
TMaiusculas = ‘A’..‘Z’;
TMes = 1..12;
Enumerações
Define uma seqüência de identificadores como valores
válidos para o tipo. A cada elemento da lista de
identificadores é associado internamente um número
inteiro, iniciando pelo número 0, por isso são chamados
de tipos enumerados.
TBorderIcon = (biSystemMenu, biMinimize,
biMaximize, biHelp);
TDiaSemana = (Seg, Ter, Qua, Qui, Sex,
Sab, Dom);
Ponteiros
Ponteiros armazenam endereços de memória, todas as
classes em Object Pascal são implementadas como
ponteiros, mas raramente o programador vai precisar
usá-los como tal.
TIntPtr: ^Integer;
Records
O tipo record é uma forma de criar uma única estrutura
com valores de diferentes tipos de dados. Cada um dos
dados de um record é chamado de campo.
TData = record
Ano: Integer;
Mes: TMes;
Dia: Byte;
end;
var
Festa: TData;
begin
Festa.Ano := 1997;
Festa.Mes := Mai;
Festa.Dia := 8;
end;
Arrays
Arrays fornecem uma forma de criar variáveis que
contenham múltiplos valores, como em uma lista ou
tabela, cujos elementos são do mesmo tipo. Veja abaixo
alguns exemplos de arrays de dimensões variadas.
TTempDia = array [1..24] of Integer;
TTempMes = array [1..31, 1..24] of
Integer;
TTempAno = array [1..12, 1..31, 1..24] of
Integer;
var
TD: TTempDia;
I: Integer;
begin
for I := 1 to 24 do
TD[I] :=
StrToIntDef(InputBox(‘Temperaturas’,
‘Digite a temperatura na hora ‘ +
IntToStr(I), ”), 30);
end;
Um array pode ser definido como constante tipada, onde
todos os seus elementos devem ser inicializados.
FAT: array[1..7] of Integer = (1, 2, 6,
24, 120, 720, 5040);
O tipo dos elementos de um array pode ser qualquer
um, você pode ter uma array de objetos, de conjuntos,
de qualquer tipo que quiser, até mesmo um array de
arrays.
TTempMes = array [1..31] of TTempDia;
TBtnList = array [1..10] of TButton;
Sets
São conjuntos de dados de um mesmo tipo, sem ordem,
como os conjuntos matemáticos. Conjuntos podem
conter apenas valores ordinais, o menor que um
elemento pode assumir é zero e o maior, 255.
TBorderIcons = set of TBorderIcon;
BorderIcons := [biSystemMenu, biMinimize];
if MesAtual in [Jul, Jan, Fev] then
ShowMessage(‘Férias’);
Os conjuntos podem ser definidos como constantes ou
constantes tipadas, como abaixo.
DIG_HEXA = [‘0’..‘9’, ‘A’..‘Z’, ‘a’..‘z’];
DIG_HEXA: set of Char = [‘0’..‘9’,
‘A’..‘Z’, ‘a’..‘z’];
18.0 Procedimentos, Funções e Métodos
As ações de um objeto devem ser definidas como
métodos. Quando a ação não pertence a um objeto,
como uma transformação de tipo, essa ação deve ser
implementada em forma de procedimentos e/ou
funções.
Procedimentos
Procedimentos são sub-rotinas, que realizam uma tarefa
e não retornam um valor. A declaração de um
procedimento é feita na seção interface e a definição, na
seção implementation. Ao chamar o identificador do
procedimento, com os parâmetros necessários, esse
procedimento será executado. Veja abaixo o exemplo de
uma unit com a implementação um procedimento.
unit Tools;
interface
procedure ErrorMsg(const Msg: string);
implementation
uses Forms, Windows;
procedure ErrorMsg(const Msg: string);
begin
Application.MessageBox(PChar(Msg),
‘Operação inválida’, MB_ICONERROR);
end;
end.
Funções
Funções são muito semelhantes a procedimentos a
única diferença é que as funções retornam um valor. O
tipo do valor de retorno deve ser informado no
cabeçalho da função. Na implementação da função
deve-se atribuir o valor de retorno à palavra reservada
Result ou ao identificador da função. Pode-se então usar
a função em expressões, atribuições, como parâmetros
para outras funções, em qualquer lugar onde o seu valor
possa ser usado.
function Average(A, B: Double): Double;
begin
Result := (A + B) / 2;
end;
Métodos
Métodos são funções ou procedimentos que pertencem
a alguma classe, passando a fazer parte de qualquer
objeto dessa classe. Na implementação de um método
precisamos indicar qual a classe à qual ele pertence.
Para chamar um método em algum lugar não
pertencente à sua classe, como procedimentos, funções
ou métodos de outras classes, deve ser indicado o
objeto que deve executar o método. Os métodos usam
os mesmos níveis de encapsulamento dos atributos.
type
TFrmMsg = class(TForm)
LblMsg: TLabel;
BtnOk: TButton;
BtnCancelar: TButton;
ImgMsg: TImage;
public
procedure ShowMsg(const Msg: string);
end;
procedure TFormMsg.ShowMsg(const Msg:
string);
begin
LblMsg.Caption := Msg;
ShowModal;
end;
Parâmetros
Existem três tipos de passagem de parâmetros, que
devem ser indicados na declaração da função ou
procedimento. Parâmetros de tipos diferentes de vem
ser separados por ponto e vírgula.
function MultiStr(const S: string; N:
Double; var Erro: Integer): string;

Quando não é indicado o tipo de passagem, é


passado o valor do parâmetro, como constante.
Ao usar a palavra-chave var, não será enviado o
valor do parâmetro e sim uma referência a ele,
tornando possível mudar o valor do parâmetro no
código do procedimento.
Como alternativa você pode passar um parâmetro
por referência constante, para isso use a palavra
const antes da declaração do parâmetro.

19.0 With
Usado para facilitar o acesso às propriedades e
métodos de um objeto.
with Edt do
begin
CharCase := ecUpperCase;
MaxLenght := 10;
PasswordChar := ‘*’;
Text := ‘Brasil’;
end;
20.0 Self
Self é usado quando se quer referenciar a instância
atual da classe. Se você precisar referenciar a instância
atual de uma classe, é preferível usar Self em vez de
usar o identificador de um Objeto, isso faz com que o
código continue funcionando para as demais instâncias
da classe e em seus descendentes.
21.0 Criando e Destruindo Objetos
Antes de tudo, você deve declarar o objeto, se quiser
referenciá-lo. Para criá-lo, use o método Create, que é
um método de classe. Para você usar um método de
classe, referencie a classe, não o Objeto, como
mostrado abaixo.
var
Btn: TBitBtn;
begin
Btn := TBitBtn.Create(Self);
With Btn do
begin
Parent := Self;
Kind := bkClose;
Caption := ‘&Sair’;
Left := Self.ClientWidth - Width - 8;
Top := Self.ClientHeight - Height - 8;
end;
end;
Porém, se você não precisar referenciar o Objeto,
poderia criar uma instância sem referência.
with TBitBtn.Create(Self) do
begin
Parent := Self;
Kind := bkClose;
Caption := ‘&Sair’;
Left := Self.ClientWidth - Width - 8;
Top := Self.ClientHeight - Height - 8;
end;
Para destruir um objeto, use o método Free. Para
Forms, é recomendado usar o Release, para que todos
os eventos sejam chamados.
O parâmetro do método Create é usado apenas em
Componentes, para identificar o componente dono. Ao
criar Forms, poderíamos usar o Objeto Application.
FrmSobre := TFrmSobre.Create(Application);
FrmSobre.ShowModal;
FrmSobre.Release;
Para criar objetos não componentes, você não precisa
de nenhum parâmetro no método Create.
var
Lst: TStringList;
begin
Lst := TStringList.Create;
Lst.Add(‘Alô, Teresinha!’);
Lst.Add(‘Uhh uhh…’);
Lst.SaveToFile(‘Teresinha.txt’);
Lst.Free;
end;
22.0 RTTI
Run Time Type Information é a informação de tipo dos
objetos em tempo de execução. O operador is é usado
para fazer comparações e o operador as é usado para
fazer um TypeCast seguro com objetos.
for I := 0 to ComponentCount - 1 do
if Components[I] is TEdit then
TEdit(Components[I]).Clear;
(Sender as TEdit).Color := clYellow;
603 - Criando uma base de dados
MS Access pelo Delphi
Resumo:
Aprenda como criar uma base de dados MS Access sem
o MS Access. Cria a base, as tabelas, índices, enfim,
tudo utilizando puro código delphi.
INTRODUÇÃO
Quando se cria um sistema para ambientes desktop
sempre surge a dúvida de qual base de dados usar.
Geralmente são usados bancos DBase, Paradox ou MS
Access. Destes, a base mais robusta e confiável é, sem
dúvida, MS Access. Mas existe um grande problema
para se criar a base de dados MS Access, pois faz-se
necessário o uso do ambiente MS Access.
Algumas pessoas não têm este aplicativo instalado em
sua máquina e então torna-se inviável o uso desta base
de dados, impedindo, desta forma, um crescimento
tecnológico do programador que fica preso a
ferramentas obsoletas.
Neste tutorial você irá aprender como criar uma base de
dados MS Access a partir do nada, usando puro código
Delphi e a Tecnologia ADO Extensions que é distribuída
pela Microsoft.
ADOX, faz parte dos componentes ADO, quer dizer, é
uma extensão do ADO. O ADOX fornece ferramentas de
acesso a estrutura, segurança, definições de tabelas e
muitos outros.
Como dito anteriormente, ADOX é uma library
distribuída pela Microsoft, o arquivo chama-se
“Msadox.dll”, sua definição é “Microsoft ADO Ext. 2.x for
DDL and Security” e é este arquivo que iremos importar
para nossa IDE no Delphi.
INSTALANDO
Para usar este objetos no Delphi basta seguir os
seguintes passos:
1- Selecione PROJECT > IMPORT TYPE LIBRARY
2- Procure pela descrição: “Microsoft ADO Ext. 2.x for
DDL and Security (Version 2.x)”
2- Em CLASS NAMES, altere o nome dos objetos
acrescentando ADOX após a letra T, exemplo: TTable
mude para TADOXTable, TColumm mude para
TADOXColumn. Repita este procedimento para todos
objetos nesta lista.
3- Em PALETTE PAGE selecione ou digite um novo
nome para a paleta onde os componentes ficarão,
exemplo: ADOX.
4- Pressione INSTALL, logo depois pressione Ok
confirmando o início da instalação.
5- Pressione YES confirmando que você quer instalar os
componentes.
6- Pressione Ok na tela que indica os objetos instalados.
7- Selecione FILE > CLOSE ALL e pressione YES para
salvar este package criado.
O motivo da troca do nome dos objetos é muito óbvio,
estes nomes de classe como Ttable já existem, então
iria gerar conflitos na compilação, por isso bastou trocar
o nome da classe.
Pronto, os objetos estão instalados, agora sempre que
você utilizar estes objetos será inserido na clausula
USES a Unit ADOX_TLB pois este é o nome da unit
criada a partir da importação da DLL.
Agora, mãos à obra.
DEFININDO A BASE DE DADOS E
OBJETOS A SEREM USADOS
Vamos criar uma base onde serão armazenados
informaçõe sobre animais de estimação (para sair um
pouco da rotina de CLIENTES/PRODUTOS/PEDIDOS).
Para esta base serão criadas as seguintes tabelas:
> PROPRIETARIO
> PRO_ID
> PRO_NOME
>ANIMAL
> ANI_ID
> ANI_PROPRIETARIO
> ANI_NOME
> ANI_NASCIMENTO
Onde um proprietario pode ter mais de um animal
formando assim um relacionamento UM PARA MUITOS.
No Delphi, crie uma nova aplicação. Será criado um
novo Form, a este insira os seguintes componentes:
> 3 TButtons
Para lançar os procedimentos de criação da base de
dados e das tabelas.
Altere as seguintes propriedades para cada TButtons
respectivamente:
Caption: Criar base
Name: btnBase
Caption: Criar tabelas
Name: btnTabelas
Caption: Navegar
Name: btnNavegar
> 1 TEdit
Para armazenar o path da base de dados a ser criada.
Altere as seguintes propriedades:
Name: edtPath
Text: (deixe em branco)
> 1 TSaveDialog
Para navegar no disco e informar o path da base de
dados.
Altere as seguintes propriedades:
Filter: Base MS Access|*.mdb
Title: Salvar como…
DefaultExt: .mdb
> 1 TADOConnection
Para fazer a conexão com a base criada.
Altere as seguintes propriedades:
Login prompt: False
> 1 TADOCommand
Para fazer a ligação e criação das tabelas.
Altere as seguintes propriedades:
Connection: Selecione o ADOConnection1
> 1 TADOXCatalog
Para criar a base de dados.
CRIANDO A BASE DE DADOS
Agora vamos ao código. Clique duas vezes no objeto
btnNavegar e digite:
procedure TForm1.btnNavegarClick(Sender:
TObject);
begin
if SaveDialog1.Execute then
edtPath.Text := SaveDialog1.FileName;
end;
Com isso informamos o nome que a base terá.
Clique duas vezes no objeto btnBase e digite o seguinte
procedimento:
procedure TForm1.btnBaseClick(Sender:
TObject);
var
Base: String;
begin
if edtPath.Text = ” then
begin
ShowMessage(‘Nome da base de dados não
informada.’);
exit;
end;
Base :=
‘Provider=Microsoft.Jet.OLEDB.4.0’+
‘;Data Source=’ + edtPath.Text +
‘;Jet OLEDB:Engine Type=4’;
ADOXCatalog1.Create1(Base);
end;
Primeiro verificamos se há algum texto no objeto TEdit,
em seguida atribuímos a string de conexão à variável
BASE informando vários parâmetros, mas atente para a
seguinte linha: “…Engine Type=4…”, isto quer dizer que
iremos criar uma base Access 97, para Access 2000
informe 5.
Em seguida é efetivamente criado a base de dados
através do método Create1 do objeto ADOXCatalog,
passando para este a string da BASE. Observe que o
método é Create1 e não simplesmente Create, pois o
método Create já existe e é da classe.
Pronto, criamos uma base de dados vazia, não existe
nada nela, mas já é um arquivo comum ao MS Access e
pode ser aberto normalmente.
CRIANDO TABELAS

Vamos começar a criar as tabelas, seus índices e


integridade referencial. Para isso clique duas vezes no
objeto btnTabelas e digite:
procedure TForm1.btnTabelasClick(Sender:
TObject);
var
base, comando: string;
begin
{ definindo a base de dados }
base :=
‘Provider=Microsoft.Jet.OLEDB.4.0’ +
‘;Data Source=’ + edtPath.Text +
‘;Persist Security Info=False’;
ADOConnection1.ConnectionString := base;
{ Criando as tabelas… }
{>>> PROPRIETARIO <<<}
comando := ‘CREATE TABLE PROPRIETARIO (‘
+
‘PRO_ID INT,’ +
‘PRO_NOME TEXT(50))’;
ADOCommand1.CommandText := comando;
ADOCommand1.Execute;
{ ADICIONANDO INDICES }
comando := ‘CREATE INDEX IDX_PRO_ID ‘ +
‘ON PROPRIETARIO (PRO_ID) WITH PRIMARY’;
ADOCommand1.CommandText := comando;
ADOCommand1.Execute;
{>>> ANIMAL <<<}
comando := ‘CREATE TABLE ANIMAL (‘ +
‘ANI_ID INT,’ +
‘ANI_PROPRIETARIO INT ‘ +
‘CONSTRAINT IDX_PRO_ID ‘ +
‘REFERENCES PROPRIETARIO (PRO_ID),’ +
‘ANI_NOME TEXT (50),’ +
‘ANI_NASCIMENTO DATETIME)’;
ADOCommand1.CommandText := comando;
ADOCommand1.Execute;
end;
CONCLUÍNDO
Pronto, tudo muito fácil e simples. Agora rode o
programa e faça os testes. Clique em navegar, selecione
um diretório e digite o nome que sua base terá, então
clique em CRIAR BASE e veja que o programa criará a
base, logo após isto clique em CRIAR TABELAS então
as tabelas serão criadas.
Agora ficou fácil criar sistemas desktops usando uma
base mais robusta sem a necessidade de se ter o MS
Access instalado em sua máquina. É possível criar e
acessar todos os recursos de tabelas da base de dados
MS Access usando os objetos ADOX, aqui foi mostrado
como criar utilizando linguagem DDL, ou seja,
escrevemos diretamente para que o comando fosse
executado, mas é possível ter acesso à estes recursos
diretamente com os componentes distribuídos por esta
library, mas este assunto ficará para outra ocasião.
Se você tiver o MS Access instalado em sua máquina
pode abri-lo e verificar nossa base de dados, caso
contrário (como é o meu caso) crie uma simples
aplicação com dois DBGrids para exibir os campos das
tabelas, assim como inserir dados.
[]’s
Henrique Meira - www.pedgih.hpg.com.br
680 - Cuidados ao usar o OnExit
(Parte I):
É comum fazermos uso do evento OnExit quando
queremos validar o conteúdo de um Edit. E essa pode
ser uma boa prática quando necessitamos verificar o
que foi digitado apenas quando o usuário terminar de
fazer a entrada de dados, como, por exemplo, um Edit
que vai receber o CPF ou CNPJ.
Ao colocarmos um código qualquer no evento OnExit ele
sempre será executado quando o usuário sair do Edit, o
que acontece quando ele pressiona a tecla TAB, clica
com o mouse em um outro Edit ou pressiona um botão
OK, por exemplo.
No entanto, existem algumas situações especiais em
que o evento OnExit não é gerado. Quer um exemplo?
Você está no Edit e, ao invés de clicar no botão OK,
você pressiona as teclas ALT + O (considerando que o
botão OK tem a tecla O como atalho). É como se você
tivesse pressionado o botão OK, porém, sem perder o
foco que está no Edit. Só mais um exemplo: Os botões
do tipo SpeedButton não recebem foco, então, mesmo
que clique com o mouse sobre um SpeedButton, o foco
continuará no Edit e, conseqüentemente, o evento
OnExit não será gerado.
E a solução?
A solução para esse pequeno inconveniente é simples.
Basta você colocar o seguinte código no evento OnClick
do botão.
procedure TForm1.Button1Click(Sender:
TObject);
begin
ActiveControl := nil;

end;
Com isso você força a saída de qualquer Edit ou outro
componente que esteja com o foco, gerando assim o
evento OnExit.
681 - Cuidados ao usar o OnExit
(Parte II):
Dando continuidade aos problemas enfrentados quando
se usa o evento OnExit, vamos ver outro caso onde
pode acontecer um pequeno problema:
Suponhamos que você possua 2 Edits em um
formulário. Supondo também que você queira dar
alguma informação ao usuário da aplicação logo depois
que ele sair do Edit1 você faz:
procedure TForm1.Edit1Exit(Sender:
TObject);
begin
MessageDlg(‘Mensagem…’, mtInformation,
[mbOk], 0);
end;
A princípio está tudo ok, ou melhor, parece estar tudo
ok.
Se você altera o foco para o outro Edit através do
pressionamento da tecla TAB, tudo bem. Mas
experimente alterar o foco clicando com o mouse sobre
o Edit2. Neste segundo caso a mensagem será exibida
normalmente. Mas ao fechar o dialogo onde aparece a
mensagem, o foco simplesmente se perde. Para setar o
foco no Edit2 é necessário clicar novamente sobre ele.
Isso poderia não problema nenhum até que seu usuário
experimente esta situação. Nada que ele digitar será
acatado.
Mas existe uma maneira fácil de resolver o problema.
Basta você cancelar o foco e forçar uma reentrada no
componente Edit2. Como fazer isso? Veja o código:
procedure TForm1.Edit1Exit(Sender:
TObject);
begin
MessageDlg(‘Mensagem…’, mtInformation,
[mbOk], 0);
// cancela o foco e força novamente a
entrada
ActiveControl := nil;
PostMessage(Edit2.Handle, WM_SETFOCUS,
0, 0);
Edit2.SetFocus;
end;
Porém, você nunca terá certeza se o usuário clicou foi
no Edit2. Então temos que criar uma rotina genérica que
leva o foco para qualquer outro controle:
procedure TForm1.Edit1Exit(Sender:
TObject);
var
Ctrl: TWinControl;
begin
MessageDlg(‘Mensagem…’, mtInformation,
[mbOk], 0);
// cancela o foco e força novamente a
entrada
Ctrl := ActiveControl;
ActiveControl := nil;
PostMessage(TWinControl(Ctrl).Handle,
WM_SETFOCUS, 0, 0);
TWinControl(Ctrl).SetFocus;
end;
Observe que antes de cancelar o foco com
ActiveControl := nil, salvamos qual é o controle que
detém o foco fazendo Ctrl := ActiveControl.
Depois enviamos uma mensagem ao controle que
detinha o foco, forçando-o a receber o foco novamente.
573 - Desvendando a programação
“Client/Server”
O que é “Client/server”
A filosofia cliente/servidor nasceu do conceito de
processamento distribuído, originalmente idealizados
pelos desenvolvedores de sistemas operacionais de
rede. É aquele tipo de invenção que começa direcionada
para aplicações complexas, e um dia acaba vindo parar
em nossas mãos, como a suspensão ativa e o telefone
celular.
Mas a idéia é muito simples. Você tem que envelopar
1.000 cartas, depois colá-las e pedir a um ajudante que
as leve até o correio. Ora, que tal pedir para o ajudante
ir colando algumas enquanto você ainda está
envelopando outras? Isto é processamento distribuído,
ou serviço distribuído. E é sobre este tão simples
conceito que repousa a filosofia da programação
cliente/servidor.
Desta forma, a máquina cliente (a máquina do usuário
final) não fica encarregada de todo o processamento.
Ela funciona como front-end, sendo utilizada
basicamente para entrada e visualização de dados. O
processamento mais pesado é feito no servidor.
O servidor recebe pedidos, ou requisições, do cliente e
as processa, enviando imediatamente uma resposta.
Para quem leu o primeiro artigo da série “O Delphi e a
Internet” (publicado neste site) verá que os conceitos
apresentados naquele artigos são similares aos agora
mencionados.
Mas como tudo isto acontece na prática? É necessário
haver uma aplicação servidora, instalada em uma
máquina, e uma aplicação cliente, instalada em outras
máquinas. As aplicações cliente fazem pedidos à
aplicação servidora, que as atende. Isto já deixa claro
que o equipamento onde será instalada a aplicação
servidora deve ser provido de maiores quantidades de
recursos, tais como memória, disco e velocidade de
processamento.
No mundo comercial de hoje, o principal objetivo das
organizações é processar dados, e disparar
processamentos a estes relacionados. Assim, a
aplicação servidora é na verdade um servidor de banco
de dados. Nele são concentrados todos os dados da
empresa, e podem ser concentrados ainda os
processamentos ligados a estes dados, sobre o que
falaremos a frente.
O cliente é qualquer sistema que acesse o servidor, e
que em nosso caso será uma aplicação Delphi. Como
servidor (a título de exemplo) usaremos o Microsoft SQL
Server 6.5, por ser muito fácil de usar, bastante robusto
e relativamente barato.
Quais são suas vantagens
Mas talvez esteja agora perguntando: para que serve
toda esta tecnologia, toda esta mudança nos métodos
de programação? Qual será a real vantagem de se usar
estas técnicas, se é que realmente existem alguma?
Existem várias vantagens. Uma delas é a escalabilidade
que a filosofia Client/Server oferece. Imagine que
trabalhe com uma rede de 50 máquinas ligadas a
apenas 1 servidor. Com o passar do tempo, cada vez
mais sistemas são adicionados a esta rede, que vai
ficando cada vez mais lenta. O processamento não é
distribuído, ou seja, é feito sempre na parte cliente, e o
servidor serve apenas para centralizar os dados. O que
seria necessário para melhorar a performance da rede?
Como o processamento é feito basicamente no lado
cliente, precisaríamos acrescentar recursos aos 50
computadores clientes, talvez memória. Se
decidíssemos adicionar 16 MB Ram em cada máquina,
e se cada pente de 16 custasse R$ 35,00, teríamos um
custo total de R$ 1.750,00. E este custo aumentaria
muito se tivéssemos mais clientes na rede.
Agora vamos mudar de cenário. Nesta rede rodam
aplicações que adotaram a filosofia Client/Server. Deste
modo, a maior parte do processamento é feito no
servidor, digamos em nosso Sql Server. Assim, para
melhorar a performance de toda a rede, seria necessário
acrescentar recursos basicamente no equipamento
servidor, que responderia mais rapidamente aos
clientes, desafogando assim toda a rede. Digamos então
que a decisão é adicionar 128 MB Ram ao equipamento
servidor (o que representa uma significativa melhora).
Chegaríamos a um custo de R$ 280,00, assumindo que
compraríamos 8 pentes de 16 MB Ram. Este custo
ainda poderia diminuir um pouco, levando-se em
consideração que 2 pentes de 64 MB custariam um
pouco menos do que 8 pentes de 16 MB.
A escalabilidade que a filosofia Client/Server oferece é
uma de suas grandes vantagens.
Velocidade
Os programas que operam com técnicas Client/Server
trafegam uma quantidade muito menor de dados pela
rede. Isto se dá porque o cliente faz um pedido ao
servidor, e o pedido é todo processado por ele (o
servidor), retornando apenas uma pequena quantidade
de dados para o cliente como resposta. Assim, as
únicas transações em rede são o pedido do cliente e a
resposta do servidor.
Isto deixa a rede muito mais leve, com menos tráfegos
de dados. O resultado final, é um ganho na velocidade
de todas as aplicações na rede. É claro que isto significa
para nós programadores uma mudança na forma de
programar, e até de analisar nossos sistemas. Em breve
falaremos mais diretamente sobre este assunto.
Segurança
A segurança é talvez a mais notável vantagem da
filosofia Client/Server. Os servidores de banco de dados
são muito robustos e preparados para fornecer a maior
segurança possível. Os métodos de armazenamento e
de cache já são em si mesmos uma grande fonte de
segurança, e contam com os algoritmos mais complexos
que se possa imaginar para garantir isso.
Os sistemas de Backup, manuais e automáticos,
disponibilizam à organização um grau ainda maior de
segurança, oferecendo também uma grande flexibilidade
para recuperar dados em pouco tempo.
Quanto a nós, programadores, passamos a contar com
um eficiente sistema de transações, que garantem aos
nossos sistemas que processamentos não serão
interrompidos no meio. Um exemplo disto é uma baixa
de Nota Fiscal. Digamos que ao dar a baixa da Nota, o
sistema lance duplicatas a receber, e lance também a
saída no estoque. Se houver uma interrupção de
energia, ou qualquer outro problema durante o
processamento, pode acontecer que este seja
interrompido no meio, deixando a Nota baixada, as
duplicatas geradas e sem os lançamentos de saída no
estoque. Este tipo de problema pode ser facilmente
evitado usando-se as técnicas de transações oferecidas
pelos sistemas gerenciadores de banco de dados, como
o Sql Server.
Mudanças de conceito
Mas algumas mudanças conceituais devem ser feitas.
Os velhos e bons grids que exibiam todos os registros
de uma tabela, e que permitiam ao usuário “passear” por
estes registros, deixa de existir na programação
Client/Server. O problema é que agora precisamos
trafegar a menor quantidade de dados possível na rede,
o que significa que não podemos abrir tabelas inteiras,
ou usar comandos SQL do tipo “select * from tabelatal”.
As tabelas estão centralizadas no servidor, e se abrimos
uma tabela, todos os seus registros trafegam pela rede
até chegar ao equipamento cliente. Só então são
aplicados filtros ou processamentos a estes dados.
O que queremos é aplicar os filtros e processamentos
na fonte dos dados, ou seja, no servidor. É por isso que
passaremos a programar usando basicamente
componentes TQuery, em nossos comandos SQL
usaremos sempre a cláusula WHERE.
Onde ficam as regras de negócios?
“Regras de negócios” é apenas um nome bonito para
“rotinas de processamento”. Assim, a pergunta é: onde
ficam nossas rotinas de processamento? Sim, agora
aquelas rotinas pesadas, tipo fechamento de mês,
recalculo de saldos e outras mais, podem ficar tanto no
servidor quanto no cliente.
Quando as regras de negócio ficam no cliente, isto
significa que as rotinas de processamento ficam em
nosso programa Delphi, acessando os dados no
servidor. A vantagem deste método é que o sistema
inteiro pode ser migrado para um banco de dados
diferente, sem grandes traumas. A desvantagem é que o
processamento destas rotinas ficam um pouco mais
lentos, e dependem da máquina cliente – se for uma
máquina rápida, o processamento vai ser rápido, se for
uma máquina lenta, o processamento vai ser lento.
Quando as regras de negócio ficam no servidor, isto
significa que as rotinas de processamento ficam no
próprio servidor, acessando os dados ali mesmo. Neste
caso, as rotinas de processamento devem ser escritas
na linguagem que o servidor entenda, e armazenadas
em unidades conhecidas como Store Procedures. A
grande vantagem é a velocidade de processamento, que
é muito maior. E a principal desvantagem é que em caso
de uma eventual migração para outro banco de dados,
seria necessário migrar todas as Store Procedures para
o outro banco de dados, o que pode envolver muito
trabalho, uma vez que as linguagens possuem muitas
diferenças.
Este artigo é o primeiro de uma série, que vai ajudá-lo a
efetivamente programar dentro do conceito
Client/Server. Falaremos sobre os componente
apropriados a este conceito, e a melhor forma de usá-
los.
By Andre Campos
558 - Paradox X InterBase
Introdução
A primeira vista, as tabelas Paradox não apresentam muitas diferenças das
tabelas criadas no InterBase e as seguintes semelhanças são evidentes:

o acesso pode ser feito através de um Alias;

os tipos dos campos possíveis são similares, apesar de possuirem


nomes diferentes;

as tabelas podem ser criadas com o DataBase Desktop;

são utilizados os mesmos componentes TTable e TQuery para


acesso;

Na realidade, o BDE (Borland DataBase Engine) cria uma ilusão de que


tabelas InterBase e Paradox comportam-se da mesma maneira.
Para alguns desenvolvedores, entretanto esta ilusão termina logo. A
primeira decepção vem com a utilização do Database Desktop para
manipulação de tabelas InterBase. Enquanto o Database Desktop é a
ferramenta ideal para criação e reestruturação de tabelas Paradox, é
deficiente com relação ao Interbase, onde a restruturação e a utilização de
características mais avançadas só podem ser alcançadas através da
montagem de scripts que serão executados no Interbase Windows ISQL.
As pesquisas e índices no InterBase diferenciam maiúsculas e minúsculas,
enquanto que no Paradox esta diferenciação é configurável. Ainda no
InterBase a definição de chaves primárias e estrangeiras é realizada
facilmente, porém a alteração destas chaves não é tão trivial. Algumas
operações utilizando o InterBase são mais lentas do que no Paradox.
Torna-se rapidamente claro que o InterBase não é automaticamente melhor
que o Paradox.
A idéia de que o InterBase não é sempre mais adequado do que o Paradox
é verídica.Os dois produtos apresentam diferenças significativas e a
escolha de qual utilizar é plenamente dependente das condições e dos
objetivos do aplicativo final. Na realidade, a única coisa que eles tem em
comum é que ambos armazenam dados em tabelas. Cada um possui
pontos fortes e fracos dependendo da realidade a ser trabalhada. O
importante é decidir qual deles é apropriado para uma situação particular. A
decisão tomada, usar Paradox ou InterBase, afetará de forma significativa
o desenvolvimento do seu projeto.
Paradox: Baseado em Arquivos
O Paradox é um sistema de banco de dados baseado em arquivos. Os
arquivos de dados contêm registros de dados que possuem uma ordem
fixa. Em outras palavras, o registro de número 106 será sempre o mesmo
registro, até que seja movido fisicamente dentro do arquivo, através de
uma operação de ordenação, por exemplo. O que é mais importante, ele
será sempre o sucessor do registro 105 e o antecessor do 107, até que
esta ordem seja explicitamente alterada. Isto permite uma fácil navegação
entre os registros, através do cursor, já que é possível localizar um registro
em uma tabela através da sua posição, sem necessidade de referenciar
seu conteúdo.
Esta ordenação explícita de registros em uma tabela, apresenta algumas
vantagens: a movimentação para o início ou para o final de um arquivo de
dados é simples e os registros podem ser facilmente relidos quando um
cursor é posicionado sobre eles. A concepção de navegação (browsing)
pode ser conveniente para usuários e desenvolvedores. Isto permite que os
registros sejam manipulados um de cada vez e em uma ordem previsível.
Este comportamento de navegação nas tabelas Paradox é uma das
características mais difíceis de serem adaptadas ao sistema InterBase, e
muitos desenvolvedores em InterBase têm grandes problemas em efetuar
esta transição.
InterBase: Baseado em Conjuntos
O InterBase é na realidade um sistema de banco de bados relacional. As
tabelas não são armazenadas em arquivos individuais e o que é mais
interessante: os registros não encontram-se ordenados. Matematicamente
falando, os conjuntos são desordenados. A ordem é “descoberta” somente
quando o conjunto for representado, como por exemplo em uma consulta
ao banco de dados. Você não pode contar duas vezes com o fato de o
mesmo registro ser o registro número 105, a menos que explicitamente
seja imposta uma certa ordenação na consulta. Uma vez que não podemos
identificar positivamente um registro pela sua posição dentro de uma tabela
devemos nos referir a valores internos a este registro. Entretanto, para
identificações positivas de um registro, pelo menos um campo ou a
combinação de alguns campos devem conter um valor único para cada
registro, o que é conhecido por Chave Primária.
É possível que mais de um campo ou combinações de campos possam
fornecer valores únicos. Estes campos - ou combinações - são
denominados Chaves Candidatas. É imprescindível para o gerenciamento
de um sistema de banco de dados a identificação de Chaves Primárias.
Uma tabela que possui uma Chave Primária é chamada de R-table e todos
os Data Sets (tables, query e stored-procedures) devem ser R-tables para
que o modelo relacional possa funcionar corretamente.
A vantagem deste conceito de dados baseado em conjunto é que os
conjuntos e as operações neles realizadas possuem a propriedade de
“encapsulamento”. Isto significa que quando realizamos operações em um
conjunto sempre geraremos um outro conjunto, que poderá, então, ter uma
nova operação com ele realizada, produzindo um novo conjunto, e assim
suscessivamente. Este é um poderoso conceito lógico que, se
corretamente implementado, tornará o desenvolvimento de aplicações
independente das características físicas de armazenamento. Esta é a base
dos modelos relacionais.
Os sistemas “baseados em cursor” (cursor-based) como o Paradox
permitem que você trabalhe somente com um registro de cada vez.
Sistemas “baseados em conjuntos” (set-based) permitem a manipulação de
conjuntos de dados como se fossem uma entidade única. Esta
característica permite a simplificação do desenvolvimento de aplicações,
além de melhor garantir a integridade dos dados.
Projetos Físicos e os Impactos de
Velocidade
O Paradox é um sistema-cliente no qual os dados são completamente
manipulados por clientes individuais. Quando você quiser que os dados
sejam lidos ou manipulados, eles devem ser transportados para a
aplicação. Cada aplicação manipula todo o processamento por si só. Se
múltiplos usuários estiverem acessando a tabela simultaneamente sobre
uma rede, cada aplicação usuária transporta os dados requeridos para a
máquina usuária.
Cada instância de aplicação Paradox não tem retorno de outra. Se uma
instância precisa garantir a estabilidade dos dados por alguma razão, ela
deve proibir outras instâncias de alterarem os dados através de um
esquema de travamento (locking scheme).
Quando, em uma aplicação Paradox, precisamos procurar em uma tabela,
a seguinte rotina será efetuada: (1) os dados brutos e índices necessários
devem ser carregados na memória da máquina cliente; (2) a atividade
física da procura é conduzida; (3) os resultados são gerados; e (4) os
dados tornados desnecessários após a operação são então descartados.
Esta rotina é repetida para cada operação sobre cada cliente. O servidor de
arquivos que contem os arquivos de dados não faz nada além de enviar os
dados brutos requeridos, através da rede, para as máquinas clientes, sem
realizar quaisquer esforços de processamento dos dados. Funciona, assim,
como um disco rígido remoto.
Em suma, o Paradox é veloz em um disco rígido local mas a sua
performance diminui drasticamente em uma rede. A rede fica
sobrecarregada, com um grande volume de processamentos sendo
realizados repetidamente na máquina cliente. Mesmo em uma rede
pequena a performance é rapidamente afetada quando um novo usuário é
conectado.
O InterBase é um sistema “baseado em servidores” (server based). Em vez
de diferentes processos manipulando fisicamente os dados armazenados,
somente um processo central, “rodando” na máquina servidora, possui
acesso direto aos dados. Todas as aplicações clientes desenvolvem
políticas de requerimento ao processo servidor, o qual é processado
diretamente na máquina servidora enquanto o cliente aguarda.
Quando o servidor termina ele transmite apenas os resultados de volta ao
cliente, que retoma então suas atividades. O impacto mais direto deste
esquema é que a rede não necessita ficar congestionada com grandes
volumes de dados redundantes sendo enviados pelos clientes. Alem disso,
as tarefas frequentemente complexas de processamento de dados podem
ser delegadas de máquinas clientes, normalmente menos poderosas, para
as normalmente mais poderosas máquinas servidoras.
Deve-se perceber que tudo sobre o desenvolvimento em InterBase implica
em um ambiente multi-usuário. O InterBase foi desenvolvido desde o
princícpio como um sistema multi-usuário. O Paradox, por outro lado, foi
basicamente desenvolvido para um único usuário, sendo que
características que visavam permitir o atendimento a múltiplos usuários
foram depois sendo adicionadas.
InterBase Não é Para Navegação
Conforme foi mencionado anteriormente o InterBase constitui-se em um
verdadeiro RDBMS (Sistema Relacional de Gerenciamento de Banco de
Dados) mas a performance de algumas operações são realmente mais
lentas do que em tabelas Paradox. Esta questão torna-se evidente quando
temos uma tabela com uma quantidade muito grande de registros. Se você
utilizar o método Last com o objetivo de mover o ponteiro para o último
registro da tabela certamente perceberá uma grande diferença na
performance dos dois sistemas. Portanto, para estas operações, a
utilização de tabelas Paradox torna a aplicação mais veloz do que em
tabelas InterBase.Em tabelas Paradox o índice aponta para um endereço
físico onde se encontra o registro.
O cursor na tabela Paradox moverá quase que instantaneamente para a
posição determinada porque ele conhece a localização física (endereço)
deste registro na tabela. Esta operação na tabela InterBase poderá
apresentar alguns problemas. Primeiro porque os dados encontram-se
desordenados e existe uma questão sobre o que constitui o “Último”. A
operação deve impor uma ordem antes de decidir qual registro é o último.
Por default o último registro será considerado aquele registro cuja Chave
Primária possui o maior valor.
Portanto, é necessário determinar o valor da maior Chave Primária. Uma
vez que este valor foi determinado o registro que possui este valor pode ser
recuperado. Se for necessário recuperar os últimos registros (como no
caso da apresentação dos dados em um grid) o processo deve ser repetido
algumas vezes, tornando-se um pouco complicado. Para recuperar o
penúltimo registro, o InterBase deve agora encontrar o maior valor da
chave primária que seja inferior ao valor máximo desta. Para o
antepenúltimo registro, ele deve procurar o valor mais próximo ao mais
próximo do valor máximo da chave primária, e assim consecutivamente,
até o número necessário de registros ser recuperado. Uma operação que é
uma “moleza” para o Paradox torna-se uma tremenda “dor-de-cabeça” para
o InterBase. Em geral, a navegação de trás para frente através de tabelas
SQL é ineficiente. O BDE armazena grupos de registros para minimizar
este problema, mas se você avançar muito para trás em tabelas
relativamente extensas, acabará tendo que aguardar por pausas
significativas.
Travamento (locking)
Quando dois usários tentam acessar a mesma faixa de dados podem surgir
problemas ameaçando a integridade do banco de dados. O Paradox e o
InterBase lidam com estes problemas de maneiras diferentes.
Como o Paradox não possui nenhum conhecimento do que outro processo
Paradox está fazendo, ele utiliza um esquema pessimista de travamento
(Pessimistic Locking Scheme). Assim que um usuário tenta mudar um
registro o registro é travado. Nenhum outro usuário pode fazer alterações
neste registro até que o primeiro usuário termine as alterações ou cancele
a operaçao. Por um lado, este esquema de travamento é positivo se
considerarmos que o usuário que obteve o travamento poderá concluir com
sucesso a sua operação de alteração. Por outro lado, isto é negativo no
sentido em que um usuário poderá mononopolizar um registro
indefinidamente. Isto seria um problema, por exemplo, num sistema de
reserva de viagens. Um viajante indeciso poderia “trancar” um assento por
um longo período, levando os outros a acreditarem que assento já foi
tomado, sendo que no final o indeciso pode acabar desistindo do assento.
O InterBase, por outro lado, lida com a manipulação de todos os dados
através de um esquema de concorrência otimista (Optimistic Concurrency
Scheme). Na verdade, quando um usuário processa uma alteração o
registro não impedirá que outras pessoas tentem também alterar este
registro. Quando um usuário começa a alterar um registro InterBase uma
cópia do registro original é salva. O usuário executa seu serviço, mas os
outros usuários não estão sob nenhuma forma impedidos de acessar o
mesmo registro.
Quando algum usuário termina sua alteração e efetua um post (atualização
no banco) a cópia do registro original é comparada com o registro corrente.
Se os valores são diferentes (provavelmente porque outro usuário alterou
mais rapidamente o mesmo registro) as alterações efetuadas pelo usuário
no registro são rejeitadas.
Isto significa que usuários individuais não podem travar o acesso de outros
usuários ao mesmo registro. No exemplo anterior de reservas de viagens, o
primeiro passageiro a confirmar a reserva ficaria com o lugar, mesmo se
vários outros usuários estivessem simultaneamente considerando o mesmo
lugar. O lado ruim da estória, porém, é que as alterações são rejeitadas
apenas no momento em que se tenta efetuar a atualização no banco, após
todo o trabalho de alteração ter sido efetivado. Isto pode ser corrigido
relendo-se (pelo método refresh) os campos alterados e tentando-se
novamente efetuar a atualização. Os camponentes TTable ou TQuery
tornam esta operação transparente através da propriedade UpdateMode. A
verificação, quando enviamos comando de atualização no banco, pode ser
feita dependendo do valor desta propriedade, em todos as campos,
somente nos campos alterados ou somente nas chaves primárias.
Estas duas visões refletem as diferenças básicas nas duas filosofias. O
modelo pessimista Paradox assume que as colisões serão frequentes e
deverão ser tratadas de uma forma rigorosa, enquanto o modelo otimista
InterBase assume que as colisões serão ocasionais e maximiza a
habilitação dos usuários para o compartilhamento de dados sem
interferência de um com o outro, enquanto estiver sendo mantida a
integridade.
Um importante benefício do modelo do InterBase é que um usuário que
quer visualizar um conjunto de dados estáveis, talvez para gerar uma série
de relatórios que precisam refletir a situação atual dos dados, não sofrerá
interferencia de outro usuário que estiver naquele momento alterando os
dados. Em tabelas Paradox, o gerador de relatórios deverá colocar um
“write lock” na tabela para garantir que os dados não sejam alterados e
ninguém poderá efetuar transações na tabela até que este lock tenha
deixado de existir.
No InterBase as versões dos registros mais antigos, são retidas durante o
tempo em que o usuário estiver algum interesse sobre elas. Isto significa
que nem os leitores dos dados impedem a ação dos “editores” e nem os
últimos comprometem o resultado dos primeiros. InterBase é o único banco
SQL que torna isto transparente. Quando os adeptos do InterBase são
questionados sobre as vantagens do banco, este controle da
disponibilidade do registro é normalmente a primeira vantagem a ser
mencionada.
Processamento de Transações
Como você já sabe, o modelo “baseado em conjuntos” constitui-se em um
conjunto de dados que podem ser tratados como entidades individuais,
levando em consideração o conteúdo específico destes conjuntos. O
processamento de transações é uma extensão destas idéias. Uma
transação é um grupo de operações onde ou todas elas são bem ou mal
sucedidas. Nunca deverá ocorrer a situação onde apenas algumas sejam
bem ou mal sucedidas.
Por exemplo, um caixa automático realiza transações com bancos de
dados. Sempre que você retira dinheiro, duas operações devem ser
realizadas para que o banco possa contabilizar seu ativo apropriadamente:
o saldo da sua conta deve ser reduzido e o saldo de dinheiro disponível no
banco deve ser reduzido na mesma quantia. Obviamente, a situação
preferível é aquela na qual as duas operações sejam bem sucedidas, mas
se acabar a energia no meio de uma operação, é totalmente inaceitável
que uma conta seja atualizada e a outra não - ambas operações deveriam
“falhar” para manter uma contabilização apropriada.
O processamento de transações permite que isto aconteça. As operações
em uma transação não são permanentes até que seja efetuado o commit
na transação. Até que isto aconteça, as operações podem ser desfeitas,
retornando-se ao ponto de partida. Um Rollback pode ser implementado
explicitamente, utilizando-se o método Rollback, ou automaticamente,
quando ocorre uma falha do sistema.
O InterBase suporta totalmente o conceito de transações. Na realidade,
todas as operações ocorrem dentro de um contexto de transação. Na
ausência de um controle explícito do programador, o BDE automaticamente
envolve todas as operações na sua própia transação. Por exemplo, toda
vez que você atualiza um registro, a transação é inicializada (started) e
finalizada (commited) automaticamente após cada confirmação (post).
Usando o componente TDataBase você pode explicitamente controlar uma
única transação, e também fazê-la conter quantas operações você quiser.
O Paradox porém não suporta transações. Sempre que um registro é
atualizado no banco, as mudanças são permanentemente gravadas na
tabela. Será necessária uma nova alteração para desfazer manualmente as
alterações anteriores se um Rollback for desejado. Além disto, o sistema
não irá garantir que, em um grupo de operações, todas elas serão bem
sucedidas ou todas elas falharão. É possível simular algumas destas
características através de certos truques de programação e tabelas
temporárias, mas eventualmente, haverá a necessidade de se modificarem
os registros um de cada vez, em lote, o que deixaria aberturas para a
ocorrência de falhas. Além disto, é impossível de se programar um
aplicativo Paradox para se recuperar de uma falha de sistema como queda
de força ou danos na memória secundária.
Gatilhos (triggers) e procedimentos
(procedures)
Uma Stored Procedure consiste em um “pedaço” de código armazenado
em um banco de dados junto aos dados que este contém. Isto permite ao
servidor efetuar manipulações complexas de dados inteiramente no próprio
servidor. As vantagens principais disto são que processos ainda mais
complexos podem ser delegados ao servidor, e qualquer número de
diferentes aplicações clientes podem chamar os mesmos procedimentos.
Se o procedimento for modificado no servidor, nenhuma das aplicações
necessitará ser reescrita, desde que a interface do procedimento continue
a mesma.
Um trigger consiste em uma Stored Procedure que não é explicitamente
chamado por uma aplicação, mas é executado em resposta a uma ação
ocorrida com determinados dados, como por exemplo, uma inserção de
novos registros. A utilização de triggers permite que você realize validações
de dados extremamente complexas, sendo que as operações planejadas
ocorrerão garantidamente no interior da mesma transação que disparou o
“engatilhamento”. Se alguma das operações falhar, todas as alterações
feitas por triggers associados a esta operação serão também desfeitas
(rolled back).
O InterBase suporta Stored Procedures que retornam Result sets, os quais
são tratados exatamente como tabelas somente de leituras, assim como
triggers que simplesmente executam transações de dados e não retornam
nenhum resultado. O InterBase suporta essencialmente um número
ilimitado de triggers para cada tabela os quais podem ocorrer antes ou
depois das operações de inserção, alteração e remoção de registros. Se
mais de um trigger é associado a uma operação a ordem de execução
pode ser especificada. Triggers podem efetuar mudanças que disparem
outros triggers, numa reação em cadeia, mas estas ações em cascata
continuarão contidas numa única transação.
O Paradox não suporta nenhum destes conceitos. Todos os
processamentos de dados devem ser realizados no cliente. Cada aplicação
deve conter a mesma codificação para manutenção dos dados, e cada uma
delas deve também ser modificada caso o método de manipulação de
dados necessitar ser alterado.
Não existe uma garantia que uma aplicação será completada uma vez que
tenha sido iniciada. Por exemplo a operação de se efetuar uma deleção em
cascata de registros “detalhe” após a deleção de um registro “mestre” pode
falhar no seu meio, deixando alguns registros detalhe sem serem
apagados. Se esta “cascata” fosse implementada por meio de triggers no
InterBase, ou todos os registros ou nenhum deles seriam apagados. Além
disto, numa aplicação Paradox, a codificação para perpetuar a deleção
deveria ser escrita em cada uma das aplicações diferentes que utilizassem
os dados do sistema Paradox. Utilizando-se InterBase, por outro lado, a
codificação necessita ser escrita apenas uma vez, no trigger. A aplicação
simplesmente deleta o registro “mestre” e o InterBase cuida da deleção dos
registros “detalhe”.
Fazendo a melhor escolha
Escolher entre Paradox e InterBase pode ter implicação importante para o
seu projeto. Portanto, é essencial saber o que é mais adequado em cada
situação. A figura 1 mostra alguns princípios gerais que podem ajudá-lo a
tomar a melhor decisão.
Isto são sugestões e não devem ser encaradas como regras. A maioria
pesume que uma rede estará envolvida. Se você está implementando um
sistema mono-usuário, o Paradox é usualmente a melhor escolha. O
servidor InterBase local pode ser indicado para um sistema mono-usuário,
mas sem os aspectos de concorrência, as vantagens básicas do InterBase
não estarão sendo utilizadas.
Conclusão
É importante relembrar que o Paradox e o InterBase são sistemas
consideravelmente diferentes, mesmo que o BDE crie uma ilusão de
semelhança. Esta é uma sedutora mas perigosa idéia pois converter uma
aplicação de um mecanismo para outro (InterBase em Paradox ou vice e
versa) envolve muito mais do que uma simples mudança de Alias. Requer
na verdade, significativas diferenças de conceito e projeto.
Escolher qual sistema utilizar é uma decisão crucial que deve ser tomada
no início do projeto. Esta decisão terá um impacto profundo no
desenvolvimento da sua aplicação.

Paradox é melhor quando… InterBase é melhor quando…

a aplicação é utilizada com menos de 10 a aplicação é utilizada com mais de 10


usuários concorrentemente usuários concorrentemente

dados e estruturas de dados devem ser dados devem ser centralizados, mantidos e
facilmente modificados por usuários finais protegidos

a máquina cliente é proporcionalmente a máquina servidora é muito mais potente


mais potente que a máquina servidora que a máquina cliente

largura de banda da rede satisfatória rede está carregada

velocidade e “conveniencia” são mais integridade de dados é crucial


importantes que integridade

baixa disponibilidade de administradores disponibilidade de administradores de rede e


de rede e banco de dados qualificados banco de dados qualificados

por
Alexandre de Andrade Gonçalves Analista/Programador
Minas Export Ltda
www.minasexport.com.br
638 - Protegendo o seu programa e
o seu bolso
Caso você seja um desenvolvedor contratado por
alguma empresa criando sistemas específicos para cada
cliente talvez isto nunca seja uma preocupação séria
pois há poucas possibilidades do sistema interessar
outra pessoa física ou jurídica com características
operacionais diferentes (não estou me referindo a
código-fonte aqui mas ao produto acabado).
Mas caso você esteja no mercado de softwares para o
público em geral, bem-vindo ao grande clube dos
programas pirateados. Este artigo visa introduzir alguns
conceitos de proteção de software para programadores
em geral mas antes de começarmos há uma coisa muito
importante sobre a qual gostaria de dizer: Muitas
grandes empresas liberam softwares com baixa
proteção contra pirataria exatamente visando uma
divulgação indireta do produto (ocorre muito com
componentes para Delphi, a maioria possui uma chave
publicamente divulgada). É uma tática que dá certo em
países aonde há uma certa lei e consciência por parte
dos usuários com software mas isto acredito não se
aplica ao Brasil.Um conselho: não faça isso ! Ninguém
vai comprar aqui o seu produto e a quantidade que
comprar não cobrirá os custo do desenvolvimento.
Você poderá distribuir o seu software como produto de
prateleira ou como um shareware pela Internet. A
grande vantagem do shareware é a divulgação boca à
boca (ou seria clique à clique ?) que ele oferece mas o
ideal é as duas abordagens ao mesmo tempo. Isto
possibilita que o usuário que ficou hesitante em adquirir
o produto na loja possa baixar e testá-lo. Obviamente
nunca esqueça de divulgar o seu site na embalagem.
Para vender software, um bem intangível materialmente,
é preciso um bom sistema de proteção pois o seu
programa poderá virar um freeware em poucos
segundo. É só encontrar um hacker que goste dele.
Interessante é que dificilmente um hacker irá quebrar a
proteção de um produto do qual não goste ou não use,
portanto quando encontrar cracks para o seu programa
em vários sites da web sinta-se elogiado ! Depois pode
ficar triste por não ter recebido um tostão com o seu
trabalho.
Algumas técnicas de proteção (os
prós e contras)
Para avaliação do software:
Nag-Screen: O programa sempre exibe uma tela
avisando que é uma cópia de execução restrita (ou algo
semelhante) e solicita o registro do mesmo por um
determinando período.
Prós: O Usuário sempre é lembrado com uma tela de
aviso que está com uma cópia restrita ou não totalmente
funcional. Alguns nag-screens apenas roubam um
pouco do tempo de uso do software mas não chegam a
atrapalhar o uso efetivo, o que é ótimo para o usuário: a
lógica da comida grátis que vicia.
Contras: Se a limitação for apenas o nag-screen todo
mundo se acostuma com ela e depois de um certo
tempo até se esquece que ela existe. Não é eficiente.
Período: Um programa funciona dentro de um certo
período de avaliação.
Prós: O usuário usará todo o software com todos os
recursos e poderá testar tudo.
Contras: É comum o usuário esquecer que está com
uma cópia de avaliação. Alguns softwares, com uma
péssima proteção, podem ser contornados
simplesmente voltando o calendário do sistema.
Recursos Chaves Desabilitados: O programa possui
alguns recursos que não funcionam como opções para
salvar, exportar etc.
Prós: O Usuário tem mais liberdade que todos os
métodos acima e sempre que tentar fazer o salvamento
de dados lembrará que está com um software não
totalmente funcional forçando uma compra.
Contras: É uma das formas mais fáceis de um
programa receber um crack para liberar o recurso
protegido.
Para licenciamento do software:
Número Serial: O Programa possui um número único
serial que o habilita completamente.
Prós: O usuário somente digita o serial e pronto, o
programa está liberado. Ideal para softwares de
prateleira aonde o usuário já adquiriu o produto. O
sistema preferido para a divulgação indireta.
Contras: Centenas de outros usuários somente digitam
o mesmo serial e pronto: centenas de programas
registrados. Use esta forma caso não deseje receber
pelo seu programa ou queira uma divulgação indireta do
mesmo e esperar pela consciência do usuário, isso não
funciona no Brasil. Centenas ou milhares de usuário
podem usar o mesmo serial. Esta caindo em desuso
rapidamente pois há centenas de sites com index
sofisticados de seriais para qualquer programa o que
torna o sistema quase completamente inútil hoje em dia.
HardLocks: Um pequeno dispositivo é colocado na
porta serial, paralela ou USB com uma identificação
única para liberar o funcionamento do sistema.
Prós: Um dos sistemas mais difíceis de serem
quebrados e definitivamente o mais seguro. Garante a
taxa de uma licença por máquina o que é o ideal. Para
sistemas caros (algo acima de $1000,00) considere
seriamente o uso de HardLocks.
Contras: Custo do HardLock por cópia licenciada e
alguns problemas (raros) com periféricos usando aquela
mesma porta, mas nada tão sério assim para prejudicar
o usuário. As portas seriais e paralelas estão caindo em
desuso com o USB e já existem HardLocks para elas
também. Os Hardlocks pode apresentar defeitos
dependendo do tipo.
Você deve adquirir um kit de gravação e um Hardlock
para cada cópia de distribuição. Não é muito caro mas o
seu software deve compensar isto obviamente.
Disquete de Habilitação: Um disquete é fornecido junto
com o programa para a sua habilitação ou desabilitação.
Prós: É o hardlock dos pobres sem o mesmo nível de
proteção.
Contras: Não faça proteção via disquetes de
habilitação/desabilitação como o Dr. Case e outros. É
perda de tempo ! Há vários utilitários que fazem a cópia
perfeita do disquete sendo possível habilitá-lo em
qualquer máquina. E ainda pode-se ter o problema de
superfície no disco e um belo dia quando o usuário
precisar instalar o software em outra máquina ele terá a
surpresa do disco já mofado ou perdido. Tenha certeza
que isto sempre acontece no final de semana quando
ele liga para o seu escritório na segunda descarregando
o seu vocabulário.
Identidade Única: Uma das melhores e mais eficientes
tipos de proteções é de identidade do equipamentos
recentemente implementado pela própria Microsoft. Isto
consiste em recolher dados únicos sobre o seu
computador como serial do HD, informação da BIOS
(não aconselhável), Versão do OS, Nome do
computador etc. Com base nestas informações você
poderá gerar uma fechadura de identificação. Essa
fechadura precisará de uma chave fornecida por você
para habilitar o seu software unicamente para aquela
máquina.
Prós: Difícil de ser quebrado quando bem implementado
e permite alta adaptabilidade contra cracks criado contra
o sistema como patchs invisíveis que permitem a
modificação do sistema. Permite a taxa de apenas uma
licença por computador.
Contras: Caso o usuário formate a maquina, modifique
periféricos chaves o sistema pode desabilitar a cópia
automaticamente. Isto cria problemas com a solicitação
de uma nova licença para instalação. O usuário pode
simplesmente ligar alegando este fato e de boa fé você
terá que fornecer uma nova liberação.
Habilitação Pela Internet: Ao adquirir um produto o
usuário recebe uma senha que permite a geração de um
número para habilitação e instalação em uma máquina.
Prós: Após habilitar, o número é automaticamente
invalidado para outros usuário o que evita o problema de
divulgação do mesmo pela rede.
Contras: O seu site deve estar em um provedor 100%
confiável ou esteja preparado para aquele cliente que
comprou o produto no sábado a tarde e o seu site ficou
fora do ar no domingo sem ele poder autorizar o
software para o uso.
Conclusão
Não há método melhor ou pior na minha opinião para
proteger um programa mas, mais trabalhoso ou menos
trabalhoso para um hacker quebrar. O Ideal é que que
você use duas ou mais técnicas para proteger o
programa.
Há um princípio básico que ao se usar dois sistemas
simples de proteção independentes cria-se um sistema
forte de proteção. Por exemplo, caso use o sistema de
data é fácil monitorar aonde se esta gravando esta
informação (quando o programa foi instalado) e adiar o
tempo limite de uso. Nag-Screens podem ser rastreadas
e um hacker com bons conhecimentos de assembler
pode editar diretamente o seu código binário fazendo
jumps nas avaliações de restrições. Agora combinando
duas ou três técnicas as coisas complicam para ele e
talvez o trabalho não valha a pena (coisa que ele
realmente não é acostumado).
Mas antes de começar a desenvolver o sistema de
proteção para o seu programa, siga algumas dicas que
aprendemos depois de muito prejuízo com pirataria.
1- Nunca coloque literalmente as mensagens referentes
a registro, nag-screens, avisos de limitação e etcs, em
um formato legível para um ser humano. Faça uma
encriptação destas mensagens. Uma técnica bem
simples dos hackers consiste em procurar no código
binário por uma determinada ocorrência tipo ” Cópia
Trial” e perto tem um “IF” aonde se pode bloquear e lá
se foi a sua proteção. Portanto, faça uma função de
codificação e decodificação e grave todas as
mensagens codificadas no seu programa (no código-
fonte) sendo que as mesmas somente serão exibidas
quando você chamar a função de decodificação.
2- Faça uma estampa no software. Ou seja, todos os
programas possuem uma informação referente ao seu
tamanho físico, data e hora de criação e CRC. Caso o
seu programa tenha sido alterado após aquela data,
através de uma função, o programa poderá verificar em
sua estampa interna se ele foi modificado. Aqui pode
ocorrer alguns problemas com programas anti-virus que
usam a mesma técnica para monitorar alteração de
executáveis aplicando uma “vacina” neles mas já é da
responsabilidade do usuário.
3- Grave dados no registry sempre encriptados e, se
eles forem sobre as informações de registro nunca
coloque na mesma árvore das outras definições do seu
software. Isto dificulta e muito as coisa. Mas se o hacker
possui um programa de monitoramento do registry ele
poderá facilmente contornar isto mas não antes sem um
bom trabalho de adivinhação. E, nunca use chaves com
nomes óbvios tipo “Serial”, “SenhaPrograma”,
“DataLimite” e etc. Dê sempre preferência a gravar
dados de configuração e autorização no registry do que
em arquivos INI (lembra-se deles ?). O registry é mais
difícil de ser manipulado por um leigo e é possível
colocar chaves observando a mudança de outras
chaves o que torna as coisas mais complexas.
4- Se possível, implemente um sistema periódico de
verificação da licença via site na web.
Coloque este alerta em seu termo de uso do seu
software e o faça de tal forma que seja invisível, indolor
(não fique interrompendo o usuário) e que desabilite o
software imediatamente ao verificar uma cópia com o
número de série irregular ou divulgado. É importante
aqui implementar nos CGI do site um alerta via e-mail
quando ocorrer várias tentativas de liberação de um
mesmo serial. Assim você descobre rapidamente quem
vazou um serial para o público.
5- Tenha uma proteção não divulgada. Por exemplo,
após o software executar 300 vezes uma mensagem
surge do nada indicando o download de uma cópia mais
atualizada. Nesta nova cópia você já deve ter
contornado todos os problemas com cracks que
apareceram no período.
6- Faça Check Point em pontos não óbvios do seu
software e em vários lugares. Use uma periodicidade
completamente aleatória para fazer isto. Por exemplo,
quando o usuário abrir uma determinada tela não muito
utilizada, ocorre uma verificação em background sobre a
validade da licença esta verificação pode e deve ser
aleatória. Após validar e algo estiver errado, nunca exiba
no mesmo momento que a licença é irregular pois se
torna uma referência para o Hacker aonde ele deve
procurar no código binário para quebrar o seu programa.
Lembre-se que tudo serve como marcação no código
binário: um caption de um form, o conteúdo string de um
controle etc.
7- Use constantes. Abuse delas em vez de escrever
diretamente nos dialogs para comunicação com usuário.
Faça uma Unit separada aonde somente é armazenado
estas constantes. Isso confunde quem olha o código
binário do executável pois fisicamente no executável
elas não estarão próximas.
Todas estas informações foram adquiridas com a nossa
experiência e, principalmente, com dicas de dois
conhecidos especialistas em quebras de programas e
criação de cracks. Na primeira divulgação de um dos
nossos softwares um deles me retornou uma cópia
crackeada em questão de horas (segundo ele, estava
sem tempo por isso demorou tanto), e ficamos
envergonhados para dizer a verdade. Depois ao
implementarmos a codificação de string e outras
técnicas, ele levou uma semana mas não conseguiu
liberar todos os recursos. Ao ativarmos os sistemas
randômicos de verificação em background e validação
pelo site ainda não tivemos uma quebra. Claro que ela
irá ocorrer, mas enquanto isto estamos recebendo pelo
nosso trabalho.
Acho que seguindo estas dicas você terá uma boa
chance de receber pelo seu trabalho na quantidade
justa. Lembre-se que há uma legião de pessoas ai fora
tentando quebrar a proteção pelo simples prazer de
dizer que foram eles.
Portanto a questão não é fazer um sistema 100%
seguro (o que é quase impossível) mas um que seja
110% trabalhoso para eles. Tenha em mente também
que eles são em maior número e problema não é se vão
quebrar a segurança mas quando e o que você vai fazer
em seguida.
Não poderíamos terminar este artigo sem falar sobre
alguns componentes para proteção.
Uma coisa que percebi é que certos componentes de
proteção são tão complicados que você as vezes tem
que passar uma semana implementando ele no seu
sistema. Mas aqui estão alguns que são ótimos pela
simplicidade e fácil implementação.:
OnGuard (TurboPower) - Não é propaganda pessoal !
Os componentes da TurboPower tem uma grande
qualidade e o OnGuard faz tudo o que se precisa de
proteção. Validação e criação de serial, limitação por
data, estampa no executável, dias de execução e muito
mais. A grande vantagem é que há exemplos para tudo
que podem ser fácil e rapidamente adaptados.
Lock&Key - Gosto do Lock&Key pela sua simplicidade
de uso. Ele gera uma “fechadura” com base nos dados
do HD do usuário e com este número-fechadura você
cria um número único para liberar o software. Trabalha
com níveis o que é ideal para proteção progressiva. Não
estamos usando mais este, apesar de sua boa
qualidade.
SharewareIt - Crie sistemas de shareware de forma
bem simples. A vantagem é que é gratuito.

Este artigo foi escrito por Murilo Oliveira,


proprietário da FastByte.
Contou com a colaboração de Fred Montier.
700 - O Dilema do envio de e-mail
Um grande dilema pelo qual passei foi o envio de e-mail
´s por programas feitos em Delphi. Os detalhes do
problema seguem abaixo:
- Fiz um programa para um cliente que tinha como
opção o envio de relatórios por e-mail;
- Todo o processo estava pronto e funcionando
perfeitamente;
- Quando passei para o cliente nada funcionou!
Isso me deixou muito confuso, no meu computador
continuava a funcionar perfeitamente!
Como “todos” sabem precisamos configurar o NMSMTP
com um servidor smtp (host) para o envio de e-mail´s.
No meu caso estava usando UOL e sendo assim eu
estava usando o SMTP.UOL.COM.BR como Host. Só
que o meu cliente não usa UOL. E esse aparentemente
era o problema.
Não encontrei a solução sozinho e pedi ajuda a vários
colegas programadores o qual um me respondeu da
seguinte maneira:
“Se eu não me engano, no Uol vc deve primeiro
baixar as mensagens para que depois ele deixe vc
enviar, ou seja, para poder enviar mensagens, vc
precisa estar autenticado la no UOL.
Espero ter ajudado.
Abraços,
Fernando Gonçalves,”
Foi só isso que precisei para resolver todo o “Dilema”.
Só precisaria me identificar no POP3 do UOL que
estaria tudo resolvido.
Então eu fiz:
- Coloquei um componente NMPOP3 e antes dos
comandos do NMSMTP eu coloquei esses do NMPOP3:
//Processo de reconhecimento no POP3 do
UOL
NMPOP31.AttachFilePath := ‘.’;
NMPOP31.DeleteOnRead := FALSE;
NMPOP31.ReportLevel := Status_Basic;
NMPOP31.TimeOut := 20000;
NMPOP31.Host := ‘pop3.uol.com.br’;
NMPOP31.Port := 110;
NMPOP31.UserID := ‘MeuLogin’;
NMPOP31.Password := ‘Minha Senha’;
NMPOP31.Connect;
//Conexão não feita ele sai
//Conexão feita ele desconecta e prossegue
if not NMPOP31.Connected then exit else
NMPOP31.Disconnect;
//Prosseguindo ele agora tenta se conectar
ao SMTP do UOL
NMSMTP1.ClearParams := TRUE;
NMSMTP1.Host := ‘smtp.uol.com.br’
NMSMTP1.Port := 25;
NMSMTP1.UserID := ‘MeuLogin’
NMSMTP1.Connect;
//Conexão não feita ele sai
//Conexão feita ele prossegue
If not NMSMTP1.Connected then exit;
//Processo de envio
NMSMTP1.PostMessage.Body.Clear;
NMSMTP1.PostMessage.ToAddress.Clear;
NMSMTP1.PostMessage.FromAddress :=
‘MeuLogin@MeuProvedor.com.br’
NMSMTP1.PostMessage.FromName := ‘Meu Nome
Completo’
NMSMTP1.PostMessage.Body.Add(‘Teste de
envio de email’);
NMSMTP1.PostMessage.Subject := (‘Teste de
Envio’);
NMSMTP1.PostMessage.ToAddress.Add(‘destino
@DestinoProvedor.com.br’);
NMSMTP1.SendMail;
Depois de estabelecer a conexão com o POP3 do UOL
o envio pelo SMTP do UOL ficou liberado não
importando em que provedor eu estivesse conectado.
No meu caso eu pude usar POP3 e SMTP do UOL pois
sou assinante do UOL, porém vc pode simplesmente
criar um e-mail no IG, IEG ou outro serviço de e-mail
grátis e pronto é só utilizar a dica!!
Obs.: Nem todos os e-mail´s grátis tem serviço POP3!
By Lloyd Dickinson
LloydSoft
Biblioteca para operações com
Arquivos
{*****************************************
**************}
{ }
{ Delphi Runtime Library }
{ Windows Messages and Types }
{ }
{ Copyright (c) 1991,96 Walter Alves
Chagas Junior }
{ }
{*****************************************
**************}

unit Arquivos;

interface

uses
Windows, Dialogs, Messages, SysUtils,
Classes, Controls, StdCtrls,FileCtrl,
Graphics, shellapi, Printers;

function fileSize(const FileName: String):


LongInt;
function GetFileDate(TheFileName: string):
string;
function FileDate(Arquivo: String):
String;
function FillDir(Const AMask: string):
TStringList;
function WinExecAndWait32(FileName:String;
Visibility : integer):integer;
Function RecycleBin(sFileName : string ) :
boolean;
function NumLinhasArq(Arqtexto:String):
integer;
function FileCopy(source,dest: String):
Boolean;
function ExtractName(const Filename:
String): String;
function FileTypeName(const aFile:
String): String;
Procedure CopyFile( Const sourcefilename,
targetfilename: String );
Procedure ZapFiles(vMasc:String);
function PrintImage(Origem:
String):Boolean;

implementation

function fileSize(const FileName: String):


LongInt;
{Retorna o tamanho de um arquivo}
var
SearchRec : TSearchRec;
begin { !Win32! -> GetFileSize }
if
FindFirst(FileName,faAnyFile,SearchRec)=0
then Result:=SearchRec.Size
else Result:=0;
FindClose(SearchRec);
end;

function GetFileDate(TheFileName: string):


string;
var
FHandle: integer;
begin
FHandle := FileOpen(TheFileName, 0);
result :=
DateToStr((FileDateToDateTime(FileGetDate(
FHandle))));
FileClose(FHandle);
end;

function FileDate(Arquivo: String):


String;
{Retorna a data e a hora de um arquivo}
var
FHandle: integer;
begin
if not fileexists(Arquivo) then
begin
Result := ‘Nome de Arquivo Inválido’;
end
else
begin
FHandle := FileOpen(Arquivo, 0);
try
Result :=
DateTimeToStr(FileDateToDateTime(FileGetDa
te(FHandle)));
finally
FileClose(FHandle);
end;
end;
end;

Procedure ZapFiles(vMasc:String);
{Apaga arquivos usando mascaras tipo:
*.zip, *.* }
Var Dir : TsearchRec;
Erro: Integer;
Begin
Erro := FindFirst(vMasc,faArchive,Dir);
While Erro = 0 do Begin
DeleteFile(
ExtractFilePAth(vMasc)+Dir.Name );
Erro := FindNext(Dir);
End;
FindClose(Dir);
End;

function FillDir(Const AMask: string):


TStringList;
{Retorna uma TStringlist de todos os
arquivos localizados
no path corrente , Esta função trabalha
com mascaras}
var
SearchRec : TSearchRec;
intControl : integer;
begin
Result := TStringList.create;
intControl := FindFirst( AMask,
faAnyFile, SearchRec );
if intControl = 0 then
begin
while (intControl = 0) do
begin
Result.Add( SearchRec.Name );
intControl := FindNext( SearchRec );
end;
FindClose( SearchRec );
end;
end;

function WinExecAndWait32(FileName:String;
Visibility : integer):integer;
{ Tenta executar o aplicativo finalizando-
o corretamente apos o uso. Retorna -1 em
caso de falha}
var
zAppName:array[0..512] of char;
zCurDir:array[0..255] of char;
WorkDir:String;
StartupInfo:TStartupInfo;
ProcessInfo:TProcessInformation;
begin
StrPCopy(zAppName,FileName);
GetDir(0,WorkDir);
StrPCopy(zCurDir,WorkDir);
FillChar(StartupInfo,Sizeof(StartupInfo),#
0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags :=
STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not
CreateProcess(nil,zAppName,nil,nil,false,C
REATE_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS,nil,
nil,StartupInfo,ProcessInfo) then
begin
Result := -1;
end
else
begin

WaitforSingleObject(ProcessInfo.hProcess,I
NFINITE);

GetExitCodeProcess(ProcessInfo.hProcess,Re
sult);
end;
end;

Function RecycleBin(sFileName : string ) :


boolean;
// Envia um arquivo para a lixeira (
requer a unit Shellapi.pas)
var
fos : TSHFileOpStruct;
Begin
FillChar( fos, SizeOf( fos ), 0 );
With fos do
begin
wFunc := FO_DELETE;
pFrom := PChar( sFileName );
fFlags := FOF_ALLOWUNDO
or FOF_NOCONFIRMATION
or FOF_SILENT;
end;
Result := (0 = ShFileOperation(fos));
end;

function NumLinhasArq(Arqtexto:String):
integer;
// Retorna o número de linhas que um
arquivo possui
Var
f: Textfile;
linha, cont:integer;
Begin
linha := 0;
cont := 0;
AssignFile(f,Arqtexto);
Reset(f);
While not eof(f) Do
begin
ReadLn(f);
Cont := Cont + 1;
end;
Closefile(f);
result := cont;
end;
function FileCopy(source,dest: String):
Boolean;
{copia um arquivo de um lugar para outro.
Retornando falso em caso de erro}
var
fSrc,fDst,len: Integer;
size: Longint;
buffer: packed array [0..2047] of Byte;
begin
if source <> dest then
begin
fSrc := FileOpen(source,fmOpenRead);
if fSrc >= 0 then
begin
size := FileSeek(fSrc,0,2);
FileSeek(fSrc,0,0);
fDst := FileCreate(dest);
if fDst >= 0 then
begin
while size > 0 do
begin
len :=
FileRead(fSrc,buffer,sizeof(buffer));
FileWrite(fDst,buffer,len);
size := size - len;
end;
FileSetDate(fDst,FileGetDate(fSrc));
FileClose(fDst);
FileSetAttr(dest,FileGetAttr(source));
Result := True;
end
else
begin
Result := False;
end;
FileClose(fSrc);
end;
end;
end;

Procedure CopyFile( Const sourcefilename,


targetfilename: String );
{Copia um arquivo de um lugar para outro}
Var
S, T: TFileStream;
Begin
S := TFileStream.Create( sourcefilename,
fmOpenRead );
try
T := TFileStream.Create( targetfilename,
fmOpenWrite or fmCreate );
try
T.CopyFrom(S, S.Size ) ;
finally
T.Free;
end;
finally
S.Free;
end;
end;

function ExtractName(const Filename:


String): String;
{Retorna o nome do Arquivo sem extensão}
var
aExt : String;
aPos : Integer;
begin
aExt := ExtractFileExt(Filename);
Result := ExtractFileName(Filename);
if aExt <> ” then
begin
aPos := Pos(aExt,Result);
if aPos > 0 then
begin
Delete(Result,aPos,Length(aExt));
end;
end;
end;

function FileTypeName(const aFile:


String): String;
{Retorna descrição do tipo do arquivo.
Requer a unit ShellApi}
var
aInfo: TSHFileInfo;
begin
if
SHGetFileInfo(PChar(aFile),0,aInfo,Sizeof(
aInfo),SHGFI_TYPENAME)<>0 then
Result := StrPas(aInfo.szTypeName)
else begin
Result := ExtractFileExt(aFile);
Delete(Result,1,1);
Result := Result +’ File’;
end;
end;

function PrintImage(Origem:
String):Boolean;
// imprime um bitmap selecionado
retornando falso em caso negativo
// requer as units Graphics e printers
declaradas na clausula Uses
var
Imagem: TBitmap;
begin
if fileExists(Origem) then
begin
Imagem := TBitmap.Create;
Imagem.LoadFromFile(Origem);
with Printer do
begin
BeginDoc;
Canvas.Draw((PageWidth - Imagem.Width)
div 2,(PageHeight - Imagem.Height) div
2,Imagem);
EndDoc;
end;
Imagem.Free;
Result := True;
end
else
begin
Result := False;
end;
end;

end.
516 - Biblioteca para operações
com DiskDrives
{
Objeto…: Biblioteca para operações com
disk-drives.
Categoria: Open-Source
Autor….: Daniel Pereira Guimarães
E-mail…: tecnobyte@ulbrajp.com.br
Home-Page: www.ulbrajp.com.br/~tecnobyte
Revisão..: 21 de Fevereiro de 2001
}

unit tbDskDrv;

interface

uses Windows, SysUtils;

type
TtbDriveType = (dtUnknown, dtNotExist,
dtRemovable, dtFixed,
dtRemote, dtCdRom, dtRamDisk, dtError);

TtbVolInfo = record
Name: string;
Serial: Cardinal;
IsCompressed: boolean;
MaxCompLen: Cardinal;
FileSysName: string;
end;

{ Retorna o número do drive: A=1, B=2,


C=3, etc. }
function tbDriveByte(const Drive: Char):
byte;
{ Retorna true se o drive existe }
function tbDriveExists(const Drive: Char):
boolean;
{ Retorna true se o drive está preparado }
function tbDriveIsOk(const Drive: Char):
boolean;
{ Retorna uma string contendo as letras de
unidades de existentes }
function tbDriveLetters: string;
{ Retorna o tipo do drive. Veja
TtbDriveType }
function tbDriveType(const Drive: Char;
Path: PChar): TtbDriveType;
{ Retorna o nome de volume de uma unidade
}
function tbVolName(const Drive: Char;
Path: PChar): string;
{ Retorna o número serial de uma unidade }
function tbVolSerial(const Drive: Char;
Path: PChar): Cardinal;
{ Retorna informações diversas sobre uma
unidade. Veja TtbVolInfo }
function tbVolInfo(const Drive: Char;
Path: PChar): TtbVolInfo;

implementation

{ *** Drives *** }


function tbDriveByte(const Drive: Char):
byte;
{ Uso: X := tbDriveByte(‘C’) }
begin
if Drive = #0 then
Result := 0
else
Result := Ord(UpCase(Drive)) - 64;
end;
function tbDriveExists(const Drive: Char):
boolean;
{ Uso: if tbDriveExists(‘A’) then … }
begin
Result := Pos(UpCase(Drive),
tbDriveLetters) > 0;
end;

function tbDriveIsOk(const Drive: Char):


boolean;
{ Uso: if tbDriveIsOk(‘A’) then … }
begin
Result :=
SysUtils.DiskSize(tbDriveByte(Drive)) >=
0;
end;

function tbDriveLetters: string;


{ Uso: S := tbDriveLetters; - retorna
‘ACD’ se existir as unidades
A:, C: e D: }
var
Drives: LongWord;
I: byte;
begin
Result := ”;
Drives := GetLogicalDrives;
if Drives <> 0 then
for I := 65 to 90 do
if ((Drives shl (31 - (I - 65))) shr 31)
= 1 then
Result := Result + Char(I);
end;

function tbDriveType(const Drive: Char;


Path: PChar): TtbDriveType;
{ Uso: T := tbDriveType; – T é do tipo
TtbDriveType }
begin
if Path = nil then
Path := PChar(Drive + ‘:');

case Windows.GetDriveType(PChar(Path))
of
0: Result := dtUnknown;
1: Result := dtNotExist;
DRIVE_REMOVABLE: Result := dtRemovable;
DRIVE_FIXED: Result := dtFixed;
DRIVE_REMOTE: Result := dtRemote;
DRIVE_CDROM: Result := dtCdRom;
DRIVE_RAMDISK: Result := dtRamDisk;
else
Result := dtError;
end;
end;

function tbVolName(const Drive: Char;


Path: PChar): string;
{ Uso: S := tbVolName(‘A’, nil); ou
S := tbVolName(#0, ‘\computador\c'); }
var
MaxCompLen, FileSysFlag, PrevErrorMode:
Cardinal;
begin
if Path = nil then
Path := PChar(Drive + ‘:');

SetLength(Result, 255);

PrevErrorMode :=
SetErrorMode(SEM_FAILCRITICALERRORS);
try
if GetVolumeInformation( PChar(Path),
PChar(Result), 255,
nil, MaxCompLen, FileSysFlag, nil, 0)
then
Result := string(PChar(Result))
else
Result := ”;
finally
SetErrorMode(PrevErrorMode);
end;
end;

function tbVolSerial(const Drive: Char;


Path: PChar): Cardinal;
{ Uso: S := tbVolSerial(‘A’, nil); ou
S := tbVolSerial(#0, ‘\computador\c'); }
var
MaxCompLen, FileSysFlag, PrevErrorMode:
Cardinal;
begin
if Path = nil then
Path := PChar(Drive + ‘:');

PrevErrorMode :=
SetErrorMode(SEM_FAILCRITICALERRORS);
try
if not GetVolumeInformation(PChar(Path),
nil, 0,
@Result, MaxCompLen, FileSysFlag, nil,
0) then
Result := 0;
finally
SetErrorMode(PrevErrorMode);
end;
end;

function tbVolInfo(const Drive: Char;


Path: PChar): TtbVolInfo;
{ Uso: Info := tbVolInfo(‘A’, nil); ou
Info := tbVolInfo(#0, ‘\computador\c');
}
const
cVolNameLen = 255;
cSysNameLen = 255;
var
Flags, PrevErrorMode: Cardinal;
begin
if Path = nil then
Path := PChar(Drive + ‘:');

SetLength(Result.Name, cVolNameLen);
SetLength(Result.FileSysName,
cSysNameLen);

PrevErrorMode :=
SetErrorMode(SEM_FAILCRITICALERRORS);
try
if GetVolumeInformation(Path,
PChar(Result.Name), cVolNameLen,
@Result.Serial, Result.MaxCompLen,
Flags,
PChar(Result.FileSysName), cSysNameLen)
then
begin
Result.Name :=
string(PChar(Result.Name));
Result.FileSysName :=
string(PChar(Result.FileSysName));
Result.IsCompressed := (Flags and
FS_VOL_IS_COMPRESSED) > 0;
end else begin
Result.Name := ”;
Result.Serial := 0;
Result.IsCompressed := false;
Result.MaxCompLen := 0;
Result.FileSysName := ”;
end;
finally
SetErrorMode(PrevErrorMode);
end;
end;

end.
Biblioteca para operações com
Hardware
{*****************************************
**************}
{ }
{ Delphi Runtime Library }
{ Windows Messages and Types }
{ }
{ Copyright (c) 1991,96 Walter Alves
Chagas Junior }
{ }
{*****************************************
**************}

unit Hardware;

interface

uses
Windows, Dialogs, Messages, SysUtils,
Classes, Controls, StdCtrls, Graphics,
Printers, shellapi, MMSystem;

function TestaPlaca(Value:integer):
Boolean;
function DiscoNoDrive(const drive : char):
boolean;
function
NumeroSerie(Unidade:PChar):String;
function DetectaDrv(const drive : char):
boolean;
function NumeroDeCores : Integer;
function Percentdisk(unidade: byte):
Integer;
function IsPrinter : Boolean;
function CorrentPrinter :String;

implementation

Function TestaPlaca(Value:integer):
Boolean;
{Testa se existe uma placa de som no seu
computador}
begin
if WaveOutGetNumDevs > 0 then
begin
result := True
end
else
begin
Result := False;
end;
end;

function DiscoNoDrive(const drive : char):


boolean;
{Detecta se há disco no Drive}
var
DriveNumero : byte;
EMode : word;
begin
result := false;
DriveNumero := ord(Drive);
if DriveNumero >= ord(‘a’) then
begin
dec(DriveNumero,$20);
EMode :=
SetErrorMode(SEM_FAILCRITICALERRORS);
end;
try
if DiskSize(DriveNumero-$40) = -1 then
begin
Result := False;
end
else
begin
Result := True;
end;
Except
SetErrorMode(EMode);
end;
end;

function
NumeroSerie(Unidade:PChar):String;
{Retorna o Número serial da unidade
especificada}
var
VolName,SysName : AnsiString;
SerialNo,MaxCLength,FileFlags : DWord;
begin
try
SetLength(VolName,255);
SetLength(SysName,255);

GetVolumeInformation(Unidade,PChar(VolName
),255,@SerialNo,

MaxCLength,FileFlags,PChar(SysName),255);
result := IntToHex(SerialNo,8);
except
result := ‘ ‘;
end;
end;

function DetectaDrv(const drive : char):


boolean;
{Detecta quantas unidade possui no
computador}
var
Letra: string;
begin
Letra := drive + ‘:';
if GetDriveType(PChar(Letra)) < 2 then
begin
result := False;
end
else
begin
result := True;
end;
end;

function NumeroDeCores : Integer;


{Retorna a quantidade atual de cores no
Windows (16, 256, 65536 = 16 ou 24 bit}
var
DC:HDC;
BitsPorPixel: Integer;
begin
Dc := GetDc(0); // 0 = vídeo
BitsPorPixel :=
GetDeviceCaps(Dc,BitsPixel);
Result := 2 shl (BitsPorPixel - 1);
end;

function Percentdisk(unidade: byte):


Integer;
{Retorna a porcentagem de espaço livre em
uma unidade de disco}
var
A,B, Percentual : longint;
begin
if DiskFree(Unidade)<> -1 then
begin
A := DiskFree(Unidade) div 1024;
B := DiskSize(Unidade) div 1024;
Percentual:=(A*100) div B;
result := Percentual;
end
else
begin
result := -1;
end;
end;

function IsPrinter : Boolean;


Const
PrnStInt : Byte = $17;
StRq : Byte = $02;
PrnNum : Word = 0; { 0 para LPT1, 1 para
LPT2, etc. }
Var
nResult : byte;
Begin (* IsPrinter*)
Asm
mov ah,StRq;
mov dx,PrnNum;
Int $17;
mov nResult,ah;
end;
IsPrinter := (nResult and $80) = $80;
End;

function CorrentPrinter :String;


// Retorna a impressora padrão do windows
// Requer a unit printers declarada na
clausula uses da unit
var
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port : array[0..255] of char;
hDMode : THandle;
begin
Printer.GetPrinter(Device, Driver, Port,
hDMode);
Result := Device+’ na porta ‘+Port;
end;

end.
517 - Biblioteca para Operações
com Mouse
{
Objeto…: Biblioteca para operações com
mouse.
Categoria: Open-Source
Autor….: Daniel Pereira Guimarães
E-mail…: tecnobyte@ulbrajp.com.br
Home-Page: www.ulbrajp.com.br/~tecnobyte
Revisão..: 21 de Fevereiro de 2001
}

unit tbMouse;

interface

uses Windows, Controls, Messages, Forms;

{ Simula - click de mouse }


procedure MouseClick(const Duration:
Word);
{ Aprisiona o mouse em um retângulo }
function MouseClip(const Rct: TRect):
boolean;
{ Retorna o número de botões do mouse }
function MouseGetButtons: byte;
{ Retorna a posição do mouse }
function MouseGetPos(var Pt: TPoint):
boolean;
{ Retorna true se o mouse está sobre a
janela }
function MouseInWindow(const WinHandle:
HWnd): boolean;
{ Retorna true se o mouse está configurado
}
function MouseIsPresent: boolean;
{ Move o ponteiro do mouse para um
controle (componente visual) }
function MouseMoveToControl(const Control:
TControl): boolean;
{ Define a posição do mouse }
function MouseSetPos(const Pt: TPoint):
boolean;
{ Exibe ou oculta o ponteiro do mouse }
function MouseShowCursor(const Show:
boolean): boolean;
{ Deslisa o ponteiro do mouse até um
controle }
function MouseSlideToControl(const
Control: TControl; Jump, JumpTime: Word):
boolean;
{ Inverte os botões do mouse }
function MouseSwapButtons(const Swap:
boolean): boolean;
{ Retorna true se os botões estão
invertidos }
function MouseSwappedButtons: boolean;
{ Libera o mouse - previamente aprisionado
com MouseClip }
function MouseUnClip: boolean;

implementation

{ *** Mouse *** }


procedure MouseClick(const Duration:
Word);
var
Win: HWnd;
Pt: TPoint;
Msg: TMsg;
FlagMouseDown, FlagMouseUp: DWord;
begin
{ Se os botões estiverem invertidos… }
if MouseSwappedButtons then begin
FlagMouseDown := MOUSEEVENTF_RIGHTDOWN;
FlagMouseUp := MOUSEEVENTF_RIGHTUP;
end else begin; { Se os botões estiverem
normais… }
FlagMouseDown := MOUSEEVENTF_LEFTDOWN;
FlagMouseUp := MOUSEEVENTF_LEFTUP;
end;

{ Obtém o handle da janela que está sob


o cursor }
Windows.GetCursorPos(Pt);
Win := Windows.WindowFromPoint(Pt);

{ Inicia o click }
mouse_event(FlagMouseDown, 0, 0, 0, 0);

{ Processa as mensagens do mouse


pertencentes à janela sob o cursor }
while PeekMessage(Msg, Win,
WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_REMOVE)
do
DispatchMessage(Msg);

Sleep(Duration);

{ Conclui o click }
mouse_event(FlagMouseUp, 0, 0, 0, 0);
end;

function MouseClip(const Rct: TRect):


boolean;
begin
Result := Windows.ClipCursor(@Rct);
end;

function MouseGetButtons: byte;


begin
Result :=
GetSystemMetrics(SM_CMOUSEBUTTONS);
end;

function MouseGetPos(var Pt: TPoint):


boolean;
begin
Result := Windows.GetCursorPos(Pt);
end;

function MouseInWindow(const WinHandle:


HWnd): boolean;
var
Pt: TPoint;
begin
Result := GetCursorPos(Pt) and
(WindowFromPoint(Pt) = WinHandle);
end;

function MouseIsPresent: boolean;


begin
Result :=
GetSystemMetrics(SM_MOUSEPRESENT) <> 0;
end;

function MouseMoveToControl(const Control:


TControl): boolean;
var
Pt: TPoint;
begin
Pt.x := Control.Width div 2;
Pt.y := Control.Height div 2;
Pt := Control.ClientToScreen(Pt);
Result := SetCursorPos(Pt.X, Pt.Y);
end;

function MouseSetPos(const Pt: TPoint):


boolean;
begin
Result := Windows.SetCursorPos(Pt.X,
Pt.Y);
end;

function MouseShowCursor(const Show:


boolean): boolean;
var
I: integer;
begin
I := ShowCursor(LongBool(true));
if Show then begin
{ ShowCursor(true) incrementa um
contador interno do Windows.
Quando este contador ficar >= 0, então o
cursor é exibido }
Result := I >= 0;
while I < 0 do begin
Result := ShowCursor(LongBool(true)) >=
0;
Inc(I);
end;
end else begin
{ ShowCursor(false) decrementa um
contador interno do Windows.
Quando este contador ficar < 0, então o
cursor é ocultado }
Result := I < 0;
while I >= 0 do begin
Result := ShowCursor(LongBool(false)) <
0;
Dec(I);
end;
end;
end;

function MouseSlideToControl(const
Control: TControl; Jump, JumpTime: Word):
boolean;
var
ToPoint, Pt: TPoint;

function ExecJump: boolean;


begin
if (Pt.x = ToPoint.x) and (Pt.y =
ToPoint.y) then begin
Result := false; { Chegou }
Exit;
end;
{ Calcula X }
if Pt.x < ToPoint.x then begin
Inc(Pt.x, Jump);
if Pt.x > ToPoint.x then { Se passou… }
Pt.x := ToPoint.x;
end else if Pt.x > ToPoint.x then begin
Dec(Pt.x, Jump);
if Pt.x < ToPoint.x then
Pt.x := ToPoint.x;
end;
{ Calcula Y }
if Pt.y < ToPoint.y then begin
Inc(Pt.y, Jump);
if Pt.y > ToPoint.y then { Se passou… }
Pt.y := ToPoint.y;
end else if Pt.y > ToPoint.y then begin
Dec(Pt.y, Jump);
if Pt.y < ToPoint.y then
Pt.y := ToPoint.y;
end;
Result := SetCursorPos(Pt.x, Pt.y);
end;

begin
if Jump = 0 then
Jump := 1;
SetCursor(Screen.Cursors[Control.Cursor]);
with Control do begin
ToPoint.x := Width div 2;
ToPoint.y := Height div 2;
ToPoint := ClientToScreen(ToPoint);
end;
if GetCursorPos(Pt) then
while ExecJump do Sleep(JumpTime);

Result := GetCursorPos(Pt) and


(Pt.x = ToPoint.x) and (Pt.y =
ToPoint.y);
end;

function MouseSwapButtons(const Swap:


boolean): boolean;
begin
Result :=
Windows.SwapMouseButton(LongBool(Swap));
end;

function MouseSwappedButtons: boolean;


begin
Result :=
GetSystemMetrics(SM_SWAPBUTTON) <> 0;
end;

function MouseUnClip: boolean;


begin
Result := Windows.ClipCursor(nil);
end;

end.
519 - Biblioteca para Operações
com o Sistema
{
Objeto…: Biblioteca de rotinas de
sistema.
Categoria: Open-Source
Autor….: Daniel Pereira Guimarães
E-mail…: tecnobyte@ulbrajp.com.br
Home-Page: www.ulbrajp.com.br/~tecnobyte
Revisão..: 21 de Fevereiro de 2001
}

unit tbSys;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;

{ Retorna true se o computador está


configurado para rede }
function NetIsPresent: boolean;
{ Retorna o nome do computador }
function SysComputerName: string;
{ Retorna o diretório do Windows }
function SysWinDir: string;
{ Retorna a identificação da plataforma }
function SysPlatform: DWord;
{ Define o nome do computador }
function SysSetComputerName(const S:
string): boolean;
{ Retorna o diretório System do Windows }
function SysSystemDir: string;
{ Retorna o diretório Temp do Windows }
function SysTempDir: string;
{ Retorna o nome do usuário logado no
Windows }
function SysUserName: string;
{ Retorna informações de versão do Windows
}
function SysVersion(var Ver:
_OSVERSIONINFOA): boolean;
{ Retorna uma string contendo a versão do
Windows }
function SysVersionStr: string;

{ Processa as mensagens enviadas a uma


janela }
procedure WndProcessMessages(const Wnd:
HWnd);
{ Processa as mensagens enviadas a uma
janela - somente o intervalo
de mensagens informado }
procedure WndProcessMessagesEx(const Wnd:
HWnd; const FromMsg, ToMsg: Cardinal);

implementation

{ *** Net *** }


function NetIsPresent: boolean;
begin
Result := GetSystemMetrics(SM_NETWORK)
<> 0;
end;

{ Sys }
function SysComputerName: string;
var
I: DWord;
begin
I := MAX_COMPUTERNAME_LENGTH + 1;
SetLength(Result, I);
Windows.GetComputerName(PChar(Result),
I);
Result := string(PChar(Result));
end;

function SysWinDir: string;


begin
SetLength(Result, MAX_PATH);

Windows.GetWindowsDirectory(PChar(Result),
MAX_PATH);
Result := string(PChar(Result));
end;

function SysPlatform: DWord;


var
Ver: _OSVERSIONINFOA;
begin
if SysVersion(Ver) then
Result := Ver.dwPlatformId
else
Result := 0;
end;

function SysSetComputerName(const S:
string): boolean;
begin
Result :=
Windows.SetComputerName(PChar(S));
end;

function SysSystemDir: string;


begin
SetLength(Result, MAX_PATH);
if GetSystemDirectory(PChar(Result),
MAX_PATH) > 0 then
Result := string(PChar(Result))
else
Result := ”;
end;

function SysTempDir: string;


begin
SetLength(Result, MAX_PATH);
if GetTempPath(MAX_PATH, PChar(Result))
> 0 then
Result := string(PChar(Result))
else
Result := ”;
end;

function SysUserName: string;


var
I: DWord;
begin
I := 255;
SetLength(Result, I);
Windows.GetUserName(PChar(Result), I);
Result := string(PChar(Result));
end;

function SysVersion(var Ver:


_OSVERSIONINFOA): boolean;
begin
Ver.dwOSVersionInfoSize := SizeOf(Ver);
Result := GetVersionEx(Ver);
end;

function SysVersionStr: string;


var
Ver: _OSVERSIONINFOA;
begin
if SysVersion(Ver) then
Result := IntToStr(Ver.dwMajorVersion) +
‘.’ +
IntToStr(Ver.dwMinorVersion)
else
Result := ”;
end;

procedure WndProcessMessages(const Wnd:


HWnd);
begin
WndProcessMessagesEx(Wnd, 0, 0);
end;

procedure WndProcessMessagesEx(const Wnd:


HWnd; const FromMsg, ToMsg: Cardinal);
var
Msg: tagMsg;
begin
while PeekMessage(Msg, Wnd, FromMsg,
ToMsg, PM_REMOVE) do
DispatchMessage(Msg);
end;
end.
518 - Biblioteca para Operações
com Strings
{
Objeto…: Biblioteca para operações com
string.
Categoria: Open-Source
Autor….: Daniel Pereira Guimarães
E-mail…: tecnobyte@ulbrajp.com.br
Home-Page: www.ulbrajp.com.br/~tecnobyte
Revisão..: 21 de Fevereiro de 2001
}

unit tbStr;

interface

uses SysUtils;

{ Retorna a string ao lado esquerdo do


separador }
function tbGetShortStr(const S: string;
const Sep: Char): string;
{ Retorna string ao lado direito do
separador }
function tbGetLongStr(const S: string;
const Sep: Char): string;
{ Semelhante a PadC do clipper }
function tbPadC(const S: string; const
Len: integer; const Ch: Char): string;
{ Semelhante a PadL do clipper }
function tbPadL(const S: string; const
Len: integer; const Ch: Char): string;
{ Semelhante a PadR do clipper }
function tbPadR(const S: string; const
Len: integer; const Ch: Char): string;
{ Replica um caractere n vezes formando
uma string }
function tbReplChar(const Ch: Char; const
Len: integer): string;
{ Replica uma string até atingir o tamanho
especificado }
function tbReplStr(const S: string; const
Len: integer): string;
{ Retorna uma string de N espaços }
function tbSpace(const Len: integer):
string;
{ Forma um número inteiro com zeros à
esquerda }
function tbStrZero(const Value, Len:
integer): string;

implementation

function tbGetShortStr(const S: string;


const Sep: Char): string;
var
I: Integer;
begin
I := AnsiPos(Sep, S);
if I = 0 then
Result := S
else
Result := Copy(S, 1, I - 1);
end;

function tbGetLongStr(const S: string;


const Sep: Char): string;
var
I: Integer;
begin
I := AnsiPos(Sep, S);
if I = 0 then
Result := ”
else
Result := Copy(S, I + 1, High(integer));
end;

function tbPadC(const S: string; const


Len: integer; const Ch: Char): string;
var
I, J: integer;
Pad: string;
Impar: boolean;
begin
I := Length(S);
if I < Len then begin
J := Len - I;
Impar := J mod 2 = 1;
J := J div 2;
Pad := tbReplChar(Ch, J);
Result := Pad + S + Pad;
if Impar then
Result := Result + Ch;
end else if I > Len then begin
J := I - Len;
Impar := J mod 2 = 1;
J := J div 2;
Result := S;
Delete(Result, I-J+1, J);
Delete(Result, 1, J);
if Impar then begin
Dec(I, J * 2);
Delete(Result, I, 1);
end;
end else
Result := S;
end;

function tbPadL(const S: string; const


Len: integer; const Ch: Char): string;
var
LenS: integer;
begin
LenS := Length(S);
if LenS < Len then
Result := tbReplChar(Ch, Len - LenS) + S
else if LenS > Len then
Result := Copy(S, LenS-Len+1, Len)
else
Result := S;
end;

function tbPadR(const S: string; const


Len: integer; const Ch: Char): string;
var
LenS: integer;
begin
LenS := Length(S);
if LenS < Len then
Result := S + tbReplChar(Ch, Len - LenS)
else if LenS > Len then
Result := Copy(S, 1, Len)
else
Result := S;
end;

function tbReplChar(const Ch: Char; const


Len: integer): string;
var
I: integer;
begin
SetLength(Result, Len);
for I := 1 to Len do
Result[I] := Ch;
end;

function tbReplStr(const S: string; const


Len: integer): string;
begin
Result := ”;
while Length(Result) < Len do
Result := Result + S;
Result := Copy(Result, 1, Len);
end;

function tbSpace(const Len: integer):


string;
begin
Result := tbReplChar(#32, Len);
end;

function tbStrZero(const Value, Len:


integer): string;
var
I: integer;
begin
Result := IntToStr(Value);
I := Length(Result);
if I < Len then
Result := tbReplChar(‘0’, Len-I) +
Result
else if I > Len then
Result := tbReplChar(‘*’, Len);
end;

end.
569 - Biblioteca com funções para
Strings
{*****************************************
**************}
{ }
{ Delphi Runtime Library }
{ Windows Messages and Types }
{ }
{ Copyright (c) 1991,96 Walter Alves
Chagas Junior }
{ }
{*****************************************
**************}

unit Strings;

interface

uses
Windows, Dialogs, Messages, SysUtils,
Classes, Controls, StdCtrls, Mask;

function ArredontaFloat(x : Real): Real;


function
RoundNum(Valor:Extended;Decimais:Integer):
Extended;
function
Gerapercentual(valor:real;Percent:Real):re
al;
function IntToBin(Value: LongInt;Size:
Integer): String;
function BinToInt(Value: String): LongInt;
function DecToBase( Decimal: LongInt;
const Base: Byte): String;
function Base10(Base2:Integer):Integer;
assembler;
function DecToBinStr(n: integer): string;
function DecToRoman( Decimal: LongInt ):
String;
function NumToHex(Num: Word): String;
function Min(A, B: Integer): Integer;
function Max(A, B: Integer): Integer;
function IntPrime(Value: Integer):
Boolean;
function strByteSize(Value: Longint):
String;
Function StrToReal(inString :String):
Real;
function BuscaDireita(Busca,Text : string)
: integer;
function BuscaTroca(Text,Busca,Troca :
string) : string;
Function Codifica( const Str1: string):
String;
function ContaCaracs(Edit:String):
integer;
function Empty(inString:String): Boolean;
function LTrim(Texto:String):String;
function Maiuscula(Texto:String): String;
function Padr(s:string;n:integer):string;
function RemoveAcentos(Str:String):
String;
function Replicate( Caracter:String;
Quant:Integer ): String;
function RTrim(Texto:String):String;
function StringToFloat(s : string) :
Extended;
Function Strs(I:longint):string ;
function StrToPChar(const Str: string):
PChar;
function Alltrim(const Search: string):
string;
function
StrZero(Zeros:string;Quant:integer):String
;
function StrZerodec(Numero: Double; Total,
Decimal: integer): string;
function Padl(s:string;n:integer):string;
Function wordcount(str : string) :
integer;
function LineIsEmpty(Text:string):boolean;
function PadC(S:string;Len:byte):string;
function
FullFill(Str:String;FLen:byte;symb:char):s
tring;
function Before(const Search, Find:
string): string;
function after(const Search, Find:
string): string;
function MaskString(Valor: String) :
String;
function Encrypt( Senha:String ): String;
function ExisteInt(Texto:String): Boolean;

implementation

function ArredontaFloat(x : Real): Real;


{Arredonda um número float para convertê-
lo em String}
Begin
if x > 0 Then
begin
if Frac(x) > 0.5 Then
begin
x := x + 1 - Frac(x);
end
else
begin
x := x - Frac(x);
end;
end
else
begin
x := x - Frac(x);
end;
result := x
end;

function
RoundNum(Valor:Extended;Decimais:Integer):
Extended;
{Quando houver,Arredonda uma possivel
terceira casa decimal em uma variável}
var
I:Integer;
Multiplicador:Integer;
begin
if Decimais > 15 then
begin
Decimais := 15;
end
else if Decimais < 0 then
begin
Decimais := 0;
end;
Multiplicador := 1;
for I:=1 to Decimais do
begin
Multiplicador := Multiplicador*10;
end;
Result :=
round(Valor*Multiplicador)/Multiplicador;
end;

function
Gerapercentual(valor:real;Percent:Real):re
al;
// Retorna a porcentagem de um valor
begin
percent := percent / 100;
try
valor := valor * Percent;
finally
result := valor;
end;
end;

// Integer
function IntToBin(Value: LongInt;Size:
Integer): String;
{Converte uma string em binário}
var
i: Integer;
begin
Result:=”;
for i:=Size downto 0 do
begin
if Value and (1 shl i)<>0 then
begin
Result:=Result+‘1’;
end
else
begin
Result:=Result+‘0’;
end;
end;
end;

function BinToInt(Value: String): LongInt;


{Converte um numero binário em Inteiro}
var
i,Size: Integer;
begin
Result := 0;
Size := Length(Value);
for i:=Size downto 0 do
begin
if Copy(Value,i,1)=‘1’ then
begin
Result := Result+(1 shl i);
end;
end;
end;

function DecToBase( Decimal: LongInt;


const Base: Byte): String;
{converte um número decimal na base
especificada}
const
Symbols: String[16] =
‘0123456789ABCDEF’;
var
scratch: String;
remainder: Byte;
begin
scratch := ”;
repeat
remainder := Decimal mod Base;
scratch := Symbols[remainder + 1] +
scratch;
Decimal := Decimal div Base;
until ( Decimal = 0 );
Result := scratch;
end;

function Base10(Base2:Integer):Integer;
assembler;
{Converte uma string em Base 10}
asm
cmp eax,100000000 // check upper limit
jb @1 // ok
mov eax,-1 // error flag
jmp @exit // exit with -1
@1:
push ebx // save registers
push esi
xor esi,esi // result = 0
mov ebx,10 // diveder base 10
mov ecx,8 // 8 nibbles (10^8-1)
@2:
mov edx,0 // clear remainder
div ebx // eax DIV 10, edx mod 10
add esi,edx // result = result +
remainder[I]
ror esi,4 // shift nibble
loop @2 // loop for all 8 nibbles
mov eax,esi // function result
pop esi // restore registers
pop ebx
@exit:
end;

function DecToBinStr(n: integer): string;


{Converte um numero decimal em binário}
var
S: string;
i: integer;
Negative: boolean;
begin
if n < 0 then
begin
Negative := true;
end;
n := Abs(n);
for i := 1 to SizeOf(n) * 8 do
begin
if n < 0 then
begin
S := S + ‘1’;
end
else
begin
S := S + ‘0’;
end;
n := n shl 1;
end;
Delete(S,1,Pos(‘1’,S) - 1);//remove
leading zeros
if Negative then
begin
S := ‘-‘ + S;
end;
Result := S;
end;

function DecToRoman( Decimal: LongInt ):


String;
{Converte um numero decimal em algarismos
romanos}
const
Romans: Array[1..13] of String = ( ‘I’,
‘IV’, ‘V’, ‘IX’, ‘X’, ‘XL’, ‘L’, ‘XC’,
‘C’, ‘CD’, ‘D’, ‘CM’, ‘M’ );
Arabics: Array[1..13] of Integer =( 1, 4,
5, 9, 10, 40, 50, 90, 100, 400, 500, 900,
1000);
var
i: Integer;
scratch: String;
begin
scratch := ”;
for i := 13 downto 1 do
while ( Decimal >= Arabics[i] ) do
begin
Decimal := Decimal - Arabics[i];
scratch := scratch + Romans[i];
end;
Result := scratch;
end;

function NumToHex(Num: Word): String;


//Converte um numero em Hexadecimal
Var
L : string[16];
BHi,BLo : byte;
Begin
L := ‘0123456789ABCDEF’;
BHi := Hi(Num);
BLo := Lo(Num);
result := copy(L,succ(BHi shr 4),1) +
copy(L,succ(BHi and 15),1) +
copy(L,succ(BLo shr 4),1) +
copy(L,succ(BLo and 15),1);
end;

function Min(A, B: Integer): Integer;


{Compara dois valores Retornando o maior
deles}
begin
if A < B then
Result := A
else
Result := B;
end;

function Max(A, B: Integer): Integer;


{Compara dois valores Retornando o maior
deles}
begin
if A > B then
Result := A
else
Result := B;
end;

function IntPrime(Value: Integer):


Boolean;
{Testa se um numero é primo ou não}
var
i : integer;
begin
Result := False;
Value := Abs(Value);
if Value mod 2 <> 0 then
begin
i := 1;
repeat
i := i + 2;
Result:= Value mod i = 0
until Result or ( i > Trunc(sqrt(Value))
);
Result:= not Result;
end;
end;

function strByteSize(Value: Longint):


String;
{Retorna uma conversão de Bytes para
integer}
Const
KBYTE = Sizeof(Byte) shl 10;
MBYTE = KBYTE shl 10;
GBYTE = MBYTE shl 10;
begin
if Value > GBYTE then
begin
Result := FloatToStrF(Round(Value /
GBYTE),ffNumber,6,0)+’ GB’;
end
else if Value > MBYTE then
begin
Result := FloatToStrF(Round(Value /
MBYTE),ffNumber,6,0)+’ MB’;
end
else if Value > KBYTE then
begin
Result := FloatToStrF(Round(Value /
KBYTE),ffNumber,6,0)+’ KB’;
end
else
begin
Result :=
FloatToStrF(Round(Value),ffNumber,6,0)+’
Byte’;
end;
end;

// Strings
Function StrToReal(inString :String):
Real;
{converte um número em Float}
Var
i : Real;
k : Integer;
Begin
Val(inString,i,k);
StrToReal := i;
End;

function BuscaDireita(Busca,Text : string)


: integer;
{Pesquisa um caractere à direita da
string,
retornando sua posição}
var n,retorno : integer;
begin
retorno := 0;
for n := length(Text) downto 1 do
begin
if Copy(Text,n,1) = Busca then
begin
retorno := n;
break;
end;
end;
Result := retorno;
end;

function BuscaTroca(Text,Busca,Troca :
string) : string;
{ Substitui um caractere dentro da string}
var n : integer;
begin
for n := 1 to length(Text) do
begin
if Copy(Text,n,1) = Busca then
begin
Delete(Text,n,1);
Insert(Troca,Text,n);
end;
end;
Result := Text;
end;

Function Codifica( const Str1: string):


String;
{Encripta uma string}
var
Mascara,Str2: String;
PonM, PonS: Byte;
begin
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
begin
PonM:=1;
end;
Result := Str2;
end;
end;

function ContaCaracs(Edit:String):
integer;
{Retorna quantos caracteres tem um Edit
especificado}
begin
Result := Length(Edit);
end;

function Empty(inString:String): Boolean;


{Testa se a variavel está vazia ou não}
Var
index : Byte;
Begin
index := 1;
Empty := True;
while (index <= Length(inString))and
(index <> 0) do
begin
if inString[index] = ‘ ‘ Then
begin
inc(index)
end
else
Begin
Empty := False;
index := 0
end;
end;
end;

function LTrim(Texto:String):String;
{Remove os Espaços em branco à direita da
string}
var
I : Integer;
begin
I := 0;
while True do
begin
inc(I);
if I > length(Texto) then
break;
if Texto[I] <> #32 then
break;
end;
Result := Copy(Texto,I,length(Texto));
end;

function Maiuscula(Texto:String): String;


{Converte a primeira letra do texto
especificado para
maiuscula e as restantes para minuscula}
var
OldStart: Integer;
begin
if Texto <> ” then
begin
Texto :=
UpperCase(Copy(Texto,1,1))+LowerCase(Copy(
Texto,2,Length(Texto)));
Result := Texto;
end;
end;

function Padr(s:string;n:integer):string;
{alinha uma string à direita}
begin
Result:=Format(‘%’+IntToStr(n)+’.’+IntToSt
r(n)+‘s’,[s]);
end;

function RemoveAcentos(Str:String):
String;
{Remove caracteres acentuados de uma
string}
Const ComAcento =
‘àâêôûãõáéíóúçüÀÂÊÔÛÃÕÁÉÍÓÚÇÜ’;
SemAcento =
‘aaeouaoaeioucuAAEOUAOAEIOUCU’;
Var
x : Integer;
Begin
For x := 1 to Length(Str) do
Begin
if Pos(Str[x],ComAcento)<>0 Then
begin
Str[x] :=
SemAcento[Pos(Str[x],ComAcento)];
end;
end;
Result := Str;
end;
function Replicate( Caracter:String;
Quant:Integer ): String;
{Repete o mesmo caractere várias vezes}
var I : Integer;
begin
Result := ”;
for I := 1 to Quant do
Result := Result + Caracter;
end;

function RTrim(Texto:String):String;
{Remove os Espaços em branco à esquerda da
string}
var
I : Integer;
begin
I := length(Texto)+1;
while True do
begin
Dec(I);
if I <= 0 then
break;
if Texto[I] <> #32 then
break;
end;
Result := Copy(Texto,1,I);
end;

function StringToFloat(s : string) :


Extended;
{ Filtra uma string qualquer, convertendo
as suas partes
numéricas para sua representação
decimal, por exemplo:
‘R$ 1.200,00’ para 1200,00 ‘1AB34TZ’
para 134}
var
i :Integer;
t : string;
SeenDecimal,SeenSgn : Boolean;
begin
t := ”;
SeenDecimal := False;
SeenSgn := False;
{Percorre os caracteres da string:}
for i := Length(s) downto 0 do
{Filtra a string, aceitando somente
números e separador decimal:}
if (s[i] in [‘0’..‘9’,
‘-‘,’+’,DecimalSeparator]) then
begin
if (s[i] = DecimalSeparator) and (not
SeenDecimal) then
begin
t := s[i] + t;
SeenDecimal := True;
end
else if (s[i] in [‘+’,’-‘]) and (not
SeenSgn) and (i = 1) then
begin
t := s[i] + t;
SeenSgn := True;
end
else if s[i] in [‘0’..‘9’] then
begin
t := s[i] + t;
end;
end;
Result := StrToFloat(t);
end;

Function Strs(I:longint):string ;
{Converte uma variavel numérica em string}
Var
X : string[16] ;
begin
STR (I,X) ;
Strs := X ;
end ;

function StrToPChar(const Str: string):


PChar;
{Converte String em Pchar}
type
TRingIndex = 0..7;
var
Ring: array[TRingIndex] of PChar;
RingIndex: TRingIndex;
Ptr: PChar;
begin
Ptr := @Str[Length(Str)];
Inc(Ptr);
if Ptr^ = #0 then
begin
Result := @Str[1];
end
else
begin
Result := StrAlloc(Length(Str)+1);
RingIndex := (RingIndex + 1) mod
(High(TRingIndex) + 1);
StrPCopy(Result,Str);
StrDispose(Ring[RingIndex]);
Ring[RingIndex]:= Result;
end;
end;

function Alltrim(const Search: string):


string;
{Remove os espaços em branco de ambos os
lados da string}
const
BlackSpace = [#33..#126];
var
Index: byte;
begin
Index:=1;
while (Index <= Length(Search)) and not
(Search[Index] in BlackSpace) do
begin
Index:=Index + 1;
end;
Result:=Copy(Search, Index, 255);
Index := Length(Result);
while (Index > 0) and not (Result[Index]
in BlackSpace) do
begin
Index:=Index - 1;
end;
Result := Copy(Result, 1, Index);
end;

function
StrZero(Zeros:string;Quant:integer):String
;
{Insere Zeros à frente de uma string}
var
I,Tamanho:integer;
aux: string;
begin
aux := zeros;
Tamanho := length(ZEROS);
ZEROS:=”;
for I:=1 to quant-tamanho do
ZEROS:=ZEROS + ‘0’;
aux := zeros + aux;
StrZero := aux;
end;

function StrZerodec(Numero: Double; Total,


Decimal: integer): string;
{Insere Zeros e decimais à frente de uma
string}
var
TempStr: string;
begin
Str(Numero:0:Decimal,TempStr);
while length(TempStr) < Total do
begin
Insert(‘0’,TempStr,1);
end;
Result := TempStr;

end;

function Padl(s:string;n:integer):string;
// Alinhamento pela esquerda
{alinha uma string à esquerda}
begin

Result:=Format(‘%-‘+IntToStr(n)+’.’+IntToS
tr(n)+‘s’,[s]);
end;

Function wordcount(str : string) :


integer;
// Retorna o número de palavras que contem
em uma string
var
count : integer;
i : integer;
len : integer;
begin
len := length(str);
count := 0;
i := 1;
while i <= len do
begin
while ((i <= len) and ((str[i] = #32) or
(str[i] = #9) or (Str[i] = ‘;’))) do
inc(i);
if i <= len then
inc(count);
while ((i <= len) and ((str[i] <> #32)
and (str[i] <> #9) and (Str[i] <> ‘;’)))
do
inc(i);
end;
wordcount := count;
end;

function LineIsEmpty(Text:string):boolean;
// Testa se uma linha de texto está vazia
ou não
var
i:byte;
begin
for i:=1 to length(Text) do
begin
if Text[i]<>’ ‘ then
begin
result := False;
exit;
end;
end;
Result := True;
end;
function PadC(S:string;Len:byte):string;
// Centraliza uma string em um espaço
determinado
var
Str:String;
L:byte;
begin
str :=”;
if len < Length(s) then
begin
Result := ”;
Exit;
end;
l:=(Len-Length(S)) div 2;
while l > 0 do
begin
str:=str+’ ‘;
dec(l);
end;
for l:=1 to length(S) do
begin
str := str+s[L];
end;
Result := str;
end;

function
FullFill(Str:String;FLen:byte;symb:char):s
tring;
// Preenche o restante da string com um
caractere especificado
var
S:String;
i:byte;
begin
s:=Str;
if Length(s) >= FLen then
begin
Result := s;
Exit;
end;
for i := Length(s) to FLen do
begin
S := S + symb;
end;
Result := s;
end;

function Before(const Search, Find:


string): string;
{Retorna uma cadeia de caracteres
antecedentes a uma parte da string
selecionada}
const
BlackSpace = [#33..#126];
var
index: byte;
begin
index:=Pos(Find, Search);
if index = 0 then
Result:=Search
else
Result:=Copy(Search, 1, index - 1);
end;

function after(const Search, Find:


string): string;
{Retorna uma cadeia de caracteres após a
parte da string selecionada}
var
index: byte;
begin
index := Pos(Find, Search);
if index = 0 then
begin
Result := ”;
end
else
begin
Result := Copy(Search, index +
Length(Find), 255);
end;
end;

function MaskString(Valor: String) :


String;
begin
Result :=
FormatMaskText(‘!aaaaaaaaaaaaaa;0; ‘,
(FormatFloat(‘#,##0.00’,StrToFloat(valor))
));
end;

function Encrypt( Senha:String ): String;


{Encripta uma String}
Const
Chave : String = ‘Jesus’;
Var
x,y : Integer;
NovaSenha : String;
begin
for x := 1 to Length( Chave ) do begin
NovaSenha := ”;
for y := 1 to Length( Senha ) do
NovaSenha := NovaSenha + chr(
(Ord(Chave[x]) xor Ord(Senha[y])));
Senha := NovaSenha;
end;
result := Senha;
end;

function ExisteInt(Texto:String): Boolean;


{Testa se em uma string existe um numero
inteiro valido ou não}
var
i:integer;
begin
try
i := StrToInt(Texto);
Result := True;
except
Result := False;
end;
end;
end.
CD Titulo Conteúdo Valor
Super Coletânea com o que há de
01 Clique Aqui R$ 40,00
melhor
02 Coletânea de Códigos Fontes Clique Aqui R$ 30,00
Apostilas, Tutoriais, Cursos Sobre
03 Clique Aqui R$ 25,00
Delphi
04 Componentes Para Delphi 5 Clique Aqui R$ 25,00
05 Componentes Para Delphi 6 Clique Aqui R$ 25,00
06 Componentes Para Delphi 7 Clique Aqui R$ 25,00
07 Coletânea de Utilitários Clique Aqui R$ 30,00

Verifique aqui o Valor da postagem para seu estado.

Verifique aqui um Exemplo de Compra dos CD´s


Sistema de Brindes
- Na compra de 2 CD´s você leva 1 Brinde de presente;
- Na compra de 3 CD´s você leva 2 Brindes de
presente;
- Na compra de 4 CD´s você leva 3 Brindes de
presente;
e na compra de 5 ou mais CD´s você leva 4 Brindes de
presente!
Envie um e-mail para lloydsoft@uol.com.br e peça (sem
compromisso) a lista de brindes atualizada.
Você pode encomendar estes cd´s pelos e-mails
lloydsoft@uol.com.br ou lloydsoft@ig.com.br
Super Coletânea com o que há de
melhor
- Mais de 240 Apostilas;
Este CD contêm 19 apostilas sobre Visual Basic e
VBScript, 14 sobre Linguagem C e Assembler, 14
sobre HTML e CSS, 11 sobre Java e Java Script, 1
Flash, 10 sobre ASP, PHP, Perl e CGI, 6 sobre
Clipper e Cobol, 11 sobre Projeto e Analise de
Sistemas, 13 sobre Técnicas de Programação, 45
sobre Pascal e Delphi, 24 sobre MySQL, mSQL,
Oracle, SQL Server e Banco de Dados, entre
outras.
Bônus
2 Montagem de micro, 1 Portas paralelas, 1
cabeamento, 2 rede, 1 roteadores, 1 modem, 1
diversos e 1 intranet, entre outras.
- 21 Programas comerciais com
fontes para Delphi 5;
No CD também contêm 21 Sistemas Comerciais,
sem restrições de uso e de revenda, dos mais
requisitados por empresas e escritórios do
mercado.Obtendo este CD você terá o direito de
usar 21 programas de grande utilidade para
automatização da sua empresa além de poder
revendê-los livremente, sem nenhuma limitação.
Acompanha também recebe o código fonte (em
Delphi 5) de todos os 21 programas. Dessa forma
você pode gerar programas personalizados de
acordo com as necessidades da sua empresa ou de
seus clientes. Confira abaixo a lista dos 21
programas comerciais pertencentes ao pacote:
Administração Empresarial, Vendas no Balcão,
Controle de Estoque, Impressão de Requerimento,
Impressão de Darf, Impressão de Holerith, Cadastro
de Clientes, Mala Direta, Contas a Pagar e a
Receber, Administração Escolar, Video Locadora,
Auto Escola, Farmácia, Agenda, Despesas
Domésticas, Editor de Texto, Impressão de
Etiquetas de Código de Barras, Validação CIC,
Validação CGC, Album de Fotos, Impressão de
Declaração de Firma Individual.
- Mais de 700 Componentes
Freeware para Delphi 5;
Componentes FREEWARE de todos os
tipos:Arquivos, Backup, Botões, calendário,
Coleções(x2000, yupack, rxlib275 D4,D5 e D6,
Freelib, etc…), Comunicação internet, Database,
Debugging, Dialogos, Expert components, Forms,
Graficos, grids, grids, impressão, labels, edits, lists,
combs, menus, misc, Ole DDE, panels, sistema,
som, texto, Treeview, utilitários, etc…
- Mais de 100 utilitários Freeware
Utilitários: Mensagens dos Delphi em Portugues
(Versões 1,2,3,4, 5 e 6), Mensagens do Install
Shield em Portugues, Compactador de Executáveis
Delphi ASPACK, Programa para criar e editar
icones e cursores animados, Visualizador de
Arquivos *.PAS (cdview.exe), Visualizador de Banco
de dados (dbinfo.zip), Visualizador de erros
(wincode.zip), banco de dados de todas as cidades
do Brasil, 2 descompiladores
(Descompiler,EXE2DPR,DEDE,ETC), Disassebler
W32Dasm, Delphi Message Assistent, entre
outros… são mais de 100.
Atualizações para o Delphi 4,5 e 6
Interbase 6 - Open Source - Server e Client e
Firebird 1.0
- Mais de 250 pequenos exemplos
(com fonte);
- Clique aqui e veja a lista de alguns dos exemplos
- Mais de 40.000 figuras entre
icones e imagens para uso em
projetos.
- E o mais importante: essa
maravilhosa lista de dicas. :)

Tudo isso em um único CD!!!


Agora pense um pouco…
Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Coletânea de Códigos Fontes
Mala Direta
FTP Completo - semelhante ao CuteFTP e WSPFTP
Compactação ZIP ( idtêntico ao WinZip )
Vídeo Locadora
Cadastro de Clientes
Fluxo de Caixa
Contas a Pagar e a Receber
Envio de E-Mails em grande quantidade
Internet Browser
Controle de Usuários - controle de acessos de
usuários com LOG
Livro Caixa - programa completo para controle de
livro caixa.
QComércio - Controle de Comércio Completo ! - Este
sistema foi desenvolvido para uma empresa que realiza
importação e efetua vendas em todo o Brasil. Destaque
aos seguintes recursos :
- Emissão de cobrança Bancária, Conciliação bancária
- Registro de pedidos
- Registro de Vendas, Comissões e Cadastro de
vendedores
- Emissão de notas fiscais
- Controle de Estoque e muitas outras rotinas
- Clientes
- Vendedores
- Produtos
- Fornecedores
- Usuários com nível de acesso
- Pedidos/Notas Fiscais
Folha de Pagamento (Necessita ReportSmith não
incluso no CD)
Advocacia - Controle completo de processos - Este
sistema gerencia o acompanhamento de processos,
agendas, audiências e arquivamento dos mesmos. É
utilizado atualmente por um grande escritório em São
Paulo e o banco de dados atual gerencia 30 mil
processos com seus respectivos históricos, o que dá
para ter uma idéia da base de dados que já está por
volta de 90 MB.
Atualmente a versão mais nova conta com muitos
outros recursos que não estão incluidos nesta (de
10/10/99) e com banco de dados MS-SQL 7.0. <br>
Características :
Sistema feito em Delphi 3 para uso em rede com 30
usuários (esta versão ainda não contém o
gerenciamento de Rede)
Diferenças para a nova edição :
-Integração com o MS-Word para criação de docs que
acompanham os processos
- Total gerencimamento de usuário e comunicação entre
eles via rede Novell
- Novos modos de pesquisa de processos e
gerenciamento
- Suporte a diversas filiais
- Suporte a Internet
- Módulo para consulta da mesma base de dados na
Internet
- Reparo de muitos bugs no banco de dados e no código
- Maior uso de Instruções SQL em todas as rotinas (no
lugar dos filtros)
- Banco de dados MS-SQL 7.0
Controle de Vendas - Ótimo para aquele que estão
procurando alguma coisa para começar um controle de
vendas. Possui muitos recursos importantes como
gerenciamento de vários usuários, vendedores,
pontuação por vendas, gráficos e um sistema simples de
backup.
Gera Drive - gera mapeamento de unidades de redes
via programação
Balanço Orçamentário - Programa de Balanço
Orçamentário muito bem feito e de ótima interface.
Funcionários - sistema para controle de funcionários
UBackup Pro - Para quem procurava um sistema
completo de Backup aqui está a solução.
SysCheque - Um sistema de cadstro de cheques com
controle de clientes e fornecedores (bem simples).
Sistema de Importação e Exportação - Nesta edição
temos um presentão a você, um Sistema completo de
Importação e Exportação, com os Fontes em Delphi.
Toda sua documentação se encontra junto. É um
sistema quase todo desenvolvido em SQL.
Controle Bancário versões I e II
Controle de Estoque SGE Completo
Sistema de Cadastro de Clientes e Controle de
Estoque
Sistema em Delphi que Simula Envio e Recebimento
de Mensagens por ICQ
Exemplo com Fontes de Definição de Impressora
Mini-Servidor Web utilizando o componente TCPIP -
THTTP
Troca de Pedidos de Produtos via E-Mail
Exemplos de como registrar bibliotecas OCX
Controle de Estoque - D4, D5
ScreenCapture - D4, D5 - Este exemplo, é um Sistema
de Captura de Telas, onde você informa as coordenadas
da tela a ser capturada.
Controle de Farmácia
Oficina de Peças
E Mais:
Mais de 20 sistemas com fontes para tocar,
reproduzir e alterar músicas e vídeos em formato
WAV, MP3, MPEG, etc utilizando a biblioteca
MMTools
Mais de 500 exemplos de dicas, tutoriais com os
fontes. Todos os tipos de exemplos de soluções que
você possa imaginar - Veja ALGUNS DOS
EXEMPLOS ABAIXO :
 Descrição
Completo programa de FTP
Manipulação de Registro
Revela senhas de Asteristico (****)
Programa de Chat, com versão Servidor e Cliente
Programa Hacker de verificação de portas por IP
Exemplo de CD-Player
Exemplo de utilização do DirectX
Exemplo de Sistema de E-Mail
Muito cuidado com estes exemplos - São na
verdade dois exemplos que estão compactados.
Ambos limpam as informações da CMOS.
Este é uma linguagem Script para o Microsof
Windows. Isto é capaz de destruir seu computador,
desde que que você não aceitr scripts de outras
pessoas. O criador deste programa não se
responsabiliza pelos dados que possam causar,
este programa é apenas instrutivo.
Visualiza, Procura e Captura ícones de aplicações.
Visualiza e Captura Icones, é necessário RXLib
Programa que envia mensagens de ICQ
Manipula a CMOS
Outro programinha que manipula a CMOS
Exemplo de Delay
Outro de manipulação de CMOS
Exemplo de criação de links de internet em
formulários
Captura o IP da Máquina
Exemplo bastante interessante, vou deixar que você
mesmo veja!
Mais um exemplo de manipulação de BIOS - CMOS
Mais um exemplo de manipulação de BIOS - CMOS
Exemplo que calcula a virada de um novo ano,
conforme religião ortodoxa… (ridiculo!)
Registra todas os sites visitados em seu
computador.
WebBrowser em Delphi
Exemplo de abrir e fechar o drive de CD-ROM do
computador
Para quem trabalha com desenvolvimento de
Sistemas voltado a internet, vale a pena dar uma
olhada.
Exemplo de sistema de e-mail, para envio de
arquivos atachados
Converte Temperatura de Celsus em Farenait e
vice-verca
Conversor de Metragens
Detecta portas LPT e COM
Proteção de Tela
Um Editor de Textos bem diferente.
Conversor de DBE
Move sua janela
Exemplos de Formulários transparentes
Conecta a servidores e elimina cookies
Editor de Textos, acompanha componentes.
Dial Up em Delphi - Acompanha componente
Programa de discagem com Dial-up… Bom!
Excelente Programa de conversação on-line, como
se fosse um ICQ, com versão Servidor e Cliente…
Exemplo de Jogo, estilo guerra nas estrelas…
combatendo asteróides.
Utilizando botão para apagar os Edits de um
Formulário.
Jogo Tetris
Exemplo de Visualizador de Vídeos AVI
Belo exemplo de calendário
Exemplo de edição e visualização de arquivos
Componente para tratar o Alias do BDE
Programa onde você pode escolher a mudança de
idiomas em tempo real.
Programinha de Datilografia
Componente conversor de Data em Dias
Componente para Icone animado no Formulário
Componente que detecta as portas COM
Programa que executa o Note Pad ou edição do
Autoexec.bat - Inclui componentes
PRograma de Dial Up - Acompanha os
componentes
Programa de Rodar Músicas
PRocura e visualiza imagens em um diretório
Brincadeira de troca de icones na hora de sair do
programa
Learn Sockets - PRograma de redes e conversa em
chat
Exemplo de ADO
Programa que ensina sobre o Registro do Windows
Programa que captura a tela do Desktop
PRograma que captura a velocidade atual de seu
processador
PEga IP das Máquinas conectadas
Ótimo programa de localização e descrição de
arquivos
Cálculos
Exemplo interessante…
Editor de Textos para Pascal
MUITO BOM!! Revela senha de ****
Editor de Textos
Veja por sí só!!
Programa para se cadastrar em diversos Sites de
Busca
Encripta arquivos textos
Captura imagens, conforme coordenadas
Habilita e desabilita as funções do Windows
Extrai ícones de executáveis.
Simples projeto de exemplo que mostra como incluir
imagens em um StringGrid, através do evento
onDrawCell e componente ImageList. Compatível
com o Delphi 3 - Delphi 4 - Delphi 5
Simples projeto de exemplo para efeturar somatório
de horas. Compatível com o Delphi 2 - Delphi 3 -
Delphi 4 - Delphi 5
Simples projeto de exemplo que permite a
passagem de parâmetros entre um formulário e
outro, permitindo dessa forma saber “quem
chamou” o formulário.
Verifica se o projeto já está rodando. Ver rotina no
arquivo .DPR Compatível com o Delphi 3 - Delphi 4
- Delphi 5
Cadastro de clientes. Muito simples.
Mensagem entre micros.
Projeto para soma de meses.
Controle de saldo
projeto com senha
Projeto com tela de splash ( tela de abertura )
Ultimo dia do mes
retorna o usuário da rede
Projeto para visualizar e alterar o tamanho de um
arquivo BMP.
Projeto que explica como criar um sequencia de
numeros em um cadastro sem que o numero se
repita. Com este exemplo você pode controlar por
exemplo uma sequencia de códigos em um
cadastro de clientes.
Exemplo para criação de grupos e ícones.
Exemplo de DDE sendo usado para permitir que
dois aplicativos se comuniquem em uma conversa.
Executa um programa DOS sincronamente.
Rotina para converter textos e numeros para
Hexadecimal em Delphi Compatível com o Delphi 2
- Delphi 3 - Delphi 4 - Delphi 5
Exemplo de utilização de calendário
Converte hora para segundo e segunda para horas
Veja como colocar o ícone de sua aplicação junto
ao relógio da barra de tarefas do Windows 95.
Filtro por mes através da propriedade
OnFilterRecord.
Numero de serie do Winchester para Delphi.
Retorna o path do alias
Exemplo de acesso ao Word via OLE Automation.
Verifica a qual aplicativo um arquivo está vinculando
no Windows através da sua extensão.
Simples projeto de exemplo de envio de e-mail’s
com arquivos anexados que utiliza o OutLook via
OLE Automation, sem abrir o OutLook. Compatível
com o Delphi 3 - Delphi 4 - Delphi 5
Exemplo utilizando componente Treeview para
fazer uma árvore dos diretórios e seu arquivos
Fonte (para ser instalada no Windows) para
geração de códigos de barras, inclui projeto de
exemplo com cálculos necessários para a geração
do código.
Exemplo utilizando componente Treeview para
fazer uma árvore dos diretórios e seu arquivos
Verifica se o Internet Explorer e/ou o Outlook estão
rodando na máquina.
Como retornar a Hora, minutos, segundos e
Milisegundos somente para Delphi5. Neste exemplo
utilizamos o TTimeStamp e o FormatDateTime que
no Delphi5 tem formatação para MileSegundos.
Compatível com o Delphi 5
Obter as informações gravadas no “Info” de um
aplicativo.
Simples projeto de exemplo que mostra como
colorir as células em um StringGrid através do
evento onDrawCell.
Simples projeto de exemplo para fazer manutenção
em alias no BDE, inclui, altera e exclui.
Simples projeto de exemplo de aplicação multi
empresa… Cria um diretório para cada empresa a
partir de um cadastro de empresas.
Força mostrar o hint ao entrar no componente.
Simples projeto de exemplo para alinhar valores a
direita no StringGrid
Simples projeto de exemplo de criação de campos
lookup via programação. Aplicável também a
campos calculados. Compatível com o Delphi 2 -
Delphi 3 - Delphi 4 - Delphi 5
Exemplo muito simples de um sistema com banco
de dados Oracle. Compatível com o Delphi 3 -
Delphi 4 - Delphi 5
Conversor de arquivos DBF para arquivos DB. Com
os fontes.
Retorna o valor do campo autoincremente do
Paradox e atribui novo valor. Compatível com o
Delphi 2 - Delphi 3 - Delphi 4 - Delphi 5
Filtro por pedaço do nome utilizando o evento
OnFilterRecord do componente Table.
Gravar imagens JPG no Paradox. Compatível com
o Delphi 3 - Delphi 4 - Delphi 5
Mostra como adicionar e remover os TFields em um
componente TTable/TQuery em tempo de
execução. Compatível com o Delphi 2 - Delphi 3 -
Delphi 4 - Delphi 5
Simples projetos de exemplo utilizando o banco de
dados Interbase… Stored Procedure, Query com
UpdateSQL e IBX. Compatível com o Delphi 4 -
Delphi 5
Projeto para retornar a linha e a coluna corrente de
um componente DBGrid. Essa linha e coluna
correspondem as linhas e colunas visíveis no
DBGrid. Compatível com o Delphi 2 - Delphi 3 -
Delphi 4 - Delphi 5
Congelar coluna do DBGrid Compatível com o
Delphi 3 - Delphi 4 - Delphi 5
Simples projeto de exemplo que faz o registro do
BDE, gerando uma instalação em apenas 1 disco.
Preparado para Paradox, porém lendo a
documentação que acompanha o projeto é possível
utilizar para outros bancos de dados. Compatível
com o Delphi 2 - Delphi 3 - Delphi 4 - Delphi 5
Instalador do BDE com o DAO para acesso ao
Access. Compatível com o Delphi 3 - Delphi 4 -
Delphi 5
Componentes que acompanham o CD
UBackup Pro v6.5 Src D345
VCLZip v2.21.32 Src D345
MMTools v1.7 (Working by DAFix) Crk D45
Quickreport PowerPack v1.12 Src D5 e C5
Quick Report Professional v3.07 Src D5
Quick Report Professional v3.05 Src D4
ReportBuilder Enterprise v5.0 Src D45
ReportPrinter Pro v3.00G Src D12345 e CB134
Internet Mail Suite v2.02 Crk D5
IP*Works SSL v4.0 Src D345
Abakus VCL v2.01 Crk D45
Varian Led Studio v3.34 Src D345
Envision Image Library v1.1 Src D345 e C4
FreeBarcode v1.16 Src D345
ImageLib Corporate Suite 5 Full D45
ImageEN v1.8 Src D345
TBarcode v3.22 Src D345
TeeChart Professional 4.03 Delphi 5 Src D5
InfoPower Professional 2000.17 Src D45 e C5
LMD Tools 5.01.02 Src D345
RxLib 2.75 Fixed Free D12345
TBarcode v3.22 Src D345
TeeChart Professional 4.03 Delphi 5 Src D5

Observação
Tudo isso em um único CD!!!
Agora pense um pouco…
Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Apostilas, Tutoriais, Cursos Sobre
Delphi
Um Cd especialmente preparado com Apostilas, dicas
de Delphi e ainda algumas apostilas de outros assuntos

Aplicativos de Servidor WEB em Delphi 3


Apostila Borland Delphi windows
Bíblia do delphi
Borland Delphi - Básico
Comandos e funções do Delphi
Como trabalhar com registro do Windows em
Delphi
Criação de Componentes em Delphi
Curso Básico de Delphi 4
Curso de Delphi
Curso de Delphi 3.02
Apostila 4 - InstallShield
Curso Delphi II
Delphi Avançado
Delphi 4 - Curso Básico
Apostila de Delphi 5
Delphi 5 - Novos recusos
Delphi Básico
Apostila de Delphi - Desvendando o Caminho das
Pedras
Curso Completo de Delphi 5
Apostila Ilustrada Delphi
Delphi e SQL - Delphi e Internet e o uso
inteligente dos componentes
Delphi em 10 capítulos.
Delphi Park - Tutorial
Estudo dirigido a Delphi
Installing BDE Applications & Network Installation
of Delphi-Inglês
Linguagem Técnica de Programação Delphi
Manual de programação em Delphi
Manual Delphi 4
Trabalhando com arquivos INI no Delphi
Trabalhando com DLL’s no Delphi
Tutorial Delphi
Apostila de Banco de Dados
Utilização do Delphi em Rede utilizando tabelas
Paradox
Utilização do Delphi em Rede utilizando tabelas
Paradox - II
Apostila de Liguagem SQL Oracle
Manual Completo do MySQL ( Inglês )
Curso de SQL
Configurando uma rede local com acesso a
Internet
HOWTO de Firewall e Servidor Proxy
TCP-IP Tutorial
Modelagen de Dados
Apostila e Curso Microsoft SQL Server 6.5
Apostila e Curso Microsoft SQL Server 7.0
Curso de Comandos SQL padrão ANSI 92
Curso Interativo sobre Banco de Dados
Curso Básico de SQL - Oracle
Diferenças entre o ORACLE e o SQL Server 7.0
Curso completo de SQL Server
Curso de Interbase
Cursos Completíssimo de Interbase e liguagem
SQL ( EXCELENTE )
Guia da Linguagem SQL ( Comandos, Variáveis,
Exemplos, etc )
Guia de Referência de SQL com todos os
comandos padrão ANSI92
Curso sobre Banco de dados, SQL e SGBD
Visão geral do SQL Server
Curso de Engenharia de Software
completo que aborda:
- Análise de Requisitos, Análise Essencial, Análise
Estruturada, Análise Orientada a Objetos, Análise
Orientada a Objetos utilizando UML, Engenharia de
Software, Ferramenta CASE, Garantia da Qualidade de
Software, Gerenciamento de Mudanças ,Modelagem de
Dados e Formas Normais, Modelagem de Processos,
Modelos ,Práticas XP, Projeto de Sistemas de Software,
Qualidade do software, Reutilização e
Componentização, Técnicas para Mensuração de
Software, Testes de Software Estratégias e Técnicas;
Dicas, Exemplos, Funções, etc

Geral
Uma calculadora “Pauleira!”
CooCalc
Exemplo de um programa de E-Mail
EMail
Como obter a diferença entre duas Datas e Duas horas
DifData
Exemplo de como obter a distância em metros.
Distancia
Exemplo de como somar meses à uma data especificada
SomaMes
Exemplo de como obter o último dia do mês
Ultdia
Exemplo de um Calendário muito bom
Calendar
Como chamar uma calculadora
NewCal
Exemplo de como usar CGI no delphi
CgiDelphi
Como fazer dois computadores se comunicarem entre si
DDE
Como converter horas em segundos e segundos em horas
HoraSeg
Programa de manipulação de mensagens em rede
Mensagens
Um Relogio Bacana
Relógio
Exemplo de um FTP com Delphi
FTP
Exemplo de Macrosubstituição
MacroSubst
Exemplo de chat
Chat
Um bom exemplo de Calculadora
Calculadora
Um utilitário para manipular código fonte pascal
CodeApp
Exemplo de um encriptador de dados
Cryt
Exemplo de como manipular os cursores do mouse
DemoCursor
Exemplo de como criar um programinha de instalação
Install
Exemplo de como não permitir que seu demo rode fora do
Register
Delphi
Rescalc
Tabela de código de cores para resistores
Factorial
Exemplo de como trabalhar com um Fatorial.
Calendario
Um modelo de calendário
InvaDate
Exemplo básico de como tratar datas inválidas
OpArit
Exemplo de como trabalhar com operadores aritméticos
Classref
Exemplo de manipulação de classes

Componentes
Calorias Exemplo de como fazer a comunicação entre dois ListBox
ComboActive Exemplo de como deixar um Combobox aberto
EditChange automáticamente
CursorMemo Como fazer uma pesquisa em um Listbox através de um
Combinação Edit
Lista Como obter a posição do cursor em um componente
Marquee TMemo
Selecao Exemplo de como retornar o item de um Combobox
Mirror Exemplo de como inserir um item em um listbox
QuickReport Exemplo de como criar um Banner controlado
Relatorios Exemplo de como Selecionar um item de um listbox
CriaComp Exemplo de um Espelho muito “Doidão”
CombSgrid Varios exemplos para você fazer relatórios com o
QuickReport
MoveRuntime Como trabalhar com relatorios via QuickReport ou
ScrolList Tprinter
TreeView Como criar um componente em tempo de execução
Parser Como inserir um ComboBox dentro de um StringGrid
DragDrop Como mover um componente em Run-Time
DragDropDem Como colocar um ScrollBar em um componente ListBox.
DragDrop1 Exemplo de como usar o TreeView
DragDrop3 Como enviar o conteúdo de um Edit para um MEMO
DragDropTB Exemplo do método DragDrop
DemoCursor Outro exemplo do método DragDrop
FlyToolBar Outro bom exemplo de como usar o Evento Drag’n Drop
LinColMemo Outro bom exemplo de como usar o Evento Drag’n Drop
MenuEx97 Exemplo de como arrastar um botão para a Barra de
SpeedButton ferramentas
ExTrview Exemplo de como manipular os cursores do mouse
ComboOpen Exemplo de como criar uma barra de tarefas flutuante
Contagem Exemplo de como obter linha e coluna em um Memo
Eventos Exemplo de como fazer um menu igual ao do Office 97
OpClass Um bom exemplo com os SpeedButons
CommMemo Outro exemplo de como usar o TreeView
DBLookUpGrid Exemplo de como Abrir um Combobox em Run-Time
ComboLarge Exemplo de como Contar os caracteres de um TMemo
IconeNoButton Exemplo de como Trabalhar com os eventos do
ListHorizontal componente
Menuprj Exemplo de como obter o nome da classe de um
componente
Exemplo de como fazer um Memo se comunicar com
outro
Como Incorporar um DBLookUpCombobox em um
DBGrid.
Exemplo de como Expandir a lista do Combobox.
Exemplo de como inserir um icone em um TButton
Exemplo de como colocar um ScrollBar horizontal no
ListBox
Exemplo de como inserir Bitmaps no fundo do menu

Forms
LabelMovel Exemplo de como fazer um banner em um form
FormTotal Exemplo de como criar um Form em tela cheia
ParametForm Exemplo de como passar parâmetros de um form para
VarInvisible outro
FormDinamic Como manipular variaveis entre dois ou mais forms
ClipBoard Como criar formulários dinamicos
DibTest Como colar no form, uma figura da area de transferência
BitmpaForm Exemplo de como criar um Form Exótico
RestrictSize Como colocar um bitmap lado a lado no fundo de um
CircleForm form
FrameForm Exemplo de como bloquear o redimensionamento do Form
Poligon Exemplo de como criar um form circular
PopUp Exemplo de como colocar frames em um form
DifLinhas Exemplo de como desenhar um poígono em um form
FormBitmap Exemplo de como criar um menu PopUp em um form
TBitmaPlus Exemplo de como desenhar linhas no form
FormTake Como colar um Bitmap no fundo do Form pela API do
CopyClipBrd Windows
MoveForm Outro exemplo de como colocar um Bitmap no fundo do
ScreenSBit Form
RolupForm Como suspender a animação de minimizar e maximizar o
RotateCube form
Region Exemplo de como copiar o Form para a área de
SineWave transferência
DfmToTxt Como mover um form clicando em qualquer lugar nele
ClasProc Exemplo de como carregar Bitmpas no Form
Invisible Como criar um Form que role na tela semelhante à uma
persiana
Random
Work Exemplo de como criar um cubo rotatório no form
Como obter posições de figuras no form com o mouse
Mousmove
Exemplo de como desenhar ondas senoidais no Form
CriaRuntime
CenterForm Este Exemplo converte e exibe um arquivo DFM no modo
TXT
NDragDrop
Exemplo de como Manipular Classes no Delphi
FormProps
Exemplo de como fazer um form invisível
Syscomand
Exemplo de como produzir recursos animados em um
DrawForm
form
NoTarget
Exemplo de como trabalhar com uma thread.
CapButton
Exemplo de como obter a posição do mouse em um Form.
Params
Exemplo de como criar um Botão no Form, em Run-Time.
CloneIco
Exemplo de como centralizar um Form em Run-Time
Estrela
Outro Exemplo de Drag-drop
ExecutaCom
Outro Exemplo obter as propriedades de um Form
splash
Exemplo de como fazer todos os forms minimizarem
TituloForm
juntos
Exemplo de como Desenhar formas do form
Exemplo de como Ocultar e exibir um aplicativo.
Exemplo de como Colocar um botão na barra de título do
form.
Exemplo de como Passar parâmetros de um Form para o
projeto.
Exemplo de como clonar um Icone em um form
Exemplo de criar um form em formato de estrela
Como executar comandos Dos e formatar a saida deles
no Form
Exemplo de como gerar um Splash form em seu aplicativo
Exemplo de como colocar um titulo diferente no form

Arquivos
W95Files Um Bom exemplo de como copiar arquivos
CompareFile Exemplo de como comparar dois arquivos linha a linha
Win95files Mais dois exemplos de como copiar arquivos
TextFile Exemplo de como manipular um arquivo Texto
Search Exemplo de como procurar um texto em um arquivo
FileCompare Exemplo de como comparar dois arquivos
WFileList Exemplo de como exibir os arquivos em uma janela
AviCreate Exemplo de como criar um arquivo .Avi em codigo Delphi
DirList Como efetuar uma procura de arquivos em um diretorio
Wntdy202 Exemplo de Busca e deleção de arquivos
CopyFiles Um Bom exemplo de como copiar arquivos
Attribute Exemplo de um gerenciador de atributos de arquivos
IniFile Exemplo de como gerar um arquivo INI
catlst_s Como criar aquivos Help a partir de um Arquivo RTF
dcrfix Corrige arquivos DCR danificados por Bug no ImageEdit
Url2html Como inserir as URL´s dos “Favoritos” em um arquivo
Dropfile HTML
Exinifile.zip Arraste um arquivo para o form e veja seu nome sendo
MiniDir exibido
VisualPas Exemplo de como obter dados de um Arquivo .ini
EArquivos Exemplo de como criar uma lista de arquivos de uma
HtmlCoder unidade
Resmaker Exemplo de como visualizar um arquivo Texto em um
TextDemo Memo.
VolInfo Exemplo de como carregar um arquivo Texto em um
TMemo
Exemplo de como Converter um Arquivo texto em HTML.
Ferramenta para criar arquivos .RES
Exemplo de como carregar um arquivo Texto em um
TMemo
Exemplo de como Obter todas as informações de um
Drive.

Sistema
1vez Exemplo de como executar o aplicativo somente uma vez
AnimCursor Classe que usa um cursor no estilo do Windows NT
bios Exemplo de como obter o numero da Bios de seu
Empresa sistema.
Ambiente Como obter o nome do usuário registrado no windows
Ras Exemplo de como obter dados do Ambiente do
OSVersion Dos/Windows
TaskList Excelente programa de Conexão Dial-up (c/Fontes)
TipoDrv Exemplo que retorna diversas informações do sistema
WindFlag Exemplo de como criar uma lista de tarefas
WinMsg Como obter os Drives do computador em TMemo
ResWatch Como obter dados da CPU em um componente TMemo
CriaGrupo Exemplo de como enviar mensagems para o Windows
SysInfo Como obter os recursos do sistema
ChangeRes Como criar grupo de programa e ícones
CpuIdent Exemplo de como obter os dados do sistema
CriaAtalho Exemplo de como trocar automaticamente a resoluçào do
DiskBeench vídeo
MapMemory Exemplo de como obter dados da CPU
PortTest Exemplo de como criar um atalho no Windows
SendMessage Exemplo de como Testar a velocidade de um drive
Serial D1 Exemplo de como A memoria é mapeada
Conecta Exemplo de como testar uma porta serial em seu
DefaultPrn computador
GetDriveSpace Exemplo de como enviar mensagens para o Windows
Modemsyp Como obter o numero serial do HD no Delphi 1
Memory Ccomo acessar sua conexão Dial-up através do Delphi
Version Exemplo de como alterar a impressora padrão do
RasApi Windows.
TestDial Como obter o espaço em disco formatado com a FAT32
Icmp Programa que acessa o seu modem
Testport Exemplo de como exibir dados da memória no Form
cursor.zip Exemplo de como exibir informações internas de um
dlg_demo arquivo
bk1sys Exemplo de como usar os recursos do Dial-up com o
Reg Delphi
FDrive Como usar os recursos da Discagem automática com o
MonitorOnOff Delphi
BandejaCD Exemplo de como “Pingar” uma estação
SSEnable Exemplo de como se comunicar com uma porta serial
TempoDecor Exemplo de como trocar o cursor do mouse em uma
aplicação
Screen
Exemplo de como usar as mensagens de aviso no Delphi.
ShiftState
KeyChange Exemplo de como obter mensagens em um TMemo.
Exemplo de como obter chaves no registro do Windows.
TrayApp
Este exemplo diz que formata até a unidade C Voce
TimeOut
arrisca?
MenuChoice
Exemplo de como desligar o Monitor via Delphi
OnShow
Exemplo de como abrir e fechar a bandeja do CD-Rom
TApiDialup
Exemplo de como habilitar o Scren Saver do Windows
IconHide
Exemplo de como obter o tempo que o programa esteve
MouseConfig
aberto
TaskApplic
Exemplo de como trocar a fonte e o cursor em um
TreeScan
aplicativo
wSC Exemplo de como obter o estado de certas teclas
WordTest
Exemplo de como ativar e desativar teclas via Delphi
Exemplo de como Minimizar a aplicação na barra de
tarefas
Exemplo de como fechar um aplicativo depois de um
certo tempo
Exemplo de como Inserir um Item no Menu do sistema
Exemplo de como Ocultar e exibir um aplicativo.
Exemplo de como usar a discagem automática via Delphi.
Exemplo de como ocultar o aplicativo
Exemplo de como configurar os botões do Mouse via
Delphi
Como minimizar seu aplicativo à um Icone na barra de
tarefas
Como obter a estrutura de um diretorio atraves de um
Treeview
Bibliotecas com recursos para voce acessar as portas
seriais
Como fazer seu aplicativo se comunicar com o Wodr

Tabelas
DBpTXT Como converter uma tabela paradox em Txt e vice versa
TabHtml Gera um codigo HTML para exibir uma tabela no browser
Inmemdel Exemplo de como Copiar dados de uma tabela para outra
Filter Exemplo de como trabalhar com filtros em tabelas
Filtro Outro exemplo de como trabalhar com filtros em tabelas
findnear Exemplo de como trabalhar com o FindNearest em
TableGenerate tabelas
TableScanner Gera um código para criar uma tabelas
GetStructure Outro gerador de código para criar tabelas
DbfToSql Extrai a estrutura de uma tabelas Paradox
NdxBuild Importa dados de um DBF para um Interbase SQL
KeyViolation Exemplo de construtor de índices NDX
Convet Exemplo de como tratar a Exceção KeyViolation
Pedaço Conterte Tabelas Dbase em Paradox
Relaction Como filtrar uma tabela por partes de um dado
DBGrid Exemplo de como relacionar tabelas em Delphi
CorGrid Como retornar a celula ativa de um DBGrid
BotNavigator Como mudar a cor de uma célula de um DBGrid
Reindex Como Navegar por uma tabela com a filosofia do
DBDragDrop DBNavigator
LiveQuery Pequeno programinha para reindexar tabelas (C/Interface
MSelDBGrid e tudo)
CopySort Exemplo do método DragDrop aplicado em uma tabela
CreateData Exemplo de Uso de Filtro em um Query
IReferencial Exemplo de multiseleção em um DBGrid
JPEGPdx Exemplo de como copiar tabelas cheias
Addpswd Exemplo de como criar uma tabela
Delcfg32 Como manipular a integridade referencial de uma tabela
TestGIF Exemplo de como guardar imagens JPG em uma tabela
ThExeption paradox
DBDemo Exemplo de como Manipular Senhas em tabelas
TUtil Programa que permite voce manipular dados no BDE via
Delphi
CriqArquivo
SQLDemo Exemplo de como Manipular imagens Gif
Exemplo de como tratar exeções
DataExplorer
Bom Exemplo de como trabalhar com tabelas, no geral.
PkParadox
Recno Como usar a Tutil32.dll para consertar Tabelas paradox.
Exemplo de como criar uma Tabela em tempo de
Sharedm
execução.
lookup
Exemplo para iniciantes de como usar uma Query/Sql c/o
Pwh
Delphi.
CampoCalc
Como usar um Treeview para exibir os dados de uma
ThrQuery
tabela.
Calc
Exemplo de como dar um pack em uma tabela paradox.
Cop_sor
Exemplo de como obter o registro corrente da tabela.
DBFQuery
Como Fazer uma edição de dados a partir de um DBGrid.
DBGridcombo
Exemplo de como trabalhar com uma thread.
Gensql
Programa que rastreia senhas em tabelas Paradox.
RefInt Exemplo de como trabalhar com campos calculados
Exemplo de como trabalhar com Query’s
Exemplo de como manipular campos calculados
Exemplo de como copiar dados de uma tabela para outra
Exemplo de passar parametros para uma Query
Exemplo de como colocar um ComboBox em um DBGrid
Programa que gera Instruções SQL
Como trabalhar c/a integridade referencial de uma tabela

Variáveis
Maior Exemplo de como comparar dois números
Round Como manipular variáveis de ponto flutuante
AsciiConv Exemplo que retorna o valor Ascii de um caractere
Translate Exemplo de como converter um Numero em seu extenso
Uint Programa que faz diversas operações com numeros
FmtTest Exemplo de como formatar dados

Multimídia
Exemplo de como usar o componente Media Player
MPlayer
Outro exemplo de como usar o componente Media Player
XPlayer
Exemplo de como fazer um CD-Player
CD-Player
Exemplo de como incomporar um Arquivo Wav no
SoundExe
Executável
Media
Programa que toca CD
MMvolume
Programa que altera o volume de sua placa de som
WaveRec
Programa gravador de Wave totalmente escrito em Delphi

Gráficos
Exemplo de como manipular Gráficos
Grafics Exemplo de como colocar Bitmaps em um Menu
Exemplo de como manipular imagens Gif’s inclusive
MenuBitmap
animados
GifMAnager
Exemplo de como converter um ícone em um Bitmap
IconToBmp
Dll para ser inserida no Explorer. Exibe os dados de um
BmpProp
Bitmap
BtListBox
Como colocar bitmaps em um ListBox e em um ComboBox
MixUp
Exemplo de como desmontar um Bitmap
MoveIcon
Exemplo de como colocar um Icone animado em um form
PieChart
Exemplo de como usar o TChart
TstPr2Fm
Imprime um Bitmap e todas as suas características
RtfToBmp
Exemplo de como converter uma string em Bitmap
Bmp2Tiff
Pequeno pograminha que converte Bitmaps em Tiff´s
BmpGrabb
Programa que pesquisa o HD a procura de ícones
Bmpmenu
Exemplo de como criar menus com glyphs
clipprinter
Exemplo de como imprimir o conteúdo da área de
glyphpro
transferência
glypht Demo para catalogar Glyphs
glyphv11
Outro Demo para catalogar Glyphs
Dragicon
Outro Demo para catalogar Glyphs
Poster Arraste um executável para a janela e extraia seus icones
BmpDraw
Exemplo de como gerar uma imagem a partir de um Edit
Exemplo de como desenhar um bitmap em um form

Sistema
SysDateTime Permite que você altere a data e a hora do sistema
RemoveChave Remove um valor de uma chave do registro
eSetCDAutoRun Ativa o “AutoRun” no Windows.
DelphiCarreg Funções que verificam se o delphi está carregado ou
CloneProgram não
GetCpuSpeed Gera um clone do aplicativo
CPUSpeed Retorna a frequencia do processador usado
TipodeDrive Retorna a velocidade do processador
DetectaDrv Retorna o tipo de unidade referente a letra
DiscoNoDrive especificada.
PercentDisk Verifica as unidades que existem no computador
ExisteDrives Verifica se há disquete no Drive especificado
NumCores Retorna a porcentagem de espaço livre em um Drive
IsPrinter Retorna todos os drives existentes na maquina.
CorrentPrinter Retorna o número de cores da resolução atual.
NumSerie Testa se a impressora está ativa ou não.
TestaPlaca Retorna a impressora padrão do windows.
ShutDown Retorna o Número serial da unidade especificada
KeyLeads Testa se o seu computador possui uma placa de
WindowsDir som.
SystemDir Faz uma reinicilização do computador
TempDir Verifica as teclas Caps, Scroll e NUM sem usar o
SetTaskBar Timer
GetDosEnv Retorna o diretorio onde o windows está instalado
BiosDate Retorna o subdiretorio system do windows
GetPrintN Retorna o Diretorio Temp do Windows
IsTaskbarHid Oculta ou Exibe A Barra de Tarefas
GetMemTP Rotina de resgate das variáveis de ambiente DOS
Portas Retorna a data da fabricação do chip da bios
MemoryReturn Retorna o nome da impressora padrão do Windows
SetWallpaper Verifica se a barra de tarefas do Windows está oculta
ExecExplorer ou não
RControlPanel Retorna a quantidade de memoria que o computador
SWCWin possui
Duas funções que se comunicam com portas seriais
OpIExplorer
Retorna varias informações sobre a memoria do
NetGotoURL
sistema
ROnStartup
Troca o papel de parede do Windows
FormResize
Executa o Windows Explorer a partir de uma
LBClipBoard
determinada pasta
CheckPentium
Executa um módulo do painel de controle (Arquivos
Executa
.CPL)
RetornaBit
Alinha um form baseado nas coordenadas de um
GetBrowser outro
SetJustify Executa o Internet explorer a partir de uma URL
WinCloseProg requerida
CrDisabledBitmap Executa o Netscape a partir de uma URL requerida
DrawTrans Insere um chave no Registro para executar algum
QChangeRes programa
DyResolution Permite que seu form exiba, com fundo, a tela do
TurnOffKey computador
TestaPlaca Envia o conteúdo de um ListBox para a área de
SizeForTaskBar transferência
LetraCDROM Testa se seu processador pentium tem o Bug fatal
CloseCD Executa um programa e espera sua finalização
EjectCD Retorna o valor de cada bit de um determinado byte
LastPos Retorna o Path de seu Browser padrão
IsWindowInMemory Alinha o Menu para a direita do form
ExecuteFile Fecha um aplicativo via Delphi
ExecutaApp Cria um clone Monocromático de um outro Bitmap
EscondeIniciar Redesenha um bitmap trocando a cor da linha do
DiskSpace desenho
Delay Procedure que troca a resolução do seu video
AppIsRunning Função que troca a resolução do seu video
DiskExists Desliga uma Tecla
IsDriveCD Testa se existe uma placa de som no seu
IsFloppy computador
IsNT Expande o Form para a area total da tela
LeMCI Retorna a letra atribuida a unidade de CDRom
MandaMCI Fecha a bandeja do CD-Rom
GetTState Ejeta a bandeja do CD-Rom
CaptureScreenRect Retorna a última posição encontrada em uma string
EnumWindowsProc Testa se a janela ja foi criada
ExploreWeb Executa um aplicativo, já abrindo um arquivo anexo
FileExec Executa o aplicativo somente se ele não estiver
GetExe aberto
GetExetype Oculta/exibe o botão “Inciar” da barra de tarefas
RodaPrograma Retorna o espaço livre em disco
CDinCDROMDrive Promove um estado de espera no aplicativo
OpenCdTray Testa se a sua aplicacao já esta sendo executada
RunOnStartup Testa se existe um disco no Drive especificado
OpenIExplore Testa se a unidade especificada é um CD-Rom
AjustaPapel Testa se a unidade especificada é um Floppy
InfoSys Testa se o sistema operacional é o Windows NT
TarjaLateral Le o Retorno de um Comando MCI
Envia um Comando para um Dispositivo MCI
Testa se uma certa tecla está pressionada ou não
Captura a tela atual em uma área retangular
Retorna todos os programas que estão abertos na
memoria
Executa uma URL a partir do Browser padrão
Tenta executar um programa
Retorna o path do aplicativo que está associado a
um arquivo
Retorna o tipo de executável que é o arquivo.
Tenta executar um programa
Testa se tem CD no CD-Rom.
Abre a bandeja do CD-Rom
Insere um programa na chave “Run” do Registro
Executa uma URL a partir do Internet explorer
Determina um número de cópias para a impressão
Retorna diversas informações do sistema
Gera, no form, uma tarja lateral com um texto

Componentes
AjustaForm Ajusta um form conforme a resolução do monitor
LimpaEdit Limpa Todos os Edit’s de um Form de uma só vez
AddButtonNB Adiciona um botão em um TNotebook
AddButtonTB Adiciona um botão em um TabbedNotebook
Titulo Alinha o título da barra de títulos a Esquerda ou a
ChFBlankText direita
ExportaBMPtoWMF Avisa se algum Edit no formulário não foi preenchido
GetMemoSize Exporta uma imagem de um TImage para um arquivo
StrIsInList Retorna o tamanho de um campo memo.
Insere um Item em um Listbox ou Combobox.

Rede
Redireciona a porta de impressora em tempo de
execução
NetMapPrinter Mapea um Drive de rede via programação
MapeaRede Disconecta uma unidade mapeada via programação
DesconectaRede Retorna o nome do usuário logado na rede (Via
LogUser registro)
WinLogin Retorna o nome do usuário logado na rede (Via
MapeaPasta Sistema)
GetHostName mapea uma pasta via programação
GetIP Retorna o Host onde seu TCP/IP está conectado
LocalIP Retorna o IP da máquina que está conectada
GetNetStation Retorna o Endereço IP de uma maquina
NomeComputador Retorna informações sobre o Computador na rede
NomeDoComputador Retorna o nome da estação na rede
GetNetworkMaps Retorna o nome da estação na rede
Retorna as unidades mapeadas na Estação com
seus paths

Data e Hora
DiasNoMes Retorna quantos dias tem um referido mes do ano
AddicionaHora Adiciona à hora atual um determinado numero de horas.
DifHoras Retorna a diferença entre duas horas
DifDias Retorna a diferenca de dias entre duas datas
DifDateUtil Retorna a quantidade de dias uteis entre duas datas
DateMais Soma um determinado número de dias à data atual
DiaSemana Retorna o dia da semana em Extenso de uma
NomeDoMes determinada data
NumDiasExt Retorna o nome do mes, em extenso, de uma
DataExtenso determinada data
Year Retorna o número de dias calculados em extenso
UltDiadoMes Retorna o extenso de uma determinada data
Minutos Retorna o ano de uma determinada data
Horas Retorna o Ultimo dia do mes de uma determinada data
PeriodoMes Retorna os minutos de uma determinada hora
CorrigeData Retorna a hora de uma determinada hora
AnoBis Retorna o numero correspondente ao periodo
Bug2000 Retorna o ultimo dia de um determinado mes
Datafinal Testa se o ano é Bissexto ou não.
ConverteData Testa se o Windows está preparado para o ano 2000
ChDateFormat Retorna uma data acresçida de um certo número de dias
AjustaData Insere em uma data, um caractere separador
IdadeN Converte o caractere separador de datas para o
IdadeAtual caractere “-”
WeekNum Corrige a data ajustando o ultimo dia do mes
RetornaMes
ProximoDiaUtil Retorna a idade de uma pessoa a partir da data de
PrimeiroDiaUtil nascimento
IsWeekEnd Retorna a idade de uma pessoa a partir da data de
HoraValida nascimento
HoraToMin Retorna quantos fins de semana já se passaram no ano
DiaUtilAnterior Retorna o Extenso do mes da data especificada
DataValida Retorna o próximo dia útil de uma a data
Retorna data do primeiro dia Util do mes
Verifica se uma data cai em um final de semana
Testa se uma string no formato Hora é valida ou não
Converte hora (formato HH:MM) para minutos
Retorna o Ultimo dia Útil de uma data
Testa se uma data é valida

Validação de dados
Testa se uma string pode ser convertida em numero
inteiro
ExisteInt Testa se o CPF é válido ou não
TestaCPF Testa se o CGC é válido ou não
TestaCGC Checa se o Pis é válido ou não
ValidaPis Testa se uma data é válida ou não
ValiData Checa se o Simbolo da UF é Valido
ChecaEstado Testa se o dado é um digito (numero) ou um caractere
Isdigit.zip qualquer
IsImPar Testa de um valor Integer é Impar
IsPar Testa de um valor Integer é par
IsInteger Testa se uma String pode ser convertida em formato
IsAM integer
isStrDateTime Testa se a hora é antes de Meio dia
Testa se uma String pode ser convertida em formato
Data

DataBase
CheckState Checa o estado de uma tabela
AliasCreate Cria um determinado alias temporário
CriaTabela Cria uma tabela
CriaAlias Cria um alias no BDE em tempo de execução
CriaTab Outra função para criar tabelas
AMasterPass Inclui uma senha em uma tabela paradox
RMasterPass Remove uma senha em uma tabela paradox
EsvaziaTabela Esvazia uma tabela especificada
CriaIndice Permite que seu DBF ignore o indice MDX e recrie-o
TipoIndice Retorna de que tipo é o índice especificado
GetPathDoAlias Retorna o Path do Alias
pathalias.zip Outra função que Retorna o Path do Alias
IsRecLocked Testa se um Registro está travado
NumReg.zip Retorna o número do registro atual em tabelas .DB ou
TableCopiReg .DBF
CreateATable Copia todos os registros de uma tabela para outra
DBLoadListQry Cria uma tabela
DBLoadListTbl
FRecno Carrega em um ListBox, os registros de um campo da
LockPDXTable tabela
ValidaCampo Carrega em um ListBox, os registros de um campo da
SetShare tabela
SetAlias Retorna o registro corrente da tabela
RLock Bloqueia uma Tabela paradox.
LockTable Valida campos impedindo a inserção de dado
TableUnlock duplicado
IsRecordLocked Altera o Local Share Via programação
fDbiGetSysVersion Cria um alias em tempo de execução
SetDelete Testa se o registro está travado ou não
TablePack Testa se a tabela esta bloqueada ou nao
DBasePack Desbloqueia uma tabela
AbreExclusivo Testa se o registro da tabela está travado ou não
Retorna informações sobre a versão usada do BDE
Permite que a tabela exiba os registros deletados
Dá um pack em uma Tabela
Efetua um pack em tabelas Dbase
Tenta abrir uma tabela em modo exclusivo

Manipulação de arquivos
DeleteDir Apaga um diretório com todos os seus arquivos.
FDirList.zip Pesquisa arquivos retornando-os em um StringList.
FileCopy Copia um arquivo de um lugar para outro
CopyFile Procedure que copia um arquivo de um lugar para
DirSize outro
NLinhasArq Retorna o Tamanho de um diretório
WinExeWait Retorna o número de linhas que um arquivo possui
PrintImage Executa o aplicativo finalizando-o corretamente apos
ZapFiles o uso.
RecycleBin Tenta imprimir um bitmap selecionado
FillDir Apaga arquivos usando mascaras tipo: *.zip, *.*
ExtractName Envia um arquivo para a lixeira. Requer a unit
FileTypeName Shellapi
CShortcut Retorna todos os arquivos localizados no path
ConverteParaUrl corrente.
DeleteFile Retorna o nome do Arquivo sem extensão
GFLAcTime Retorna descrição do tipo do arquivo. Requer a unit
ShellApi
ProcArq
ProgPath Permite que voce Crie atalhos no Windows
Converte o nome de um arquivo para uma URL
GetFileList
Deleta um arquivo
BarraInvert
FindReplace Retorna a hora do último acesso à um arquivo.
ExecFile Copia ou move arquivos usando a API do Windows
Retorna o Path de onde o programa está sendo
DirList.zip
executado
RemExtens
Retorna um StringList com todos os arquivos de um
SHCopyFiles
diretório
FErase
Insere uma barra invertida após um nome
CriaDir
especificado.
FileVerInfo
Substitui uma string em um campo memo/DBmemo
LoadJPEG Executa um aplicativo Associado
SaveJPEG
Pesquisa arquivos retornando-os em um StringList.
Deltree Retorna o nome do arquivo especificado sem a
IsFileInUse extensão
MkSubDir Copia um arquivo via API do Windows
EditaArq Apaga um arquivo especificado
Cria um diretório
Obtem diversas informações de um arquivo
executável
Carrega uma imagem Jpg
Salva uma imagem Jpg em um arquivo.
Apaga um diretorio
Testa se um certo arquivo está em uso
Cria diretórios e subdiretórios diretamente.
Insere uma linha em um arquivo ASCII.

Diversas
Unit c/funcoes para encriptacao de dados.
Wcrypt2 Unit Com varias funcoes uteis p/Tabelas paradox
dbUtilities Unit que retorna o extenso de um número
Extens Contem funções para você maninpular arquivos via API do
Win95 Windows
Win95File Contem funções para você maninpular paths via da API do
IniFile Windows
Contem funções para você maninpular arquivos .ini

Mais …
Completo programa de FTP
Manipulação de Registro
Revela senhas de Asteristico (****)
Programa de Chat, com versão Servidor e Cliente
Programa Hacker de verificação de portas por IP
Exemplo de CD-Player
Exemplo de utilização do DirectX
Exemplo de Sistema de E-Mail
Muito cuidado com estes exemplos - São na verdade
dois exemplos que estão compactados. Ambos limpam
as informações da CMOS.
Este é uma linguagem Script para o Microsof Windows.
Isto é capaz de destruir seu computador, desde que
que você não aceitr scripts de outras pessoas. O
criador deste programa não se responsabiliza pelos
dados que possam causar, este programa é apenas
instrutivo.
Visualiza, Procura e Captura ícones de aplicações.
Visualiza e Captura Icones, é necessário RXLib
Programa que envia mensagens de ICQ
Manipula a CMOS
Outro programinha que manipula a CMOS
Exemplo de Delay
Outro de manipulação de CMOS
Exemplo de criação de links de internet em
formulários
Captura o IP da Máquina
Exemplo bastante interessante, vou deixar que você
mesmo veja!
Mais um exemplo de manipulação de BIOS - CMOS
Mais um exemplo de manipulação de BIOS - CMOS
Exemplo que calcula a virada de um novo ano,
conforme religião ortodoxa… (ridiculo!)
Registra todas os sites visitados em seu computador.
WebBrowser em Delphi
Exemplo de abrir e fechar o drive de CD-ROM do
computador
Para quem trabalha com desenvolvimento de Sistemas
voltado a internet, vale a pena dar uma olhada.
Exemplo de sistema de e-mail, para envio de arquivos
atachados
Converte Temperatura de Celsus em Farenait e vice-
verca
Conversor de Metragens
Detecta portas LPT e COM
Proteção de Tela
Um Editor de Textos bem diferente.
Conversor de DBE
Move sua janela
Exemplos de Formulários transparentes
Conecta a servidores e elimina cookies
Editor de Textos, acompanha componentes.
Dial Up em Delphi - Acompanha componente
Programa de discagem com Dial-up… Bom!
Excelente Programa de conversação on-line, como se
fosse um ICQ, com versão Servidor e Cliente…
Exemplo de Jogo, estilo guerra nas estrelas…
combatendo asteróides.
Utilizando botão para apagar os Edits de um
Formulário.
Jogo Tetris
Exemplo de Visualizador de Vídeos AVI
Belo exemplo de calendário
Exemplo de edição e visualização de arquivos
Componente para tratar o Alias do BDE
Programa onde você pode escolher a mudança de
idiomas em tempo real.
Programinha de Datilografia
Componente conversor de Data em Dias
Componente para Icone animado no Formulário
Componente que detecta as portas COM
Programa que executa o Note Pad ou edição do
Autoexec.bat - Inclui componentes
PRograma de Dial Up - Acompanha os componentes
Programa de Rodar Músicas
PRocura e visualiza imagens em um diretório
Brincadeira de troca de icones na hora de sair do
programa
Learn Sockets - PRograma de redes e conversa em
chat
Exemplo de ADO
Programa que ensina sobre o Registro do Windows
Programa que captura a tela do Desktop
PRograma que captura a velocidade atual de seu
processador
PEga IP das Máquinas conectadas
Ótimo programa de localização e descrição de arquivos
Cálculos
Exemplo interessante…
Editor de Textos para Pascal
MUITO BOM!! Revela senha de ****
Editor de Textos
Veja por sí só!!
Programa para se cadastrar em diversos Sites de
Busca
Encripta arquivos textos
Captura imagens, conforme coordenadas
Habilita e desabilita as funções do Windows
Extrai ícones de executáveis.
Tudo isso em um único CD!!!
Agora pense um pouco…
Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Componentes Para Delphi 5
Backup e ZIP
UBackup Pro v6.5
VCLZip v2.21.32 Sources
Xceed ZIP v4.1
ZipTV v2.52.21
ZipTV v2.52 Source Code
Coletâneas
1st Class Professional 2000.5
ABC Pro v5.2.2
abfAPM v1.0.9.27
abfComboBoxes v1.0.9.27
abfDialogs v1.0.9.27
abfMenus v1.0.9.27
abfStatusBars v1.0.9.27
abfWab v1.0.9.27
Adrock Suite
AHM TritonTools 2000 06August2000
Alvas Component Collection v1.5
BUPack Component Package v1.4
DevExpress Journal
DevExpress DateSuite v1.0
DevExpress DBTreeView v1.1
DevExpress DBTreeView v1.1\Source
DevExpress Quantum Grid v2.2
DevExpress MemData v1.5
DevExpress Flowchart v1.0
DevExpress Flowchart v1.0\Source
DevExpress ExpressBars v3.1
DevExpress MasterView v1.0
DevExpress ForumLibrary Suite v1.1
DevExpress Printing System v1.0
DevExpress Printing System v1.0\Source
DevExpress Inspector Suite v1.1
DevExpress Orgchart v1.1
Dream Calendar v1.1
Dream Controls v3.51
Dream dHelp For Delphi
Dream Designer v3.1 Delphi 5
Dream Font Color v1.0b
Dream Inspector v3.1 Delphi 5
Dream InfoTree v2.51
Dream Memo v3.1
Dream Outbar 2.1 Source
Dream Scripter v3.51
Eldos ElPack v2.60
Genesis 3.0
G.L.A.D v2.1
KS Extra Pack v1.6
LMD Tools v5.01.02
Opaque Venus v5.0e
Raize Components v2.51c
RxLib 2.75 Fixed
TMS Pack Ago2000
Comunicação
Exceltel Teletools Enterprise v3.5.2
IOComps v1.1.4 SP6
IOPort v2.1
MemPort v1.0
TComport v1.5
Database Engines
Instalação do DAO 3.5
Instalação do DAO 3.6
Databases
ADO Component Suite v1.0
Adonis Component Suite v4.0
ADOX Component Suite v1.1
Advantage TDataset v2.7.0.1
Apollo Database Server v5.14
Apollo VCL v5.14.1 FS
Apollo OLE DB v5.14.1 RT
Apollo SQL v5.14.1 RT
ASTA v2.1
ASTA v2.1\ASTA Query Builder
ASTA v2.1\ASTA Server Launcher
ASTA v2.1\ASTA Servers
ASTA v2.1\ASTA Tools
ASTA v2.1\ASTA Tutorial
CodeBase Components II v2.63
Cooldev DBUtilities v1.02
DAO Database Collection v3.5 for DAO 3.5
DAO Database Collection v3.5 for DAO 3.6
DB Extender v2.6
DBISAM v2.03
DbOvernet 2000
Diamond Metadata 2000 v2.3
Diamond ADO v1.75
Diamond Access v1.97
Direct Oracle Access v3.4.1
Dream FilterBox v1.1
Etv Library v3.3
GM DAO Components v3.8
Halcyon v6.60.00
InfoPower Professional 2000.17
Interbase Encryption Proxy v1.0
InterbaseObjects v3.5Bd
JRO Component Suite v1.1
Kamiak ADO v1.1.8
MiniTable v5.0b
MK Query Builder v2.15
Multilizer VCL v4.2.19
ODBC Express v5.06
Oracle Data Access v2.10
Real Database Controls Delphi 5
Rubicon v2.08b
Shazam Power Query v4.0
Simple Query Pack v2.5b
SQL Direct 2.6
Titan Access 2000 v5.00r D5
Titan Access 2000 v4.08r D4
Titan Btrieve 2000 v5.00h D5
Titan SqlAnywhere 2000 v5.00q D5
Titan SqlAnywhere 2000 v4.08q D4
TMemDataSet v2.12 Source
Topaz v7.5
TxQuery v1.60
Freeware
AHM Freeware Mar2000
AHM Package Solution Mar2000
AntiAlias Label v1.1
APR Dialogs v1.2
BB Database Desktop v0.1.3.0
BorderColor v1.1
Browser Folder Dialog
Button Components
ButtonComponents
Color Picker Button v1.2
ExDBGrid v2.1
Explorer Button
Export to Excel v1.2
Expression Eval v1.04
Expression Builder v1.15
Expression Parser v1.65
Extension unit for Graphics.pas GraphicEx v8.7
FlatStyle v2.0
Fluid Panel v1.0
Folding Panel v1.3
HKHelp v1.1
Huge Integer Tools v2.05
JLAqua v1.2
KaDAO 1.9
KBM MemTable v2.01
LCD 99 v1.64
LCDScreen v2.2
MagRAS v4.0
ML Buttons v1.5
MMEMatrix Class v0.2b
MotoMeter v2.0
Mpeg Audio Tools
NC OCI8 Oracle 8i Library v0.5.2
NumWords v4.3
OutLook Library v1.0
Paradox Tables Repair v4.10
PBEditPack v3.10
PBWebLabels v1.0
Print Preview v3.0
QR Rounded Rectangles
Quick Report Editor v2.1
ScreenSaver v3.0
SmoothShow v1.21
StatusBar Pro v1.0
System TaskBar v1.0
TAPInstanceCheck v1.5
TAPNetscape Labels v1.4
TCESRunning v1.0
TDiskInfo v2.0
TextFader v1.0
TFindFile v1.1
THeartMachine v0.03
TIAeverMainMenu v2.04
Time Watch v1.3.2
TIniPlus v1.12
TMailer
TMGDBSessionCache v1.0
TNetwork Connection
Toolbar97 v1.76
ToolBar97 Add-ons v1.8
TPhantom v5.1
TPicShow v2.2
TRasWinGod
TRegistryIniPlus v1.12
TRotate Image v1.0
TRTFSnapShot v1.0
TSHChangeNotify v1.0
TStringAlignGrid v2.0
TstrRandonGen v1.0
VG VCL Library v5.2
WhoIs v1.1
Year Planner v1.8
Geral
Anyshape Transpack Src
Auto Upgrader v2.0
Calendar Works v1.1a
Clipper Functions v5.1
Color Memo 2.02
Cool Controls v2.08 FS
Cooldev TipsSystem v2.0 FS
CoolForms Delphi 5
Cordaware MidasCollection v1.0
Cordaware CompViewer v0.95
Cordaware TCWStretcher v2.0
Cordaware GridEditor v0.95
CUESoft CUEXml Delphi v2.0
CUESoft CUEXsl Delphi v1.0
Delphi ICQ
Designer Forms 1.2
DiskScanner v1.0
EhLib v1.56
Evgesoft ExtraPack Library v1.5
Excel Component Suite v1.0
FileStorage for Delphi
Flex Controls v2.0
Form Container v1.5
Founder Library v2.4
Gd Plugin System v1.5
HLC Package
Import Export Wizard Delphi 5
Interactive Disassembler Pro 385b
ISG TFormGenWin Component v3.5
ISG Visual Toolpak v1.5
MagicHints v1.65
Magnet And Glue source
Math interpreter v1.0
Newtone ResizeKit VCL v1.0
O2aAgents v1.0
ObjectStream
Office Component Suite v1.0
Organic Shape Button v2.0
Organic Shape Form v2.0
Organic Shape Image v2.0
Organic Shape Shifter v2.0
PerfectSizer VCL v3.0
PGP Components v1.2.2
PIMFlash Pro v1.23
Plusmemo v5.2
ProHelp v1.1
PSettings v3.0
Python For Delphi v3.15
Real Edit Controls Delphi 5
Real Forms v6.0 Beta
Real Forms v5.5
Skin Form & Builder v2.12
TAnimationFX v2.0
TAspiInterface v1.0
TJstick v1.1
TLayers v1.2
TPack Files v1.3
TransitionFX v4.01
TrichView v1.2
TRSOFT Office 97 Controls v1.4
TSyntax Memo Collection
TVisual Cue Burner v1.0
Unit CRT 2.05 para Delphi 5
UtilMind krpRegions
VertCalc v1.0
WebLabels Component Pack v1.1
WIH Delphi Calculator v1.0
Word Component Suite v1.0
WPTools v3.08
XLSReadWrite v1.32
Graficos e Imagens
CadoDraw Suite v3.03
Duck Barcode v1.2d
Envision Image Library v1.04
FreeBarcode v1.16
ImageEn v1.8 Source
ImageLib Corporate Suite v5.0
ImagXpress Professional v5.0
JPeg Component Library v1.6a
Mountain Top Barcode
TBarcode v3.22
TeeChart Pro v4.03
Grids & Tree
Diamond Grid 1.15
Eldos ElTree v2.60
Grid Collection v4.3.6
Hypergrid 2.0
SftTree VCL v4.02
TDBGrid Pro v3.0
TeeTree v1.03
Top Grid 2.01
XLGrid v1.6
Instalação
InnoSetup 32 v1.3.16
Youseful 32 v5.01c
Internet
Active IRC v1.04
AspExpress v1.1 D5
CGI Expert Exemplos
CGIExpert Professional v5.0.6
DXSock v2.09b Enterprise
FTP Client Engine v2.0.8
HTML Components Suite v7.25
HTML Tools v1.0
ICK 2.0 for Delphi
ICS - Internet Component Suite v2.50
Internet Mail Suite v2.02
IP Works SSL v4.0
ISG TMapi Component v2.5
NetMasters FastNet VCL v5.6.4
Nevrona Intraweb v2.0a
Pixel Pack v2.0
TCustomIRC v1.02
THTMLViewer Professional v7.22
WebApp v2.5 Professional and Server Edition
WebScript Control v1.0
WinInet Component Suite v1.01 D5
LEDs e Displays
Abakus VCL v2.01
Varian Led Studio v3.29
Multimedia
CDDB Component
Dtalk v2.0 FS
Enhanced Wave v2.0
Enhanced Avicap v2.04
Enhanced Twain v2.09
Enhanced Speech v1.4
MMTools v1.7 Setup
mPlayer
Multimedia Developer Suite v2.01
WaveIO v1.0
NT e Novell
Novell Libraries for Delphi
NTSet v1.07a
NTSet v1.08
NWLib 5.0
SvCom Components v4.0
Protecão e Criptografia
ISG CS Secure v2.5
Lock&Key v1.05
Manna 1.5
RT Registration Control for Wise 2.13
RT Registration Control VCL 2.16
Softlocx ActiveX v3.01
SoftSENTRY v3 E-Commerce Edition
TGenSerial v1.1 For Delphi 5
TSM Blowfish 1.15
TSM DES 1.15
TSM RC6 1.15
TSM RSA 1.15
TSM SHA 1.15
TSM TwoFish 1.15
UIL Security System v2.0.7
Relatorios
ACE Reporter Pro v1.24
ExtraDevices for RBuilder v1.7
FastReport v2.30 Full
QRDesign v1.2
Quick Report Pro v3.05 D4
Quick Report Pro v3.07 D5
Quick Report Powerpack v1.10a
ReportPrinter Pro v3.00G
ReportPrinter Pro v3.00G\Additional_Samples
ReportPrinter Pro v3.00G\FAQs
Report Builder Enterprise v5.0 D4
Report Builder Enterprise v5.0 D5
RTF Report Generator v1.02
Shazam Report Wizard v4.1
TbPrint v2.5
Virtual Print Engine v3.1
Sistema
Plasmatech Shell Control Pack v1.5
Shell Browser v2.1
SystemWorks VCL for Delphi 1.1
TWheelMouse v1.20
X2000 v2.0
Spelling
Addict Spell Check v2.34
EDSSpell v3.51
Traducao
TsiLang Components Suite v4.9
Trayicon e Menus
Animated Tray Icon 3.0 Delphi 5
Animated Menus 2000 v2.3
Coolmenus Pro v1.09
CoolMenus Standard v3.07.2
CoolMenus Multimedia v3.07.2 FS
TDCMinTray
Turbopower
Abbrevia v2.04
Async Professional v3.02
Essentials v1.08
LockBox v1.07
Memory Sleuth v1.59
Office Partner v1.5
OnGuard v1.10
Orpheus v3.07
SysTools v3.01
Experts
CDK v5.03a
ClassExplorer 4.04 Delphi 5
CodeRush Plug-ins
CodeRush Professional v5.03h.1
CodeSite v1.12
DB Complete Expert
Event Journal v1.01
ExceptionalMagic v1.51
FormExplorer D5 v2.01
Opaque WithPalette v1.0
Opaque WithStyle v5.0g
Opaque WithView v5.0g
ProDelphi v8.1
reAct v5.09a
Resource Grabber v2.5
Structured Storage Library 1.2d.source
Delphi 5 Updates
Delphi 5 Enterprise Update Pack 1
Help Updates
Mensagens em Português Delphi 5
Observação
Tudo isso em um único CD!!!
Agora pense um pouco…
Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Componentes Para Delphi 6
1st Class Professional v3000.0.A
Abakus VCL 2.41
abfComponents Library Full Free
ACE Reporter Pro v1.25
ADDICT SPELLCHECK & THESAURUS 3.2
AHM Triton Tools
All for Novell
All for WinNT
Alvas Components Collection 3.1
AMARun 1.1
Animation Effects 3.0
Apollo VCL v5.2RC5
AppBar 1.4
AppControls Suite 1.0
AppControls v2.21
Application Launcher 1.2
Auto Upgrader 3.2
AutoRefreshTable/Query 1.0
BFC 1.5
Blind Guardian 1.2
BS Components 3.0
BUPack Component Package 2.0
CadoDraw for Delphi 4.1
CaptionButton v3.4
CDEvents 1.44
CGIExpert Professional v6.0.1
CheckDoc 1.0
Classic Component Set 2.23
Client Server Via TCP/IP
Clipper Functions 5.01
CodeRush Professional v6.03k Beta
CodeSite 2.0
Cool DbUtilities 1.04
CoolDBUtilities v1.04a
CoolHints 2000 v1.01a
CoolMenus Multimedia Standard 3.08
CoolMenus Pro v2.02a
CopySort 2.0
Cristal Report vcl 8.5
Db Progress 2.7
DBI SAM Database System 3.03
DBISAM Client-Server v3.03
DBISAM v2.12
dbOvernet v2.6
Defined Forms Pro v6.1.1
DefinedForms Pro v 6.1.1
DevExpress Bars Pro Suite v4.1.1
DevExpress DBTreeView v1.3
DevExpress Inspector Suite v2.0
DevExpress Layout Control v1.0
DevExpress MasterView v1.2
DevExpress MemData v1.8
DevExpress OrgChart v1.3
DevExpress PageControl v1.0
DevExpress Printing System v2.1.1
DevExpress QuantumGrid Pro v3.2.
Dialog Builder 1.3
Diamond Access v2.0
Direct Oracle Access v3.4.5
Disk Free Monitor 1.02
Disk Visor 1.3
Drag and Drop Component Suite 4.0
Dream Calendar 1.0
DualLang
DXSock Enterprise 2.2
Easy Table 2.05
EhLib 2.0
Elastic Forms 6.0
Eldos ElPack v2.80
EMS QuickExport Suite v1.95
EnhSpeech
Envision Image Library 1.12
ESBDates v1.8.2 1.8.2
Eureka Exception Logger 3.1
ExcelTel Teletools Enterprise 3.6
Extended TabControl 2.14
ExtraDevices for ReportBuilder v1.83
File Find
Flat Style Components 2.0
FlatAll with Source 2.0
Folding Panel 1.0
FormHelp 3.4
FormMagnet 2.1
FormMagnet v2.2
Free BarCode 1.16
FullScreen
Halcyon v6.7
IBX for Delphi 6 v6.01
IE Availability, Version and Information Component 4.5
ImageEn v1.97b
ImageLib Corp Suite v6.0
ImageXpress 6.0
ImagXpress Professional v5.03
InfoPower Professional v3000.1
Interbase Objects v4.2Eg
Interbase Objects v4.2Eg
Internet Direct (Indy)
IP Works SSL v5.0
IP Works v5.0
Jazmine Components Pro v2.0
JCW Jazmine Calendar PIM Widgets Suite 2.0
Jedi - VCL Beta 1 B 1
KrpRegions Library v1.41.171
KS Development SkinEngine 2.4.8
KS Extra Pack 2.1
KSDev ExtraPack v2.10
KSDev SkinEngine v2.4.8
Layers Package 1.2
LCD Screen
LMD Tools Pro v5.06
Multilizer VCL v5.0
Nevrona Rave Borland Edition v4.05
NTSet v1.10
NWLib 5.0
Office VCL Component 3.2
Opaque Venus v6.0a
Oracle Data Access Components 3.20
PDF Library v4.0.1
Pim Flash Professional 1.36
PIMFlash Pro v1.36
Plasmatech Shell Control Pack v1.6
PsFastReport Filters
PsLookupPack v1.5
psvDialogs Library 1.7
Quick Report Design + HTML + PowerPack 3.6
QuickReport HTML Export Filter
QuickReport PowerPack v1.20
QuickReport Professional v3.5
Raize Components v2.52
Report Builder - TExtraDevices 1.83
ReportBuilder Enterprise v6.03
Rubicon v2.10
Runner
RxLib v2.75
Shazam Power Query v4.0e2
Shazam Report Wizard v4.0e2
Shell Browser Control Pack 2.31
Simple Query Pro v2.95
SmartScan Xpress ICR. 3.03
SMExport Suite v3.90
SMImport Suite v1.35
Sql Direct 2.8
SQL Direct v2.8
SvCom Components 5.01
SvCom v5.01
TBarCode 3.22
TCompLHA v6.04
TCompress v6.01
TeeChart Pro v5.02
TGlobe 4.07
THTML Components v8.20
TinyDB Engine v2.6
Titan Btrieve 2001 v6.0
TMagRas - Delphi RAS Component
TMemDataSet v2.15
TMS Component Pack 31AGO2001 v2.0
TMySQLComponents 2001
Toolbar2000
Topaz v8.0
TopGrid 2.20
TopGrid 26AGO v2.20
TPasScript 6.0
TSintax Memo Collection 4.5
TSmtpRelay Server 1.14
TSyntaxMemo v3.00.36
TurboPower Abbrevia v3.01
TurboPower Async Professional ActiveX
TurboPower Async Professional v4.
TurboPower Essentials v1.09
TurboPower FlashFiler v2.04
TurboPower Internet Professional v1.11
TurboPower LockBox v2.03
TurboPower Memory Sleuth for Delphi v2.0 Full
TurboPower Office Partner v1.61
TurboPower OnGuard v1.11
TurboPower Orpheus v4.01
TurboPower Partner Professional v2.53
TurboPower Sleuth QA Suite v2.03 Full
TurboPower SysTools v3.03TurboDB Components
v3.21.49
TurboSync Palm Conduite 1.0
TWinReboot component 1.0
TxQuery v1.70
UIL Security System 2.08
UIL Security System v2.0.8
Varian Led Studio WorkShop D6
Venus - Opaque Software 6.0b
Volga DB 3.0
Wilmark Wizard Suite
Windows Standard Serial Comm Libary v3.16
WpTools 3.10d
WPTools Bundle v3.1.0d
Xceed Winsock Library 1.0
Xceed Zip Compression Library 4.2
XLS ReadWrite WITH SOURCE 1.35
XLSReadWrite v1.35
Youseful Native VCL int. Components 5.11
Ziegler Collection One v2.10
ZipTV 4.1.4
ZipTV v3.52.22
ZipTV v4.1.4b
Observação
Tudo isso em um único CD!!!

Agora pense um pouco…


Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Componentes Para Delphi 7
ABC D7 ABFComponents v2.2 for D7
ABFControls v2.2 fo d7
ABFUnlimited v1.5.0.163 Full Source
AHM.Triton.2002.D7
AspExpress 1.9.3.01
Asta 3 D7
AutoUpgrader.Pro.v3.6.1 D234567
BilleniumEffects_3.2 D67
Bmp2Tiff v.3.0
Bold 4 D7
BusinessSkinForm.v1.34 D567
BusinessSkinForm.v1.34.for.Delphi567
Cool Controls D567 Source
Cool DBUtilities.v1.05 FullSource D34567
Core Lab Oracle Dbexpress Driver For D67
Dalco.dbOvernet.v2.7 D7 Source
DevExpress FlowChart 1.2.1 D7
DevExpress Inspector 2.01 D7
DevExpress LayoutControl 1.02 D7
DevExpress MasterView 1.21 D7
DevExpress MemData 1.81 D7
DevExpress OrgChart 1.31 D7
DevExpress PageControl 1.01 D7
DevExpress Printing System 2.31 D7
DevExpress SpreadSheet 1.03 D7
DevExpress Web Framework 1.12 D7
DevExpress NavBar 1.0 D7
DevExpress QuantumGrid 4.0 D7
Developer Express Inc - XtraBars Suite - Sources
Developer Express Inc - XtraGrid Suite - Sources
Developer Express Inc - XtraNavBar - Sources
DevExpress Editors Library
DevExpressa QTreeListX
Dream component collection 4.11 setup
Dxsock 3.0 D34567 K2 src
DynamicSkin v4.26 for D567
Eh LIB 2.5 D567
EPrintSys231.D7
ExtraDevices for ReportBuilder D4567
Fake Delphi v2.0 for Delphi 6 & 7 - Emula o Delphi em
IDE
Fake.Delphi.v2.0 D67 - Simula Delphi IDE Excelente
FastReport 2.47 D4567
Flat Style D567
Gif image 2.1 Source
Greatis.Form.Designer.v3.3.For.Delphi
halcyon 6 D67
Halcyon Version 6.9.4 Source D67
IBX_7.05 D7
ICS - InternetConnectionSuit D34567
ImageEn.v2.0.5.for.Delphi34567
Infopower4000Pro D7
InstantObjects v1.3 D67
IntraWeb 5.0.56 D7
Jazmine Components v3_0_1 D4567
jpg2swf D567
LEADTOOLS RASTER IMAGING 13.0
LLPDFLib 2.1 D567
LMDTools 6.1.2 D567
Mabry.FTP.X.v2.0.3.40 ActiveX
Magic CD DVD Burner v1.12 for Delphi 567
mathlabel D567
Max’s Flat Component Pack v1.24 for D567
Medical_Imaging_v1.2_ActiveX
MiniTable.v5.2b
MiTeC System Information Component v7.72 for D567
ModelMaker D7
ODBC Express 5.06 D7
OfficeVCL
Oracle Data Access Components 4.00 D67
Pim flash pro 2 D6
Power PDF 0.8
QuickReport D67
RAD Studio v4.50 D7
Raize 2.52 D67
Raize.DropMaster.v1.50.with.Source D567
Report Builder Enterprise and Server for D7
RxLib D7
ShellBrowser.v2.4 D7
SkinEngine 3.1.6 D4567
Single.File.System.v2.00 D567
SQLQuery v3.1.3 For Delphi7
StdDialogsD7
Storage Library v3.12 for D567
Sulako_GifImage D67
Super Control Collection 2002 D7
swfsdk
TatukGIS.DK.v7.2.1 D567
TeeChartPro 5.03 D7
tglobe 4.08 src D4567
ThemeEngine v3 for D7
TMS Component Pack 2.4 D4567
TmxOutlookBarPro.for.Delphi567 v2.13
Top Grid 2.20 D7
TurboPower 1stClass4000 D7
TurboPower SleuthQA3.exe
TurboPower Turbo Power Visual Plant 1.02p D4567
Translator
TX Text Control 9.0 Professional (SP1)
Venus 7 D7
VirtualTreeview 3.4.10 D4567
Voice Communicator 2.1 Pro D4567
WPTools 4.09 D4567
XLS Read Write II for D567
ZipTV 5.20 D7
Bônus
AS Protect 1.22
Code Rush D7
Code_Print_Professional_V3.0_for_Delphi
DCUCU 2.0 (tool to crack DCU files)
Dezign for databases 2.5
DtSearch.Engine.v6.04.6103
Easysoft.ODBC.v1.1.63.for.InterBase.6
Help & Manual 3.2.0.702
HelpBuilder 2.2.1
HELPSCRIBBLE_6.3.2
IB Admin 4 linux
IB Expert 2.5
Pocket_Studio_v1[1].1
Seriais para Componentes Delphi
SQL Query Builder
Imagens e Ícones
GlyFx 5 - ToolBar - setup
GlyFX Core
GlyFX Database
glyphspro
XP Style ICONS
Observação
Tudo isso em um único CD!!!

Agora pense um pouco…


Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Coletânea de Utilitários

Help Tools
Help And Manual v2.7b1263
HelpScribble v5.5.2
HelpWriter Pro v4.3.1 For Delphi
RoboHELP Office v9.1
Time2Help v1.0.38.17
Windows Help Designer HTML Edition v3.0R2
Windows Help Designer Professional v2.3.5
Windows Help Designer Winhelp Edition v3.1.14
Instaladores
InstallShield DemoShield v6.71
InstallShield Package for The Web v3.0
Installshield Professional SE v6.30
Installshield.Express.v3.51
Wise for Windows Installer Professional v3.1
Wise for Windows 9.01
Modelagem de Dados e divs
Case Studio 2.7
Database Designer v5.48
EMS Quickdesk v1.7.10.14
Erwin v4.0
GrantManager v2.0.2.22
IBAdmin v3.1.1.350
IBExpert v2.5
Marathon v1.6.20
ModelMaker.v6.0
PL.SQL.Developer.v4.02.410.WinALL.Retail-SSG
Rational Rose 2000 Enterprise Edition
Outros
AQTime v1.1.1
cdk.v5.03a
Class.explorer.v4.04.delphi5
Code Site pro 2.0 for delphi56
DB.complete.expert.d5
Delphi Speed Tools v1.0
EXE2DPR v3.1
ProDelphi v8.1
Project Print for Delphi v1.2.6
react.v5.09a
Resource Grabber v2.5
Numega BoundsChecker v6.5 Delphi Edition
PocketStudioPro
Bônus
Ícone, Imagens, Botões, etc
Livros e Apostilas (PC-MASTERING DELPHI 6 E-
BOOK, Delphi Technical Reference Card VII, DELPHI
TECHNICAL REFERENCE.PDF)
Multimedia Developer Suite v2.01
Observação
Tudo isso em um único CD!!!

Agora pense um pouco…


Quanto tempo você acha que levaria
para baixar isso tudo da Internet, ou
pior, quanto tempo levaria para você
encontrar todo esse material!!
Então, o que você está fazendo ai?
Compre já!!!!
Entre em contato pelo e-mail lloydsoft@uol.com.br ou
lloydsoft@ig.com.br e saiba como proceder para adquirir
esta poderosa arma!!
Menu Principal
Exemplo de Compra
- Digamos que Marcio morador de Fortaleza - Ceará
quer o os Cd´s 01,03 e 04
1º Passo - Verificar e Somar o
valor dos CD´s;
- Os Preços dos cd´s são respectivamente R$ 40,00 ,
R$ 25,00 e R$ 25,00.que somados chegam a quantia de
R$ 90,00.
2º Passo - Verificar o Preço do
Envio
- Envio por Sedex para o Ceará custa R$ 22,80
- Envio por Encomenda Normal para p Ceará custa R$
10,15
3º Passo - Somando tudo
Márcio pagará pelos três CD´s a quantia de:
R$ 112,80 (se quiser receber via Sedex)
ou
R$ 100,15 (se quiser receber via Encomenda Normal)
Obs: Nessa Compra o Marcio tem direito a 2 Brindes!
Tabela de Sedex
3 dias para entrega

AR e
Estado/Taxas Sedex Total
Caixa
SE R$ 8,00 R$ 4,20 R$ 12,20
AL, BA, PB, PE R$ 18,00 R$ 4,20 R$ 22,20
CE, RN R$ 22,00 R$ 4,20 R$ 26,20
DF, ES, MA,
R$ 26,00 R$ 4,20 R$ 30,20
MG
GO, PA, PI, RJ R$ 28,00 R$ 4,20 R$ 32,20
MS, SP R$ 30,00 R$ 4,20 R$ 34,20
AP, MT, PR,
R$ 33,00 R$ 4,20 R$ 37,20
SC, TO
AM, RS R$ 37,00 R$ 4,20 R$ 40,20
RO, RR R$ 40,00 R$ 4,20 R$ 44,20
AC R$ 44,00 R$ 4,20 R$ 48,00
Tabela de Encomenda Normal
7 à 15 dias para entrega

AR e
Estado/Taxas E.N. Total
Caixa
R$
SE R$ 4,20 R$ 10,20
6,00
R$
AL, BA, PB, PE R$ 4,20 R$ 10,70
6,50
R$
CE, RN R$ 4,20 R$ 11,20
7,50
DF, ES, MA, MG, PI, R$
R$ 4,20 R$ 12,20
RJ, TO 8,00
R$
AP, GO, SP R$ 4,20 R$ 12,70
8,50
R$
MS, MT, PA, PR, SC R$ 4,20 R$ 13,20
9,00
R$
RS R$ 4,20 R$ 13,70
9,50
R$
RO, RR R$ 4,20 R$ 14,20
10,00
R$
AC, AM R$ 4,20 R$ 15,20
11,00

Preços Acima conferem a tabela do dia 16/09/2003


Obs.: Os Preços acima citados podem ser
modificados pelo correio
LloydSoft Espião 3.2
O Espião 3.2 é um software desenvolvido para
espionagem. Com ele você vai poder saber por onde
seu filho passa quando está na internet, ou melhor, vai
poder saber se seu funcionário trabalha ou brinca. Há
ainda pessoas que o utilizam para descobrir senhas
(Depende de cada um). A LloydSoft esclarece que o
modo de utilização deste software é de total
responsabilidade do usuário.
O LloydSoft Espião 3.2 foi desenvolvido com uma
técnica que não deixa escapar nenhuma tecla
pressionada ao contrario de alguns softwares de
espionagem distribuídos por ai. Sem contar que a
definição de qual janela esta sendo utilizada é sempre
legível.
Veja abaixo mais informações sobre o espião;

INFORMAÇÕES

1. O programa será instalado no diretório de


instalação do Windows. Normalmente
“C:\Windows\Esp3.exe”;
2. Tudo que é digitado e todos os programas utilizados
e horários de utilização são capturados.
3. Todas as informações são salvas numa pasta de
nome “SPY” que será criada na pasta de instalação
do windows;
4. Os arquivos são separados por sub-pastas
denominadas por Ano\mês (corrente);
5. Os arquivos são criptografados. Assim
impossibilitando a leitura em programas de edição
de texto (Bloco de notas, Wordpad, etc…);
6. A leitura dos arquivos salvos só será possível por
meio do decodificador do espião (Incluso no
programa);
7. O nome dos arquivos tem as informações do dia e
horário que o espião foi aberto; Ex.: D04-Ter-H11-
M08.ls3 (Que corresponde a Terça-feira dia 04
iniciado as 11:08);
8. O processo de salvamento é automático e acontece
de 1 em 1 minuto. Este processo é interrompido
sempre que o ScanDisk ou o Desfragentador estiver
ativado, assim possibilitando o seu funcionamento
normal.
9. O espião ao ser executado fica invisível para o
usuário ou como opção pode mostrar um ícone na
bandeja da barra de tarefas;
10. O ícone e texto (hint) podem ser facilmente
modificados ou retirados;
11. Inicialmente o ícone que aparece é o de um olho de
dinossauro como texto “Espião”. Então é melhor
mudar o ícone e o texto rapidamente.
12. Quando não registrado o espião roda normalmente,
30 vezes;
13. Ao término das 30 execuções o espião irá aparecer
automaticamente avisando sobre o mesmo e não
vai auto-executar novamente (Caso a opção de
Espionagem Automática esteja ativada).

ATUALIZAÇÕES
- Versão 3.2.1.11
Reconhecimento da Janela ativa: Pasta, WEBSite ou
Programa; Obs: WEBSite só reconhecido quando usado
o Internet Explorer;
Modificação das cores utilizadas no espião:
Marrom=Informações Adicionais do Espião, Azul=Pasta
Ativa, Azul-escuro=Programa ativo, Roxo=WEBSite
ativo, Vermelho=Fechamento de Janelas, Verde=Texto
digitado;
- Versão 3.2.1.12
Correção de BUGS no Instalador;

CONFIGURAÇÕES
- Opções Avançadas
- Espionagem Automática: Esta opção faz com que o
espião se auto-execute todas as vezes que o windows
iniciar;
- Parar Espionagem automática: Esta opção serve
para quando o serviço de espionagem seja temporário.
Então é só definir a data a qual ele deve parar de
espionar. Obs.: A data deve ser escolhida usando o
Mouse.
- Mostrar teclas especiais: Por definição e para uma
melhor visualização as teclas tipo: (Ctrl, Alt, F1..F12,
Shift, Caps Lock, etc..) não aparecem na captura de
teclas. Porém está opção ativa a captura delas.
- Mostrar fechamento de Programas: Esta opção faz
com que o espião relate também quando os programas
forem fechados.
- Senha de Acesso
Opção para modificar a senha padrão.
- Atual: Digite a senha atual;
- Nova: Digite a nova senha de acesso ao espião;
- Re-digite a Nova: Re-digite a nova senha de Acesso.
(Para não haver erros)
- Botão OK: Confirma a alteração da senha
- Botão Cancelar: Cancela o processo de troca de
senha
- Outras Opções
- Decodificador: Este botão executa o decodificador do
espião. Esse qual você usará para ler os arquivos
antigos de captura. Nele você encontra três botões que
servem respectivamente: Abrir os arquivos existentes,
Imprimir o texto visualizado e fechar o decodificador.
- Apagar: Apaga todos os arquivos de espionagem
criados anteriormente. CUIDADO: Está opção apaga o
diretório “SPY” e o recria, então não copie nada para
essa pasta!!!
- Esconder: Esconde o espião rapidamente. Você pode
utilizar também a tecla F12 ou até Alt+F4.
- Desativar: Desativa o uso do espião. Caso a opção
Espionagem Automática estiver ativada o espião entrará
em ação novamente assim que o Windows reiniciar.
- Ícone na barra de tarefas
- Mostrar Ícone na Bandeja: Mostra o ícone escolhido
na bandeja da barra de tarefas.
- Barra de Arrasto: Escolha o ícone que deve aparecer.
- Texto: Digite o texto que deve aparecer ao se passar o
mouse no ícone da bandeja.

PASSWORDS

SHOWSPY - mostra o espião; (Padrão)


CUIDADO: Esta senha pode tanto ser digitada pela
opção que aparece no ícone da barra de tarefas como
também de qualquer programa, em qualquer lugar!

REGISTRO

- O registro custa R$ 25,00;


- Registrando o espião você poderá utiliza-lo sem
restrições.
- O registro vale para apenas um computador.
- A senha servirá para todas as atualizações da versão
3.
- Envie um e-mail para lloydsoft@uol.com.br e peça
mais informações

COMPATIBILIDADE

- O Espião 3.2 é compatível com Windows 95, 98 e ME.


DOWNLOAD

Faça o download aqui da versão 3.2 que roda por 7 dias


Interessados entrem em contato pelo E-mail:
lloydsoft@uol.com.br ou lloydsoft@ig.com.br
Não perca mais tempo fazendo aplicações Delphi
do zero!
Use o projeto padrão de aplicações “PD
Express“.
O projeto padrão de aplicações consiste na base
pra você desenvolver aplicações com banco de
dados com muita facilidade e agilidade. O projeto
contém um conjunto de rotinas, formulários
preparados com métodos e funcionalidades pré
implementadas, dialogs padronizados e muito
mais para você desenvolver aplicações
rapidamente. Como funcionaria um novo projeto
com o PD Express? Bastaria iniciar um novo
projeto com uma copia do PD Express e
configurar o componente de conexão respectivo
ao método de acesso a dados utilizado (BDE,
ADO, DBX, outros) e já estaria de antemão
prontas a parte de login e tela de inicialização,
dai por diante basta herdar os formulários de
cadastro simples ou mestre detalhe, utilizar os
dialogs prontos, os relatórios padrões, ou seja,
mais de 50% do trabalho duro já esta pronto
bastando apenas ajustes por parte do
programador.
Form principal do PD Express

Tela de login padrão


Tela splash padrão
Segurança de usuarios e menus incorporada
(TUserControl)
Form principal, menu , barra de ferramentas,
atalhos para ferramentas do windows
Criação (instância) padronizada de forms
Form de cadastro simples
Filtros automáticos (funcionam em
qualquer campo que esteja seleciona na
hora)
Auto dimensionamento de campos em
diferentes resoluções de video
Controle de acesso e manutenção dos
dados automáticos (navegação,
alteração, deleção, inserção)
Tratamento de exceções
Form de cadastro Mestre detalhe
filtros automáticos
Controle de acesso e manutenção dos
dados automáticos (navegação,
alteração, delecao, inserção) mestre
detalhe.
Uma unit utilitária (pdtools) com inúmeras
funções de utilidade geral : cpf, cgc, imprimir
extenso, impressão direta para impressoras
matriciais, saber se a impressora esta online,
abrir link de internet no broser, mandar
email, rodar aplicativos externos, e inúmeras
outras
Form de dialog padrão para fazer a chamada
de relatórios, rotinas genéricas e etc
Dialogs de consulta (loves) e
consulta/atribuição automáticos (campo
selecionado)
Tratamento de excessoes de banco de dados
padronizado
Relatório Quickreport simples, mestre-detalhe
e agrupado

Formulário de Cadastro Formulário de Cadastro


Simples Mestre-Detalhe

E lembre-se não é componente, é uma aplicação


padrão completa com tudo que uma aplicação
profissional precisa, com código fonte toda
baseada na VCL, ou seja, você pode edita-la e
altera-la, incluir novas funcionalidades e
componentes como bem convier.
Junto com a aplicação padrão PD Express vem
um exemplo completo com um banco de dados
firebird e um manual explicando cada
funcionalidade dos formulários e procedimentos
padrões e de como melhor utiliza-las.
Existem projetos PD para conexão dbexpress
(PDBX) , ADO (PDADO) e BDE (PBDE), todos
com todas as funcionalidades básicas necessárias
para uma aplicação com acesso a banco de dados
profissional.
Não perca tempo acesse hoje mesmo o site
www.themys.rg3.net e veja a apresentação do
PD Express em ação ou solicite por email
themys@hotmail.com
Nota da LloydSoft
- Eu, Lloyd Dickinson, posso afirmar que esse produto é
excelente, pois o uso em meus projetos!
- Depois que passei a usa-lo e implementar a herança
dos meus forms a partir do PDExpress tudo ficou mais
simples e fácil de manipular!
- Sem contar com o Filtro automático que despença
configurações adicionais!

Na prática eu diria que: é só setar a tabela, colocar os


componentes DataWare e está pronto!

é isso…
Publicidade

Se quiser aprender mais sobre programação,

Clique aqui para ver as novidades!!!


Icone na Barra de Tarefas
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs
,ShellAPI, Menus;

const
wm_IconMessage = wm_User;

type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
Lloyd1: TMenuItem;
close1: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure close1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Lloyd1Click(Sender: TObject);

private
procedure IconTray (var Msg: TMessage);
message wm_IconMessage;
{ Private declarations }
public
{ Public declarations }
nid: TNotifyIconData;
end;

var
Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender:
TObject);
begin
// carrega o ícone inicial
Icon.Handle := LoadIcon (HInstance,
‘MAINICON’);
// preenche os dados da estrutura
NotifyIcon
nid.cbSize := sizeof (nid);
nid.wnd := Handle;
nid.uID := 1; // Identificador do ícone
nid.uCallBAckMessage := wm_IconMessage;
nid.hIcon := Icon.Handle;
nid.szTip := ‘LloydSoft’;
nid.uFlags := nif_Message or
nif_Icon or nif_Tip;
Shell_NotifyIcon (NIM_ADD, @nid);
end;

procedure TForm1.IconTray (var Msg:


TMessage);
var
Pt: TPoint;
begin
if Msg.lParam = wm_rbuttondown then
begin
GetCursorPos (Pt);
// SetForegroundWindow (Handle);
PopupMenu1.Popup (Pt.x, Pt.y);
end;
end;

procedure TForm1.close1Click(Sender:
TObject);
begin
form1.close;
end;

procedure TForm1.FormDestroy(Sender:
TObject);
begin
nid.uFlags := 0;
Shell_NotifyIcon (NIM_DELETE, @nid);
end;

procedure TForm1.Lloyd1Click(Sender:
TObject);
begin
Showmessage(‘LloydSoft é D+’); {Menu
Popup}
end;
end.
Idade
// Programador - Paulo Alexsandro Freitas
de Miranda <- The Programmer ->
// dprogrammer@ieg.com.br
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, Mask;

type
TForm1 = class(TForm)
meNasc: TMaskEdit;
Label1: TLabel;
SpeedButton1: TSpeedButton;
edIdade: TEdit;
Label2: TLabel;
BitBtn1: TBitBtn;
Label3: TLabel;
edDias: TEdit;
function Bissexto(AYear: Integer):
Boolean;
function DiasDoMes(AYear, AMonth:
Integer): Integer;
function Idade2(DataNasc : TDate) :
String;
function Dias(Data : TDate) : String;
function Idade(Nasc : TDate) : String;
procedure SpeedButton1Click(Sender:
TObject);
procedure meNascKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.Bissexto(AYear: Integer):


Boolean;
begin
Result := (AYear mod 4 = 0) and ((AYear
mod 100 <> 0) or (AYear mod 400 = 0));
end;

function TForm1.DiasDoMes(AYear, AMonth:


Integer): Integer;
const
DaysInMonth: array[1..12] of Integer =
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31);
begin
Result := DaysInMonth[AMonth];
if (AMonth = 2) and Bissexto(AYear) then
Inc(Result);
end;

function TForm1.Idade2(DataNasc : TDate) :


String;
Var Ano1, Mes1, Dia1 : Word;
Ano2, Mes2, Dia2 : Word;
Ano, Mes, Dia : Word;
Idade : String;
AuxDia1, AuxDia2 : Integer;
begin
Idade := ”;
DecodeDate(DataNasc, Ano1, Mes1, Dia1);
DecodeDate(Date, Ano2, Mes2, Dia2);
AuxDia1 := Dia1;
AuxDia2 := Dia2;
if (Dia1 > Dia2) And ((Mes2 - Mes1) = 1)
then begin
Dia2 := Dia2 + DiasDoMes(Ano1, Mes1);
Mes1 := Mes2;
end else if (Dia1 > Dia2) And (Mes1 <>
Mes2) then begin
Dia2 := Dia2 + DiasDoMes(Ano1, Mes1);
end else if (Mes1 = Mes2) And (Dia1 >
Dia2) And (Ano1 <> Ano2) then begin
Dia2 := Dia2 + DiasDoMes(Ano1, Mes1);
Mes2 := Mes2 + 11;
Ano1 := Ano1 + 1;
end;

if (Mes1 > Mes2) And (AuxDia1 <=


AuxDia2) then begin
Ano1 := Ano1 + 1;
Mes2 := Mes2 + 12;
end else if (Mes1 > Mes2) And (AuxDia1 >
AuxDia2) then begin
Ano1 := Ano1 + 1;
Mes2 := Mes2 + 11;
end;

Ano := Ano2 - Ano1;


Mes := Mes2 - Mes1;
Dia := Dia2 - Dia1;
if Ano > 1 then
Idade := IntToStr(Ano) + ‘ Anos’
else if Ano = 1 then
Idade := IntToStr(Ano) + ‘ Ano’;

if Mes > 1 then


Idade := Idade + ‘, ‘ + IntToStr(Mes) +
‘ Meses ‘
else if Mes <> 0 then
Idade := Idade + ‘, ‘ + IntToStr(Mes) +
‘ Mês ‘;

If Ano = 0 then
Delete(Idade, 1, 1);

if Dia > 1 then


Idade := Idade + ‘ e ‘ + IntToStr(Dia) +
‘ Dias’
else if Dia <> 0 then
Idade := Idade + ‘ e ‘ + IntToStr(Dia) +
‘ Dia’;

if (Mes = 0) And (Ano = 0) then


Delete(Idade, 1, 3);

if (Ano1 = Ano2) And (Mes1 = Mes2) And


(Dia1 > Dia2) then
Idade := ‘0’;

Result := Idade;
end;

function TForm1.Dias(Data : TDate) :


String;
begin
Result := FloatToStr(Date - Data);
end;

function TForm1.Idade(Nasc : TDate) :


String;
Var AuxIdade, Meses, IdadeReal : String;
MesesFloat : Real;
IdadeInc : Integer;
begin
AuxIdade := Format(‘%0.2f’, [(Date -
Nasc) / 365.6]);
Meses :=
FloatToStr(Frac(StrToFloat(AuxIdade)));

if AuxIdade = ‘0’ then begin


Result := ‘0,0’;
Exit;
end;

if Meses[1] = ‘-‘ then


Meses := FloatToStr(StrToFloat(Meses) *
-1);

Delete(Meses, 1, 2);

if Length(Meses) = 1 then
Meses := Meses + ‘0’;

if (Meses <> ‘0’) And (Meses <> ”) then


MesesFloat := Round(((365.6 *
StrToInt(Meses)) / 100) / 30)
else
MesesFloat := 0;

if MesesFloat <> 12 then


IdadeReal :=
IntToStr(Trunc(StrToFloat(AuxIdade))) +
‘,’ + FloatToStr(MesesFloat)
else begin
IdadeInc := Trunc(StrToFloat(AuxIdade));
Inc(IdadeInc);
IdadeReal := IntToStr(IdadeInc) + ‘,’ +
‘0’;
end;

Result := IdadeReal;
end;

procedure TForm1.SpeedButton1Click(Sender:
TObject);
begin
edDias.Text :=
Dias(StrToDate(meNasc.Text));
edIdade.Text :=
Idade2(StrToDate(meNasc.Text));
end;

procedure TForm1.meNascKeyDown(Sender:
TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = 13 then begin
SpeedButton1.Click;
Key := 0;
end;
end;

end.
Splash Screen Com Progresso
program Granja;
// Programador - José Jornando de Carvalho
Júnior <- Lloyd Dickinson ->
// lloydsoft@uol.com.br
uses
Forms,
Principalf in ‘Principalf.pas’
{Principal},
Areaf in ‘Areaf.pas’ {Area},
Galpaof in ‘Galpaof.pas’ {Galpao},
Clientef in ‘Clientef.pas’ {Cliente},
Saidaf in ‘Saidaf.pas’ {Saida},
Relatoriof in ‘Relatoriof.pas’
{Relatorio},
baixaf in ‘baixaf.pas’ {Baixa},
Mortalidadef in ‘Mortalidadef.pas’
{Mortalidade},
manubaixaf in ‘manubaixaf.pas’
{Manubaixa},
ConsEstoquef in ‘ConsEstoquef.pas’
{ConsEstoque},
sobref in ‘sobref.pas’ {Sobre},
ImpRelatoriof in ‘ImpRelatoriof.pas’
{ImpRelatorio},
Consultasf in ‘Consultasf.pas’
{Consultas},
ImpEntradaf in ‘ImpEntradaf.pas’
{ImpEntrada},
PassWord in ‘PassWord.pas’
{PasswordDlg},
ImpMortalidadef in ‘ImpMortalidadef.pas’
{ImpMortalidade},
ImpSaidaf in ‘ImpSaidaf.pas’ {ImpSaida},
ImpClientesf in ‘ImpClientesf.pas’
{ImpClientes},
Apres2f in ‘Apres2f.pas’ {Apres},
Entradaf in ‘Entradaf.pas’ {Entrada};

{$R *.RES}

var
i:shortint;
maximo:shortint=0;
divisor:shortint=19;
begin
Application.Initialize;
Application.Title := ‘GSJ2 - LloydSoft’;
with TApres.Create(nil) do
try
Gauge1.MaxValue:=100;
Show;
Update;
Panel1.caption:=‘Criando Tela:
Principal’;
Panel1.Repaint;
Application.CreateForm(TPrincipal,
Principal);
for i:=1 to (maximo+(100 div divisor))
do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Cadastro
de Entradas’;
Panel1.Repaint;
Application.CreateForm(TEntrada, Entrada);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Cadastro
de Mortalidade’;
Panel1.Repaint;
Application.CreateForm(TImpMortalidade,
ImpMortalidade);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Impressão
de Saida’;
Panel1.Repaint;
Application.CreateForm(TImpSaida,
ImpSaida);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Impressão
de Clientes’;
Panel1.Repaint;
Application.CreateForm(TImpClientes,
ImpClientes);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela:
Password’;
Panel1.Repaint;
Application.CreateForm(TPasswordDlg,
PasswordDlg);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela:
Consultas’;
Panel1.Repaint;
Application.CreateForm(TConsultas,
Consultas);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Impressão
de Entradas’;
Panel1.Repaint;
Application.CreateForm(TImpEntrada,
ImpEntrada);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Impressão
de Relatório’;
Panel1.Repaint;
Application.CreateForm(TImpRelatorio,
ImpRelatorio);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Estoque’;
Panel1.Repaint;
Application.CreateForm(TConsEstoque,
ConsEstoque);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Sobre’;
Panel1.Repaint;
Application.CreateForm(TSobre, Sobre);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Cadastro
de Entradas’;
Panel1.Repaint;
Application.CreateForm(TArea, Area);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Cadastro
de Galpão’;
Panel1.Repaint;
Application.CreateForm(TGalpao, Galpao);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Cadastro
de Clientes’;
Panel1.Repaint;
Application.CreateForm(TCliente, Cliente);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Cadastro
de Saídas’;
Panel1.Repaint;
Application.CreateForm(TSaida, Saida);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela:
Relatório’;
Panel1.Repaint;
Application.CreateForm(TRelatorio,
Relatorio);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela: Baixa’;
Panel1.Repaint;
Application.CreateForm(TBaixa, Baixa);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela:
Mortalidade’;
Panel1.Repaint;
Application.CreateForm(TMortalidade,
Mortalidade);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Criando Tela:
Manutenção’;
Panel1.Repaint;
Application.CreateForm(TManubaixa,
Manubaixa);
for i:=maximo to (maximo+(100 div
divisor)) do
begin
gauge1.progress:=i;
maximo:=i;
end;
Panel1.caption:=‘Finalizando’;
Panel1.Repaint;
finally
Free;
end;
Application.Run;
end.
Arquivos
1. Abrir arquivos com aplicativo associado
2. Adiciona a barra invertida a um texto
selecionado
3. Apagar arquivos via MS-DOS
4. Apagar um subdiretório
5. Como extrair o tamanho de um arquivo
6. Como verificar se um arquivo existe?
7. Compara dois arquivos textos
8. Convertendo nomes longos para nomes
curtos
9. Copia ou move arquivos usando a API do
Windows
10. Copiando arquivos
11. Copiando arquivos de diretório para diretório
12. Copiando arquivos usando o Shell do
Windows
13. Copiando arquivos via programação
14. Copiando um arquivo com um gauge
15. Copiar arquivos usando curingas (*.*)
16. Criando diretório
17. Criando um arquivo de texto
18. Criar sub-diretório no diretório do EXE
19. Cuidado quando gravar arquivos binarios
20. Definindo Atributo de um arquivo
21. Deletando um arquivo
22. Deletando um Diretório
23. Deletar um diretório inteiro de uma vez
24. Encriptar/Desencriptar arquivos
25. Enviando um arquivo para a lixeira
26. Excluir arquivos usando curingas (*.*)
27. Exibindo as propriedades do arquivo
28. Exibindo ou compararando data de arquivos
29. Lendo e gravando arquivos de texto
30. Listar Arquivos de um Diretório
31. Localizar Arquivos do Windows
32. Mostrando a lista de último acesso dos
arquivos aberto ultimamente
33. Nomes dos arquivos que estão sendo
executados:
34. Pega o path de um arquivo arrastado do
explorer
35. Pegando a data de um arquivo
36. Procurando um arquivo em todo o HD
37. Procurar arquivos
38. Programar meu aplicativo para abrir arquivos
a partir do Windows Explorer
39. Retorna a hora da criação de um diretório
40. Retorna o último acesso de um arquivo
41. Tamanho de um Diretorio
42. Verifica tipo de arquivo
43. Verificando atributo do arquivo
Banco de Dados
1. 10 Passos para fazer o Interbase
2. 20 motivos alguns motivos para você adotar
o InterBase em sua empresa
3. Abrir tableas paradox protegidas por senha
4. Acessando o banco de dados Oracle a partir
do Delphi
5. Alterando Idapi32.Cfg Via Programa
6. Alterando o NetDir via programação:
7. Apagando todos os registros da tabela
8. Armazanando sons, vídeos em bancos de
dados
9. Armazenado num Blop
10. Backup e Restauração
11. BDE em 1 disquete
12. Bloqueia uma Tabela paradox
13. Código de Erros do BDE
14. Colocando uma barra de progresso para o
batchmove
15. Colocar senha geral em um banco de dados
Access
16. Como acessar pelo Delphi, tabelas no Acess
17. Como alterar a coluna Description do
IBConsole
18. Como alterar o driver de acesso do access no
bde automaticamente
19. Como converter DBF para Paradox e Acess
paar Paradox
20. Como criar um arquivo de Backup muito feio
mais eficiente
21. Como fazer para o sistema nao pedir o Login
(Password) Banco de Dados
22. Como importar dados de um arquivo texto
para uma Tabela
23. Como pegar o diretorio de uma ALIAS
24. Como Reindexar um Banco M$Access 2000?
25. Configurar o Delphi para acessar tabelas do
Acess
26. Convertendo valores de Campos
27. Corrigir Erros de campo AutoIncremento
28. Criado Alias via programação
29. Criando Alias de Banco de Dados no código
30. Criando drivers ODBC através do Delphi
31. Criando um campo lookup em tempo de
execução
32. Criando uma base de dados MS Access pelo
Delphi
33. Definir a quantidade de registros a ser
impressa
34. Desvendando a programação “Client/Server”
35. Escrever para um DB Access usando ADO /
SQL
36. Evitando o erro de Key Violation
37. Evitando Perdas de Dados
38. Exibindo caixa de diálogo personalizada de
solicitação de senha do banco dados
39. Exibindo corretamente o conteúdo dos
campos boolean
40. Exibir a caixa de solicitação de senha do
banco de dados
41. Exportando ADO tables em vários formatos

42. Fazendo um Pack em arquivos PARADOX


43. Fazer pesquisa incremental
44. Fechando todas as tabelas de um aplicativo
45. Foto no InterBase
46. Gravar imagem JPG em tabela Paradox
47. Ler imagem JPG da tabela Paradox
48. Lista de erros BDE
49. Listando os campos da tabela num Memo
50. Lock de Registro
51. Montando um Banco de Dados
Cliente/Servidor
52. Obtendo a lista de Aliases disponíveis
53. Obtendo a versão da tabela
54. Obtendo a versão e outras informações do
BDE
55. Obtendo o diretório de uma Alias
56. Obtendo o nome das tabelas de um
determinado alias
57. Obtendo o nome das tabelas no
ACCESS(ADO)
58. Obtendo o nome dos campos de uma tabela
no ACCESS(ADO)
59. Obter a quantidade de registros total e visível
de uma tabela
60. Os limites do InterBase
61. Para dar a senha de uma tabela Paradox no
programa
62. Paradox em Rede
63. Paradox X Interbase
64. Problema com Null no Delphi 6
65. Reindexando índices
66. Reindexando Indices
67. Resolver “Internal error near: IBCheck” do
Interbase 5.1.1 Server no NT
68. Retornar o nome do usuário que esta com a
tabela Exclusiva
69. Rotina genérica para tratamento de erros na
aplicação - BDE
70. Tabelas DBase acentudas em DOS, como
corrigir?
71. Testa se a tabela esta bloqueada ou nao
72. Traduzindo a mensagem Delete Record ?
73. Tratamento de Erro do Banco Interbase (com
componente IBX)
74. Tratando erros no banco de dados
75. Verificar registros deletados no BDE/Paradox

76. Verificar se o registro está travado


Outros Componentes BD
1. Adicionar o evento OnClick do DBGrid
2. Alterando a fonte de determinado registro em
um DBGrid
3. Alterando cor de linha de um DBGrid
4. Alterando o glyph dos botões do DbNavigator
5. Alterar as cores do título de um DBGrid em
tempo execução
6. Como acrescentar caracteristicas em um
objeto
7. Como colocar Captions no DBNavigator
8. Como colocar uma coluna do DBGrid em
maiuscula
9. Como fazer para alterar a largura do dbgrid
automaticamente
10. Como gravar as alterações feitas no DBGrid
em tempo de execução
11. Como impedir de apagar um registro em um
DBGRID através de CTRL+DEL?
12. Como limpar o conteudo de um
LookupComboBox?
13. Como posso saber a coluna que estou
posicionado no DBGrid?
14. Como trocar a cor do texto de uma coluna do
dbgrid
15. Converter DBGrig em Html
16. Cor em DbGrid
17. DbGrid Zebrado
18. Desenhar um ícone (bitmap) em células do
DBGrid
19. Dicas de DbGrid
20. Gerenciando mais de uma linha selecionada
num DBGrid
21. Inserindo um Combobox num DBGrid
22. Mudar o foco do campo em um Dbgrid
23. Para você mudar as imagens do DbNavigator
24. Procura e substituição de string num campo
memo
25. QR armazenado num Blop
26. Removendo a barra de rolagem vertical do
DBGrid
27. Retornar a coluna ativa do DBGrid
28. Simulando CheckBox em DBGrid
29. Substituindo os botões do DBNavigator
30. Teclas de funções no Dbgrid
31. Transferindo o conteúdo de um memo para
um memofield
32. Trocando a cor da fonte num DBGrid
33. Trocando a cor de uma célula num DBGrid
34. Utilizando o Dblookupcombobox
Table & Query
1. Arquivos AVI e WAV em tabelas
2. Atualizando as informações em ambiente de
rede
3. BookMarks
4. Código sequencial automático
5. Colocar Senha em tabelas Paradox
6. Como Copiar os valores de campos de uma
tabela para outra
7. Como copiar tabelas Paradox para Texto ou
DBase e vice-versa
8. Como diminuir o tempo de abertura do Table
e Query
9. Como Esvaziar uma Tabela
10. Como evitar a mensagem de erro Key
Violation
11. Como filtrar registros de uma tabela pelo mês
de um campo data
12. Como retornar a uma lista os campos
indexados de um tabela
13. Como varrer uma tabela inteira
14. Compactando Tabelas
15. Compactar tabelas
16. Copiar registros de tabela para o Clipboard
17. Copiar registros de uma tabela incluindo
valores NULL
18. Criando e apagando TFields em Run-Time
19. Criando tabela em tempo de execução
20. Criando tabela em tempo de execução 2
21. Criando tabelas
22. Criando tabelas em tempo de execução 2
23. Deletar com QUERY
24. Estado de uma tabela
25. Excluir todos os registros de uma tabela
26. Exibindo solicitação de senha do banco dados
personalizada
27. Exportando uma Tabela ou uma Query para
uma página HTML
28. FindNearest numa Query
29. Função para Abrir e Fechar Query
30. Insert em duas tabelas
31. Jogar uma imagem direto para um campo da
tabela
32. Limpar um campo tipo data via programação
33. Macro no rxQuery
34. Método de procura em tabela indexada
35. O Enigma da propriedade filter do Ttable
36. Obtendo número do registro atual
37. Obter nomes dos campos de uma tabela
38. Retorna um Stringlist com todas as
informações da tabela
39. Senha em tabelas
40. Trabalhar com Filter de forma mais prática
41. Zerar Campo AutoIncremento:
SQL
1. Alterando parcialmente o conteúdo da
prop.SQL de uma Query
2. Bloco PL/SQL para inserção de dados
3. Como criar novas tabela a partir de consulta
sql
4. Como evitar que apareçam numeros
negativos na consulta
5. Como inserir um registro com o componente
UpDateSQL
6. Como usar a cláusula UNION em um Query:
7. Consulta SQL que usa a data do sistema
8. Consultando entre datas utilizando SQL
9. Consultar por mês de um campo data
10. Criando tabelas via SQL
11. Excluindo registros de uma tabela
12. Extraindo o ano, mês ou dia de uma data via
SQL
13. Impressão apartir de Consult
14. Mostrando progresso de uma SQL
15. Otimizações SQL
16. Procura com mais de um Banco de Dados
17. Selecionando registros de uma tabela que
não existam em outra tabela
18. Selecionando registros órfãos via SQL
19. Sql por campo edit pesquisando pelo nome
20. Sql relacionada com a primeira letra
21. Uso da cláusula HAVING
Datas e Horas
1. Adicionar horas
2. Colocar o mes por extenso
3. Como acrescentar dias uteis a uma data
4. Como formatar data para exibição por
extenso
5. Como incrementar 1 mês numa data
6. Como retornar quantidade de dias meses e
anos entre duas datas
7. Como saber quantos dias tem no mes
8. Como saber se o ano é bisexto
9. Como subtrair datas
10. Converte hora (formato HH:MM) para
minutos
11. converte o equivalente decimal para horas
12. Converte um certo número de segundos em
horas já formatado
13. Definir data/hora de um arquivo
14. Descobrir se uma data é fim do mês
15. Diferença entre duas horas
16. Fazendo cálculo de horas
17. Obtendo a data do último dia do mês, ou
último dia útil, de uma data informada
18. Obtendo a maior data anterior a uma data
inválida
19. Obtendo data do primeiro dia util do mês
20. Obtendo o extenso de uma data informada
21. Obtendo o extenso do mês passado por
parâmetro
22. Obtendo o próximo dia útil
23. Obtendo o último dia útil
24. Obtendo uma data acrescida de xMeses
25. Quantas Segundas tem num mês
26. Quantos fins de semana já se passaram no
corrente ano
27. Retorna a diferenca de dias entre duas datas
28. Retorna a idade atual de uma pessoa
29. Retorna a quantidade de dias uteis entre
duas datas
30. Retorna o dia da semana em formato string
31. Retorna quantos dias tem um referido mes do
ano
32. Saber se o sistema está usando 4 dígitos
para o ano
33. Testa se a hora é antes de Meio dia
34. Trabalhando com horas
35. Unit com varias funções de datas
36. Validar datas
Forms
1. A melhor maneira de liberar um form da
memoria
2. Adaptando para resoluções de video
diferentes
3. Alinha o título da barra de títulos a direita
4. Alinhar Panel ao centro do Formulário
5. Animando a abertura de um form
6. Centralizando um formulário
7. Clonando um Form
8. Coloração Gradiente no Form
9. Como controlar o fechamento de um
formulário
10. Como Criar Forms Em Tempo de Execução
11. Como criar um form completo com botões
dinamicamente
12. Como evitar efeito de maximização
13. Como incrementar a Barra de Status
14. Como mover um componente em Run-time
15. Como passar parâmetros entre 2 forms
16. Como saber qual o objeto que esta com o
foco no form
17. Como Saber se o aplicativo ja foi aberto
18. Como vazar um form usando letras
19. Como verificar que sua aplicação não está
sendo utilizada
20. Cria um MainMenu via BD automaticamente

21. Criando Formulários


22. Criando janelas não retangulares
23. Criar form sem título que possa ser arrastado
24. Definido o tamanho mínimo e máximo de um
formulário
25. Descobrindo se um form já está criado
26. Descobrindo se um form já está criado 2
27. Descobrindo se uma janela está maximizada
28. Desenhando texto 3D no form com Canvas
29. Efeito legal no caption do form
30. Efeito legal no Caption do Form 2
31. Escondendo janelas filhas minimizadas
32. Escrevendo um Texto na Diagonal usando o
Canvas
33. Evitando que o Form seja redimensionado
34. Executar algo antes de minimizar
35. Fazendo uma janela filha de outra sem usar
MDI
36. Fazer a barra de título ficar intermitente
37. Form com um furo da pra ve atraz
38. Formulário Transparente
39. Fundo do texto transparente
40. Impedir que o form seja arrastado para fora
das margens da tela
41. Manda o Form para frente
42. Mostrando um formulário Modal usando Show
43. Mostrar um Form de LogOn antes do Form
principal
44. Mover Formulário em todas as partes
45. Mudando a fonte de um menu
46. Procedimento para pedir uma senha antes de
abrir o FormPrincipal
47. Salvar/restaurar o tamanho e posição de
Form’s
48. Selecionando um formulário coberto por um
componente
49. Texto na diagonal e girando
Hardware
1. Abrir e fechar o drive de CD-ROM
2. Alterar o nome de volume (Label) de um
disco
3. Biblioteca para operações com DiskDrives
4. Capturar a data da BIOS do computador
5. Como achar um Modem e sua porta
6. Como Bloquear Mouse e Teclado
7. Como Retornar Várias informações Sobre a
BIOS
8. Como saber se o CD está no drive
9. Como saber se o disquete está no drive
10. Como tocar sons no auto-falante interno do
PC
11. Como verificar se uma porta serial está em
uso
12. Conferindo se o processador da máquina é
386, 486 ou Pentium
13. Desligar e Ligar monitor
14. Detectando o Numero Serial do HD
15. Executando sons no PC-Speaker
16. Formatar disquete
17. Habilita o Autorun para CD-Rom
18. Obter o tipo de um drive
19. Recuperar a Velocidade da CPU
20. Rotina para apagamento da senha do setup
21. Testa se seu processador pentium tem o Bug
fatal
22. Testando drives
23. Verificando o tipo de Drive
Imagens
1. Alternando Bitmaps no Fundo de um Form
2. Clone Monocromático de BitMap
3. Colocar os bitmaps na dll
4. Como alterar uma imagem desenhada na
StatusBar
5. Como apagar uma imagem de um TImage
6. Como colocar imagens em um TStatusBar
7. Como criar uma figura do tipo marca d’ água
8. Como desenhar figuras no desktop
9. Como desenhar um Bitmap num form
10. Como desenhar uma linha na diagonal
usando Canvas
11. Como retornar a cor de um pixel de uma
imagem
12. Converte um arquivo JPEG em BMP
13. Criptografando Imagens
14. Exporta uma imagem para o formato WMF
15. Gera um Thumbnail
16. Inserindo uma Imagem no Formulário
17. Mover Timage sem que ele pisque
18. Para colocar um back ground nos forms
19. Para colocarmos um .bmp como figura de
fundo
20. Transforma a imagem em negativo de
fotografia
21. Transformando ícone em um bitmap
Impressão
1. Adicionando a soma de Fields no
QRExpression do QuickReport
2. Código usados pelas impressoras HP
3. Como alterar o caption da janela de preview
do quickreport
4. Como alterar o tamanho do papel na
impressão
5. Como chamar o formulario de setup para
impressão de Gráficos
6. Como criar um contador de página no QR
7. Como imprimir com codigo fonte
8. Como imprimir escolhendo uma faixa de
Paginas no QR
9. Como Imprimir um arquivo direto para a
Impressora
10. Como Resolver o Erro “QRStandPreview
Already Exists”
11. Como saber quantas paginas vão ser
impressas com Quickrep
12. Como Salvar o Relatório do QR em imagens
JPG ou BMP
13. Como usar os arquivos QRP criados com
QuickReport
14. Data por extenso no Quickreport
15. Definir o tamanho do papel em Tprinter
16. Desabilitando o Splash Screen do Report
Smith
17. Descobrindo se há impressora instalada
18. Dica impressora matricial
19. Dicas QuickReport
20. Emissao de NF e boleto
21. Enviar relatório do Quickreport para TXT
22. Exportando Relatório do QuickReport para
HTML, DOC, TXT ou XLS
23. Fazendo uma impressão direta
24. Fazer um campo memo ocupar 2 páginas
25. Filtrando registros com o Quickreport
26. Impressão Com o TPrinter
27. Imprime o conteúdo de um TRichEdit
28. Imprimindo com o Bloco de Notas
29. Imprimindo Forms
30. Imprimindo o conteúdo de um Memo
31. Imprimindo um bitmap utilizando TPrinter
32. Imprimindo um campo memo via Canvas
33. Imprimir caracteres acentuados diretamente
para a impressora
34. Imprimir com precisão milimétrica
35. Imprimir Direto Para Impressora
36. Imprimir em impressora matricial em modo
caracter
37. Imprimir em impressora matricial em modo
caracter via Rede
38. Imprimir na Vertical no QuickReport
39. Imprimir no Delphi como no DOS “a mesma
fonte”
40. Imprimir texto justificado na impressora
Epson LX-300
41. Mudar Impressora padrão pelo nome
42. Nome da Impressora Padrão
43. Nomeando um relatório no spool de
impressão do Windows
44. Passando variáveis para o ReportSmith
45. Problemas Delphi X Imp. Xerox
46. Relatórios em HTML
47. Resolvendo Problemas do Print-Setup do
QuickReport
48. Saber se a impressora atual possui
determinada fonte
49. Tirando os botões Load e Save do Preview do
QuickReport
50. Traduzindo o preview padrão do Quickreport
51. Troca de tamanho do papel
52. Verificando se a impressora está ativa
53. Verificar se Impressora esta Conectada
Mouse
1. Biblioteca para Operações com Mouse
2. Carregar um cursor animado
3. Clicando um componente sem clicar nele
4. Clicar com o mouse
5. Como mostrar o mouse como uma ampulheta
6. Como pegar a posição do mouse na tela
7. Como Trocar o Cursor do Mouse
8. Cursor customizado
9. Inverter os botões do mouse
10. Limitando a região de movimentação do
mouse
11. Movimentando o ponteiro do mouse sem a
intervenção do usuário
12. Obter a célula de um StringGrid que está sob
o cursor do mouse
13. Ocultar/exibir o cursor do mouse
14. Posicionar o cursor do mouse em um controle
Multimédia
1. Como alterar o volume do som do
computador com o Delphi
2. Executando sons contidos num ListBox
através de chamadas MCI
3. Executar um AVI no Form
4. Gravando Sons do Microfone Com o Delphi

5. Reproduzir um arquivo WAV


6. Rodar videos em um panel
7. Tocando Sons WAV
8. Usar eventos de som do Windows
Comandos
1. Como executar programas externos
2. Como extrair o ícone de um executável
3. Como fazer para o computador soar o beep
4. Executar um programa do DOS
5. Executar um programa do Windows
6. Executar um programa DOS
7. Exponenciação
8. Fechar outro programa
9. Formatando Strings
10. OnGetEditMask, OnGetEditText e
OnSetEditText do TStringGrid
11. Para Saber Somente o Path da Aplicação
12. Principais Procedimentos e Funções Pré
definidas
13. StrToIntDef
14. Usando MessageBox
15. Utilizar o MessageBox com parâmetros
Object Pascal
1. Aguardar um determinado número de
segundos
2. Armazenando BMP’s em arquivos RES
3. Array de Edit boxes
4. Arredondando valores
5. Calcular percentual de Valor
6. Colocar zeros a esquerda no componente Edit
7. Comandos para Threads
8. Como arredondar um valor do tipo Float /
Double
9. Como atribuir um valor inicial para uma
variável global
10. Como gerar numeros randomicos para
loterias
11. Como indexar um vetor
12. Como reduzir expressões if then else
13. Como tranformar de inteiro (Milisegundos)
em formato Timer
14. Como transformar de uma Classe para outra
15. Como verificar se um campo inteiro é par ou
ímpar
16. Compilando a aplicação pelo MS-DOS
17. Construindo Threads com Delphi
18. Convertendo valor Hexadecimal para Inteiro
19. Descobrindo se um objeto tem uma
determinada propriedade
20. Desenhando com tipos diferentes de linhas
21. Desenhando em Delphi via programação
22. Formatação de Casas Decimais
23. Função de potenciação - Juros
24. Função que arredonda valores
25. Função Split
26. Funções Aritméticas suportadas pelo Pascal
27. Funções de CRC
28. Implementar rotinas assembly em Pascal
29. InputBox para entrada de Senhas (com
caracter *)
30. Inserindo zeros no inicio de um inteiro
31. MessageBox com o NÃO como default
32. Pesquisa de um string mudando o texto
33. Retorna a cor de um componente no formato
string
34. Retorna que tipo de variavel é
35. Selecionando vários objetos dentro de um
outro
36. Senhas Aleatórias
37. Sistemas Numéricos
38. Sobrescrevendo um evento
39. Sublinhando no Canvas
40. Tabela de Máscaras
41. Texto Rotativo
42. Tipos de Array
43. Transformar inteiro em romanos
44. Truncar valores reais para apenas n casas
decimais
45. Usando o objeto Sender internamente
46. Usando TList e Record como Array
47. Utilizando Threads
48. Validar Inscrições Estaduais
49. Vetor Dinamico
Hint
1. Alterar fonte do hint
2. Cor de fundo do hint
3. Eliminando os hints de uma treeview
4. Hint Com Quebra De Linha
5. Melhorando a aparência do seu Hint
6. Mostrar o HINT num Panel
7. Mostrar o Hint para cada coluna do StringGrid
Outras Dicas
1. 13 Pequenas modificações no Delphi
2. Acessando Membros Protegidos de um Objeto
3. Atalhos de Teclado da IDE do Delphi
4. Caixas de mensagens da aplicação
5. Capturando conteúdo do desktop
6. Capturar ecrã
7. Chamando Help
8. Como converter de decimal para binario
9. Como converter decimal para base
especificada
10. Como converter decimal para romanos
11. Como enviar dados do Delphi para o Excel
12. Como evitar as mensagens de Warning do
Compilador
13. Como evitar as mensagens de Warning do
Compilador (Variavel não inicializada)
14. Como fazer para um executavel se Auto-
Deletar
15. Como fazer um Hot Link
16. Como Fazer um Protetor de Tela no Delphi
17. Como fazer uma unit como biblioteca
18. Como fechar um arquivo de Help quando
encerro minha Aplicação
19. Como instalar componentes 3
20. Como Instalar no Delphi o ActiveX do Flash
21. Como Instalar RXLIB no Delphi 5
22. Como ler código de barras
23. Como mudar a cor de uma regiao de Texto
RichEdit
24. Como registrar um OCX
25. Como Usar ASSEMBLER com Delphi
26. Como usar o Install Shield
27. Como usar recursos do word
28. Como usar um frame em sua aplicação
29. Como utilizar código de barras no meu
sistema
30. Como verificar se falta algum edit para
preencher
31. Como Visualizar arquivos ARJ
32. Compilar *.pas fora do Delphi
33. Contar todos os itens e subintem de um
menu
34. Criando componentes em tempo de execução
35. Criando cores personalizadas
36. Criando e Distribuindo Aplicações Shareware
37. Criando fontes no Delphi
38. Criando uma barra de status
39. Criando uma barra de status completa
40. Criar atalho no desktop
41. Criar caixas de diálogo em tempo de
execução
42. Criar Código de Barras 2x5i
43. Criar um documento no Word
44. Criar um EXE que seja executado apenas
através de outro EXE criado por mim
45. Cuidados ao usar o OnExit (Parte I):
46. Cuidados ao usar o OnExit (Parte II):
47. Cuidados quando criar procedimentos e
funções com parametros
48. Deixando o EXE menor e mais rápido
49. Dicas Práticas
50. Enviando Caracter Aleatório à uma Janela

51. Evitar a proteção de tela durante seu


programa
52. Executando o comando ARJ em um aplicativo
Delphi
53. Executar um arquivo com extenção *.lnk
54. Exemplo de Arraste
55. Exibindo imagens em caixas de mensagens
de Aplicações CLX
56. função captura a tela e salva-a em um
Bitmap
57. Função para Criar Subescrito e Sobrecrito
58. Função para gerar Log de Erros
59. Gerar Código de Barras EAN13
60. Gerar uma tabela no Word através do Delphi
61. Habilitar e desabiliar a senha do protetor de
tela
62. Instalando componentes
63. Instalando os componentes RXLIB 2.40 no
Delphi 3
64. Instalando os componentes RXLIB
2.50/2.60/2.75 no Delphi 4
65. Marcando um pedaço do código
66. Mostrar mensagem mesmo que esteja no
Prompt do DOS
67. Mudando o foco para o próximo controle
68. O Delphi faz alguma coisa em C++.
69. Opções de Projeto
70. Procedimentos com parâmetros opcionais:
71. Protegendo o seu programa e o seu bolso
72. Quando der problema na instalação do
componente
73. Sender - Objeto
74. Significados dos componentes da RXLIB
75. Splash Screen
76. Tabela para texto (CSV) num piscar de olhos

77. Verificar se determinado programa está em


execução (Word, Delphi, etc)
78. Verificar se variavel está vazia
79. Visualizar aruqivos compactados CAB
Outros Componentes
1. Alinhando itens do menu principal à direita
2. Alinhar Texto do Edit à Direita
3. Alterando a cor dos TabSheet de um
PageControll
4. Atribuindo a uma coluna do StringGrid como
só de leitura
5. Caption do BitBtn com várias linhas
6. Caracteres Especiais que compõem uma
MaskEdit
7. Carrega os dados, salvos em um arquivo, em
um StringGrid
8. Colocando bitmaps num ComboBox
9. Colocando BMP’s em StringGrids
10. Colocando um barra Horizontal em um
ListBox
11. Colocar o cursor no final do TEdit ao receber
o foco
12. Colocar uma ProgressBar da StatusBar
13. Como Abrir Sempre o Mesmo Tabsheet
Dentro de Um Pagecontrol
14. Como abrir um TComboBox sem clicá-lo
15. Como adicionar uma linha formatada (cor,
negrito, etc) num RichEdit
16. Como colocar BitButton no messagedlg
17. Como colocar imagens numa StatusBar
18. Como colocar um componente ComboBox em
um componente StringGrid
19. Como colocar uma unica linha de uma
stringgrid editavel
20. Como colorir os itens de um TCheckListBox

21. Como evitar repetição em uma lista de


ComboBox
22. Como fazer para ajustar o tamanho da lista
de um combobox?
23. Como fazer para que o ComboBox abra na
direcao desejada
24. Como formatar um TMemo ou TRichEdit em
formato HTML
25. Como inserir um item em um TreeView em
Run Time
26. Como ir para o final de um texto com o
Richedit
27. Como Limpar Todos os Edit’s de um Form de
uma só vez?
28. Como mudar o foco após digitar toda a data
29. Como selecionar um item de um listbox
30. Como tabular um ListBox
31. Como trocar a cor do componente focado
32. Como trocar o Glyph de um BitButton em
tempo de execução
33. Convertendo a primeira letra de um EditBox
para maiúsculas
34. Criando um componente Skin
35. Criar labels em tempo de execução
36. Desabilitando um RadioButton Num
RadioGroup
37. Enviar comandos de rolagem vertical para um
TMemo
38. Espaço maior no RichEdit
39. Executando ações padrão de um Ole
Container
40. Label escrita letra a letra
41. Listbox
42. Margem para RichText
43. Modificando a posição do cursor em um
Memo
44. Mudando a cor dos componentes assim que
receber o foco
45. Mudandp o texto de um edit no evento
OnChange
46. Obtendo o indice de um componente em
tempo de execução
47. Para ocultar em tempo de execução uma
coluna de um stringgrid
48. Para trocar as cores dos botoes do radiogroup
49. Pegando a linha e coluna atuais de um memo
50. Pesquisa incremental em uma listbox
51. Posicionando o cursor numa linha de um
Memo ou RichEdit
52. Salvando e Restaurando uma Tstringgrid
53. Selecionar todo o conteúdo de um Memo ou
RichEdit com as teclas Ctrl+A
54. String Grid Colorido
Rede Local & Internet
1. Baixando arquivos da internet
2. Bloqueando um arquivo em ambiente de rede
3. Chamar um e-mail pelo Delphi
4. Chamar um site utilizando o seu browse
padrão
5. Checar se a URL existe
6. Comandos para Dial-up com Delphi
7. Como alterar a Página Inicial do IE via
Programação
8. Como compartilhar uma pasta de um outro
micro e mapear com uma letra
9. Como conectar uma unidade de rede
10. Como descobrir se você está conectado com
a Internet?
11. Como desconectar unidade de rede
12. Como enviar mensagem para todos que estão
conectados na REDE WinNT
13. Como pegar a lista de favoritos do Internet
Explorer
14. Como pegar a URL ativa no Browser
15. Como saber se estou conectado à internet
16. Configuração do BDE para ambiente de rede
17. Configurando a Rede em Win95/Win98 com
Delphi
18. Configurando RedeNovell NetWare com Delphi
19. Criar um programa para transferencia via ftp

20. Detectando o tipo de Conexão com a internet


21. Download com Thread
22. Enviar um email
23. Envio de E-Mail com Indy
24. Executa uma Url a partir do Netscape mesmo
que ele não seje o Browser padrão
25. Executando uma chamada para a Conexão
Dial-Up
26. Executar Internet Explorer
27. Fazendo um Web Browser
28. Gerando um arquivo HTML
29. Link para WEB
30. Manipulando o Internet Explorer
31. Mostrar todas as unidades mapeadas na
máquina.
32. Mudando o IP da máquina via API do
Windows
33. Nome do Host da Conexão
34. O Dilema do envio de e-mail
35. Obter o endereço IP do Dial-Up
36. Pegar nome do usuário na rede
37. Retorna o IP de sua máquina no momento
em que você está conectado
38. Retorna Path de Browser Padrão
39. Tipo de Conexão
40. Transferência de som em um CHAT
41. Usuario logado
42. Validando formato de e-mail
43. Verificando o seu endereço IP
44. Verificando se já estou conectado na Internet
String
1. Abreviando Nomes
2. Biblioteca com funções para Strings
3. Biblioteca para Operações com Strings
4. Caixa Mista
5. Centralizando uma string
6. Checa se o Simbolo da UF é Valido
7. Código gerador de senha
8. Como Calcular Digito Verificador de CNPJ e
CPF
9. Como extrair o primeiro nome de uma pessoa
10. Como obter uma string entre outras duas
11. Como separar termos de uma string
12. Como tirar os espaços no início e no final de
uma string
13. Como utilizar strings de recurso em suas
aplicações
14. Como verificar se uma string contém um
inteiro
15. Convertendo PCHAR para STRING
16. Convertendo um número real para string com
2 casas
17. Converter Binario para Inteiro
18. Converter qualquer variavel em string
19. Digito Verificador
20. Eliminar Caracteres de Strings
21. Encriptar/Desencriptar strings
22. Extrair palavra que está sob o cursor
23. Formatar CEP
24. Função para obter os termos de uma string
25. Função que deleta vários items de um listbox
26. Função que devolve tempo decorrido em uma
string
27. Função que retorna texto entre caracteres
28. Gera número por extenso
29. Invertendo uma string
30. Justificar Texto
31. Obtendo a posição da enésima ocorrência da
string ‘T’ na string ‘S’
32. Obtendo a Posição Inicial da Próxima palavra
após o caracter indicado por ‘InitPos’
33. Obtendo a próxima palavra após os espaços
determinados por ‘BlankToSkip’
34. Obtendo o nº de ocorrências de uma string
‘T’ dentro de outra ‘S’
35. Preenche com quantidade determinada de
zeros o lado esquerdo de uma string
36. Procurar Strings numa ListBox
37. Quantas Palavras existem?
38. Quebra de String
39. Quebra de String Versão 2 melhorada
40. Remove caracteres de uma string deixando
apenas numeros
41. Replace Str
42. Retirando acentos de uma string
43. Rotina para criptografia mais absoluta
44. Separar (filtrar) caracteres de uma string
45. Trabalhando com Strings
46. Trabalhar com cores no formato string
47. Transformar literal em extenso
48. Um Contador de letras
49. Validando CEP
50. Validando número de cartão de crédito
51. Validando Titulo de Eleitor
52. Verifica Validade de CGC e CPF
53. Verificação de PIS
54. Verificar se uma string contém um valor
numérico válido
55. Verificar se uma string contém uma hora
válida
56. Verificar se uma string é uma data válida
Teclas
1. Bloqueio de palavras
2. Caps Lock e Num Lock
3. Como controlar o pressionamento da tecla
Enter
4. Como definir seu próprio hotkey
5. Como desabilitar as teclas Alt + F4
6. Como descobrir o código de uma tecla
pressionada?
7. Como detectar as teclas de seta
8. Como obrigar a digitação de caracteres
maiúsculos num campo memo
9. Como posso rolar um form com PgUp e PgDn
10. Como saber o estado das teclas Num lock,
Caps lock e Scroll lock
11. Como usar as teclas de função F1, F2, etc?
12. Como validar a entrada em um TEdit
13. Desabilitar Teclas Alt+Ctrl+Del
14. Descobrir o código ASCII de uma tecla
15. Emular o pressionamento de uma tecla
16. Enter funcionando como Tab em toda a
aplicação
17. Enviando caracteres para outra aplicação
18. Enviando combinação de teclas para o buffer
do teclado
19. Evitando caracteres com acento
20. Gravando e reproduzindo as teclas digitadas
no delphi
21. Interceptando as teclas de função no seu
programa
22. Ligar/desligar a tecla Caps Lock
23. Ponto Decimal
24. Simular o pressionamento de uma
combinação de teclas
25. Simular Print Screen
26. Simular um CharCase no DBGrid
27. Substituindo TAB pelo ENTER
28. Teclas mágicas para trabalhar mais rápido
29. Testa se determinada tecla está pressionada
30. Verificar se uma determinada tecla está
pressionada
31. Virtual keys
Registro
1. Alterar o LOCAL SHARE via programação
2. AutoExecução do Programa via Registro
3. Chaves do Registro
4. Exemplos de path via registro
5. Função que retorna o nome do Computador
6. Lendo e Escrevendo dados binários no
Registro do Windows
7. Obter o tipo de dado de um valor no Registro
do Windows
8. Pegando o Nome do usuário e a Empresa do
Windows
9. Pegando o registro do windows
10. Usando o Registro do Windows
11. Usando o Registro do Windows 2
12. Utilizando o registro do Windows
Sistema
1. Biblioteca para Operações com o Sistema
2. Capturar Erros e Enviar por E-mail
3. Capturar informações do ambiente DOS
4. Chamar um programa e esperar a finalização
5. Colocando funções em uma DLL
6. Como adicionar items de menu
dinâmicamente
7. Como alterar a data e a hora do sistema
8. Como extrair o número de cores do modo de
vídeo corrente do Windows95
9. Como gerar um clone de um programa
10. Como Manipular arquivos .INI 2
11. Como manipular arquivos INI
12. Como obter informações do S.O.
13. Como reduzir o tempo e carga de um
programa
14. Configurações internacionais
15. Criando Log básico para qualquer aplicação
Delphi
16. Criando uma rotina para pegar todos os erros
do programa
17. Criar Dll´s
18. Descobrindo se o aplicativo está minimizado
19. Detectando e Finalizando o screen saver
20. Exclusividade para o programa
21. Executando uma única cópia do aplicativo
22. Executar um programa e aguardar sua
finalização antes de continuar
23. Executável com parâmetros
24. Exemplo de como pegar o nome de um
objeto ou janela
25. Fazendo sua aplicação executar sem
apresentar o form principal
26. Fechar um aplicativo com uma mensagem de
erro fatal
27. Função para Desligar o Windows 2000
28. Funções para detectar o SoftIce
29. Linkar um OBJ ao executavel
30. Manipulando Application
31. Número de cores suportadas pelo seu Monitor
32. Para chamar um HTMLHelp (.chm) a partir da
aplicação Delphi
33. Path de Aplicativo associado a uma extensão
34. Pegar informações de Executavel
35. Permitir cancelar processo demorado
36. Personalizar a mensagem de erro do Delphi
37. Resgate de variaveis do ambiente DOS
38. Retorna a versão do aplicativo
39. Tipo de Executável
40. Todos os programas que estão em execução
41. Tradução de Mensagens
42. Usando funções externas (de DLLs)
43. Verificando a memória
44. Verificando se há uma cópia em execução
45. Verificando se o Delphi esta Aberto
Windows
1. Abrir as configurações do Vídeo do Painel de
Controle
2. Adicionando uma nova fonte no Windows
3. Adicionar Fonte no Windows
4. Alterar o ícone do botão iniciar do Windows
5. Alterar o papel de parede 1
6. Alterar o papel de parede 2
7. Alterar o papel de parede 3
8. Ativar a proteção de tela
9. AutoOcultar a barra de tarefas
10. Chamar a Lista de Tarefas e Menu Iniciar
11. Como anda a lista de processos do windows
NT
12. Como chamar a pasta impressoras
13. Como desabilitar o menu pop-up do
windows(Na area de trabalho)
14. Como Finalizar o Windows sem Avisar?
15. Como saber há quanto tempo o WINDOWS
foi inicializado
16. Como utilizar o form Sobre padrão do
Windows
17. Criando um menu Janela e listando nele as
janelas abertas em tempo de execução
18. Desabilitar o botão fechar o form
19. Desligando Windows via programação
20. Detectando a finalização do Windows
21. Diretório de instalação do windows
22. Diretório Windows e System
23. Drag e Drop com o Windows Explorer
24. Esconde/Mostra a Barra de Tarefas
25. Escondendo o Programa de Ctrl+Alt+Del
26. Escondendo/Mostrando o botão Iniciar
27. Esconder icones do desktop
28. Esconder o icone da Barra de Tarefas
29. Executar o Windows Explorer com parametros
30. Exibindo o diálogo About do Windows
31. Finalizando todas as tarefas
32. Interrompendo o desligamento do Windows
33. Mostrar as fontes TrueType Instaladas
34. Mudar a resolução do vídeo via programação
35. Não aparecer na barra e tb como não
aparecer no ctr+alt+del.
36. Ocultar/Mostrar o Relógio na Barra de Tarefas
37. Saber se determinada Font está instalada no
Windows
38. Usando as APIs para Procurar e Mover janelas
do Windows
39. Verificando se uma determinada fonte esta
instalada
001 - Como Fazer um Protetor de
Tela no Delphi
Para o pessoal que queria saber…
A) No .Dpr ponha {$E SCRNSAVER} depois do uses
B) No Form principal nao ponha borda ou icone. No
metodo Activate ponha left e top como 0 e o
Windowstate como wsMaximize.
C) no form.Create ponha application.OnMessage para
um metodo que controle a desativacao do screen saver.
Ponha tb o application.OnIdle para “rodar” o dito cujo…
D) Tb no Form.Create teste a linha de comando para /c
ou /s. Estes Parametros dizem o que e’ para fazer (/c
configura)
E) Compile e renomeie o .exe p/ .scr, move para o
diretorio do windows e…
- Complemento enviado por Marcus
Vitoratti 
As pessoas devem estar sofrendo por causa desta dica,
não é? Só que tenho a solução: um componente
gratuito.

Veja a descrição:
TScreenSaver
Por Jon Baker. O componente permite a você criar
protetores de tela para Windows 95 & Nt.* Somente
coloque o componente no seu Form e irá pegar todos os
parametros, como /p, /s, /c, /a e mostrar a visualização,
configuração, password, etc.

* Eu destaquei esta parte porque funciona também


em Windows 98, funcionando também
provavelmente em Windows ME, XP e 2000.

Tamanho: 197 Kb.


Funciona a partir do Delphi 2.
Link: http://www.torry.net/vcl/system/windows/scrnsvr.zip
Totalmente Freeware.
Com fontes.

Ass.
Marcus
002 - Linkar um OBJ ao executavel
Primeiro voce deve “linkar” o OBJ ao seu executavel. No
Delphi , isto eh feito com a diretriz de compilacao $L.
Fica, na sua unit principal, assim:
{$L MyOBject.OBJ}
Incluindo as chaves.
Logo depois, voce deve declarar a funcao contida em
MyObject.OBJ da forma usual. Voce precisara conhecer
os parametros usados pela mesma, bem como o tipo e a
ordem em que sao passados. Voce deve incluir tambem
a diretriz PASCAL ou CDECL. Sugiro tentar primeiro
com PASCAL. Ficaria assim (na secao implementation:
function (Parametro1 : TipoDoParametro1,
Parametro2 : TipoDoParametro2):
TipoDoRetorno; pascal;
se nao der certo, tente:
function (Parametro1 : TipoDoParametro1,
Parametro2 : TipoDoParametro2):
TipoDoRetorno; cdecl;
caso nao seja uma funcao e sim uma procedure, tente
procedure (Parametro1 : TipoDoParametro1,
Parametro2 : TipoDoParametro2);
pascal;
ou
procedure (Parametro1 : TipoDoParametro1,
Parametro2 : TipoDoParametro2);
cdecl;
Se voce nao sabe quais os parametros usados pela
funcao/procedure, uma solucao seria linkar o seu OBJ
num programa qualquer e disassembla-lo. Ai pelo
menos voce sabera a quantidade e o tipo de cada
parametro. De qualquer forma, para saber para que
serve cada um, tera que ser na tentativa e erro…a nao
ser que voce tambem tenha paciencia para analisar o
codigo disassemblado.
OBS: Se o seu OBJ nao estiver num formato
reconhecivel pelo LINK do Delphi (um formato similar ao
COFF), voce pode tentar outros Linkers, e criar uma dll.
Existem varios linkers gratuitos, que reconhecem varios
formatos (exemplos, sao lcclnk, djlnk, walk2lnk e o
proprio linker da microsoft…tambem gratuito).
003 - Alterar o LOCAL SHARE via
programação
No WIN 95 você pode alterar diretamente a chave do
registro que seta esta opção. Fica em
HKEY_LOCAL_MACHINE > Software > … LOCAL
SHARE “TRUE” (Pesquise com o regedit). Já no WIN
3.xxx eu também gostaria de saber.
Contribuição
O Willian Vieira dos Santos enviou esse procedimento
que serve para realizar esses tipos de modificações
Procedure
ModifyBDE(Path,Chave,Valor:String);
var ParamList: TParamList;
Lista:TStringList;
cfgMode:TConfigMode;
i:Integer;
begin
Lista:=TStringList.Create;
//Recupera Lista de Configurações
Session.GetConfigParams(Path,”,Lista);
//Verifica na lista, onde a chave
modificada se encontra
For i:=0 to Lista.Count-1 do
If
Pos(UpperCase(Chave),UpperCase(Lista[i]))
<>0 Then
Lista[i]:=UpperCase(Chave)+’=’+Valor;
//Salva o atual modo de configuração da
variável de sessão
cfgMode:=Session.ConfigMode;
//Coloca em modo de alteração
Session.ConfigMode:=cmPersistent;
//Cria lista de parâmetros
ParamList := TParamList.Create(Lista);
//Chama API do BDE para modificar as
configurações
Check(DbiCfgModifyRecord(nil,
PChar(Path), ParamList.FieldCount,
PFLDDesc(ParamList.FieldDescs),
ParamList.Buffer));
//Recupera o modo de configuração da
variável de sessão
Session.ConfigMode:=cfgMode;
//Salva as configurações da sessão
Session.SaveConfigFile;
ParamList.Free;
Lista.Free;
End;

//Alguns exemplos de chamada da função


para modificar o valor no BDE
//Nota: certas chaves possuem alguma
diferença quanto ao Path no BDE
ModifyBDE(‘\System\FORMATS\NUMBER’,‘DECIMA
LSEPARATOR’,’,’);
ModifyBDE(‘\System\Init’,‘Local
Share’,‘TRUE’);
ModifyBDE(‘\Drivers\Paradox\Init’,‘Net
Dir’,‘F:');
OBSERVAÇÃO: Após utilizar a função é necessário
reiniciar o sistema, talvez por causa da variável de
sessão. Um teste que eu ainda não fiz, foi dar um
close/open na sessão para não ter que reiniciar o
sistema. Com certeza, as Query’s e Table’s serão
fechadas necessitando reabri-las.
Enviada Por:
willian@microdata-online.com.br
Willian Vieira dos Santos
Analista/Programador
Microdata S/C Ltda.
004 - Verificando se o Delphi esta
Aberto
Proteja aquele aplicativo ou objeto que vc desenvolveu
com esta rotina que identifica se o usuário está com o
Delphi aberto (disponibiliza) ou fechado (trava a
execucao).
Bom proveito !
Function
TForm1.JanelaExiste(Classe,Janela:String)
:Boolean;
var
PClasse,PJanela : array[0..79] of char;
begin
if Classe = ” then
PClasse[0] := #0
else
StrPCopy(PClasse,Classe);
if Janela = ” then
PJanela[0] := #0
else
StrPCopy(PJanela,Janela);
if FindWindow(PClasse,PJAnela) <> 0 then
result := true
else
Result := false;
end;

Function TForm1.DelphiCarregado : Boolean;


begin
Result := False;
if
JanelaExiste(‘TPropertyInspector’,‘Object
Inspector’) then
result := True
end;
procedure TForm1.FormCreate(Sender:
TObject);
begin
if DelphiCarregado then
showmessage(‘Delphi está ativo, bom
menino!’)
else
begin
Showmessage(‘Vc não poderá utilizar esta
aplicação! Mau garoto!’);
application.terminate;
end;
end;
005 - Criando Formulários
Qual a melhor maneira de criar forms em tempo de
execucao:
a) Application.CreateForm(TfmClientes, fmClientes);
Cria o Form; o proprietário é a aplicação.
b) fmClientes := TForm.Create(self);
Cria o Form; o proprietário é ele mesmo.
c) fmClientes := TForm.Create(Application);
Cria o Form; o proprietário é a aplicação.
d) fmClientes := TForm.Create(nil);
Cria o Form; teoricamente sem proprietário; na
prática é a aplicação.
e) fmClientes := TfmClientes.Create(self);
Cria o Form; o proprietário é ele mesmo.
f) fmClientes := TfmClientes.Create(Application);
Cria o Form; o proprietário é a aplicação.
g) fmClientes := TfmClientes.Create(nil);
Cria o Form; teoricamente sem proprietário; na
prática é a aplicação.
Poderiam me informar a diferenca entre elas?
Quando você cria um Form dinamicamente:
1. se criar através de CreateForm, que é um método de
TApplication, você passa como parâmetro a instância da
classe e o nome do seu objeto (TfmClientes,
fmClientes);
2. se criar através de Create - método de TForm, entre
outros - você passa como parâmetro o proprietário do
componente criado (no caso o Form).
2.1 se o proprietário for a aplicação, o Form só será
destruído quando você finalizar o aplicativo ou se
você declarar Free ou Destroy no seu programa;
(casos a, c, d, f, g);
2.2 se o proprietário for ele mesmo (self), o form
terá que ser destruído por você;
2.3 se você criar, por exemplo, Form2 e passar
como proprietário Form1; no momento em que
Form1 for destruído, Form2 também o será.
Quanto à melhor maneira, depende de como você quer
controlar a aplicação, mas leve em conta que enquanto
um objeto não é destruído, ele está na memória.
006 - Criado Alias via programação
Inclua na seção uses: DB
{ se o alias não existir… }
if not Session.IsAlias(‘MeuAlias’) then
begin
{ Adiciona o alias }
Session.AddStandardAlias(‘MeuAlias’,
‘C:\DirProg’, ‘PARADOX’);
{ Salva o arquivo de configuração do BDE }
Session.SaveConfigFile;
end;
Para criar um alias do dBase troque a string ‘PARADOX’
por ‘DBASE’. No caso acima usei como path o caminho
“C:\DirProg”, mas se você quiser poderá trocar este
caminho por ExtractFilePath(ParamStr(0)) para que o
alias seja direcionado para o local onde est
007 - Desabilitar Teclas
Ctrl+Alt+Del
Ai vai um codigo que peguei no site da Borland que
trava as teclas
(Ctrl+Alt+Del),(Alt+Tab), (Ctrl+Esc)
var
OldValue : LongBool;
begin
{liga a trava}
SystemParametersInfo(97, Word(True),
@OldValue, 0);
{desliga a trava}
SystemParametersInfo(97, Word(False),
@OldValue, 0);
end;
008 - Splash Screen
form2:=tform2.create(application);
form2.show;
form2.update;
.
.
.
form2.hide;
form2.free;
Application.Run;

Obs: apagar a primeira linha, ‘Application.Initialize’.


009 - Para Saber Somente o Path
da Aplicação
Para saber somente o path da aplicação
ExtractFilePath( Application.ExeName )
010 - Como Saber se o aplicativo ja
foi aberto
Como saber se o aplicativo já foi aberto
Insira o código abaixo dentro do arquivo .DPR de sua
aplicação
{$R *.RES}
begin
Application.Title := ”;
Application.HelpFile := ”;
if HPrevInst = 0 then
begin
F_Splash := TF_Splash.create(Application);
F_Splash.Show;
Application.CreateForm(TF_Menu, F_Menu);
Application.CreateForm(TF_Error, F_Error);
Application.CreateForm(TF_Form1, F_From1);
Application.CreateForm(TF_Form2,
F_Form2j);
Application.Run;
end
else
messagedlg(‘O sistema já foi
nicializado!’,mtinformation,[mbok],0);
end.
011 - Impressão Com o TPrinter (
Via gerenciador de impressão)

procedure TForm1.BitBtn1Click(Sender:
TObject);
var
Linha:integer;
Tamanho:integer;
Coluna:integer;
begin
Printer.Orientation := poLandscape;
Printer.BeginDoc;
Printer.Canvas.Pen.Width := 5;
Printer.Canvas.Font.Name := ‘Times New
Roman’;
Printer.Canvas.Font.Size := 10;
Linha := 20;
Coluna:= 20;
Tamanho := Printer.Canvas.TextWidth(‘a’);
Table1.First;
while not Table1.Eof do
begin
if Linha = 20 then
begin
Coluna := 20;
Printer.Canvas.TextOut(0,Linha,‘Relação de
Clientes’);
Linha := Linha -
Printer.Canvas.Font.Height + 5 ;
Printer.Canvas.TextOut(Coluna,Linha,‘Cod’)
;
Coluna:= Coluna + (Tamanho * 5 );
Printer.Canvas.TextOut(Coluna,Linha,‘Nome’
);
Coluna:= Coluna + (Tamanho * 30);
Printer.Canvas.TextOut(Coluna,Linha,‘Ender
eço’);
Coluna:= Coluna + (Tamanho * 30);
Linha := Linha -
Printer.Canvas.Font.Height + 5 ;
end;
Coluna := 20 ;
Printer.Canvas.TextOut(Coluna,Linha,Table1
.FieldByName(‘Codigo’).AsString);
Coluna:= Coluna + (Tamanho * 5 );
Printer.Canvas.TextOut(Coluna,Linha,Table1
.FieldByName(‘Nome’).AsString);
Coluna:= Coluna + (Tamanho * 30);
Printer.Canvas.TextOut(Coluna,Linha,Table1
.FieldByName(‘End’).AsString);
Coluna:= Coluna + (Tamanho * 30);
Linha := Linha -
Printer.Canvas.Font.Height + 5 ;
Table1.Next;
if Linha > Printer.PageHeight-20 then
Begin
Printer.NewPage;
Linha := 20;
end;
end;
Printer.EndDoc;
end;
012 - Imprimir Direto Para
Impressora
procedure TForm1.Button1Click(Sender:
TObject);
var
F : TextFile;
i : integer;
begin
AssignFile(F,‘LPT1’);
Rewrite(F);
i := 0;
Writeln(F,‘Teste de impressao - Linha 0’);
Writeln(F,‘Teste de impressao - Linha 1’);
Writeln(F,#27#15+‘Teste de Impressão -
Linha 2’);
Writeln(F,‘Teste de impressao - Linha 3’);
Writeln(F,#27#18+‘Teste de Impressão -
Linha 4’);
Writeln(F,‘Teste de impressao - Linha 5’);
Writeln(F,#12); // Ejeta a página
CloseFile(F);
end;
013 - Definir o tamanho do papel
em TPrinter
Esta procedure configura o tamanho do papel em Run-
Time para ser utilizado com o objeto TPrinter; Esta
procedure deve ser chamada antes de aplicar o método
Printer.BeginDoc.
procedure TForm1.SetPrinterPage(Width,
Height : LongInt);
var
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port : array[0..255] of char;
hDMode : THandle;
PDMode : PDEVMODE;
begin
Printer.GetPrinter(Device, Driver, Port,
hDMode);
If hDMode <> 0 then
begin
pDMode := GlobalLock( hDMode );
If pDMode <> nil then
begin
pDMode^.dmPaperSize := DMPAPER_USER;
pDMode^.dmPaperWidth := Width;
pDMode^.dmPaperLength := Height;
pDMode^.dmFields := pDMode^.dmFields or
DM_PAPERSIZE;
GlobalUnlock( hDMode );
end;
end;
end;
014 - Como Criar Forms Em Tempo
de Execução
Para você economizar memória, pode-se criar os forms
de sua aplicação somente no momento da execução. Na
criação do Form você define se ele é MODAL ou NÃO
MODAL. Para Isso observe os seguintes códigos:
MODAL - Mostra form em modo exclusivo
procedure TForm1.Button1Click(Sender:
TObject);
begin
Application.CreateForm(TForm2, Form2);
{Carrega form na memória}
Form2.ShowModal;{Mostra form em modo
exclusivo}
Form2.Free; {Libera Memória}
end;
NÃO MODAL - Mostra form em modo não exclusivo
procedure TForm1.Button1Click(Sender:
TObject);
begin
Application.CreateForm(TForm2, Form2);
{Carrega form na memória}
Form2.ShowModal;{Mostra form em modo
exclusivo}
end;
No evento OnClose do Form2 coloque o seguinte
código.
procedure TForm2.FormClose (Sender:
Tobject; var Action : TCloseAction);
begin
Action:= caFree;
end;
Aliado a este código, você deve alterar no delphi, no
menu Options, opção Project. Mudando os forms a
serem criados dinamicamente da coluna Auto-Create
Forms para Avaliable Forms.
015 - Adaptando para resoluções
de video diferentes?
Sempre que procurei algo sobre esse tema, ia para no
Tip da Borland #2861, que é a mesma informação do
arquivo de help da Loyd’s. Esse texto tambem aparece
nos bancos de dados da Q&A. Eu suponho que essa
seja a informação definitiva. Encontreiuma informação
que não foi mencionada aqui. Pela lista de correiros do
Delphi-Talk havia mensagens de Brien King e
MichaelNovak que discutiam esse assunto.
***
LOYD´S TIPS:
Resolução de Vídeo:
Quando criamos formulários, ãs vezes é útil escrever um
código para que a tela e todos os seus objetos sejam
mostrados nomesmo tamanho, não importando qual a
resolução da tela. Aqui esta um código que mostra como
isso é feito:
Implementation
const
ScreenWidth: LongInt = 800; {I designed my
form in 800x600 mode.}
ScreenHeight: LongInt = 600;
{$R *.DFM}
procedure TForm1.FormCreate (Sender:
Tobject);
begin
scaled := true;
if (screen.width <> ScreenWidth) then
begin
height := longint(height) *
longint(screen.height) DIV ScreenHeight;
width := longint(width) *
longint(screen.width) DIV ScreenWidth;
scaleBy(screen.width, ScreenWidth);
end;
end;
Agora, você vai querer checar, se o tamanho dos
fontes(de letra) estão OK. Antes de trocar p tamanho do
fonte, você precisará ter
certeza de que o objeto realmente tem a propriedade
fonte pela checagem da RTTI. Isso pode ser feito assim:
USES typinfo; {Add this to your USES
statement.}
var
i:integer;
begin
for i := componentCount - 1 downto 0 do
with components[i] do
begin
if GetPropInfo(ClassInfo, ´font´) <> nil
then
font.size := (NewFormWidth DIV
OldFormWidth) * font.size;
end;
end;
{Esta é a maneira longa de fazer a mesma coisa}
var
i:integer;
p:PPropInfo;
begin
for i := componentCount - 1 downto 0 do
with components [i] do
begin
p := GetPropInfo (ClassInfo, ´font´);
if assigned (p) then
font.size := (NewFormWidth DIV
OldFormWidth) * font.size;
end;
end;
Atenção: Nem todos os objetos tem a propriedade
FONT. Isso deve ser o suficiente para você começar.
Atenção: A seguir, algumas dicas para ter em mente
quando representar aplicações Delphi (formulários) em
diferentes resoluçõesde Tela:
* Decida antecipadamente, na etapa de criação do
formulário, se ele será escalável ou não. A vantagem de
um não escalável é que nada muda em tempo de
execução. A desvantagem é equivalente (seu formulário
pode ser muito pequeno ou grande para alguns
sistemas se nào for usada escala).
* Se você não for usar formulário escalável, configure o
set scaled to False.
* Ou então, configure a propriedade scaled do formulário
para True.
* Configure a propriedade AutoScroll para False.
AutoScroll = True quer dizer “não mexa no tamanho do
frame do formulário em tempo de execução”, o que não
parece bom quando o conteúdo do formulário muda de
tamanho.
* Configure a fonte do formulário para uma True Type
escalável, como a Arial MS. San Serif é uma boa
alternativa, mas lembre que ainda é uma fonte
bitmapped. Só a Arial dará uma fonte dentro de um pixel
da altura desejada.ATENÇÃO: Se a fonte usada em
uma aplicação não estiver instalada no computador, o
Windows selecionará uma fonte alternativa da mesma
família para utilizar. O tamanho dessa fonte pode não
corresponder ao da fonte original, podendo causar
problemas.
* Configure a propriedade position do formulário para
uma opção diferente de poDesigned. poDesigneddeixa o
formulário onde você o deixou ( no design Time), o que
sempre termina fora da margem, à esquerda da minha
tela 1280 x 1024 - e completamente fora da tela 640 x
480.
* Não amontoe controles no formulário - deixe pelo
menos 4 pixels entre else, para que uma mudança de
um pixel nas margens (devido a apresentação em
escala) não mostre controles sobrepostos.
* Para labels de uma linha alinhadas ã esquerda ou à
direita, configure o AutoSize para True. Para outras
formas de alinhamento configure o AutoSize para False.
* Tenha certeza de que há espaço em branco suficiente
num componente de labels para alterações no tamanho
da fonte – um espaço de 25% do comprimento da linha
de caracteres mostrada é um pouco a mais do que se
precisa, mas é mais seguro. (Você vai precisar de um
espaço equivalente a 30% de espansão para string
labels se você pretende traduzir sua aplicação para
outra linguagem). Se o Autosize estiver em False, tenha
certeza de que realmente configurou o tamanho do label
corretamente. Se o Autosize estiver em True, esteja
certo de que há espaço suficiente para que o label se
amplie.
* Em labels de múltiplas linhas ou de termos ocultos,
deixe pelo menos uma linha em branco na base. Isso vai
ser necessário para incluir o que estiver sobrando
quando o texto for oculto de maneira diferente, pela
mudança do tamanho da fonte com a escala. Não
assuma isso porque está usando fontes grandes. Você
não tem que deixar sobra de texto - as fontes (grandes)
de outros usuários podem ser maiores que as suas!
* Tenha cuidado quando abrir um projeto em IDEs com
resoluções diferentes. Assim que o formulário for aberto,
sua propriedade Pixel per Inch será moditificada, e
gravada para o DFM se você salvar o projeto. É melhor
testar a aplicação rodando sozinho, e editar o formulário
em apenas uma resolução. Editar em várias resoluções
e tamanhos de fonte provoca problemas de fluxo e
tamanho dos componentes.
*Falando em fluxo de componentes, não represente o
formulário em escala muitas vezes, quando estiver
sendo criado ou quando tiver sendo executado. Cada
escala introduz erros de roundoff que se acumulam
muito rapidamente, uma vez que as coordenadas são
rigorosamente interias. Quando valores fracionários
forem retirados das origens e tamanhos do controle com
cada sucessiva representação em escala, os conttroles
parecerão deslizar para noroeste e ficar menores. Se
você quer deixar seus usuários representarem o
formulários em escala quantas vezes quiserem, comece
com um formulário recentemente criado para que erros
de escala não se acumulem.
* Definitivamente, não mexa na propriedade Pixel pre
Inch do formulário.
* Em geral, não é necessário criar formulários em uma
resolução específica, mas é essencial que você os
revise em 640 x 480 com fontes pequenas e/ou grandes,
e em alta resolução com fontes pequenas e/ou grandes
antes de liberar suas aplicações. Isso deverser parte de
sua lista de conferência para testar a compatibilidade do
sistema regularmente.
* Preste bastante atenção em todos os componentes
que são basicamamente TMemo de uma linha - com
oTDBLookupCombo. O controle de edição (multi-linhas)
do Windows sempre mostra apenas linhas inteiras de
texto. Se o controle for muito curto para sua fonte, um
TMemo não mostrará coisa alguma, e um TEdit
mostrará um pedaço do texto. É melhor fazer esses
componentes um pouco maiores do que deixá-los um
pixel menores e não aparecer nada do texto.
* Tenha em mente que toda representação em escala é
proporcional à diferença da altura da fonte entre o modo
de execução e o modo de desenho, NÃO à resolução ou
ao tamanho do monitor. Lembre também que as origens
dos seus controles serão alteradas quando o formulário
for representado em escala. Você não pode aumentar
componentes muito bem sem também movê-los um
pouco, novamente.

Obtendo e modificando a posição do cursor em um


TMemo
Modificando a posição:
ActiveControl:=Memo1;
MemoCursorTo(Memo1,2,3);
Obtendo a Posição:
GetMemoLineCol(Memo1,Linha,Coluna);
016 - Executar um programa do
DOS
WinExec(“command.com /c
programa.exe”,sw_ShowNormal);
017 - Como posso rolar um form
com pgUp e pgDn
Versão: Todas
Plataforma: Windows/Win32
Q. Como posso fazer funções de rolagem num
componente TForm usando comandos de teclado? Por
exemplo, rolar pra cima e pra baixo quando pressionar
PgUp ou PgDown. Existe algum método simples de
fazer isso???
R. O rolamento do form é completo fazendo-se uma
modificação na posição das propriedades VertScrollbar
ou HorzScrollbar do form. Como mostrado no código a
seguir:
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word;
Shift: TShiftState);
const
PageDelta = 10;
begin
With VertScrollbar do
if Key = VK_NEXT then
Position := Position + PageDelta
else if Key = VK_PRIOR then
Position := Position - PageDelta;
end;
018 - Tocando Sons WAV
Para reproduzir sons no formato WAV em um programa
em Delphi é simples, o usuário deverá colocar na
clásula Uses o MMSystem. E no corpo do programa o
comando:
SndPlaySound(‘C:\Windows\Media\Som.wav’,SN
D_ASYNC);
019 - Colocando funções em uma
DLL
Edite diretamente no DPR, e depois salve como
Funcoes.dpr:
Library Funcoes;
Uses SysUtils,WinTypes,WinProcs;
{ Uma função que tira os espaços no início e no final de
uma string }
Function Trim(J:String):String; Export;
Begin
While J[Length(J)]=#32 do Dec(J[0]);
If Length(J)>1 then
While (J[1]=’ ‘) do
Begin
Delete(J,1,1);
If Length(J)<=1 then J:=”;
end;
Result:=J;
end;
Exports { Torna visivel para os programas
}
Trim;
Begin
End.
Para usar num programa:
Unit Unit1;
Interface
uses
SysUtils, WinTypes, WinProcs, Messages,
Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Buttons;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
Var
Form1: TForm1;
Implementation
{ Declara a funcao }
Function Trim(J:String):String; External
‘funcoes.dll’;
{$R *.DFM}
Procedure TForm1.FormClick(Sender:
TObject);
begin
Caption:=Trim(‘ Visite sempre o Delphi
Club ‘); { Note os espacos }
end;

As vantagens de colocar as funções em DLL são:


1. O programa exigirá menos memória
2. Você poderá reaproveitar as funções
3. Em alguns casos pode-se atualizar apenas as dll para
um upgrade
020 - Compactando Tabelas
Para compactar (remover fisicamente todos registros
apagados) de uma tabela Paradox deve-se utilizar o
seguinte código
procedure ParadoxPack(Table : TTable);
var
TBDesc : CRTblDesc;
hDb: hDbiDb;
TablePath: array[0..dbiMaxPathLen] of
char;
begin
FillChar(TBDesc,Sizeof(TBDesc),0);
with TBDesc do begin
StrPCopy(szTblName,Table.TableName);
StrPCopy(szTblType,szParadox);
bPack := True;
end;
hDb := nil;
Check(DbiGetDirectory(Table.DBHandle,
True, TablePath));
Table.Close;
Check(DbiOpenDatabase(nil, ‘STANDARD’,
dbiReadWrite, dbiOpenExcl,nil,0, nil, nil,
hDb));
Check(DbiSetDirectory(hDb, TablePath));
Check(DBIDoRestructure(hDb,1,@TBDesc,nil,n
il,nil,False));
Table.Open;
end;
021 - Verifica Validade de CGC e
CPF
01) Dica Original
unit CPFeCGC;
interface
function cpf(num: string): boolean;
function cgc(num: string): boolean;
implementation
uses SysUtils;

function cpf(num: string): boolean;


var
n1,n2,n3,n4,n5,n6,n7,n8,n9: integer;
d1,d2: integer;
digitado, calculado: string;
begin
n1:=StrToInt(num[1]);
n2:=StrToInt(num[2]);
n3:=StrToInt(num[3]);
n4:=StrToInt(num[4]);
n5:=StrToInt(num[5]);
n6:=StrToInt(num[6]);
n7:=StrToInt(num[7]);
n8:=StrToInt(num[8]);
n9:=StrToInt(num[9]);
d1:=n9*2+n8*3+n7*4+n6*5+n5*6+n4*7+n3*8+n2*
9+n1*10;
d1:=11-(d1 mod 11);
if d1>=10 then d1:=0;
d2:=d1*2+n9*3+n8*4+n7*5+n6*6+n5*7+n4*8+n3*
9+n2*10+n1*11;
d2:=11-(d2 mod 11);
if d2>=10 then d2:=0;
calculado:=inttostr(d1)+inttostr(d2);
digitado:=num[10]+num[11];
if calculado=digitado then
cpf:=true
else
cpf:=false;
end;

function cgc(num: string): boolean;


var
n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12:
integer;
d1,d2: integer;
digitado, calculado: string;
begin
n1:=StrToInt(num[1]);
n2:=StrToInt(num[2]);
n3:=StrToInt(num[3]);
n4:=StrToInt(num[4]);
n5:=StrToInt(num[5]);
n6:=StrToInt(num[6]);
n7:=StrToInt(num[7]);
n8:=StrToInt(num[8]);
n9:=StrToInt(num[9]);
n10:=StrToInt(num[10]);
n11:=StrToInt(num[11]);
n12:=StrToInt(num[12]);
d1:=n12*2+n11*3+n10*4+n9*5+n8*6+n7*7+n6*8+
n5*9+n4*2+n3*3+n2*4+n1*5;
d1:=11-(d1 mod 11);
if d1>=10 then d1:=0;
d2:=d1*2+n12*3+n11*4+n10*5+n9*6+n8*7+n7*8+
n6*9+n5*2+n4*3+n3*4+n2*5+n1*6;
d2:=11-(d2 mod 11);
if d2>=10 then d2:=0;
calculado:=inttostr(d1)+inttostr(d2);
digitado:=num[13]+num[14];
if calculado=digitado then
cgc:=true
else
cgc:=false;
end;
end.
02) Dica melhorada por um dos
colaboradores
function CalculaCnpjCpf(Numero : String) :
String;
var
i,j,k, Soma, Digito : Integer;
CNPJ : Boolean;
begin
Result := Numero;
case Length(Numero) of
9:
CNPJ := False;
12:
CNPJ := True;
else
Exit;
end;
for j := 1 to 2 do
begin
k := 2;
Soma := 0;
for i := Length(Result) downto 1 do
begin
Soma := Soma + (Ord(Result[i])-
Ord(‘0’))*k;
Inc(k);
if (k > 9) and CNPJ then
k := 2;
end;
Digito := 11 - Soma mod 11;
if Digito >= 10 then
Digito := 0;
Result := Result + Chr(Digito +
Ord(‘0’));
end;
end;
022 - Gera número por extenso
unit Ext;
interface
function extenso (valor: real): string;
implementation
uses
SysUtils, Dialogs;
function extenso (valor: real): string;
var
Centavos, Centena, Milhar, Milhao, Texto,
msg: string;
const
Unidades: array[1..9] of string = (‘Um’,
‘Dois’, ‘Tres’, ‘Quatro’, ‘Cinco’, ‘Seis’,
‘Sete’, ‘Oito’, ‘Nove’);
Dez: array[1..9] of string = (‘Onze’,
‘Doze’, ‘Treze’, ‘Quatorze’, ‘Quinze’,
‘Dezesseis’, ‘Dezessete’, ‘Dezoito’,
‘Dezenove’);
Dezenas: array[1..9] of string = (‘Dez’,
‘Vinte’, ‘Trinta’, ‘Quarenta’,
‘Cinquenta’, ‘Sessenta’, ‘Setenta’,
‘Oitenta’, ‘Noventa’);
Centenas: array[1..9] of string =
(‘Cento’, ‘Duzentos’, ‘Trezentos’,
‘Quatrocentos’, ‘Quinhentos’,
‘Seiscentos’, ‘Setecentos’, ‘Oitocentos’,
‘Novecentos’);
function ifs(Expressao: Boolean;
CasoVerdadeiro, CasoFalso: String):
String;
begin
if Expressao
then Result:=CasoVerdadeiro
else Result:=CasoFalso;
end;
function MiniExtenso (trio: string):
string;
var
Unidade, Dezena, Centena: string;
begin
Unidade:=”;
Dezena:=”;
Centena:=”;
if (trio[2]=‘1’) and (trio[3]<>‘0’) then
begin
Unidade:=Dez[strtoint(trio[3])];
Dezena:=”;
end
else
begin
if trio[2]<>‘0’ then
Dezena:=Dezenas[strtoint(trio[2])];
if trio[3]<>‘0’ then
Unidade:=Unidades[strtoint(trio[3])];
end;
if (trio[1]=‘1’) and (Unidade=”) and
(Dezena=”)
then Centena:=‘cem’
else
if trio[1]<>‘0’
then
Centena:=Centenas[strtoint(trio[1])]
else Centena:=”;
Result:= Centena + ifs((Centena<>”) and
((Dezena<>”) or (Unidade<>”)), ‘ e ‘, ”)
+ Dezena + ifs((Dezena<>”) and
(Unidade<>”),’ e ‘, ”) + Unidade;
end;
begin
if (valor>999999.99) or (valor<0) then
begin
msg:=‘O valor está fora do intervalo
permitido.’;
msg:=msg+‘O número deve ser maior ou
igual a zero e menor que 999.999,99.’;
msg:=msg+’ Se não for corrigido o número
não será escrito por extenso.’;
showmessage(msg);
Result:=”;
exit;
end;
if valor=0 then
begin
Result:=”;
Exit;
end;
Texto:=formatfloat(‘000000.00’,valor);
Milhar:=MiniExtenso(Copy(Texto,1,3));
Centena:=MiniExtenso(Copy(Texto,4,3));
Centavos:=MiniExtenso(‘0’+Copy(Texto,8,2))
;
Result:=Milhar;
if Milhar<>” then
if copy(texto,4,3)=‘000’ then
Result:=Result+’ Mil Reais’
else
Result:=Result+’ Mil, ‘;
if (((copy(texto,4,2)=‘00’) and
(Milhar<>”)
and (copy(texto,6,1)<>‘0’)) or
(centavos=”))
and (Centena<>”) then Result:=Result+’ e
‘;
if (Milhar+Centena <>”) then
Result:=Result+Centena;
if (Milhar=”) and (copy(texto,4,3)=‘001’)
then
Result:=Result+’ Real’
else
if (copy(texto,4,3)<>‘000’) then
Result:=Result+’ Reais’;
if Centavos=” then
begin
Result:=Result+’.’;
Exit;
end
else
begin
if Milhar+Centena=” then
Result:=Centavos
else
Result:=Result+’, e ‘+Centavos;
if (copy(texto,8,2)=‘01’) and
(Centavos<>”) then
Result:=Result+’ Centavo.’
else
Result:=Result+’ Centavos.’;
end;
end;
end.
023 - Preenche com quantidade
determinada de zeros o lado
esquerdo de uma string
unit Zero;
interface
function
RetZero(ZEROS:string;QUANT:integer):String
;
implementation
function
RetZero(ZEROS:string;QUANT:integer):String
;
var
I,Tamanho:integer;
aux: string;
begin
aux:=zeros;
Tamanho:=length(ZEROS);
ZEROS:=”;
for I:=1 to quant-tamanho do
ZEROS:=ZEROS+‘0’;
aux:=zeros+aux;
RetZero:=aux;
end;
end.
024 - Ponto Decimal
if Key in [‘,’,’.’] then Key :=
DecimalSeparator;
Coloque no evento OnKeyPress dos seus TEdits
numéricos
025 - FindNearest numa Query
Query1.Locate(‘campo onde ira
porcurar’,‘Texto a buscar’,
[loPartialKey,loCaseInsensitive]);
026 - Relatórios em HTML
Em vez de Quickreport1.Print faca :
QuickRep1.ExportToFilter(TQRHtmlExportFilt
er.Create(‘teste.html’));
027 - Desligando Windows via
programação
function ExitWindowsEx(uFlags : integer; // shutdown
operation
dwReserved : word) : boolean; // reserved
external ‘user32.dll’ name ‘ExitWindowsEx’;
procedure Tchau;
const
EWX_LOGOFF = 0; // Dá “logoff” no usuário atual
EWX_SHUTDOWN = 1; // “Shutdown” padrão do
sistema
EWX_REBOOT = 2; // Dá “reboot” no equipamento
EWX_FORCE = 4; // Força o término dos processos
EWX_POWEROFF = 8; // Desliga o equipamento
begin
ExitWindowsEx(EWX_FORCE, 0);
end;
028 - Como saber se o CD está no
drive
Uses MMSystem

Function MidiaPresente(MediaPlayer:
TMediaPlayer): Boolean;
var
Params: MCI_STATUS_PARMS;
S: array [0..255] of char;
r: Integer;
begin
//verifica se existe um cd inserido
Params.dwItem:= MCI_STATUS_MEDIA_PRESENT;
r:= MCISendCommand(MediaPlayer.DeviceID,
MCI_STATUS, MCI_STATUS_ITEM,
Integer(Addr(Params)));
if r <> 0 then
begin
MCIGetErrorString(r, S, SizeOf(S));
ShowMessage(‘Erro: ‘ + StrPas(S));
end
else
Result:= Params.dwReturn = 1;
end;
029 - Tradução de Mensagens
Depois de algum tempo pesquisando uma forma de
fazer aparecer as mensagens em português, consegui
uma solução muito fácil de implementar no ambientede
programação do Delphi 3.
CHEGA DE YES/NO !!!
messagedlg(‘Confirma ? mtConfirmation, [mbYes,
mbNo], 0);
Aí vai:
1 - No diretório DELPHI3\LIB, copie o arquivo consts.dcu
para consts.old;
2 - Inicie o Delphi e crie um nova Unit;
3 - Insira nesta, o arquivo consts.int do diretório
DELPHI3\DOC E faça as devidas alterações nas
mensagens que desejares alterar e nas partes
duplicadas da Unit como “implement” e etc, também
deixe o cabeçalho como Unit Consts.
4 - Salve esta nova Unit no diretório DELPHI\LIB e
pronto todas as mensagens alteradas por você estarão
aplicadas nos seus próximos programas sem uma linha
de programa e da forma que você quiser.

No Delphi 4.0 vc deve nenomear o arquivo consts.dcu


para consts.old e modificar o arquivo constst.pas. (Há
outros arquivos *consts*.pas que podem ser
modificados).
030 - Função que devolve tempo
decorrido em uma string
Function
NumDiasExtenso(NumDias:integer):string;
var
Anos, Meses, Dias : integer;
sAnos, sMeses, sDias : string;
begin
{ – Calcula o número de anos – }
Anos := 0;
while NumDias >= 365 do
begin
Anos := Anos + 1;
NumDias := NumDias - 365;
end;
if Anos > 1 then
sAnos := ‘ anos,’
else
sAnos := ‘ ano,’;
{ – Calcula o número de meses – }
Meses := 0;
while NumDias >= 30 do
begin
Meses := Meses + 1;
NumDias := NumDias - 30;
end;
if Meses > 1 then
sMeses := ‘ meses e ‘
else
sAnos := ‘ mês e ‘;
{ – O Número de dias é a sobra – }
Dias := NumDias;
if sDias > 1 then
sDias := ‘dias’
else
sDias := ‘dia’;
Return :=
Inttostr(Anos)+sAnos+inttostr(Meses)+sMese
s+inttostr(Dias)+sDias;
end;
031 - Criando uma rotina para
pegar todos os erros do programa
Procedure MostraErro;
Begin
ShowMessage(‘Ocorreu algum erro!’);
end;

TForm1.Create;
Begin
Application.OnException:=MostraErro;
end;
032 - Capturando conteúdo do
desktop
procedure TForm1.FormResize(Sender:
TObject);
var
R : TRect;
DC : HDc;
Canv : TCanvas;
begin
R := Rect( 0, 0, Screen.Width,
Screen.Height );
DC := GetWindowDC( GetDeskTopWindow );
Canv := TCanvas.Create;
Canv.Handle := DC;
Canvas.CopyRect( R, Canv, R );
ReleaseDC( GetDeskTopWindow, DC );
end;
033 - Obtendo número do registro
atual
Function Recno(Dataset: TDataset):
Longint;
var
CursorProps: CurProps;
RecordProps: RECProps;
begin
{ Return 0 if dataset is not Paradox or
dBASE }
Result := 0;
with Dataset do
begin
if State = dsInactive then
DBError(SDataSetClosed);
Check(DbiGetCursorProps(Handle,
CursorProps));
UpdateCursorPos;
try
Check(DbiGetRecord(Handle, dbiNOLOCK, nil,
@RecordProps));
case CursorProps.iSeqNums of
0: Result := RecordProps.iPhyRecNum; {
dBASE }
1: Result := RecordProps.iSeqNum; {
Paradox }
end;
except
on EDBEngineError do
Result := 0;
end;
end;
end;
034 - Enviando um arquivo para a
lixeira
uses ShellAPI;

Function DeleteFileWithUndo(sFileName :
string ) : boolean;
var
fos : TSHFileOpStruct;
Begin
FillChar( fos, SizeOf( fos ), 0 );
With fos do
begin
wFunc := FO_DELETE;
pFrom := PChar( sFileName );
fFlags := FOF_ALLOWUNDO
or FOF_NOCONFIRMATION
or FOF_SILENT;
end;
Result := ( 0 = ShFileOperation( fos ) );
end;
035 - Carregar um cursor animado
(*.ani)
const
cnCursorID1 = 1;
begin
Screen.Cursors[ cnCursorID1 ] :=
LoadCursorFromFile(‘c:\win95\cursors\caval
o.ani’ );
Cursor := cnCursorID1;
end;
036 - Modificando a posição do
cursor em um Memo
Modificando a posição:
ActiveControl:=Memo1;
MemoCursorTo(Memo1,2,3);
Obtendo a Posição:
GetMemoLineCol(Memo1,Linha,Coluna);
037 - Traduzindo a mensagem
“Delete Record ?”
Quando clicamos sobre o botão de deleção no
DBNavigator (o do sinal de menos) surge uma box com
a mensagem “Delete Record?” com botões Ok e Cancel.
Para fazer aparecer a mensagem em português deverá
selecionar o componente Table e mudar a propriedade
ConfirmDelete para False e no evento da tabela
BeforeDelete colocar o seguinte:
procedure
TForm1.Table1BeforeDelete(DataSet:TDataSet
);
begin
if MessageDlg(‘Eliminar o
Registro?’,mtConfirmation,[mbYes,mbNo],0)
<>mrYes then Abort;
end;
038 - Pegando o Nome do usuário e
a Empresa do Windows
Uses Registry;

Procedure GetUserCompany;
var
reg: TRegIniFile;
begin
reg :=
TRegIniFile.create(‘SOFTWARE\MICROSOFT\MS
SETUP (ACME)');
Edit1.Text := reg.ReadString(‘USER
INFO’,‘DefName’,”);
Edit2.Text := reg.ReadString(‘USER
INFO’,‘DefCompany’,”);
reg.free;
end;
039 - Escrevendo um Texto na
Diagonal usando o Canvas
procedure TForm1.Button1Click(Sender:
TObject);
var
lf : TLogFont;
tf : TFont;
begin
with Form1.Canvas do
begin
Font.Name := ‘Arial’;
Font.Size := 24;
tf := TFont.Create;
tf.Assign(Font);
GetObject(tf.Handle, sizeof(lf), @lf);
lf.lfEscapement := 450;
lf.lfOrientation := 450;
tf.Handle := CreateFontIndirect(lf);
Font.Assign(tf);
tf.Free;
TextOut(20, Height div 2, ‘Texto
Diagonal!’);
end;
end;
040 - Fundo do texto transparente
procedure TForm1.Button1Click(Sender:
TObject);
var
OldBkMode : integer;
begin
with Form1.Canvas do begin
Brush.Color := clRed;
FillRect(Rect(0, 0, 100, 100));
Brush.Color := clBlue;
TextOut(10, 20, ‘Não é Transparente!’);
OldBkMode := SetBkMode(Handle,
TRANSPARENT);
TextOut(10, 50, ‘É Transparente!’);
SetBkMode(Handle, OldBkMode);
end;
end;
041 - Formatação de Casas
Decimais
procedure TForm1.Button1Click(Sender:
TObject);
var
num : integer;
begin
num:=12450;
Edit1.text:=formatfloat(‘###,###,##0.00’,
num)
end;
042 - Escondendo/Mostrando o
botão Iniciar
procedure EscondeIniciar(Visible:Boolean);
Var taskbarhandle,
buttonhandle : HWND;
begin
taskbarhandle :=
FindWindow(‘Shell_TrayWnd’, nil);
buttonhandle := GetWindow(taskbarhandle,
GW_CHILD);
If Visible=True Then Begin
ShowWindow(buttonhandle, SW_RESTORE);
{mostra o botão}
End Else Begin
ShowWindow(buttonhandle, SW_HIDE);
{esconde o botão}
end;
end;
043 - Esconde/Mostra a Barra de
Tarefas
procedure EscondeTaskBar(Visible:
Boolean);
var wndHandle : THandle;
wndClass : array[0..50] of Char;
begin
StrPCopy(@wndClass[0],‘Shell_TrayWnd’);
wndHandle := FindWindow(@wndClass[0],
nil);
If Visible=True Then Begin
ShowWindow(wndHandle, SW_RESTORE); {Mostra
a barra de tarefas}
End Else Begin
ShowWindow(wndHandle, SW_HIDE); {Esconde a
barra de tarefas}
End;
end;
044 - Detectando o Numero Serial
do HD
Function SerialNum(FDrive:String) :String;
Var
Serial:DWord;
DirLen,Flags: DWord;
DLabel : Array[0..11] of Char;
begin
Try
GetVolumeInformation(PChar(FDrive+’:'),dLa
bel,12,@Serial,DirLen,Flags,nil,0);
Result := IntToHex(Serial,8);
Except Result :=”;
end;
end;
045 - Como Limpar Todos os Edit’s
de um Form de uma só vez?
Procedure LimpaEdit;
var
i : Integer;
begin
for i := 0 to ComponentCount -1 do
if Components[i] is TEdit then
begin
TEdit(Components[i]).Text := ”;
end;
end;
Contribuição de Fabio SVB:
procedure LimpaEdit (Form: TForm);
var
i : Integer;
begin
for i := 0 to Form.ComponentCount - 1 do
if Form.Components[i] is TCustomEdit then
(Form.Components[i] as TCustomEdit).Clear;
end;
// assim limpara todos os Edits, Memos, MaskEdits, etc…
//Valeu!!
046 - Marcando um pedaço do
código
As Vezes quando vc tem uma unidade com muitas
linhas de código (umas 1000 por exemplo), fica difícil
achar o bloco de código que você quer; e para facilitar
isso o Delphi tem um tipo de “bookmark” de código.
Para colocar o bookmark, posicione no lugar onde você
quer marcar e pressione CTRL+SHIFT+ o número do
bookmark que você vai criar de (0..9), por exemplo
CTRL+SHIFT+0.
Para retornar ao bloco marcado você deve pressionar
CTRL+ o número do bookmark. Por exemplo CTRL+1.
Ps: A opção Editor FindTextAtCursor deve estar
marcada, ou estas teclas não irão funcionar.
047 - Alterar o papel de parede 1
program wallpapr;

uses Registry, WinProcs;

procedure SetWallpaper(sWallpaperBMPPath :
String; bTile : boolean );
var
reg : TRegIniFile;
begin
// Mudando o Registro HKEY_CURRENT_USER
// Control Panel\Desktop
// TileWallpaper (REG_SZ)
// Wallpaper (REG_SZ)
reg := TRegIniFile.Create(‘Control
Panel\Desktop’ );
with reg do begin
WriteString( ”,
‘Wallpaper’,sWallpaperBMPPath );
if( bTile )then begin
WriteString( ”, ‘TileWallpaper’, ‘1’ );
end else begin
WriteString( ”, ‘TileWallpaper’, ‘0’ );
end;
end;
reg.Free;
// Mostrar que o parametro do sistema foi
alterado
SystemParametersInfo(
SPI_SETDESKWALLPAPER,0, Nil,
SPIF_SENDWININICHANGE );
end;
begin
SetWallpaper( ‘c:\winnt\winnt.bmp’, False
);
end.
048 - Alterando cor de linha de um
DBGrid
Coloque a propriedade defaultdrawdata do dbgrid em
FALSE
No evento onDrawColumnCell do seu grid coloque o
seguinte:
procedure
TForm1.DBGrid1DrawColumnCell(Sender:
TObject;
const
Rect: TRect; DataCol: Integer; Column:
TColumn;
State: TGridDrawState);
begin
If table1PRAZO.Value > DATE then //
condição
Dbgrid1.Canvas.Font.Color:= clFuchsia; //
coloque aqui a cor desejada
Dbgrid1.DefaultDrawDataCell(Rect,
dbgrid1.columns[datacol].field, State);
end;
049 - Diretório de instalação do
windows
function PegaSysDir: string;
var
MeuBuffer: Array [1..128] of Char;
retorno: Integer;
Begin
retorno:=GetSystemDirectory(@MeuBuffer,128
);
if (retorno>128) OR (retorno=0) then
PegaSysDir:=”
else
PegaSysDir:=StrPas(@MeuBuffer);
End; {prc}
050 - Exclusividade para o
programa
Gostaria de saber como fazer para que, ao iniciar minha
aplicacao Delphi, eu ” desabilite ” o shell do Windows
(Explorer). Ou seja, o que eu preciso e’ de uma forma de
fazer com que apos a minha aplicacao seja iniciada, o
usuario nao tenha como alternar entre programas,
acessar outros icones, etc
No System.ini você tem uma configuração como esta :
Shell=Explorer.exe
Basta trocar por
Shell=Myprog.exe
Ou usando delphi
procedure Tform1.ChangeShell(String
programa);
var
ArquivoIni : Tinifile;
begin
try
ArquivoIni :=
Tinifile.Create(‘System.ini’);
ArquivIni.WriteSection(‘Config’,‘Shell’,‘M
yprog.exe’);
fynally
ArquivoIni.Destroy;
end;
end;
051 - Substituindo TAB pelo
ENTER
procedure TF_Padrao.FormKeyPress(Sender:
TObject; var Key: Char);
begin
if Key = #13 then
if not (ActiveControl is TDBGrid) then
begin
Key := #0;
Perform(WM_NEXTDLGCTL, 0, 0);
end
else if (ActiveControl is TDBGrid) then
with TDBGrid(ActiveControl) do
if selectedindex < (fieldcount -1) then
selectedindex := selectedindex +1
else
selectedindex := 0;
end;

Ou então, pode-se tentar o seguinte método:


Utilize o evento onkeydown do componente e insira o
seguinte comando:
if Key = VK_RETURN then
Perform(Wm_NextDlgCtl,0,0);
este comando testa a tecla pressionada, se ela for um
enter, manda o foco para o componente posterior.
052 - Copiando arquivos
Função: CopyFile(‘Origem’,‘Destino’,True);
Exemplo:
CopyFile(‘c:\logo.sys’,‘c:\logo.bmp’,True)
True : Instrui para sobrescrever o arquivo
destino (caso encontre)
053 - Criando tabela em tempo de
execução
Use os metodos FieldDefs e CreateTable para isso. Veja
como criar uma estrutura temporaria:
with TTable.Create(Application) do
begin
Active := False;
DatabaseName := ‘C:\TEMP’;
TableName := ‘TESTE.TMP’;
TableType := ttDefault;
FieldDefs.Add(‘CODCLI’, ftString, 5,
False);
FieldDefs.Add(‘NOMCLI’, ftString, 40,
False);
FieldDefs.Add(‘DATCAD’, ftDate, 0, False);
CreateTable;
Free;
end;
054 - Armazenando BMP’s em
arquivos RES
1. Criem um arquivo texto, por exemplo:
RECURSOS.RC com um conteudo igual a este:
BITMAP_1 BITMAP “C:\Imagens\Grafico.bmp”
para todos os bitmap’s que vc deseja;
2. Compilem este arquivo usando o BRCC32.EXE que
esta no diretorio BIN do Delphi sera gerado o arquivo
RECURSOS.RES; e
3. Coloquem dentro do fonte do projeto:
{$R RECURSOS.RES}
Para usar o bitmap faca o seguinte:
VarTipoTBitmap:=
LoadBitmap(HInstance,‘BITMAP_1’);
Colocando um JPG dentro de um
.exe
Para colocar um arquivo qualquer dentro de um arquivo
.exe, primeiramente crie um arquivo com extensão .rc no
Bloco de Notas. O formato de um arquivo .rc é o
seguinte:
1 RCDATA “MyPic.jpg”
onde “1” é o índice do arquivo, “RCDATA” é significa que
é um tipo de arquivo não-padrão (os padrões são
bitmaps, ícones e cursores) e ““MyPic.jpg”” é o nome do
arquivo. Salve e execute o programa BRCC32.EXE que
fica no subdiretório Bin do Delphi (BRCC32 arquivo.rc).
Será criado um arquivo .res (arquivo.res) cujo conteúdo
terá o próprio JPG.
Nota: Você pode colocar mais de um arquivo no arquivo
.res, desde que os índices sejam diferentes.
Para colocá-lo no executável, coloque a linha:
{$R arquivo.res}
após a linha:
{$R *.DFM}
Ok, ele já vai ficar no executável. E como eu rodo esse
JPG? Simples:
procedure LoadJPEGfromEXE;
var
MyJPG : TJPEGImage;
ResStream : TResourceStream;
Index : Integer;
begin
Index := 1;
try
MyJPG := TJPEGImage.Create;
ResStream := TResourceStream.CreateFromID
(HInstance, Index, RT_RCDATA);
MyJPG.LoadFromStream (ResStream);
Canvas.Draw (12, 12, MyJPG);
finally
MyJPG.Free;
ResStream.Free;
end;
end;
Troque o valor de Index pelo valor do índice que você
criou para o arquivo que deseja abrir.
055 - QR armazenado num Blop
Os campos do Tipo TBlobField, tem metodos que
permitem que sejam armazenados dados contidos em
arquivos, ou em um Stream…
No primeiro caso (dos arquivos), o codigo seria algo
como:
TBlobField(SuaTabela.FieldByName(‘SeuCampo
’)).LoadFromFile(‘NomedoArquivo’);
No segundo caso, poderia ser feito um exemplo com o
TRichEdit:
var
Stream : TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
RichEdit1.Lines.SaveToStream(Stream);
Stream.Seek(0,soFromBeginning);
TBlobField(SuaTabela.FieldByName(‘SeuCampo
’)).LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
Ambos os exemplos, assumem que a tabela ja’ estaria
em modo de Edicao ou de Insercao.
056 - Deletando um arquivo
if FileExists(‘C:\MEUDIR\MEUARQ.DAT’) then
DeleteFile(‘C:\MEUDIR\MEUARQ.DAT’);
057 - Diretório Windows ,System e
Temp
Function ExtractWindowsDir : String;
Var
Buffer : Array[0..144] of Char;
Begin
GetWindowsDirectory(Buffer,144);
Result := FormatPath(StrPas(Buffer));
End;

Function ExtractSystemDir : String;


Var
Buffer : Array[0..144] of Char;
Begin
GetSystemDirectory(Buffer,144);
Result := FormatPath(StrPas(Buffer));
End;

Function ExtractTempDir : String;


Var
Buffer : Array[0..144] of Char;
Begin
GetTempPath(144,Buffer);
Result := FormatPath(StrPas(Buffer));
End;
058 - Alterar papel de parede 2
procedure ChangeWallpaper(bitmap: string);
var
pBitmap : pchar;
begin
bitmap:=bitmap+#0; {bitmap contém um
arquivo *.bmp}
pBitmap:=@bitmap[1];
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0, pBitmap, SPIF_UPDATEINIFILE);
end;
059 - AutoExecução do Programa
via Registro
uses registry;
var reg:TRegIniFile;
procedure TForm1.FormCreate(Sender:
TObject);
var
s,s2:string;
begin
Reg:=TRegIniFile.Create(‘LloydSoft’);
{HKEY_USERS.DEFAULT\Software\Microsoft\Win
dows\CurrentVersion\Run}
S:=ExtractFileDir(Application.ExeName);
S2:=ExtractFileName(Application.ExeName);
S:=S+’'+S2;
reg.RootKey:=HKEY_USERS;
reg.Openkey
(‘.DEFAULT\Software\Microsoft\Windows\Curr
entVersion’,false);
reg.WriteString(‘Run’, ‘Logo’, s);
button1.click;
end;
060 - Como fazer um “Hot Link”
Adicione um componente com o URL. Digite o seguinte
código no seu evento OnClick:
procedure Tform1.URLLabelClick(Sender:
TObject);
var
TempString : array[0..79] of char;
begin
StrPCopy(TempString,URLLabel.Caption);
OpenObject(TempString);
end;
Insira a seguinte procedure logo após implementation:
procedure
TTOKAboutBox.OpenObject(sObjectPath :
PChar);
begin
ShellExecute(0, Nil, sObjectPath, Nil,
Nil, SW_NORMAL);
end;
Adicione “ShellAPI” no uses.
061 - Como saber se o disquete
está no drive
function DiskInDrive(const Drive: char):
Boolean;
var
DrvNum: byte;
EMode: Word;
begin
result := false;
DrvNum := ord(Drive);
if DrvNum >= ord(‘a’) then
dec(DrvNum,$20);
EMode :=
SetErrorMode(SEM_FAILCRITICALERRORS);
try
if DiskSize(DrvNum-$40) <> -1 then
result := true else messagebeep(0);
finally SetErrorMode(EMode);
end;
end;
062 - Formatar disquete
{implementation section}
….
const
SHFMT_ID_DEFAULT = $FFFF;
// Formating options
SHFMT_OPT_QUICKFORMAT = $0000;
SHFMT_OPT_FULL = $0001;
SHFMT_OPT_SYSONLY = $0002;
// Error codes
SHFMT_ERROR = $FFFFFFFF;
SHFMT_CANCEL = $FFFFFFFE;
SHFMT_NOFORMAT = $FFFFFFFD;

function SHFormatDrive(Handle: HWND;


Drive, ID, Options: Word): LongInt;
stdcall; external ‘shell32.dll’ name
‘SHFormatDrive’

procedure
TForm1.btnFormatDiskClick(Sender:
TObject);
var
retCode: LongInt;
begin
retCode:= SHFormatDrive(Handle, 0,
SHFMT_ID_DEFAULT, SHFMT_OPT_QUICKFORMAT);
if retCode < 0 then ShowMessage(‘Could
not format drive’);
end;
063 - Como detectar as teclas de
“seta”
Use os eventos KeyDown ou KeyUp e teste se Key =
VK_LEFT ou VK_RIGHT, etc.
064 - Caps Lock e Num Lock
procedure TMyForm.Button1Click(Sender:
TObject);
Var
KeyState : TKeyboardState;
begin
GetKeyboardState(KeyState);
if (KeyState[VK_NUMLOCK] = 0) then
KeyState[VK_NUMLOCK] := 1
else KeyState[VK_NUMLOCK] := 0;
SetKeyboardState(KeyState);
End;
Para a tecla Caps Lock basta trocar VK_NUMLOCK por
VK_CAPITAL.
065 - BDE em 1 disquete
Depois que apanhei bastente do BDE, recorri a lista e
ninguem consegui me ajudar … consegui resolver o
problema. E como acredito que outras pessoas tenham
o mesmo problema, resolvi colocar essa dica na lista.
Por favor, se alguem tiver algo a acresentar ou mesmo
corrigir, sinta-se a vontade para compartilhar conosco.
Arquivos Exenciais para o BDE:
EUROPE.BLL
USA.BLL
IDR20009.DLL
IDAPI32.DLL
BLW32.DLL
IDAPI32.CFG <– esse arquivo pode ter qualquer outro
nome, desde que seja configurado no registro.
Drivers de Banco de Dados:
IDPDX32.DLL <– Driver Paradox
IDASCI32.DLL <– Driver ASCII
IDDBAS32.DLL <– Driver DBase
IDODBC32.DLL <– Driver ODBC
O BDE precisa de pelo menos um Driver de Banco de
Dados para funcionar. Esses acima sao apenas alguns,
existem varios outros.
O BDE 4.51 + Driver Paradox compactados com o
Algoritimo ZIP, ocuparam aproximadamente 650 Kb.
Entradas no Registro do Win95:
HKEY_LOCAL_MACHINE
SOFTWARE\Borland\Database Engine
DLLPATH -> localizacao do BDE (Unidade+Caminho
Completo)
CONFIGFILE01 -> localizacao do arquivo de
configuracao (Unidade+Caminho
Completo+Nome do Arquivo)
SOFTWARE\Borland\BLW32
BLAPIPATH -> localizacao do BDE (Unidade+Caminho
Completo)
LOCALE_LIB1 -> localizacao do arquivo USA.BLL
(Unidade+Caminho
Completo+USA.BLL)
LOCALE_LIB2 -> localizacao do arquivo EUROPE.BLL
(Unidade+Caminho
Completo+EUROPE.BLL)
Segue um pequeno exemplo de como registrar o BDE
no Registro do Win95:
begin
Registry.RootKey := HKEY_LOCAL_MACHINE;
Registry.CreateKey(‘SOFTWARE\Borland\Datab
ase Engine’);
Registry.OpenKey(‘SOFTWARE\Borland\Databas
e Engine’, False);
Registry.WriteString(‘DLLPATH’,
‘C:\ARQUIVOS DE PROGRAMAS\BDE');
Registry.WriteString(‘CONFIGFILE1’,
‘C:\ARQUIVOS DE
PROGRAMAS\BDE\IDAPI32.CFG’);
Registry.OpenKey(‘', False);
Registry.CreateKey(‘SOFTWARE\Borland\BLW32
’);
Registry.OpenKey(‘SOFTWARE\Borland\BLW32’,
False);
Registry.WriteString(‘BLAPIPATH’,
‘C:\ARQUIVOS DE PROGRAMAS\BDE');
Registry.WriteString(‘LOCALE_LIB1’,
‘C:\ARQUIVOS DE PROGRAMAS\BDE\USA.BLL’);
Registry.WriteString(‘LOCALE_LIB2’,
‘C:\ARQUIVOS DE
PROGRAMAS\BDE\EUROPE.BLL’);
end;

Para compilar esse codigo, sera necessario declarar a


Unit Registry.
Como eu disse, esse e um exemplo bem simples. Ele
nem mesmo verifica se o BDE ja esta registrado ou não.
Para criar o Alias atravez do seu instalador, voce pode
usar a funcão da api do BDE chamada DbiAddAlias.
066 - Cor de fundo do hint
Veja as propriedades dp TApplication…
Application.HintColor := clAqua;
Application.HintPause := …
Application.HintShortPause := …
067 - Margem para RichText
Se for um richedit e margens laterais(direita e esquerda)
tenta
RichEdit1.Paragraph.FirstIndent -> Paragrafo
RichEdit1.Paragraph.LeftIndent -> margem esquerda
RichEdit1.Paragraph.RightIndent -> margem direita
068 - Mostrando progresso de uma
SQL
Algumas pessoas estavam interessadas em saber como
apresentar o progresso de um TQuery enquanta ele esta
sendo aberto (ou executada, no caso de um
INSERT / UPDATE / DELETE).
A tecnica que vou demostrar nao apenas serve para o
proposito procurado, mas tambem serve para mostrar o
progresso de diversas outras atividades que o BDE
executa, como:
* Criacao de tabelas
* Criacao de indices para tabelas
* Reestruturacao de tabelas
* Execucao de queries (ja comentado)
* alguma outra coisa que no momento nao me ocorre…
:))
Importante:
1) No meu exemplo, estou usando o Delphi 3.02. Caso
seu Delphi seja de uma versao menor, vc devera ter um
trabalho extra para repor a classe TBDECallback.
Acredito que seja possivel fazer uma rotina que funcione
em Delphi 1, mas que com certeza dara um certo
trabalhinho, ah, isso dara…
:-/
2) Ate agora so usei esse codigo com tabelas Paradox,
mas realmente acredito que ele venha a funcionar com
base de dados Interbase, Oracle, etc…
3) Nao sei se com o uso do Opus, Apollo ou qualquer
outro substituto do BDE a tecnica ira funcionar, uma vez
que nao se estaria trabalhando com o BDE original.
Talvez alguem da lista possa dar essa informacao.
Teoria
Segundo o help do Delphi, “o TBDECallback eh um
wrapper para uma funcão de callback do BDE. Com ele
eh possivel instruir o BDE para que o mesmo execute
algumas tarefas em resposta a eventos que ocorram
durante uma chamada de uma funcao do BDE. ” - Fim
do plagio do arquivo de help.
O tipo de callback depende de um parametro CBType
que eh fornecido no momento da criacao do
TBDECallback. E, entre os diversos valores que o
CBType pode apresentar, existe um que muito nos
interessa; o cbGENPROGRESS.
:))
Assim, vc deveria criar uma funcao de callback do tipo
cbGENPROGRESS chamada AtualizaGauge e indicar
que a mesma eh que devera ser executada “entre cada
respiracao” do BDE. Na rotina AtualizaGauge, o BDE iria
te informar o percentual de progresso da tarefa .
O que voce faria nessa rotina ? Simples… atualizar o
Gauge / ProgressBar.
Tudo muito bonito, tudo muito comovente, mas agora
vamos para o lado pratico…
Pratica
Para que o BDE possa informar o progresso da tarefa,
ele precisa obter essa informacao da base de dados que
esta sendo utilizada. Acontece que, por razoes
diferentes, nem sempre ele eh capaz de saber o
PERCENTUAL da tarefa. Numa copia de registros de
uma tabela para outra, ele pode saber que ja foram
copiados 270 registros, mas nao saber que esse esforco
representa 36 % de todos os registros que serao
copiados.
Assim sendo, na funcao de callback que sera criada,
receberemos um parametro do tipo
pCBPROGRESSDesc, que por sua vez eh um ponteiro
para uma estrutura que contem duas informacoes:
iPercentDone => percentual do servico realizado
szMsg => texto descrevendo o progresso do servico.
Como usar esses parametros ? Simples: sempre que o
iPercentDone for negativo, voce devera considerar o
texto descrito no campo szMsg. Se for igual ou maior
que zero, entao vc devera considerar o valor do proprio
iPercentDone.
Uma boa noticia para quem se preocupa com as
mensagens que aparecem em ingles, quando se quer
na verdade mostra-las em portugues: a mensagem
fornecida por szMsg devera sempre aparecer no formato
<mensagem><:><valor>
…..
Exemplo:
Records copied: 170
Assim, voce pode procurar pelos dois pontos “:” e pegar
o valor que vem a seguir para montar sua propria
informacao em portugues.
Pessoalmente, ate agora nunca obtive um iPercentDone
positivo. Li no newsgroup da Borland que poucas bases
de dados eram capazes de informar o real percentual
para o BDE. Se nao me engano, o Sybase era um
deles… NAO ESTOU CERTO DISSO.
Vamos para um exemplo pratico ? Crie um projeto novo,
e coloque um:
TQuery, TButton, TProgressBar e TLabel.
Sua query deve ser montada para abrir uma tabela
razoavelmente grande, demodo que a operacao de
abertura demore um pouco.
Agora vamos aos codigos:
1) Acrescente a unit BDE no seu USES da unit.
2) Acrescente algumas declaracoes na declaracao do
seu Form:
==============================
type
TForm1 = class(TForm)
… (bla bla bla)
private
{ Private declarations }
FCBPROGRESSDesc: pCBPROGRESSDesc;
FProgressCallback: TBDECallback;
function GetDataCallback(CBInfo: Pointer):
CBRType;
public
{ Public declarations }
end;
==============================
No evento OnCreate do seu Form:
==============================
procedure TForm1.FormCreate(Sender:
TObject);
begin
FCBPROGRESSDesc :=
AllocMem(SizeOf(CBPROGRESSDesc));
FProgressCallback :=
TBDECallback.Create(Self, Query1.Handle,
cbGENPROGRESS, FCBPROGRESSDesc,
SizeOf(CBPROGRESSDesc),
GetDataCallback, True);
end;
==============================
Percebam que no segundo parametro do Create do
callback, eu coloquei Query1.Handle.
Caso voce queira usar isso numa TTable, coloque
Table1.Handle.
E se quiser que essa funcao de callback seja chamada
para todos os “progressos” de qualquer componente
DataSet, voce deixa esse parametro como
NIL.
No evento OnDestroy do Form:
==============================
procedure TForm1.FormDestroy(Sender:
TObject);
begin
FProgressCallback.Free;
FreeMem(FCBPROGRESSDesc,
SizeOf(CBPROGRESSDesc));
end;
==============================
E agora, a tao falada funcao de callback:
==============================
function TForm1.GetDataCallback(CBInfo:
Pointer): CBRType;
begin
Result := cbrCONTINUE;
with pCBPROGRESSDesc(CBInfo)^ do
begin
if iPercentDone < 0 then
begin
Label1.Caption := szMsg;
Label1.Refresh;
ProgressBar1.StepIt; {Apenas para ficar
rodando o gauge}
end
else
ProgressBar1.Position := iPercentDone;
end;
end;
==============================
Agora eh so executar a query no clicar do botao e curtir
o visual… :))
IMPORTANTE !!!!!!
Caso voce receba uma mensagem de erro informando
que nao foi possivel inicializar o BDE (o que
provavelmente acontecera, pois voce esta criando uma
funcao de callback do BDE, quando ate entao nenhuma
tabela havia sido aberta), va no DPR do seu projeto
(Menu View -> Project Source) e faca o seguinte:
1) Acrescente a unit BDE no uses do projeto.
2) Acrescente a instrucao
DbiInit(nil);
apos a instrucao Application.Initialize;
Isso deve resolver o problema.
Bom, nao vou me alongar mais, porque senao essa
mensagem vai ficar maior do que ja esta…
Espero que tenha contribuido para a solucao desse
problema de mostar progresso de uma query. Qualquer
duvida mandem mensagem.
069 - Código usados pelas
impressoras HP
Veja abaixo alguns códigos usados pelas impressoras
HP:
RESET = 027/069
BOLD1 = 027/040/115/051/066
BOLD0 = 027/040/115/048/066
ITALIC1 = 027/040/115/049/083
ITALIC0 = 027/040/115/048/083
UNDERLINE1 = 027/038/100/049/068
UNDERLINE0 = 027/038/100/064
LPI6 = 027/038/108/054/068
LPI8 = 027/038/108/056/068
CPI5 = 027/040/115/053/072
CPI6 = 027/040/115/054/072
CPI8 = 027/040/115/056/072
CPI10 = 027/040/115/049/048/072
CPI12 = 027/040/115/049/050/072
CPI17 = 027/040/115/049/054/046/054/055/072
CPI20 = 027/040/115/050/048/072
070 - Verificando atributo do
arquivo
Crie uma var do tipo word, por ex., Attributes. Depois,
atribua a esta var o valor retornado por FileGetAttr. Ex.:
var
Attributes: Word;
begin
Attributes := FileGetAttr( ‘nomedoarquivo’
);
// Supondo 4 CheckBoxe’s, 1 para cada
atributo, Ok?
CheckBox1.Checked := (Attributes and
faReadOnly) = faReadOnly;
CheckBox2.Checked := (Attributes and
faArchive) = faArchive;
CheckBox3.Checked := (Attributes and
faSysFile) = faSysFile;
CheckBox4.Checked := (Attributes and
faHidden) = faHidden;
end;
071 - Um Contador de letras
function WordsCount( s : string ) :
integer;
var
ps: PChar;
nSpaces,n : integer;
begin
n := 0;
s := s + #0;
ps := @s[ 1 ];
while( #0 <> ps^ ) do
begin
while((‘ ‘ = ps^)and(#0 <> ps^)) do
begin
inc( ps );
end;
nSpaces := 0;
while((‘ ‘ <> ps^)and(#0 <> ps^))do
begin
inc(nSpaces);
inc(ps);
end;
if ( nSpaces > 0 ) then
begin
inc( n );
end;
end;
Result := n;
end;
Observação de um usuário sobre a
dica acima:
Existe um erro na dica de contador de letras na verdade ela conta palavra,
para contrar letras deve ser feito assim:
function WordsCount( s : string ) : integer;
var
ps: PChar;
nSpaces,n,o : integer;
begin
//total de palavras
n := 0;
//total de letras
o := 0;
s := s + #0;
ps := @s[ 1 ];
while( #0 <> ps^ ) do
begin
while((‘ ‘ = ps^)and(#0 <> ps^)) do
begin
inc( ps );
//conta total de letras
inc(o);
end;
nSpaces := 0;
while((‘ ‘ <> ps^)and(#0 <> ps^))do
begin
inc(nSpaces);
inc(ps);
//conta total de letras
inc(o);
end;
if ( nSpaces > 0 ) then
begin
inc( n );
end;
end;
//recebe o total de letras contadas incluindo os espacos
Result := o;
end;

{Ass: Rodrigo Jacobowski}


072 - Obtendo o diretório de uma
Alias
uses BDE

function AliasToPath(Alias : String) :


String;
var
Desc : dbDesc;
szAlias : Array[0..255] of Char;
begin
StrPCopy(szAlias,Alias);
DbiGetDatabaseDesc(szAlias,@Desc);
Result := StrPas(Desc.szPhyName);
end;
073 - Como Finalizar o Windows
sem Avisar?
ExitWindowsEx(EWX_FORCE+EWX_SHUTDOWN,0)
074 - Como impedir de apagar um
registro em um DBGRID através das
teclas CTRL+DEL?
- Como impedir de apagar um registro em um DBGRID
através das teclas CTRL+DEL?
Colocar no evento OnKeyDown do DBGRID:
if (Shift = [ssCtrl]) and (Key = 46) Then
KEY := 0;
075 - Backup & Restauração
Para efetuar a cópia:
procedure TFormCopia.BitBtn1Click(Sender:
TObject);
var
I: Integer;
begin
Database1.Connected:=True; // Database
para controle

Table2.DatabaseName:=DirectoryListBox1.Dir
ectory; // Seleciona local de destino da
cópia
with Session1 do
begin
Active:=True;

GetTableNames(‘AliasName’,’*.*’,True,True,
Memo1.Lines); // Retorna o nome das
tabelas
end;
for I:= 0 to Memo1.Lines.Count - 1 do
begin
Table1.TableName:=Memo1.Lines[I]; //
Tabela origem
Table2.TableName:=Memo1.Lines[I]; //
Tabela destino
BatchMove1.Execute;
end;
end;
Para efetuar a restauração:
procedure
TFormRestaura.BitBtn1Click(Sender:
TObject);
var
I: Integer;
begin
Database1.Connected:=True;

Table2.DatabaseName:=DirectoryListBox1.Dir
ectory; // Origem da restauração
with Session1 do
begin
Active:=True;

GetTableNames(Table2.DatabaseName,’*.*’,Tr
ue,True,Memo1.Lines); // Retorna nomes das
tabelas
end;
for I:= 0 to Memo1.Lines.Count - 1 do
begin
Table1.TableName:=Memo1.Lines[I]; //
Tabela origem

Table2.TableName:=Memo1.Lines[I]; //
Tabela destino BatchMove1.Execute;
end;
end;

Após restaurar por este método, você deve recriar os


índices.
076 - executar um programa DOS
Acrescente a ShellApi a clausula uses de sua Unit e
escreva:
ShellExecute(0,nil,‘ARJ.EXE’,‘A BACKUP
C:\DADOS\*.DB’ ,nil,sw_hide);
077 - Trabalhando com horas
Estou tendo um enorme problema para lidar com horas
no Delphi 3. Preciso de uma variavel que acumule qtde
de horas e não a hora.. do tipo..01:00:00…
02:00:00….100:00:00 h estou usando uma variavel
TDateTime, convertida pra TTime, o problema desta que
o delphi trata esta variavel como horas…ou seja quando
chega em 24:00:00 ele zera.
Luciano
****************************************************************
****
Se vc esta querendo fazer um acumulador de horas, nao
ira conseguir deste jeito, vc pode criar dois acumulador
um para a hora e um para os minutos
Exemplo:
Type
TypeHora:Array[1..2] of interger;

Procedure Acumula:TypeHora;
Var
Hora,minuto:Integer;
Begin

Hora:=Hora+StrToInt(Copy(DateTimeToStr(Tim
e()),1,2));

Minuto:=Minuto+StrToInt(Copy(DataTimeToStr
(Time()),4,5));
If Minuto >= 60 Then
Begin
Hora:=Hora+1;
Minuto:=0;
end;
Acumula[1]:=Hora;
Acumula[2]:=Minuto;
End;
Desta forma voce pode armazemar por exemplo o
numero de horas que uma pessoa trabalhou durante o
mes…
Espero ter ajudado…
[]‘s Odimar Tomazeli
078 - Para colocarmos um .bmp
como figura de fundo
Devemos utilizar o seguinte código:
unit Unit1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages,
Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender:Tobject);
procedure FormPaint(Sender:TObject);
private
grafico: TBitmap;
public
{ Public declarations }
end;
var
Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.
FormCreate(Sender:Tobject);
begin
grafico:= TBitmap.Create;
grafico.LoadFromFile
(‘C:\netsys\netsys.bmp’);
end;
procedure
TForm1.FormPaint(Sender:TObject);
begin
Form1.Canvas.Draw(0,0,grafico);
end;
end.
079 - Escondendo o Programa de
Ctrl+Alt+Del
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
{Para ocultar um programa, deve-se
registrar este como um serviço do Windows.
Normalmente um serviço do Windows é
ativado quando com a inicialização do
sistema (Windows) e pemanece ativo até a
finalização deste. Este processo esconde o
programa da lista “Ctrl+Alt+Del”}
Const
Servico_Simples = 1;
Servico_Unregister = 1;
Function
RegisterServiceProcess(DwProcessID,
dwType: DWord): DWord; StdCall; External
‘KERNEL32.dll’;

procedure TForm1.FormCreate(Sender:
TObject);
begin

RegisterServiceProcess(GetCurrentProcessID
, Servico_Simples);
end;

procedure TForm1.FormDestroy(Sender:
TObject);
begin

RegisterServiceProcess(GetCurrentProcessID
, Servico_Unregister);
end;
end.
080 - Formulário Transparente
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormShow(Sender:
TObject);
begin
Brush.Style := BsClear;
end;
end.
081 - Mover Formulário em todas
as partes
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
private
{ Private declarations }
public
procedure WMNChitTest(var M:
TWMNchitTest);
message WM_NCHITTEST;
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMNchitTest(var
M:TWMNChitTest);
begin
inherited;
if M.result = htclient then
M.result := htCaption;
end;
end.
082 - Filtrando registros com o
Quickreport (Delphi 2.0)
Você deve usar o evento OnFilter do componente
Quickreport. O mesmo possui a variável PrintRecord do
tipo Boolean. Para que o registro não seja impresso,
basta atribuir False a esta variável.
procedure TForm1.QuickReport1Filter(var
PrintRecord: Boolean);
begin
PrintRecord:= ( table1salario.value > 200
);
end;
083 - Como executar programas
externos
Winexec(‘Command.com /C
Teste.exe’,Tipo_de_Janela);
Tipo_de_Janela :
SW_SHOWNORMAL - Visualização normal da janela
SW_MAXIMIZE - Janela maximizada
SW_MINIMIZE - Janela minimizada
SW_HIDE - Escondido
084 - Alterando Idapi32.Cfg Via
Programa
Check(DbiAddAlias(Nil, PChar(‘ AliasName
‘), Nil, PChar(‘ AliasPath’), True));
Substitua AliasName pelo nome do alias que você quer
criar e em AliasPath pelo path dos arquivos de dados
que você quer no seu alias.
Inclua na cláusula “USES” as units BD e BDE.

Complemento enviado por um colaborador:

procedure TForm1.AlterarClick(Sender:
TObject); var
AParams: TStringList;
caminho:string;
begin
caminho:=‘path=’ + edit1.text;

if not Session.IsAlias(‘Teste’) then


begin
Check(dbiInit(nil));
Check(dbiAddAlias(Nil, PChar(‘teste’),
szParadox, PChar(caminho), True));
Check(DbiExit);
end;

AParams := TStringList.Create;
try

Session.GetAliasParams(‘Teste’,AParams);
begin
AParams.Clear;
AParams.Add(caminho);
Session.ModifyAlias(‘Teste’,AParams);
Session.SaveConfigFile;
end;
finally
AParams.Free;
end;
end;

Marco Aurélio Braun


Três Coroas - RS
085 - Trocando a cor da fonte num
DBGrid
Coloque a propriedade defaultdrawdata do dbgrid em
FALSE;
No evento onDrawColumnCell do dbgrid coloque o
código para mudar a cor do font do dbgrid e a chave do
método para “desenhar” os dados.
procedure
TForm1.DBGrid1DrawColumnCell(Sender:
TObject;
const
Rect: TRect;
DataCol: Integer;
Column: TColumn;
State: TGridDrawState);
begin
If Condição then
Dbgrid1.Canvas.Font.Color:= clFuchsia; //
coloque aqui a cor desejada
Dbgrid1.DefaultDrawDataCell(Rect,
dbgrid1.columns[datacol].field, State);
end;
086 - Pegando a linha e coluna
atuais de um memo
With Memo1 do
begin
Line:= Perform(EM_LINEFROMCHAR,SelStart,
0);
Column:= SelStart - Perform(EM_LINEINDEX,
Line, 0);
end;

You can use the Windows API messages


EM_LINEFROMCHAR and EM_LINEINDEX to
determine the current line and offset within that line
(starting from SelStart).

var
LineNum: longint;
CharsBeforeLine: longint;
begin
LineNum := SendMessage(Memo1.Handle,
EM_LINEFROMCHAR, Memo1.SelStart,0);
CharsBeforeLine :=
SendMessage(Memo1.Handle, EM_LINEINDEX,
LineNum, 0);
Label1.Caption := ‘Line ‘ +
IntToStr(LineNum +1);
Label2.Caption := ‘Position ‘ +
IntToStr((Memo1.SelStart -
CharsBeforeLine) + 1);
end;
087 - Pegar nome do usuário na
rede
function TForm1.usuario : string;
var
szNetName: Array[0..48] of Char;
iResult: DBIResult;
begin
iResult:= DBIGetNetUserName(szNetName);
if iResult <> DBIErr_None then
DBIError( iResult )
else
Result:= StrPas(szNetName);
end;

Colocar na chamada de Uses de sua Unit as seguintes


DCUs : DBITYPES, DBIPROCS, DBIERRS, DBTables e
DB.
088 - Criando tabelas
var
Tabela: TTable;
Indices: TIndexOptions;
begin
Tabela:= TTable.Create;
Indices:= [ixPrimary, IxUnique];
with Tabela do
begin
active:= false;
databasename:= ‘c:\teste’;
tablename:= ‘Tabela’;
tabletype:= ttDefault;
fielddefs.clear;
fielddefs.add(‘Codigo’, ftInteger, 0,
false);

indexdefs.clear;
indexdefs.add(‘Codigo_Chave’, ‘codigo’,
Indices);
CreateTable;
end;
Exemplo 2
if
FileExists(‘c:\contatos\contatos.db’)=fals
e then
begin
TableContatos.Close;
TableContatos.DatabaseName:=‘c:\contatos’;
TableContatos.TableName:=‘Contatos’;
TableContatos.TableType:=ttParadox;
TableContatos.FieldDefs.Clear;
TableContatos.FieldDefs.Add(‘Cod’,ftAutoIn
c,0,false);
TableContatos.FieldDefs.Add(‘Contato’,ftSt
ring,50,false);
TableContatos.FieldDefs.Add(‘Telefone’,ftS
tring,12,false);
TableContatos.FieldDefs.Add(‘Curso’,ftStri
ng,20,false);
TableContatos.FieldDefs.Add(‘Observacao’,f
tMemo,100,false);
TableContatos.IndexDefs.Clear;
TableContatos.IndexDefs.Add(‘iCod’,‘Cod’,
[ixPrimary,ixUnique]);
TableContatos.IndexDefs.Add(‘iContato’,‘Co
ntato’,[ixUnique]);
TableContatos.CreateTable;
TableContatos.Open;
ShowMessage(‘As tabelas foram criadas com
êxito!’);
end
else
begin
TableContatos.Close;
TableContatos.DataBaseName:=‘C:\contatos’;
TableContatos.TableName:=‘contatos.db’;
TableContatos.Open;
end;
089 - Gerenciando mais de uma
linha selecionada num DBGrid
(Multiselect)
O DBGrid tem uma propriedade não documentada
chamada SelectedRows (Tbookmark). Com ela você
pode gerenciar Multiselect da seguinte forma:
var
contador: Integer;
begin
With Dbgrid1 do
Begin
for contador:= 0 to
Pred(SelectedRows.Count) do
Begin
Datasource.Dataset.Bookmark:=
SelectedRows[contador]; // posiciona nos
registros selecionados do DBGrid
end;
end;
090 - Traduzindo o preview padrão
do Quickreport (Delphi 3)
Abra só o arquivo QRPREV.DFM do diretório
C:\Arquivos de Programas\Borland\Delphi 3.0\Lib.
Atenção: não abra o QRPREV.DCU, ok?
Você pode traduzir várias propriedades exceto NAME
dos componentes e você não deve incluir nenhum
componente novo.
091 - Extraindo o ano, mês ou dia
de uma data via SQL
Select * from nome_tabela where
extract(year from campo_data) = 1997
Você pode extrair o mês (MONTH) ou o dia (DAY).
092 - Data por extenso no
Quickreport
var
nrdia: Integer;
diasemana: array[1..7] of String;
meses: array[1..12] of String;
dia, mes, ano: Word;
begin
diasemana[1]:= ‘Domingo’;
diasemana[2]:= ‘Segunda-feira’;
diasemana[3]:= ‘Terça-feira’;
diasemana[4]:= ‘Quarta-feira’;
diasemana[5]:= ‘Quinta-feira’;
diasemana[6]:= ‘Sexta-feira’;
diasemana[7]:= ‘Sábado’;
meses[1]:= ‘Janeiro’;
meses[2]:= ‘Fevereiro’;
meses[3]:= ‘Março’;
meses[4]:= ‘Abril’;
meses[5]:= ‘Maio’;
meses[6]:= ‘Junho’;
meses[7]:= ‘Julho’;
meses[8]:= ‘Agosto’;
meses[9]:= ‘Setembro’;
meses[10]:= ‘Outubro’;
meses[11]:= ‘Novembro’;
meses[12]:= ‘Dezembro’;
DecodeDate(DATE,ano,mes,dia);
nrdia:= DayOfWeek(DATE);
QRLabel1.Caption:= diasemana[nrdia]+’,
‘+INTTOSTR(dia)+’ de ‘+meses[mes]+’ de
‘+INTTOSTR(ano);
end;
093 - Imprimindo um campo memo
via Canvas
Coloque na clásula Uses a unit printers
procedure TForm1.Button1Click(Sender:
TObject);
var
i, altura : Integer;
sMemo : String;
begin
With Printer do
begin
Title:= ‘Imprimindo memo’;
BeginDoc;
With Canvas do
begin
altura := TextHeight(‘A’);
for i := 1 to Memo1.Lines.Count do
begin
sMemo := Memo1.Lines[I];
TextOut(1, (i - 1) * Altura, sMemo);
end;
end;
EndDoc;
end;
end;
094 - Procura e substituição de
string num campo memo
Procedure TForm1.Button1Click (Sender:
TObject);
Begin
FindReplace(Edit1.Text,Edit2.Text, Memo1);
end;

Procedure FindReplace (const Enc, subs:


String; Var Texto: TMemo);
Var
i, Posicao: Integer;
Linha: string;
Begin
For i:= 0 to Texto.Lines.count - 1 do
begin
Linha := Texto. Lines[i];
Repeat
Posicao:=Pos(Enc,Linha);
If Posicao > 0 then
Begin
Delete(Linha,Posicao,Length(Enc));
Insert(Subs,Linha,Posicao);
Texto.Lines[i]:=Linha;
end;
until Posicao = 0;
end;
end;
095 - Testando drives
function TForm1.TemDiscoNoDrive(const
drive : char): boolean;
var
DriveNumero : byte;
EMode : word;
begin
result := false;
DriveNumero := ord(Drive);
if DriveNumero >= ord(‘a’) then
dec(DriveNumero,$20);
EMode :=
SetErrorMode(SEM_FAILCRITICALERRORS);
try
if DiskSize(DriveNumero-$40) <> -1 then
Result := true
else
messagebeep(0);
finally
SetErrorMode(EMode);
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
if TemDiscoNoDrive(‘a’) then
ShowMessage(‘Tem disco no drive A:’)
else
ShowMessage(‘Não tem disco no drive A:’);
end;
096 - Como saber o estado das
teclas Num lock, Caps lock e Scroll
lock
Para saber o estado das teclas acima citadas, utilize a
função getkeystate em conjunto com o código das
teclas, ela retorna 0 se a tecla estiver OFF e 1 se a tecla
estiver ON, assim:
If getkeystate(vk_numlock) = 0 then // Num
lock está OFF
If getkeystate(vk_numlock) = 1 then // Num
lock está ON
If getkeystate(vk_scroll) = 0 then //
Scroll lock está OFF
If getkeystate(vk_scroll) = 1 then //
Scroll lock está ON
If getkeystate(vk_CAPITAL) = 0 then //
Caps lock está OFF
If getkeystate(vk_CAPITAL) = 1 then //
Caps lock está ON
097 - Como compartilhar uma pasta
de um outro micro e mapear com
uma letra
var
err : DWord;
PServer, PSenha, PLetra : PChar;
Begin
PServer := ‘\Caminho\Caminho’ + #0;
PLetra := ‘L:’;
PSenha := ”;

ERR := WNetAddConnection ( PServer ,


PSenha , PLetra );

CASE ERR of
ERROR_ACCESS_DENIED : ShowMessage (
‘Acesso negado.’ );
ERROR_ALREADY_ASSIGNED : ShowMessage ( ‘A
letra do drive especificada já está
conectada.’ );
ERROR_BAD_DEV_TYPE : ShowMessage ( ‘O tipo
de dispositivo e o tipo de recurso não são
compatíveis.’ );
ERROR_BAD_DEVICE : ShowMessage ( ‘Letra
inválida.’ );
ERROR_BAD_NET_NAME : ShowMessage ( ‘Nome
do servidor não é válido ou não pode ser
localizado.’ );
ERROR_BAD_PROFILE : ShowMessage ( ‘Formato
incorreto de parâmetros.’ );
ERROR_CANNOT_OPEN_PROFILE : ShowMessage (
‘Conexão permanente não disponível.’ );
ERROR_DEVICE_ALREADY_REMEMBERED :
ShowMessage ( ‘Uma entrada para o
dispositivo especificado já está no perfil
do usuário.’ );
ERROR_EXTENDED_ERROR : ShowMessage ( ‘Erro
de rede.’ );
ERROR_INVALID_PASSWORD : ShowMessage (
‘Senha especificada inválida.’ );
ERROR_NO_NET_OR_BAD_PATH : ShowMessage (
‘A operação não foi concluída porque a
rede não foi inicializada ou caminho é
inválido.’ );
ERROR_NO_NETWORK : ShowMessage ( ‘A rede
não está presente.’ );
else if Err > 0 then
ShowMessage (IntToStr(Err));
end;
end;

Observação mandada por pedro do


delphi@grupos.com.br
Obs.:Se “PLetra” for deixada em branco, o acesso será
liberado sem ser criada uma unidade lógica.
Valeu Pedro!!
098 - Como extrair o ícone de um
executável
Inclua a unit Shellapi na cláusula uses do seu form.
Image1.Picture.Icon.Handle:=
ExtractIcon(Handle,PChar(‘c:\windows\calc.
exe’),0);
099 - Aguardar um determinado
número de segundos
procedure TForm1.Delay(Tempo: Word);
var
x1: Double;
begin
x1:= now;
repeat until ((now-x1)*86400) > Tempo;
end;
Observação:
A dica acima serve apenas para as versões do Delphi
que não possuem a função Sleep.
Ex:
Sleep(1000); //Aguarda 1 segundo
100 - Como extrair o número de
cores do modo de vídeo corrente do
Windows95
var
hnd: THandle;
bitsPorPixel: integer;
begin
hnd:= GetDC( Handle );
bitsPorPixel:= GetDeviceCaps( hnd,
BITSPIXEL );
// 8 = 256 cores; 16 = high color; 24 =
true color
end;
101 - Verificando a memória
var
MemoryStatus: TMemoryStatus;
begin
MemoryStatus.dwLength:=
sizeof(MemoryStatus);
GlobalMemoryStatus(MemoryStatus);
Label1.Caption := ‘Total de memória física
: ‘ + IntToStr(MemoryStatus.dwTotalPhys);
end;

{typedef struct _MEMORYSTATUS}


DWORD dwLength; // sizeof(MEMORYSTATUS)
DWORD dwMemoryLoad; // percentual de
memória em uso
DWORD dwTotalPhys; // bytes de memória
física
DWORD dwAvailPhys; // bytes livres de
memória física
DWORD dwTotalPageFile; // bytes de
paginação de arquivo
DWORD dwAvailPageFile; // bytes livres de
paginação de arquivo
DWORD dwTotalVirtual; // bytes em uso de
espaço de endereço
DWORD dwAvailVirtual; // bytes livres}
102 - Trocando a cor de uma célula
num DBGrid
No evento onDrawColumnCell do dbgrid coloque o
código para mudar a cor da fonte do dbgrid e a chave do
método para “desenhar” os dados.
procedure
TForm1.DBGrid1DrawColumnCell(Sender:
TObject; const
Rect: TRect;
DataCol: Integer;
Column: TColumn;
State: TGridDrawState);
begin
if (Column.Field.FieldName =
‘NOMEDOCAMPO’) then
begin
if condição then // coloque aqui sua
condição
begin
DBGrid1.Canvas.Brush.Color:= clAqua;
DBGrid1.Canvas.Font.Color:= clWindowText;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.DefaultDrawColumnCell(Rect,
DataCol, Column, State);
end;
end;
end;
103 - Exponenciação
Inclua a unit Math na clausula uses do seu form. Depois
disso utilize a função Power.
Edit1.text:= FloatToStr(Power(2,4));
104 - Como manipular arquivos INI
Inclua a unit IniFiles na clausula uses do seu form.
Procedure TForm1.GravaIni( Numero :
Longint ; Texto : String ; Condicao :
Boolean);
var
ArqIni : TIniFile;
begin
ArqIni :=
TIniFile.Create(‘c:\windows\temp\Teste.Ini
’);
Try
ArqIni.WriteInteger(‘Dados’, ‘Numero’,
Numero);
ArqIni.WriteString(‘Dados’, ‘Texto’,
Texto);
ArqIni.WriteBool(‘Dados’, ‘Condição’,
Condicao);
Finally
ArqIni.Free;
end;
end;

Procedure TForm1.LeIni( Var Numero :


Longint ; Var Texto : String ; Var
Condicao : Boolean);
var
ArqIni : tIniFile;
begin
ArqIni :=
tIniFile.Create(‘c:\windows\temp\Teste.Ini
’);
Try
Numero := ArqIni.ReadInteger(‘Dados’,
‘Numero’, Numero );
Texto := ArqIni.ReadString(‘Dados’,
‘Texto’, Texto );
Condicao := ArqIni.ReadBool(‘Dados’,
‘Condição’, Condicao );
Finally
ArqIni.Free;
end;
end;

Utilize as procedures assim:

procedure TForm1.Button1Click(Sender:
TObject);
begin
GravaIni(1234,‘TESTE’,True);
end;

procedure TForm1.Button2Click(Sender:
TObject);
var
N: Integer;
T: String;
C: Boolean;
begin
LeIni(N,T,C);
Showmessage(IntToStr(N)+’ ‘+T);
end;
105 - Como extrair o tamanho de
um arquivo
function TamArquivo(Arquivo: string):
Integer;
begin
with TFileStream.Create(Arquivo,
fmOpenRead or fmShareExclusive) do
try
Result := Size;
finally
Free;
end;
end;

Utilize a função assim:

procedure TForm1.Button1Click(Sender:
TObject);
begin
edit1.text:=
inttostr(TamArquivo(‘CAMINHO\NOMEDOARQUIVO
’));
end;
106 - Como alterar a data e a hora
do sistema
procedure TForm1.Button1Click(Sender:
TObject);
var
SystemTime : TSystemTime;
begin
With SystemTime do
begin
//Definindo o dia do sistema
wYear:= 1996;
wMonth:= 5;
wDay:= 10;
//Definindo a hora do sistema
wHour:= 20; //hora
wMinute:= 50; //minutos
wSecond:= 59; //segundos
end;
//Colocar a hora e data do sistema
SetLocalTime(SystemTime);
end;
107 - Como obrigar a digitação de
caracteres maiúsculos num campo
memo
procedure TForm1.Memo1KeyPress(Sender:
TObject; var Key: Char);
begin
Key:= Upcase(Key);
end;
108 - Como validar a entrada em
um TEdit
procedure Edit1KeyPress(Sender: TObject;
var Key: Char);
begin
If not( key in[‘0’..‘9’,#8] ) then
begin
beep;{somente delphi 2.0 ou >}
key:=#0;
end;
end;
109 - Como conectar uma unidade
de rede
procedure TForm1.Button1Click(Sender:
TObject);
var
NRW: TNetResource;
begin
with NRW do
begin
dwType := RESOURCETYPE_ANY;
lpLocalName := ‘G:’;
lpRemoteName := ‘\servidor\c’;
lpProvider := ”;
end;
WNetAddConnection2(NRW, ‘MyPassword’,
‘MyUserName’, CONNECT_UPDATE_PROFILE);
end;
110 - Inserindo um Combobox num
DBGrid
Siga o passo-a-passo abaixo :
1. insira um Datasource, um DBGrid e dois Table’s no
form
2. link o Table1 com Datasource1 e DBGrid1
3. defina um banco de dados, uma tabela e ative o
Table1
4. defina também para o Table2, mas use uma tabela
diferente
5. adicione todos os campos do Table1 através do Fields
Editor
6. mude a propriedade Visble para False do campo do
Combobox
7. dê um clique com o botão direito do mouse sobre o
Fields Editor e escolha New Field…
8. especifique os parametros para o novo campo
a) Name: <algum nome>
b) Type: <tipo do campo>
c) Size: <tamanho>
d) Field type: Lookup
e) Key Field: <campo que receberá o valor escolhido
no combobox&
f) DataSet: Table2
g) LookUpKeys: <campo listado no combo>
h) Result Field: <campo que será mostrado para o
usuário no Combobox>
9. Execute a aplicação.
111 - Definido o tamanho mínimo e
máximo de um formulário
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;

type
TForm1 = class(TForm)
private
{ Private declarations }
procedure WMGetMinMaxInfo(var MSG:
TMessage); message WM_GetMinMaxInfo;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMGetMinMaxInfo(var MSG:


TMessage);
begin
inherited;
with PMinMaxInfo(MSG.lparam)^ do begin
ptMinTRackSize.X := 300;
ptMinTRackSize.Y := 150;
ptMaxTRackSize.X := 350;
ptMaxTRackSize.Y := 250;
end;
end;
end.
112 - Chaves do Registro
Lixeira
HKEY_CLASSES_ROOT\CLSID\{645FF040-5081-
101B-9F08-00AA002F954E}
(Padrão) - “Bagulho”
InfoTip - “Descrição”

Painel de Controle
HKEY_CLASSES_ROOT\CLSID\{21EC2020-3AEA-
1069-A2DD-08002B30309D}
(Padrão) -
InfoTip

Impressoras
HKEY_CLASSES_ROOT\CLSID\{2227A280-3AEA-
1069-A2DE-08002B30309D}
(Padrão)
InfoTip

Instalação
HKEY_LOCAL_MACHINE\Software\Microsoft\Wind
ows\CurrentVersion
RegisteredOrganization
RegisteredOwner

AutoExecução
HKEY_USERS.DEFAULT\Software\Microsoft\Wind
ows\CurrentVersion\Run

Arquivos do word não abrem se modificada


HKEY_CLASSES_ROOT.doc
(Padrão)

Arquivos do excel não abrem se modificada


HKEY_CLASSES_ROOT.xls
(Padrão)
Se Esta chave for renomeada apagase a
lixeira
HKEY_LOCAL_MACHINE\Software\Microsoft\Wind
ows\CurrentVersion

Retirar a Pasta Favoritos do botão iniciar


HKEY_CURRENT_USER\Software\Microsoft\Windo
ws\CurrentVersion\Policies\Explorer
Adicionar a chave DWORD “NoFavoritesMenu”
com o valor “1”

Outras Chaves
Meu Computador
HKEY_CLASSES_ROOT\CLSID\{20D04FE0-3AEA-
1069-A2D8-08002B30309D}

Network Neighborhood
HKEY_CLASSES_ROOT\CLSID\{208D2C60-3AEA-
1069-A2D7-08002B30309D}

Caixa de Entrada
HKEY_CLASSES_ROOT\CLSID\{00020D75-0000-
0000-C000-000000000046}

Área de Trabalho
HKEY_CLASSES_ROOT\CLSID\{00021400-0000-
0000-C000-000000000046}

Atalho
HKEY_CLASSES_ROOT\CLSID\{00021401-0000-
0000-C000-000000000046}

TAREFA DO MENU INICIAR


HKEY_CLASSES_ROOT\CLSID\{DDB008FE-048D-
11d1-B9CD-00C04FC2C1D2}
ACTIVE DESKTOP MOVER
HKEY_CLASSES_ROOT\CLSID\{72267F6A-A6F9-
11D0-BC94-00C04FB67863}

Internet Explorer
HKEY_CLASSES_ROOT\CLSID\{25336920-03F9-
11CF-8FD0-00AA00686F13}

Documento MS WORD
HKEY_CLASSES_ROOT\CLSID\{00020900-0000-
0000-C000-000000000046}

Documento MS EXCEL
HKEY_CLASSES_ROOT\CLSID\{00024500-0000-
0000-C000-000000000046}

The MS NETWORK
HKEY_CLASSES_ROOT\CLSID\{00028B00-0000-
0000-C000-000000000046}

FONTES.
HKEY_CLASSES_ROOT\CLSID\{BD84B380-8CA2-
1069-A2DE-08000948F534}
113 - Posicionando o cursor numa
linha de um Memo ou RichEdit
Para posicionar o cursor em uma linha de um Memo ou
RichEdit, deve-se utilizar o seguinte:
With Memo1 do
SelStart := Perform(EM_LINEINDEX, Linha,
0);
114 - Como verificar se um arquivo
existe?
If
not(fileexists(‘c:\windows\nuvens.bmp’))
then Showmessage(‘Arquivo inexistente’);
115 - Evitando Perdas de Dados
Um dos problemas dos programadores Delphi é salvar
as informações fisicamente no disco rígido. Quando
estamos trabalhando com o programa as informações
ficam retidas no buffer, o que, em caso de queda de
energia ou até mesmo se o usuário fechar o Windows
com a aplicação aberta resulta na perda dos dados, que
foram processados na execução atual do sistema.
Para resolver o problema, basta acrescentar no evento
AfterPost de cada componente Table as linhas de código
que estão abaixo.
Na lista de Uses acrescente a unit DBIProcs.
Dessa forma, você não precisa temer perder os seus
dados por uma falha elétrica ou pela quebra do sistema
(como um erro GPF, por exemplo), após atualizar o
banco de dados.
implementation

uses DBIProcs;

{$R *.DFM}
procedure
TForm1.Table1AfterPost(DataSet: Dataset);
begin
DBISaveChanges(Table1.Handle);
end;
end.
116 - StrToIntDef
Quando utilizamos a função StrToInt e a string original
não é um inteiro, o programa gera uma exceção. Para
evitar isto, podemos utilizar a função StrToIntDef, que
insere um valor predeterminado (default) caso a string
não possa ser convertida em inteiro.
Veja o exemplo:
procedure TForm1.Button1Click(Sender:
TObject);
var
NumberString: string;
Number: Integer;
begin
NumberString := Edit1.Text;
Number := StrToIntDef(NumberString, 1000);
Edit2.Text := IntToStr(Number);
end;
117 - Quebra de String
Nesta dica iremos mostrar uma função que cria uma
lista de strings baseado numa cadeia de string,
quebrando-a onde encontrar um caractere
predeterminado. Por exemplo:
Uma string como ‘O céu é azul’, escolhendo o caracter
espaço (‘ ‘) para quebrar, seria tranformado em uma lista
de strings que, colocada em um componente do tipo
TListBox ficaria:
O
céu
é
azul
Isto é, onde havia um espaço a string foi “quebrada”.
function sBreakApart(BaseString,
BreakString: string; StringList:
TStringList): TStringList;
var
EndOfCurrentString: byte;
TempStr: string;
begin
repeat
EndOfCurrentString := Pos(BreakString,
BaseString);
if EndOfCurrentString = 0 then
StringList.add(BaseString)
else
StringList.add(Copy(BaseString, 1,
EndOfCurrentString - 1));
BaseString := Copy(BaseString,
EndOfCurrentString + length(BreakString),
length(BaseString) - EndOfCurrentString);
until EndOfCurrentString = 0;
result := StringList;
end;

procedure TForm1.Button1Click(Sender:
TObject);
var
t: TStringList;
begin
t := TStringList.create;
ListBox1.Items.Assign(sBreakApart(Edit1.Te
xt, ‘ ‘, t));
t.free;
end;
118 - Inserindo zeros no inicio de
um inteiro
Ex: Se o inteiro for 4 fica 00004. Se for 200, fica 00200.
var
s: string;
begin
FmtStr(s, ‘%.5d’, [StrToInt(edit1.text)]);
edit1.text := s;
end;
119 - Para dar a senha de uma
tabela Paradox no programa
Pode-se usar este código:
procedure TForm1.FormCreate(Sender:
TObject);
begin
Session.AddPassWord(‘MyPass’);
Table1.Active := True;
end;
120 - Pegando o registro do
windows
Unit Registry
procedure
TSplash_Form.FormActivate(Sender:
TObject);
var
reg: TRegIniFile;
begin
reg :=
TReginiFile.Create(‘SOFTWARE\MICROSOFT\MS
SETUP (ACME)');
Label1.Caption := reg.ReadString(‘USER
INFO’,‘DefName’,”);
reg.Free;
end;
121 - Fechar outro programa
1. Exemplo de como fechar a
calculadora a partir do texto da
janela

Procedure TForm1.Button1Click(Sender:
TObject);
begin
PostMessage(FindWindow(nil,
‘Calculadora’), WM_CLOSE,0,0);
end;
2. Exemplo de como fechar a
calculadora a partir da classe

Procedure TForm1.Button1Click(Sender:
TObject);
begin
PostMessage(FindWindow(‘scicalc’, nil),
WM_CLOSE,0,0);
end;
Obs.: A classe de um programa pode ser descoberta
usando o programa Winsight32 que vem com o delphi.
By Lloyd Dickinson
122 - Como Manipular arquivos
.INI 2
Os arquivos .INI são arquivos de texto que servem para
guardar informações úteis de configuração, como a
passagem de uma data de um programa para outro, o
arquivo .INI tem o formato:
[SEÇÃO]
variável=valor
Para usar um arquivo .INI seguem os passos abaixo:
* acrescentar na Uses do projeto a bibliteca IniFiles
uses IniFiles;
* criar uma variável do tipo TIniFile
var
data:TIniFile;
* Criar o arquivo .INI
Data := TIniFile.Create(‘Data.ini’);
Onde Data.ini é o nome do arquivo (você pode colocar
inclusive o caminho do arquivo, o padrão é o diretório do
Windows).
* Gravar a informação
Data.WriteString(‘Mes/Ano’,‘Data’,Edit1.Te
xt);
Data.Free; //esta linha libera a variável
da memória
Onde Mes/Ano é o nome da seção, Data é o nome da
variável e Edit1.Text é a data digitada pelo usuário
* Ler a informação
Crie outra variável no outro programa apenas para ler a
string
Data.TiniFile.Create(‘Data.ini’);
Data.ReadString(‘Mes/Ano’,‘Data’,”);
Data.Free;
123 - Pegando a data de um
arquivo
Unit SysUtils

var
DataArq: TDateFile;
begin
DataArq:=
FileDateToDateTime(FileAge(‘NomeDoArquivo’
));
end;
124 - Compactar tabelas
Esta rotina existe para o banco de dados local Paradox
pois, mesmo os registros sendo deletados pelo usuário,
as posições deles continuam sendo utilizadas mas os
dados não estão mais acessíveis.
uses BDE;

procedure CompactarTabela(Table:TTable);
var
TableDesc: CRTblDesc;
WasActive: Boolean;
hDataBase: hDbiDB;
begin
WasActive := Table.Active;
Screen.Cursor := crHourglass;
try
{abre se estava fechado para o obter o
DBHandle válido}
if not WasActive then
begin
Table.Open;
{obtem o handle do banco de dados e
fecha a tabela}
hDataBase := Table.DBHandle;
Table.Close;
{preenche o descritor da tabela}
FillChar(TableDesc, SizeOf (CRTblDesc),
0);
end;
with TableDesc do
begin
StrPCopy(szTblName, Table.TableName);
StrPCopy(szTblType, szParadox);
bPack := True;
end;
{reestrutura a tabela, empacotando-a}
if hdataBase<>nil then
Check(DbiDoRestructure(hDataBase, 1,
@TableDesc, nil, nil, nil, False))
else
Application.MessageBox(‘A tabela não
possui dados para
compactação’,‘Compactação’,0+16);
finally
Screen.Cursor := crDefault;
{por fim, reabre}
if WasActive then
Table.Open;
end;
end;

Nota: A Table que você estiver usando deve estar


fechada (Active := false)
125 - Criando diretório
Para criar um diretório você precisa usar a função
ForceDirectories, o exemplo a baixo testa se não existe
um diretório e cria o diretório apartir de uma variável
string testando se o diretório já existe
Unit

FileCtrl

procedure TForm1.Button1Click(Sender:
TObject);
var
Dir: string;
begin
Dir := ‘C:\APPS\SALES\LOCAL’;

if not DirectoryExists(Dir) then


ForceDirectories(Dir);
Label1.Caption := Dir + ‘ foi criado’;
end;
126 - Reindexando índices
uses
dbTables, DbiProcs;
begin
table1.exclusive := true;
table1.open;
dbiRegenIndexes(table.Handle);
end;
127 - Verificando se a impressora
está ativa
Na sua unit, faça a chamada abaixo:
While not PrinterOnline() do
begin
MsgBox(‘Verifique a
Impressora!’,‘ATENÇÃO’);
end;

Function PrinterOnLine : Boolean;


Const
PrnStInt : Byte = $17;
StRq : Byte = $02;
PrnNum : Word = 0; { 0 para LPT1, 1 para
LPT2, etc. }
Var
nResult : byte;
Begin (* PrinterOnLine*)
Asm
mov ah,StRq;
mov dx,PrnNum;
Int $17;
mov nResult,ah;
end;
PrinterOnLine := (nResult and $80) =
$80;
End;
128 - Interceptando as teclas de
função no seu programa
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word; Shift:
TShiftState);
begin
if Key = VK_F5 then
showMessage(‘A Tecla F5 foi
Pressionada’);
end;

OBS: A PROPRIEDADE DO FORM KEYPREVIEW TEM QUE ESTAR


TRUE
129 - Copiando Arquivos Via
Programação
Function
CopiaArquivo(scrname,destname:string):byte
;
var
source,destination:file;
buffer:array[1..1024] of byte;
readcnt,writecnt:word;
pname,dname,fname,ename:String;
{ USO:
R:=COPIAARQUIVO(‘C:\diretorio\FILE.EXT’,‘C
:\diretorio\FILE.EXT’); Devolve 0=Ok,
1=Erro no Origem, 2=Erro no Destino,
3=Disco Cheio }
begin
AssignFile(source,scrname);
Try
Reset(source,1);
Except
CopiaArquivo:=1;
Exit;end;If
destname[length(destname)]=’' then
begin
pname:=scrname;

destname:=destname+separa(scrname,’',Ocorr
e(scrname,’')+1);
end;
AssignFile(destination,destname);
Try
Rewrite(destination,1);
Except
CopiaArquivo:=2;
Exit;
end;
Repeat

BlockRead(source,buffer,sizeof(buffer),rea
dcnt);
Try

BlockWrite(destination,buffer,readcnt,writ
ecnt);
Except
CopiaArquivo:=3; {Disco Cheio?}
Exit;
end;
until (readcnt=0) or (writecnt<>readcnt);
CloseFile(destination);
CloseFile(source);
CopiaArquivo:=0;
end;
130 - Função que retorna o nome
do Computador
Uses Registry;
function TForm1.Getcomputer : string;
var
registro : tregistry;
begin
registro:=tregistry.create;
registro.RootKey:=HKEY_LOCAL_MACHINE;
registro.openkey(‘System\CurrentControlSet
\Services\VXD\VNETSUP’,false);
result:=registro.readstring(‘ComputerName’
);
end;
131 - Escondendo janelas filhas
minimizadas
Para esconder janelas filhas minimizadas, basta
capturar a mensagem WM_Size, desta maneira:
type
TForm1 = class(TForm)
public
procedure WMSize(var M :
TWMSIZE);Message WM_Size;
end;
implementation
procedure TForm1.WMSize(var M:TWMSIZE);
begin
if M.SizeType=Size_Minimized then
ShowWindow(Handle,Sw_Hide);
end;
132 - Executando uma única cópia
do aplicativo
Se você quiser executar uma única copia do aplicativo, o
código de inicializacao do arquivo fonte do PROJETO
pode ser escrito conforme segue:
program Project1;
uses
Forms,
Windows,
Dialogs,
Unit1 in ‘Unit1.pas’ {Form1};
{$R *.RES}
Var HprevHist : HWND;
begin
Application.Initialize;
HprevHist := FindWindow(Nil,
PChar(‘TheProgrammer’));
if HprevHist = 0 then begin
Application.Title := ‘TheProgrammer’;
Application.CreateForm(TForm1, Form1);
Application.Run;
end else
MessageDlg(‘Você não pode executar outra
cópia do aplicativo’, mtInformation,
[mbOK], 0);
Com esse código o usuário pode iniciar uma nova copia
do aplicativo somente se não houver outra anterior.
Caso contrario é exibido uma mensagem para o usuário.
133 - Alterar as cores do título de
um DBGrid em tempo execução
Procedure TForm1.DBGrid1TitleClick(Column:
TColumn); var
I : integer;
begin
for i:=0 to DBGrid1.Columns.count-1 do
begin
DBGrid1.Columns[i].Title.Color :=
clBtnFace;
DBGrid1.Columns[i].Title.Font.Color :=
clBlack;
DBGrid1.Columns[i].Title.Font.Style :=
[];
end;
Column.Title.color := ClYellow;
Column.Title.Font.Style := [ fsBold,
fsItalic];
Column.Title.Font.Color := clRed;
end;
134 - Como fazer para o
computador soar o beep
messageBeep(0);
135 - Como mostrar o mouse como
uma ampulheta
try
Screen.Cursor := crHourGlass;
{ Escreva o ação a executar aqui }
finally
Screen.Cursor := crDefault;
end;
Application.ProcessMessages;
136 - Como controlar o
pressionamento da tecla Enter
procedure TForm1.EditKeyPress(Sender:
TObject; var Key: Char);
{ através do evento onKeyPress do
formulário de controle… }
begin
{ se a “var Key” retornar o código #13
corresponde a <Enter>, #9 corresponde a
tecla TAB }
if Key = #13 then
begin
Key := #0 { Suprime o som }
{ escreva aqui os seus comandos }
end;
end;
137 - Como varrer uma tabela
inteira
Table1.First;
if not Table1.Eof then
repeat
{ seus comandos para a tabela }
Table1.Next
until Table1.Eof;
138 - Como Copiar os valores de
campos de uma tabela para outra
{ Este exemplo copia apenas tabelas de
mesma estrutura }
var
Num: SmallInt;
begin
for Num := 0 to TabelaOrigem.FieldCount
- 1 do
begin
TabelaDestino.Insert;

TabelaDestino.Fields[Num].Assign(TabelaOri
gem.Fields[Num]);
TabelaDestino.Post;
end;
end;
Observação enviada por um dos
usuários da DTDelphi sobre a dica
acima:
Achei um erro na dica número 138, tentei utiliza-la e nao funcionou…
Mas corrigi o código, basta tirar duas linhas do looping FOR.

//CODIGO CORRETO
{ Este exemplo copia apenas tabelas de mesma estrutura }
var
Num: SmallInt;
begin
TabelaDestino.Insert;
for Num := 0 to TabelaOrigem.FieldCount - 1 do
TabelaDestino.Fields[Num].Assign(TabelaOrigem.Fields[Num
]);
TabelaDestino.Post;
end;

Parabéns pelo programa de dicas que vc criou!!! Se ver mais alguma


coisinha errada te mando outro mail.
[]‘s
Fernando Rodrigo Ribeiro
139 - Como verificar se um campo
inteiro é par ou ímpar
function TestaParaPar(TestaInteiro :
Integer) : boolean;
begin
if (TestaInteiro div 2) =
(TestaInteiro/2) then
result := True
else
result := False;
end;
140 - Como verificar se uma string
contém um inteiro
function IsInteger(TestaString: String) :
boolean;
begin
try
StrToInt(TestaString);
except
On EConvertError do result := False;
else
result := True;
end;
end;
141 - Como subtrair datas
function SubData(DataEmprestimo:
TDataTime) : Integer;
begin
result := Date - DataEmprestimo;
end;
142 - Principais Procedimentos e Funções Pré
definidas
procedure Beep;
Toca um beep

procedure ChDir(S: string);


Troca o diretório corrente para o diretório especificado em S.
begin
{$I-}
{ Change to directory specified in Edit1 }
ChDir(Edit1.Text);
if IOResult <> 0 then
MessageDlg(‘Cannot find directory’, mtWarning, [mbOk], 0);
end;

function Chr(X: Byte): Char;


Retorna o caracter com o código ASCII X
begin
Canvas.TextOut(10, 10, Chr(65)); { The letter ‘A’}
end;

function Concat(s1 [, s2,…, sn]: string): string;


Concatena as strings
var
S: string;
begin
S := Concat(‘ABC’, ‘DEF’); { ‘ABCDE’ }
end;

function Copy(S: string; Index, Count: Integer): string;


Retorna uma substring de S, começando a partir de Index e tendo
Count caracters
The Copy function returns a substring of a string.
var S: string;
begin
S := ‘ABCDEF’;
S := Copy(S, 2, 3);&#9;{ ‘BCD’ }
end;

function CreateDir(const Dir: string): Boolean;


Cria um novo diretório e retorna o sucesso da operação

function Date: TDateTime;


Retorna a Data atual
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := ‘Today is ‘ + DateToStr(Date);
end;

function DateToStr(Date: TDateTime): string;


Converte Data para String
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := DateToStr(Date);
end;

function DayOfWeek(Date: TDateTime): Integer;


Retorna o dia da semana especificado entre 1 e 7, onde domigo é
um e Sábado é 7
procedure TForm1.Button1Click(Sender: TObject);
var
ADate: TDateTime;
begin
ADate := StrToDate(Edit1.Text);
Label1.Caption := ‘Day ‘ + IntToStr(DayOfWeek(ADate)) + ‘ of the
week’;
end;

procedure DecodeDate(Date: TDateTime; var Year, Month, Day:


Word);
Quebra os valores especificados no parâmetro Date em Year, Month
e Day.
procedure TForm1.Button1Click(Sender: TObject);
var
Present: TDateTime;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
Present:= Now;
DecodeDate(Present, Year, Month, Day);
Label1.Caption := ‘Today is Day ‘ + IntToStr(Day) + ‘ of Month ‘
+ IntToStr(Month) + ‘ of Year ‘ + IntToStr(Year);
DecodeTime(Present, Hour, Min, Sec, MSec);
Label2.Caption := ‘The time is Minute ‘ + IntToStr(Min) + ‘ of
Hour ‘
+ IntToStr(Hour);
end;

procedure DecodeTime(Time: TDateTime; var Hour, Min, Sec, MSec:


Word);
Quebra os valores especificados em Time nos par6ametros Hour,
Min, Sec e MSec.
procedure TForm1.Button1Click(Sender: TObject);
var
Present: TDateTime;
Year, Month, Day, Hour, Min, Sec, MSec: Word;
begin
Present:= Now;
DecodeDate(Present, Year, Month, Day);
Label1.Caption := ‘Today is Day ‘ + IntToStr(Day) + ‘ of Month ‘
+ IntToStr(Month) + ‘ of Year ‘ + IntToStr(Year);
DecodeTime(Present, Hour, Min, Sec, MSec);
Label2.Caption := ‘The time is Minute ‘ + IntToStr(Min) + ‘ of
Hour ‘
+ IntToStr(Hour);
end;

procedure Delete(var S: string; Index, Count:Integer);


Remove a substring de Count caracters da string S partir da
posição Index
var
s: string;
begin
s := ‘Honest Abe Lincoln’;
Delete(s,8,4);
Canvas.TextOut(10, 10, s);&#9;{ ‘Honest Lincoln’ }
end;

function DeleteFile(const FileName: string): Boolean;


Apaga o arquivo FileName do disco. Se o arquivo não puder ser
apagado a função retorna False.
DeleteFile(‘DELETE.ME’);

function DirectoryExists(Name: string): Boolean;


Verifica se Name diretorio existe

function DiskFree(Drive: Byte): Integer;


Retorna o número de bytes livre no driver especificado em Drive.
Onde : 0 = Corrente, 1 = A, 2 = B,…
DiskFree retorna –1 se o driver for inválido
var
S: string;
begin
S := IntToStr(DiskFree(0) div 1024) + ‘ Kbytes free.’;
Canvas.TextOut(10, 10, S);
end;

function DiskSize(Drive: Byte): Integer;


Retorna o tamanho em bytes do driver especificado.
Onde : 0 = Corrente, 1 = A, 2 = B,…
DiskFree retorna –1 se o driver for inválido
var
S: string;
begin
S := IntToStr(DiskSize(0) div 1024) + ‘ Kbytes capacity.’;
Canvas.TextOut(10, 10, S);
end;
function EncodeDate(Year, Month, Day: Word): TDateTime;
Retorna uma Data formada por Year, Month e Day
procedure TForm1.Button1Click(Sender: TObject);
var
MyDate: TDateTime;
begin
MyDate := EncodeDate(83, 12, 31);
Label1.Caption := DateToStr(MyDate);
end;

function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;


Retorna a Hora formada por Hour, Min, Sec e MSec
procedure TForm1.Button1Click(Sender: TObject);
var
MyTime: TDateTime;
begin
MyTime := EncodeTime(0, 45, 45, 7);
Label1.Caption := TimeToStr(MyTime);
end;

function ExtractFileDir(const FileName: string): string;


Retorna o diretório adequado para ser passado para as funções
CreateDir, GetCurrentDir, RemoveDir e SetCurrentDir.
O resultado da função é uma string vazia se FileName não contiver
um drive e um caminho.

function ExtractFileDrive(const FileName: string): string;


Retorna uma string contendo o drive do path de um arquivo.

function ExtractFileExt(const FileName: string): string;


Retorna a extensão do arquivo FileName

function ExtractFileName(const FileName: string): string;


Retorna o nome do arquivo
Form1.Caption := ‘Editing ‘+ ExtractFileName(FileName);

function ExtractFilePath(const FileName: string): string;


Retorna o Path de um arquivo
ChDir(ExtractFilePath(FileName));

function FileAge(const FileName: string): Integer;


Retorna a data e a hora de um arquivo num valor que pode ser
convertido para TDateTime através da função FileDateToDateTime.
Retorna –1 se o arquivo não existir

function FileExists(const FileName: string): Boolean;


Retorna verdade se o arquivo existir
if FileExists(FileName) then
if MsgBox(‘Do you really want to delete ‘ +
ExtractFileName(FileName)
+ ‘?’), []) = IDYes then DeleteFile(FileName);

function FileSize(var F): Integer;


Retorna o tamanho de um arquivo, para usar FileSize o arquivo
deve esta aberto. Se o arquivo estiver vazio FileSize(F) retorna
0. F é uma variavel do tipo arquivo. FileSize não pode ser usada
com arquivo texto
var
f: file of Byte;
size : Longint;
S: string;
y: integer;
begin
if OpenDialog1.Execute then begin
AssignFile(f, OpenDialog1.FileName);
Reset(f);
size := FileSize(f);
S := ‘File size in bytes: ‘ + IntToStr(size);
y := 10;
Canvas.TextOut(5, y, S);
y := y + Canvas.TextHeight(S) + 5;
S := ‘Seeking halfway into file…’;
Canvas.TextOut(5, y, S);
y := y + Canvas.TextHeight(S) + 5;
Seek(f,size div 2);
S := ‘Position is now ‘ + IntToStr(FilePos(f));
Canvas.TextOut(5, y, S);
CloseFile(f);
end;
end;

procedure FillChar(var X; Count: Integer; value: Byte);


Preenche um vetor com determinado caracter. Value pode ser um
byte ou char
var
S: array[0..79] of char;
begin
{ Set to all spaces }
FillChar(S, SizeOf(S), ‘ ‘);
end;

function FloatToStr(Value: Extended): string;


Converte um valor em ponto flutuante (real) para uma string

procedure ForceDirectories(Dir: string);


Cria multiplos diretórios de uma só vez
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
Dir := ‘C:\APPS\SALES\LOCAL’;
ForceDirectories(Dir);
if DirectoryExists(Dir) then
Label1.Caption := Dir + ‘ was created’
end;

function FormatDateTime(const Format: string; DateTime:


TDateTime): string;
Formata o valor DateTime usando o formato de Format. Os
especificadores de formato abaixo são válidos
Specifier&#9;Displays
c&#9;Displays the date using the format given by the
ShortDateFormat global variable, followed by the time using the
format given by the LongTimeFormat global variable. The time is
not displayed if the fractional part of the DateTime value is
zero.
d&#9;Displays the day as a number without a leading zero (1-31).
dd&#9;Displays the day as a number with a leading zero (01-31).
ddd&#9;Displays the day as an abbreviation (Sun-Sat) using the
strings given by the ShortDayNames global variable.
dddd&#9;Displays the day as a full name (Sunday-Saturday) using
the strings given by the LongDayNames global variable.
ddddd&#9;Displays the date using the format given by the
ShortDateFormat global variable.
dddddd&#9;Displays the date using the format given by the
LongDateFormat global variable.
m&#9;Displays the month as a number without a leading zero (1-
12). If the m specifier immediately follows an h or hh specifier,
the minute rather than the month is displayed.
mm&#9;Displays the month as a number with a leading zero (01-12).
If the mm specifier immediately follows an h or hh specifier, the
minute rather than the month is displayed.
mmm&#9;Displays the month as an abbreviation (Jan-Dec) using the
strings given by the ShortMonthNames global variable.
mmmm&#9;Displays the month as a full name (January-December)
using the strings given by the LongMonthNames global variable.
yy&#9;Displays the year as a two-digit number (00-99).
yyyy&#9;Displays the year as a four-digit number (0000-9999).
h&#9;Displays the hour without a leading zero (0-23).
hh&#9;Displays the hour with a leading zero (00-23).
n&#9;Displays the minute without a leading zero (0-59).
nn&#9;Displays the minute with a leading zero (00-59).
s&#9;Displays the second without a leading zero (0-59).
ss&#9;Displays the second with a leading zero (00-59).
t&#9;Displays the time using the format given by the
ShortTimeFormat global variable.
tt&#9;Displays the time using the format given by the
LongTimeFormat global variable.
am/pm&#9;Uses the 12-hour clock for the preceding h or hh
specifier, and displays ‘am’ for any hour before noon, and ‘pm’
for any hour after noon. The am/pm specifier can use lower,
upper, or mixed case, and the result is displayed accordingly.
a/p&#9;Uses the 12-hour clock for the preceding h or hh
specifier, and displays ‘a’ for any hour before noon, and ‘p’ for
any hour after noon. The a/p specifier can use lower, upper, or
mixed case, and the result is displayed accordingly.
ampm&#9;Uses the 12-hour clock for the preceding h or hh
specifier, and displays the contents of the TimeAMString global
variable for any hour before noon, and the contents of the
TimePMString global variable for any hour after noon.
/&#9;Displays the date separator character given by the
DateSeparator global variable.
:&#9;Displays the time separator character given by the
TimeSeparator global variable.
‘xx’/“xx”&#9;Characters enclosed in single or double quotes are
displayed as-is, and do not affect formatting.
Format specifiers may be written in upper case as well as in
lower case letters—both produce the same result.
If the string given by the Format parameter is empty, the date
and time value is formatted as if a ‘c’ format specifier had been
given.
S := FormatDateTime(‘“The meeting is on” dddd, mmmm d, yyyy, ‘ +
‘“at” hh:mm AM/PM’, StrToDateTime(‘2/15/95 10:30am’));

function FormatFloat(const Format: string; Value: Extended):


string;
Transforma um Float numa string usando a formatação contida em
Format. Os especificadores de formato abaixo são válidos
Specifier&#9;Represents
0&#9;Digit place holder. If the value being formatted has a digit
in the position where the ‘0’ appears in the format string, then
that digit is copied to the output string. Otherwise, a ‘0’ is
stored in that position in the output string.
#&#9;Digit placeholder. If the value being formatted has a digit
in the position where the ‘#’ appears in the format string, then
that digit is copied to the output string. Otherwise, nothing is
stored in that position in the output string.
.&#9;Decimal point. The first ‘.’ character in the format string
determines the location of the decimal separator in the formatted
value; any additional ‘.’ characters are ignored. The actual
character used as a the decimal separator in the output string is
determined by the DecimalSeparator global variable. The default
value of DecimalSeparator is specified in the Number Format of
the International section in the Windows Control Panel.
,&#9;Thousand separator. If the format string contains one or
more ‘,’ characters, the output will have thousand separators
inserted between each group of three digits to the left of the
decimal point. The placement and number of ‘,’ characters in the
format string does not affect the output, except to indicate that
thousand separators are wanted. The actual character used as a
the thousand separator in the output is determined by the
ThousandSeparator global variable. The default value of
ThousandSeparator is specified in the Number Format of the
International section in the Windows Control Panel.
E+&#9;Scientific notation. If any of the strings ‘E+’, ‘E-‘,
‘e+’, or ‘e-‘ are contained in the format string, the number is
formatted using scientific notation. A group of up to four ‘0’
characters can immediately follow the ‘E+’, ‘E-‘, ‘e+’, or ‘e-‘
to determine the minimum number of digits in the exponent. The
‘E+’ and ‘e+’ formats cause a plus sign to be output for positive
exponents and a minus sign to be output for negative exponents.
The ‘E-‘ and ‘e-‘ formats output a sign character only for
negative exponents.
‘xx’/“xx”&#9;Characters enclosed in single or double quotes are
output as-is, and do not affect formatting.
;&#9;Separates sections for positive, negative, and zero numbers
in the format string.
The locations of the leftmost ‘0’ before the decimal point in the
format string and the rightmost ‘0’ after the decimal point in
the format string determine the range of digits that are always
present in the output string.
The number being formatted is always rounded to as many decimal
places as there are digit placeholders (‘0’ or ‘#’) to the right
of the decimal point. If the format string contains no decimal
point, the value being formatted is rounded to the nearest whole
number.
If the number being formatted has more digits to the left of the
decimal separator than there are digit placeholders to the left
of the ‘.’ character in the format string, the extra digits are
output before the first digit placeholder.
To allow different formats for positive, negative, and zero
values, the format string can contain between one and three
sections separated by semicolons.
One section: The format string applies to all values.
&#9;Two sections: The first section applies to positive values
and zeros, and the second section applies to negative values.
&#9;Three sections: The first section applies to positive values,
the second applies to negative values, and the third applies to
zeros.
If the section for negative values or the section for zero values
is empty, that is if there is nothing between the semicolons that
delimit the section, the section for positive values is used
instead.
If the section for positive values is empty, or if the entire
format string is empty, the value is formatted using general
floating-point formatting with 15 significant digits,
corresponding to a call to FloatToStrF with the ffGeneral format.
General floating-point formatting is also used if the value has
more than 18 digits to the left of the decimal point and the
format string does not specify scientific notation.
0&#9;&#9;&#9;1234&#9;&#9;-1234&#9;&#9;1&#9;&#9;0
0.00 &#9;&#9;&#9;1234.00&#9;&#9;-1234.00&#9;&#9;0.50&#9;&#9;0.00
#.## &#9;&#9;&#9;1234&#9;&#9;-1234&#9;&#9;.5&#9;
#,##0.00&#9;&#9;&#9;1,234.00&#9;&#9;-1,234.00&#9;0.50&#9;&#9;0.00
#,##0.00;(#,##0.00)&#9;1,234.00&#9;&#9;
(1,234.00)&#9;0.50&#9;&#9;0.00
#,##0.00;;Zero
&#9;&#9;1,234.00&#9;&#9;-1,234.00&#9;0.50&#9;&#9;Zero
0.000E+00 &#9;&#9;1.234E+03&#9;-1.234E+03&#9;5.000E-
01&#9;0.000E+00
#.###E-0 &#9;&#9;1.234E3&#9;&#9;-1.234E3&#9;5E-1&#9;&#9;0E0
function Frac(X: Real): Real;
Retorna a parte fracional do parâmetro X
var
R: Real;
begin
R := Frac(123.456); { 0.456 }
R := Frac(-123.456); { -0.456 }
end;

function GetCurrentDir: string;


Retorna uma string contendo o diretório corrente

procedure GetDir(D: Byte; var S: string);


Rerorna o diretório corrente do driver especificado.
O onde D pode ser :
Value&#9;Drive
0&#9;Corrente
1&#9;A
2&#9;B
3&#9;C
var
s : string;
begin
GetDir(0,s); { 0 = Current drive }
MessageDlg(‘Current drive and directory: ‘ + s, mtInformation,
[mbOk] , 0);
end;

procedure Inc(var X [ ; N: Longint ] );


Incrementa de uma ou N unidades o parâmetro X
var
IntVar: Integer;
LongintVar: Longint;
begin
Inc(IntVar);&#9;&#9;{ IntVar := IntVar + 1 }
Inc(LongintVar, 5);&#9;{ LongintVar := LongintVar + 5 }
end;

function IncMonth(const Date: TDateTime; NumberOfMonths:


Integer): TDateTime;
Retorna Date acrescido ou decrescido de NumberOfMonths meses.

function InputBox(const ACaption, APrompt, ADefault: string):


string;
Exibe uma Caixa de Entrada onde o usuário pode digitar uma
string.
ACaption representa o título do Input Box e APrompt é o título do
edit e ADefault representa o valor inicial do Edit.
uses Dialogs;
procedure TForm1.Button1Click(Sender: TObject);
var
InputString: string;
begin
InputString:= InputBox(‘Input Box’, ‘Prompt’, ‘Default string’);
end;

function InputQuery(const ACaption, APrompt: string; var Value:


string): Boolean;
Semelhante ao InputBox, sendo que retorna True se o usuário
fechou a O InputBox com OK e False se fechou com Cancel ou ESC. E
Value armazena a string digitada.
procedure TForm1.Button1Click(Sender: TObject);
var
NewString: string;
ClickedOK: Boolean;
begin
NewString := ‘Default String’;
Label1.Caption := NewString;
ClickedOK := InputQuery(‘Input Box’, ‘Prompt’, NewString);
if ClickedOK then { NewString contains new input string }
Label1.Caption := ‘The new string is ”’ + NewString + ””;
end;

procedure Insert(Source: string; var S: string; Index: Integer);


Insere uma string em outra a partir da posição Index
var
S: string;
begin
S := ‘Honest Lincoln’;
Insert(‘Abe ‘, S, 8); { ‘Honest Abe Lincoln’ }
end;

function IntToHex(Value: Integer; Digits: Integer): string;


Converte o inteiro Value num Hexadecimal (Base 16). Digits indica
o número mínimo de dígitos Hexa a serem retornados
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := IntToHex(StrToInt(Edit1.Text), 6);
end;

function IntToStr(Value: Integer): string;


Trasnforma um Inteiro numa String
procedure TForm1.Button1Click(Sender: TObject);
var
Value: Integer;
begin
Value := 1234;
Edit1.Text := IntToStr(Value);
end;
function IsValidIdent(const Ident: string): Boolean;
Indica se um identificador é válido para o Pascal

function Length(S: string): Integer;


retorna o número de caracters usados na string S
var
S: string;
begin
S := ‘The Black Knight’;
Canvas.TextOut(10, 10, ‘String Length = ‘ + IntToStr(Length(S)));
end;

function MaxIntValue(const Data: array of Integer): Integer;


Retorna o maior inteiro de um vetor

function MaxValue(const Data: array of Double): Double;


Retorna o maior valor de um vetor

function Mean(const Data: array of Double): Extended;


Retorna a média aritmética de um vetor

function MessageDlg(const Msg: string; AType: TMsgDlgType;


AButtons: TMsgDlgButtons; HelpCtx: Longint): Word;
Exibe uma Caixa de Mensagem e obtem uma resposta do usuário.
Onde
Msg : Mensagem
AType : Tipo da caixa de mensagem
Value&#9;Meaning
mtWarning&#9;A message box containing a yellow exclamation point
symbol.
mtError&#9;&#9;A message box containing a red stop sign.
mtInformation&#9;A message box containing a blue “i”.
mtConfirmation&#9;A message box containing a green question mark.
mtCustom&#9;A message box with no bitmap. The caption of the
message box is the name of the application’s executable file.
AButtons : Quais botões aparecerão na caixa de mensagem
Value&#9;&#9;&#9;&#9;Meaning
mbYes&#9;&#9;&#9;A button with the text ‘Yes’ on its face
mbNo&#9;&#9;&#9;A button with the text ‘No’ on its face
mbOK&#9;&#9;&#9;A button with the text ‘OK’ on its face
mbCancel&#9;&#9;A button with the text ‘Cancel’ on its face
mbHelp&#9;&#9;&#9;A button with the text ‘Help’ on its face
mbAbort&#9;&#9;A button with the text ‘Abort’ on its face
mbRetry&#9;&#9;&#9;A button with the text ‘Retry’ on its face
mbIgnore&#9;&#9;A button with the text ‘Ignore’ on its face
mbAll&#9;&#9;&#9;A button with the text ‘All’ on its face
mbYesNoCancel&#9;&#9;Puts Yes, No, and Cancel buttons in the
message box
mbOkCancel&#9;&#9;Puts t OK and Cancel buttons in the message box
mbAbortRetryIgnore&#9;Puts Abort, Retry, and Ignore buttons in
the message box
MessageDlg returns the value of the button the user selected.
These are the possible return values:
Return &#9;values
mrNone&#9;&#9;mrAbort&#9;&#9;mrYes
mrOk&#9;&#9;mrRetry&#9;&#9;mrNo
mrCancel&#9;mrIgnore&#9;mrAll
procedure TForm1.Button1Click(Sender: TObject);
begin
if MessageDlg(‘Welcome to my Object Pascal application. Exit
now?’,
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
MessageDlg(‘Exiting the Object Pascal application.’,
mtInformation,
[mbOk], 0);
Close;
end;
end;

function MessageDlgPos(const Msg: string; AType: TMsgDlgType;


AButtons: TMsgDlgButtons; HelpCtx: Longint; X, Y: Integer): Word;
Semelhante a MessageDlg exceto por permitir indicar a posição na
qual a janela será exibida
procedure TForm1.Button1Click(Sender: TObject);
begin
MessageDlgPos(‘Are you there?’,mtConfirmation, mbYesNoCancel, 0,
200, 200);
end;

function MinIntValue(const Data: array of Integer): Integer;


Retorna o menor inteiro do vetor

function MinValue(const Data: array of Double): Double;


Retorna o menor valor de um vetor

procedure MkDir(S: string);


Cria um novo diretório
uses Dialogs;
begin
{$I-}
{ Get directory name from TEdit control }
MkDir(Edit1.Text);
if IOResult <> 0 then
MessageDlg(‘Cannot create directory’, mtWarning, [mbOk], 0)
else
MessageDlg(‘New directory created’, mtInformation, [mbOk], 0);
end;

function Now: TDateTime;


Retorna a data e a hora corrente
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := ‘The date and time is ‘ + Str(Now);
end;

function Ord(X): Longint;


Retorna a ordem de um valor ordinal
uses Dialogs;
type
Colors = (RED,BLUE,GREEN);
var
S: string;
begin
S := ‘BLUE has an ordinal value of ‘ + IntToStr(Ord(BLUE)) +
#13#10;
S := ‘The ASCII code for “c” is ‘ + IntToStr(Ord(‘c’)) + ‘
decimal’;
MessageDlg(S, mtInformation, [mbOk], 0);
end;

function Pi: Extended;


Retorna o valor de PI
3.1415926535897932385.

function Pos(Substr: string; S: string): Integer;


Procura por uma sub-string numa string e retorna a posição da
primeira ocorrência ou zero se não encontrou
var S: string;
begin
S := ‘ 123.5’;
{ Convert spaces to zeroes }
while Pos(‘ ‘, S) > 0 do
S[Pos(‘ ‘, S)] := ‘0’;
end;

function Power(Base, Exponent: Extended): Extended;


Potência

function Pred(X);
Retorna o predecessor de um ordinal
uses Dialogs;
type
Colors = (RED,BLUE,GREEN);
var
S: string;
begin
S := ‘The predecessor of 5 is ‘ + IntToStr(Pred(5)) + #13#10;
S := S + ‘The successor of 10 is ‘ + IntToStr(Succ(10)) + #13#10;
if Succ(RED) = BLUE then
S := S + ‘In the type Colors, RED is the predecessor of BLUE.’;
MessageDlg(S, mtInformation, [mbOk], 0);
end;

function Random [ ( Range: Integer) ];


Retorna um valor Randômico
0 <= X < Range.
var
I: Integer;
begin
Randomize;
for I := 1 to 50 do begin
{ Write to window at random locations }
Canvas.TextOut(Random(Width), Random(Height), ‘Boo!’);
end;
end;

procedure Randomize;
Inicializa o modo Randomico
var
I: Integer;
begin
Randomize;
for I := 1 to 50 do begin
{ Write to window at random locations }
Canvas.TextOut(Random(Width), Random(Height), ‘Boo!’);
end;
end;

function RemoveDir(const Dir: string): Boolean;


Remove um diretório retornando True caso tenha conseguido e False
caso contrário

procedure Rename(var F; Newname);


F is a variable of any file type. Newname is a string-type
expression or an expression of type PChar
uses Dialogs;
var
f : file;
begin
OpenDialog1.Title := ‘Choose a file… ‘;
if OpenDialog1.Execute then begin
SaveDialog1.Title := ‘Rename to…’;
if SaveDialog1.Execute then begin
AssignFile(f, OpenDialog1.FileName);
Canvas.TextOut(5, 10, ‘Renaming ‘ + OpenDialog1.FileName + ‘ to ‘
+
SaveDialog1.FileName);
Rename(f, SaveDialog1.FileName);
end;
end;
end;
function RenameFile(const OldName, NewName: string): Boolean;
Renomeia arquivos e retorna o sucesso ou insucesso
The following code renames a file:
if not RenameFile(‘OLDNAME.TXT’,‘NEWNAME.TXT’) then
ErrorMsg(‘Error renaming file!’);

procedure RmDir(S: string);


Remove um diretório
uses Dialogs;
begin
{$I-}
{ Get directory name from TEdit control }
RmDir(Edit1.Text);
if IOResult <> 0 then
MessageDlg(‘Cannot remove directory’, mtWarning, [mbOk], 0)
else
MessageDlg(‘Directory removed’, mtInformation, [mbOk], 0);
end;

function Round(X: Extended): Longint;


Arredonda um número real

function SelectDirectory(var Directory: string; Options:


TSelectDirOpts; HelpCtx: Longint):Boolean;
Exibe um Caixa de Dialogo para seleção de Diretório. O Diretório
passado para a função aparece como diretório corrente e o
diretório escolhido é retonado no mesmo Diretório (Directory). O
valor do diretório corrente não é alterado
These are the possible values that can be added to the Options
set:
Value&#9;&#9;Meaning
sdAllowCreate&#9;An edit box appears to allow the user to type in
the name of a directory that does not exist. This option does not
create a directory, but the application can access the Directory
parameter to create the directory selected if desired.
sdPerformCreate&#9;Used only when Options contains sdAllowCreate.
If the user enters a directory name that does not exist,
SelectDirectory creates it.
sdPrompt&#9;Used when Options contains sdAllowCreate. Displays a
message box that informs the user when the entered directory does
not exist and asks if the directory should be created. If the
user chooses OK, the directory is created if Options contains
sdPerformCreate. If Options does not contain sdPerformCreate, the
directory is not created: the application should create it when
SelectDirectory returns.
The function returns True if the user selected a directory and
chose OK, and False if the user chose Cancel or closed the dialog
box without selecting a directory.
This example uses a button on a form. When the user clicks the
button, a Select Directory dialog box appears. The current
directory displayed in the dialog box is C:\MYDIR. The user can
select a directory from the directory list, or enter a new
directory in the edit box. If the user enters a new directory, a
message box asks the user if the directory should be created. If
the user chooses Yes, the directory is created. If the user
chooses No, the message box goes away without creatubg the
directory. The name of the directory the user selects appears as
the caption of the label:
uses FileCtrl;
procedure TForm1.Button1Click(Sender: TObject);
var
Dir: string;
begin
Dir := ‘C:\MYDIR’;
if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate,
sdPrompt]) then
Label1.Caption := Dir;
end;

function SetCurrentDir(const Dir: string): Boolean;


Torna o Dir o diretório corrente e retorna o sucesso da operação

procedure SetLength(var S: string; NewLength: Integer);


Coloca um novo tamanho para uma string
S[0] := NewLength.

procedure ShowMessage(const Msg: string);


Exibe uma mensagem ao usuário
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(‘Push this button’);
end;

function Sqr(X: Extended): Extended;


Retorna o quadrado de X

function Sqrt(X: Extended): Extended;


Retorna a raiz quadrada de X

function StrComp(Str1, Str2 : PChar): Integer;


Compara duas strings em case sensitivity
Return value&#9;Condition
<0&#9;if Str1< Str2
=0&#9;if Str1= Str2
>0&#9;if Str1 > Str2

function StringOfChar(Ch: Char; Count: Integer): string;


Retorna uma string contendo Count caracters Ch
S := StringOfChar(‘A’, 10);
{sets S to the string ‘AAAAAAAAAA’}

function StrToDate(const S: string): TDateTime;


Converte uma string em data
procedure TForm1.Button1Click(Sender: TObject);
var
ADate: TDateTime;
begin
ADate := StrToDate(Edit1.Text);
Label1.Caption := DateToStr(ADate);
end;

function StrToDateTime(const S: string): TDateTime;


Converte uma string para o formato DateTime
procedure TForm1.Button1Click(Sender: TObject);
var
ADateAndTime: TDateTime;
begin
ADateAndTime := StrToDateTime(Edit1.Text);
Label1.Caption := DateTimeToStr(ADateAndTime);
end;

function StrToFloat(const S: string): Extended;


Converte uma string num Float

function StrToInt(const S: string): Integer;


Converte uma string num inteiro
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
I: Integer;
begin
S := ‘22467’;
I := StrToInt(S);
Inc(I);
Edit1.Text := IntToStr(I);
end;

function StrToTime(const S: string): TDateTime;


Converte uma string em hora
procedure TForm1.Button1Click(Sender: TObject);
var
ATime: TDateTime;
begin
ATime := StrToTime(Edit1.Text);
Label1.Caption := TimeToStr(ATime);
end;

function Succ(X);
Retorna o sucessor de um ordinal
uses Dialogs;
type
Colors = (RED,BLUE,GREEN);
var
S: string;
begin
S := ‘The predecessor of 5 is ‘ + IntToStr(Pred(5)) + #13#10;
S := S + ‘The successor of 10 is ‘ + IntToStr(Succ(10)) + #13#10;
if Succ(RED) = BLUE then
S := S + ‘In the type Colors, RED is the predecessor of BLUE.’;
MessageDlg(S, mtInformation, [mbOk], 0);
end;

function Sum(const Data: array of Double): Extended register;


Calcula a soma de dos elementos de um vetor

function SumInt(const Data: array of Integer): Integer register;


Calcula a soma dos elementos de um vetor de inteiros

function Time: TDateTime;


Retorna a hora corrente
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := ‘The time is ‘ + TimeToStr(Time);
end;

function TimeToStr(Time: TDateTime): string;


Converte hora para string
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := TimeToStr(Time);
end;

function Trim(const S: string): string;


Retira os espaços em brancos a esquerda e a direita da string S

function TrimLeft(const S: string): string;


Retira os espaços em brancos a esquerda da string S

function TrimRight(const S: string): string;


Retira os espaços em brancos a direita da string S

function Trunc(X: Extended): Longint;


Retorna a parte inteira de um número
function UpCase(Ch: Char): Char;
Converte o caracter Ch em maiúscula
uses Dialogs;
var
s : string;
i : Integer;
begin
{ Get string from TEdit control }
s := Edit1.Text;
for i := 1 to Length(s) do
s[i] := UpCase(s[i]);
MessageDlg(‘Here it is in all uppercase: ‘ + s, mtInformation,
[mbOk], 0);
end;

function UpperCase(const S: string): string;


Converte a string S em maiúsculas
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
begin
for I := 0 to ListBox1.Items.Count -1 do
ListBox1.Items[I] := UpperCase(ListBox1.Items[I]);
end;
143 - Definindo Atributo de um
arquivo
function FileSetAttr(const FileName:
string; Attr: Integer): Integer;
Exemplo:
FileSetAttr (‘C:\logo.sys’,0);
Onde Attr:Interger:
0=Sem Atributos;
1=Somente Leitura;
2=Oculto;
3=Somente Leitura e Oculto;
4=Sistema;
5=Somente Leitura e Sistema;
6=Sistema e Oculto;
7=Somente Leitura,Sistema e Oculto;
144 - Executável com parâmetros
procedure TForm1.FormCreate(Sender:
TObject);
var i:integer;
for I := 1 to ParamCount do begin
if ParamStr(I) = ‘/sai’ then
Application.Terminate;
end;
Outro exemplo
procedure TForm1.FormCreate(Sender:
TObject);
var i:integer;
begin
for i:=1 to paramcount do
showmessage(ParamStr(i));
end;
end.
145 - Funções Aritméticas
suportadas pelo Pascal
Função Argumento Resultado Operação
Abs(x) Real ou Real ou Valor Absoluto
Inteiro Inteiro
Arctan(x) Real ou Real Arco Tangente
Inteiro
Cos(x) Real ou Real Cosseno
Inteiro
Exp(x) Real ou Real Exponenciação
Inteiro
Frac(x) Real ou Real Parte decimal de x
Inteiro
Int(x) Real ou Real Parte Inteira de x
Inteiro
Ln(x) Real ou Real Logaritmo natural
Inteiro
Pred(x) Inteiro Inteiro x-1
Random Real Real Nº Aleatório entre 0
e1
Random(x) Inteiro Inteiro Nº Aleatório entre 0
e x-1
Round(x) Real Inteiro x arredondado
Sin(x) Real ou Real Seno
Inteiro
Sqr(x) Real ou Real Quadrado de x
Inteiro
Sqrt(x) Real ou Real Raiz quadrada
Inteiro
Succ(x) Inteiro Inteiro x+ 1
Trunc(x) Real Inteiro x sem a parte
decimal
146 - Formatando Strings
A função Format requer como parâmetros uma string
com o texto básico e alguns marcadores de lugar
(usualmente indicadas pelo sínbolo %) e um array de
valores, um de cada marcador de lugar. Por exemplo,
para formatar dois números em uma string você pode
escrever.
Format (‘Primeiro %d, Segundo %d ‘, [n1,
n2]);
Onde n1 e n2 são dois valores Integer.

Especificador Descrição
d (decimal) O valor inteiro correspondente é convertido
para uma string de dígitos decimais
x O valor inteiro correspondente é convertido
(hexadecimal) para uma string de dígitos hexadecimais
p (ponteiro) O valor inteiro correspondente é convertido
para uma string expressa com dígitos
decimais
s (string) A string correnpondente, caractere, ou valor
Pchar é copiado para uma string
e O valor de ponto flutuante correspondente é
(hexadecimal) convertido para uma string.
f (ponto O valor de ponto flutuante correspondente é
flutuate) convertido para uma string.
g (geral) O valor de ponto flutuante correspondente é
convertido para uma string decimal menor
possível usando notação de ponto flutuante
ou exponencial.
x (número) O valor de ponto flutuante correspondente é
convertido para uma string de ponto
flutuante mas usa também separador de
milhares.
m (moeda) O valor de ponto flutuante correspondente é
convertido para uma string representando
uma quantidade em dinheiro. A conversão é
baseada nas configurações regionais.
147 - Como controlar o fechamento
de um formulário
procedure TForm1.FormCloseQuery(Sender:
Tobject;
var CanClose: Bolean);
begin
if MessageDlg ( ‘Você tem certeza de que
quer sair?’,
mtConfirmation, [mbYes, mbNo], 0) = idNo
then
Canclose:=False;
end;
148 - Método de procura em tabela
indexada
procedure TSaida.Edit1Change(Sender:
TObject);
begin
Table1.setkey;
Table1Notasaida.AsString:=Edit1.text;
Table1.GotoNearest;
end;
149 - Como evitar repetição em
uma lista de ComboBox

procedure TProcRep.ComboBox1Click(Sender:
TObject);
begin
WITH COMBOBOX1 DO
IF (TEXT <> ”) AND (ITEMS.INDEXOF (TEXT) <
0) THEN
ITEMS.ADD (TEXT);
end;
150 - Caracteres Especiais que
compõem uma MaskEdit
Caracter Descrição
! Espaços em branco não aparecerão
Todos os caracteres seguintes serão
>
maiúsculos até que apareça o caracter
Todos os caracteres seguintes serão
<
minúsculos até que apareça o caracter
\ Indica um caracter literal
l (L Somente caracter alfabético
minusculo)
Obrigatoriamente um caracter alfabético (A-
L
Z, a-z)
a Somente caracter alfanumérico
Obrigatoriamente caractere alfanumérico (
A
A-Z, a-z, 0-9)
9 Somente caracter numérico
0 Obrigatoriamente caracter numérico
c permite um caracter
C Obrigatoriamente um caracter
Permite um caracter numérico ou sinal de
#
mais ou de menos, mas não os requer.
: Separador de horas, minutos e segundos
/ Separador de dias, meses e anos
151 - Exemplo de Arraste
{Este exmplo faz que o painel fique com a
cor da label que originou o arraste.
Somente a Label(Tlabel)}
{no exemplo as labels devem ter a
propriedade DRAGMODE=AUTOMATIC}
procedure TForm1.Panel1DragOver (Sender.
Source: TObject; x,y:Integer;
State:TDragState; var Accept: Boolean);
begin
Accept:=Source is Tlabel;
end;

procedure TForm1.Panel1DragDrop (Sender.


Source: TObject; x,y:Integer);
begin
Panel1.color:=(Source as Tlabel).Color;
end;
152 - Convertendo a primeira letra
de um EditBox para maiúsculas
Para converter a primeira letra de um EditBox para
maiúsculas este código pode ser utilizado:
procedure TForm1.Edit1Change(Sender:
TObject);
var
OldStart : Integer;
begin
With Edit1 do
if Text <> ” then begin
OnChange := NIL;
OldStart := SelStart;
Text :=
UpperCase(Copy(Text,1,1))+LowerCase(Copy(T
ext,2,Length(Text)));
SelStart := OldStart;
OnChange := Edit1Change;
end;
end;
153 - Criando janelas não
retangulares
Para criar uma janela não retangular, voce deve criar
uma Região do Windows e usar a função da API
SetWindowRgn, desta maneira:
var
hR : THandle;
begin
{cria uma Região elíptica}
hR := CreateEllipticRgn(0,0,100,200);
SetWindowRgn(Handle,hR,True);
end;
154 - Detectando a finalização do
Windows
Para detectar a finalização do Windows, deve-se
capturar a mensagem WM_ENDSESSION. Estes
passos devem ser tomados:
Declarar uma rotina de manipulação de mensagens na
sessao private de sua form:
procedure WMEndSession(var Msg :
TWMEndSession); message WM_ENDSESSION;
Adicionar a procedure à seção implementation de sua
unit:
procedure TForm1.WMEndSession(var Msg :
TWMEndSession);
begin
if Msg.EndSession = TRUE then
ShowMessage(‘O Windows está finalizando
‘ + #13 + ‘às ‘ +
FormatDateTime(‘c’, Now));
inherited;
end;
155 - Alinhando itens do menu
principal à direita
Para alinhar itens do menu principal à direita, deve-se
utilizar o seguinte código:
{Isto justifica todos itens à direita do
selecionado}
procedure SetJustify(Menu: TMenu;
MenuItem: TMenuItem; Justify: Byte);
{$IFDEF WIN32}
var
ItemInfo: TMenuItemInfo;
Buffer: array[0..80] of Char;
{$ENDIF}
begin
{$IFDEF VER80}
MenuItem.Caption := Chr(8) +
MenuItem.Caption;
{$ELSE}
ItemInfo.cbSize :=
SizeOf(TMenuItemInfo);
ItemInfo.fMask := MIIM_TYPE;
ItemInfo.dwTypeData := Buffer;
ItemInfo.cch := SizeOf(Buffer);
GetMenuItemInfo(Menu.Handle,
MenuItem.Command, False, ItemInfo);
if Justify = 1 then
ItemInfo.fType := ItemInfo.fType or
MFT_RIGHTJUSTIFY;
SetMenuItemInfo(Menu.Handle,
MenuItem.Command, False, ItemInfo);
{$ENDIF}
end;
156 - Usando funções externas (de
DLLs)…
Usar funções externas, de uma ou mais DLLs é muito
simples, basta declara-las da seguinte forma:
function NomeDaFuncao(Parâmetros: Tipo):
TipoRetorno; stdcall; external
‘NomeDaDLL’;
Você pode ver o nome de uma função da DLL na
Visualização Rápida do Windows (se esta estiver sido
instalada), para isso encontre o arquivo DLL, clique nele
com o botão direito do mouse e escolha visualização
rápida.
157 - Manipulando “Application”…
A classe TApplication proporciona muitas manipulações
úteis do aplicativo como um todo. Por exemplo, caso
você queira que quando um aplicativo for minimizado
apareça a hora atual no título da barra de tarefas, e
quando ele for restaurado não apareça, use o seguinte
código no evento OnLoad do formulário, por exemplo:
Application.OnMinimize := ShowDate;
Application.OnRestore := NShowDate;

procedure ShowDate;
begin
TForm1.Timer1Timer(Sender);
Timer1.Enabled := True;
end;

procedure NShowDate;
begin
Timer1.Enabled := False;
Application.Title := ‘Título do
Aplicativo’;
end;
Este exemplo considera que o aplicativo possua um
relógio que atualiza de tempos em tempos (a cada 250
milésimos de segundo por exemplo). Este é desabilitado
quando o formulário é restaurado.
158 - Executando ações padrão de
um Ole Container
Para executar ações padrão de um Ole Container (abrir
um documento Word ou Excel ou rodar uma
apresentação Powerpoint), pode-se usar este código:
procedure TForm1.Button1Click(Sender:
TObject);
begin
OleContainer1.DoVerb(ovprimary);
end;
159 - Verificando se há uma cópia
em execução
program Project1;
uses
Forms,
windows,
dialogs,
Unit1 in ‘Unit1.pas’ {Lloydsoft};

{$R *.RES}

var
Hwnd: Thandle;
begin
Hwnd := FindWindow (‘TLloydSoft’, ‘LloydSoft’);
if Hwnd = 0 then
begin
Application.Initialize;
Application.CreateForm(TLloydsoft, Lloydsoft);
Application.Run;
end
else
begin
MessageDlg (‘Este programa já esta aberto’,mtinformation,[mbok], 0);
SetForegroundWindow (Hwnd);
end;
end.

{obs: para o exemplo acima funcionar a propriedade Caption do Formulário deve ser ‘LloydSoft’}
160 - Alterando o glyph dos botões
do DbNavigator
Declare um novo tipo na sua unit:
type
NewTypeNav = class( TDbNavigator );
Depois é só utilizar:
NewTypeNav( DbNavigator1
).Buttons[nbInsert].Glyph := …
161 - PARADOX EM REDE
Arquivos Paradox podem ser compartilhados em rede.
Para que isto ocorra devemos :
·Adicionar o DATABASE ENGINE CONFIGURATION
(BDE CONFIG)
·Selecionar a página DRIVERS
·Selecionar o driver PARADOX e alterar o parâmetro
NET DIR para o local onde serão gravados os arquivos
de controle para compartilhamento. Por exemplo,
“G:\MEUAPLIC”, onde G : corresponde ao drive de rede
e MEUAPLIC, o diretório aonde está o aplicativo
(executável)
·Depois selecionar a página SYSTEM
·Alterar o parâmetro LOCAL SHARE para TRUE. Após
isto o BDE controlará o compartilhamento de arquivos
PARADOX em rede
162 - Hint Com Quebra De Linha
Para incluir mais de uma linha no Hint você deve utilizar
o evento OnMouseMove de cada componente. Veja
abaixo como ficará o código em um Edit por exemplo.
procedure TForm1.Edit1MouseMove(Sender:
TObject; Shift: TShiftState; X, Y:
Integer);
begin
Edit1.hint := ‘Primeira
Linha’+#13+‘Segunda Linha’+#13+ ‘Terceira
Linha’+#13+‘Quarta Linha’;
end;
Obs. Não esquecer de mudar para TRUE o evento
ShowHint
163 - AutoOcultar a barra de
tarefas
Ocultar…….
ShowWindow(FindWindow(‘Shell_TrayWnd’,
nil), SW_HIDE);
Mostrar…..
ShowWindow(FindWindow(‘Shell_TrayWnd’,
nil), SW_SHOWNORMAL);
Voltar como Estava…..
ShowWindow(FindWindow(‘Shell_TrayWnd’,
nil), SW_RESTORE);
164 - Como mover um componente
em Run-time
No exemplo abaixo deve ser incluído um componente
Button. Para testar este exemplo mantenha a tecla
CTRL pressionada clique com o mouse no componente
Button. Feito isto, basta arrastar o componente Button
para qualquer lado.
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1MouseDown(Sender:
TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1MouseMove(Sender:
TObject; Shift: TShiftState; X,
Y: Integer);
procedure Button1MouseUp(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
MouseDownSpot : TPoint;
Capturing : bool;
end;
var
Form1: TForm1;

implementation
{$R *.DFM}

// Evento OnMouseDown do Form


procedure TForm1.Button1MouseDown(Sender:
TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ssCtrl in Shift then begin
SetCapture(Button1.Handle);
Capturing := true;
MouseDownSpot.X := x;
MouseDownSpot.Y := Y;
end;
end;

// Evento OnMouseMove do Form


procedure TForm1.Button1MouseMove(Sender:
TObject; Shift: TShiftState; X, Y:
Integer);
begin
if Capturing then begin
Button1.Left:= Button1.Left-
(MouseDownSpot.x-x);
Button1.Top:= Button1.Top -
(MouseDownSpot.-y);
end;
end;

// Evento OnMouseUp do Form


procedure TForm1.Button1MouseUp(Sender:
TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Capturing then begin
ReleaseCapture;
Capturing := false;
Button1.Left := Button1.Left -
(MouseDownSpot.x -x);
Button1.Top := Button1.Top -
(MouseDownSpot.y - y);
end;
end;
165 - Executar um AVI no Form
procedure TForm1.BitBtn1Click(Sender:
TObject);
begin
with MediaPlayer1 do
begin
FileName := ‘c:\windows\help\scroll.avi’;
Open;
Display := Form2;
Form2.Show;
Play;
end;
end;
166 - Colocar zeros a esquerda de
um valor digitado no componente
Edit

procedure TForm1.Edit1Exit(Sender:
TObject);
begin
Edit1.Text :=
FormatFloat(‘000000’,StrToFloat(Edit1.Text
));
end;
167 - Mostrar o HINT num Panel
procedure TForm1.FormCreate(Sender:
TObject);
begin
Application.OnHint := DisplayHint;
end;
procedure TForm1.DisplayHint(Sender:
TObject);
begin
Panel1.Caption := Application.Hint;
end;

Obs. Não é necessário Atribuir True para o ShowHint


168 - Configuração do BDE para
ambiente de rede
Para o seu aplicativo feito em Delphi rodar em rede,
você deve instalar o BDE em todas as estações. No
BDE de cada estação, você deve colocar no parâmetro
NET DIR do drive PARADOX o local onde estão as
bases de dados e na PATH do Alias especificar o
caminho das base de dados. Mas muita atenção, todas
as estações devem estar com a mesma configuração do
BDE. Veja o exemplo abaixo para configuração do
parâmetro NET DIR do drive PARADOX e o PATH do
Alias.
Estação n.1
NET DIR F:\
Path do Alias F:\DIRETORIO
Estação n.2
NET DIR F:\
Path do Alias F:\DIRETORIO
Estação n.3
NET DIR F:\
Path do Alias F:\DIRETORIO
Não é aconselhável que os aplicativos feitos em Delphi
1, sejam executados no servidor da base de dados, pois
o PARADOX apresenta problemas de corrupção de
arquivos e índices neste caso. É aconselhável que no
servidor você coloque somente as bases de dados. Mas
caso você tenha necessidade de utilizar o servidor você
pode utilizar uma solução alternativa para o problema do
PARADOX, esta solução esta sendo satisfatória na
maioria dos casos. Digamos que a letra do drive de rede
que você vai acessar o servidor, seja a letra “F:”, então,
faça o seguinte: Coloque a linha abaixo no arquivo
AUTOEXEC.BAT, do servidor.
SUBST F: C:
Configure o BDE do servidor para que ele acesse o
drive “F:”
Esta linha deverá ser colocada apenas no servidor, com
isso você passa a ter em seu servidor, um drive virtual
para acessar o
drive C:, evitando o problema do PARADOX.
No Delphi 2 e Delphi 3, você deve utilizar um instalador
de programas. No CD do Delphi 2 e Delphi 3 existe um
instalador
chamado InstallShield para fazer a instalação e
configuração do aplicativo e do BDE.
Veja abaixo os exemplos da configuração do BDE p/
Delphi 2 e 3:
Servidor Estação 1
NET DIR \SERVIDOR\C NET DIR \SERVIDOR\C
PATH DO ALIAS \SERVIDOR\C\DIRETORIO PATH DO
ALIAS \SERVIDOR\C\DIRETORIO
LOCAL SHARE TRUE LOCAL SHARE FALSE
Estação 2 Estação 3
NET DIR \SERVIDOR\C NET DIR \SERVIDOR\C
PATH DO ALIAS \SERVIDOR\C\DIRETORIO PATH DO
ALIAS \SERVIDOR\C\DIRETORIO
LOCAL SHARE FALSE LOCAL SHARE FALSE
DICA:
O executável pode ser colocado em cada máquina da
rede, diminuindo assim o tráfego de rede.
169 - Verificando o seu endereço
IP
A fonte do projeto principal ficará algo como:
implementation

uses Winsock;

{$R *.DFM}

procedure TForm1.FormCreate(Sender:
TObject);
var
wVersionRequested : WORD;
wsaData : TWSAData;
begin
wVersionRequested := MAKEWORD(1, 1);
WSAStartup(wVersionRequested, wsaData);
end;

procedure TForm1.FormDestroy(Sender:
TObject);
begin
WSACleanup;
end;

procedure TForm1.BtnIPClick(Sender:
TObject);
var
p : PHostEnt;
s : array[0..128] of char;
p2 : pchar;
begin
GetHostName(@s, 128);
p := GetHostByName(@s);
Memo1.Lines.Add(p^.h_Name);
p2 :=
iNet_ntoa(PInAddr(p^.h_addr_list^)^);
Memo1.Lines.Add(p2);
end;

end.
170 - Verificando se já estou
conectado na Internet
Use o componente TCP para fazer isso.

procedure TForm1.Button1Click(Sender:
TObject);
begin
if TCP1.LocalIp = ‘0.0.0.0’ then
ShowMessage(‘Você não está conectado!’);
end;
171 - Desabilitar o botão fechar o
form
procedure TForm1.Button1Click(Sender:
TObject);
var
hwndHandle : THANDLE;
hMenuHandle : HMENU;
begin
hwndHandle := FindWindow(nil, ‘Sem título
- Bloco de Notas’);
if (hwndHandle <> 0) then
begin
hMenuHandle := GetSystemMenu(hwndHandle,
FALSE);
if (hMenuHandle <> 0) then
DeleteMenu(hMenuHandle, SC_CLOSE,
MF_BYCOMMAND);
end;
end;
172 - Chamar um site utilizando o
seu browse padrão
uses UrlMon;

procedure TForm1.Button1Click(Sender:
TObject);
begin
HlinkNavigateString(nil,‘http://www.lloyds
oft.hpg.ig.com.br’);
End;
173 - Localizar arquivos do
Windows

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;
174 - Criar um documento no Word
Uses ComObj

procedure TForm1.Button1Click(Sender:
TObject);
var
MSWord: Variant;
begin
MSWord:= CreateOleObject (‘Word.Basic’);
MSWord.AppShow;//mostra o word
MSWord.FileNew;//inicia um novo
documento
MSWord.insert(‘Contrato de Locação’);
//Escreve algo
MSWord.insert(#13+‘Contrato de
Locação’);//Pula uma linha e escreve
MSWord.FontSize(24);//muda o tamanho da
fonte
MSWord.italic;//coloca italico
MSWord.bold;//coloca negrito
MSWord.underline;//sublina
MSWord.insert(#13+‘Contrato de
Locação’);//pula a linha e escreve
novamente
MSWord.FontSize(12);//muda o tamanho da
fonte
MSWord.Font(‘Arial’);//muda a fonte
usada
MSWord.underline(false);//retira o
sublinhado
MSWord.italic(false);//retira o italico
MSWord.bold(false);//retira o bold
MSWord.insert(#13 +‘teste’);
MSWord.insert(#13+#9 +‘teste’);//nova
linha e um TAB
MSWord.insert(#13+Table1Razao_Social.Value
);//insere algo de uma tabela
MSWord.LineUp(2, 1); //seleciona uma
parte do texto
MSWord.TextToTable(ConvertFrom := 2,
NumColumns := 1);// monta uma tabela com o
texto selecionado
MSWord.FileSaveAs(‘c:\temp\test.txt’,
3); //Salva o arquivo
end;

Obs feita pelo Ruberval

MSWord.JustifyPara; // alinhamento
justificado
MSWord.RightPara; // alinhamento a direita
MSWord.LeftPara; // alinhamento a esquerda
MSWord.InsertPageBreak; // quebrar página
175 - Ativar a proteção de tela do
Windows.
Inclua na seção uses: Windows
{ Ativa a proteção de tela do Windows, se
estiver configurada. }
SendMessage(Application.Handle,
WM_SYSCOMMAND, SC_SCREENSAVE, 0);
176 - Desligar/Ligar monitor
Inclua na seção uses: Windows
No Win95 podemos desligar o monitor afim de
economizar energia elétrica. Normalmente este recurso
é controlado pelo próprio Windows. Porém sua
aplicação Delphi também pode fazer isto. O exemplo
abaixo desliga o monitor, aguarde 5 segundos e re-liga
monitor.
SendMessage(Application.Handle,
WM_SYSCOMMAND,
SC_MONITORPOWER, 0);
Sleep(5000); { Aguarde 5 segundos }
SendMessage(Application.Handle,
WM_SYSCOMMAND,
SC_MONITORPOWER, -1);
Observações
Este recurso pode não funcionar dependendo da
configuração do sistema.
177 - Abrir e fechar o drive de
CD-ROM
Inclua na seção uses: MMSystem
{ Para abrir }
mciSendString(‘Set cdaudio door open
wait’, nil, 0, handle);

{ Para fechar }
mciSendString(‘Set cdaudio door closed
wait’, nil, 0, handle);
178 - Copiar todos os registros de
uma tabela para o Clipboard
Inclua na seção uses: Clipbrd
procedure TForm1.Button1Click(Sender:
TObject);
const
SeparadorCampoValor = ‘: ‘;
SeparadorCampo = #13#10; { Quebra de
linha }
SeparadorRegistro = ‘===========’ +
#13#10;
var
S: string;
I: integer;
begin
S := ”;
Table1.First;
while not Table1.EOF do begin
for I := 0 to Table1.FieldCount -1 do
S := S + Table1.Fields[I].FieldName +
SeparadorCampoValor +
Table1.Fields[I].AsString +
SeparadorCampo;
S := S + SeparadorRegistro;
Table1.Next;
end;
Clipboard.AsText := S;
end;

Para testar:
- Execute este aplicativo;
- Clique no botão;
- Vá em outro aplicativo (ex: MS-Word) e mande colar
(Ctrl+V).
Observações
CUIDADO! Não use este recurso com tabelas grandes,
pois poderá usar memória demasiadamente. No teste
que fiz, o tamanho da string S atingiu 20K e funcionou
normalmente. Mas isto pode variar de uma máquina
para outra.
179 - Personalizar a caixa de
mensagem de exceções (erro) do
Delphi
- Declare um método (procedure) na seção private do
form principal conforme abaixo:
private
procedure ManipulaExcecoes(Sender:
TObject; E: Exception);
- Vá até a seção implementation e implemente este
método, conforme o exemplo:
procedure TForm1.ManipulaExcecoes(Sender:
TObject; E: Exception);
begin
MessageDlg(E.Message + #13#13 +
‘Suporte técnico:’#13 +
‘tecnobyte@ulbrajp.com.br’,
mtError, [mbOK], 0);
end;

- No evento OnCreate do Form principal escreva o


código abaixo:
procedure TForm1.FormCreate(Sender:
TObject);
begin
Application.OnException :=
ManipulaExcecoes;
end;
=== Para testar ===
- Coloque um Button no form;
- No evento OnClick deste botão coloque o código
abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
StrToInt(‘ABCD’); { Isto provoca uma
exception }
end;
Observações
Cuidado! Não coloque código que possa gerar exceção
na rotina que manipula as exceções, pois se ocorrer
uma exceção neste rotina, esta será chamada
recursivamente até estourar a pilha.
180 - Colocar uma ProgressBar
numa StatusBar
- Coloque uma StatusBar no form.
- Adicione dois paineis na StatusBar (propriedade
Panels).
- Ajuste as propriedades do primeiro painel conforme
abaixo:
Style = psOwnerDraw
Width = 150
- Coloque uma ProgressBar no form e mude sua
propriedade
Visible para false.
- No evento OnDrawPanel da StatusBar digite o código
abaixo:
procedure
TForm1.StatusBar1DrawPanel(StatusBar:
TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
begin
{ Se for o primeiro painel… }
if Panel.Index = 0 then begin
{ Ajusta a tamanho da ProgressBar de
acordo com
o tamanho do painel }
ProgressBar1.Width := Rect.Right -
Rect.Left +1;
ProgressBar1.Height := Rect.Bottom -
Rect.Top +1;
{ Pinta a ProgressBar no DC (device-
context) da StatusBar }

ProgressBar1.PaintTo(StatusBar.Canvas.Hand
le, Rect.Left, Rect.Top);
end;
end;
- Coloque um Button no form
- Digite no evento OnClick do Button o código abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
I: integer;
begin
for I := ProgressBar1.Min to
ProgressBar1.Max do begin
{ Atualiza a posição da ProgressBar }
ProgressBar1.Position := I;
{ Repinta a StatusBar para forçar a
atualização visual }
StatusBar1.Repaint;
{ Aguarda 50 milisegundos }
Sleep(50);
end;

{ Aguarde 500 milisegundos }


Sleep(500);
{ Reseta (zera) a ProgressBar }
ProgressBar1.Position :=
ProgressBar1.Min;
{ Repinta a StatusBar para forçar a
atualização visual }
StatusBar1.Repaint;
end;
- Execute e clique no botão para ver o resultado.
181 - Verificar se uma string
contém uma hora válida
- Use a função abaixo:
function StrIsTime(const S: string):
boolean;
begin
try
StrToTime(S);
Result := true;
except
Result := false;
end;
end;
182 - Verificar se uma string
contém um valor numérico válido
- Use uma das funções abaixo, conforme o tipo de dado
que se quer testar:
function StrIsInteger(const S: string):
boolean;
begin
try
StrToInt(S);
Result := true;
except
Result := false;
end;
end;

function StrIsFloat(const S: string):


boolean;
begin
try
StrToFloat(S);
Result := true;
except
Result := false;
end;
end;
183 - Mudar a resolução do vídeo
via programação
- Coloque um ListBox no form
- Modifique o OnCreate do form assim:
procedure TForm1.FormCreate(Sender:
TObject);
var
i : Integer;
DevMode : TDevMode;
begin
i := 0;
while EnumDisplaySettings(nil,i,Devmode)
do begin
with Devmode do
ListBox1.Items.Add(Format(‘%dx%d %d
Colors’,
[dmPelsWidth,dmPelsHeight, 1 shl
dmBitsperPel]));
Inc(i);
end;
end;
- Coloque um botão no form
- Altere o evento OnClick do botão conforme abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
DevMode : TDevMode;
begin

EnumDisplaySettings(nil,Listbox1.ItemIndex
,Devmode);
ChangeDisplaySettings(DevMode,0);
end;
Observações
Nos testes que fiz, nem tudo funcionou adequadamente.
Mas vale a pena experimentar
184 - Simular um CharCase no
DBGrid
Para converter a digitação para maiúsculo, coloque isto
no evento OnKeyPress do DBGrid:
Key := AnsiUpperCase(Key)[1];
Para converter para minúsculo, troque por:
Key := AnsiLowerCase(Key)[1];
185 - Verificar se uma string é
uma data válida
Escreva a função abaixo:
function tbStrIsDate(const S: string):
boolean;
begin
try
StrToDate(S);
Result := true;
except
Result := false;
end;
end;
Para testar:
- Coloque um Edit no form;
- Coloque um Button;
- No evento OnClick do botão coloque o código abaixo:
if tbStrIsDate(Edit1.Text) then
ShowMessage(Edit1.Text + ‘ é data
válida.’)
else
ShowMessage(Edit1.Text + ‘ NÃO é data
válida.’);
186 - Limpar um campo tipo data
via programação
Table1.FieldByName(‘Data’).Clear;
{ ou }
Table1.FieldByName(‘Data’).AsString := ”;
Observações
Podemos usar este recurso para limpar também campos
numéricos, string, etc.
187 - Obter o endereço IP do
Dial-Up
Inclua na seção uses: WinSock
{ Esta função retorna o endereço IP do Dial-Up. }

function GetLocalIP : string;


type
TaPInAddr = array [0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe : PHostEnt;
pptr : PaPInAddr;
Buffer : array [0..63] of char;
I : Integer;
GInitData : TWSADATA;
begin
WSAStartup($101, GInitData);
Result := ”;
GetHostName(Buffer, SizeOf(Buffer));
phe :=GetHostByName(buffer);
if phe = nil then Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^[I] <> nil do begin
result:=StrPas(inet_ntoa(pptr^[I]^));
result := StrPas(inet_ntoa(pptr^[I]^));
Inc(I);
end;
WSACleanup;
end;
Observações
Se o endereço IP for designado pelo servidor, a cada
conecção teremos um endereço IP diferente e,
obviamente, se não estivermos conectados, não
conseguiremos obtê-lo.
188 - Exibir a caixa de diálogo
padrão de solicitação de senha do
banco de dados
Inclua na seção uses: DbPwDlg
{ Coloque um botão no form e escreve seu
evento OnClick como abaixo }
procedure TForm1.Button1Click(Sender:
TObject);
var
pw: TPasswordDialog;
begin
pw := TPasswordDialog.Create(Self);
try
pw.Caption := ‘Banco de Dados’;
pw.GroupBox1.Caption := ‘Senha’;
pw.AddButton.Caption := ‘&Adicionar’;
pw.RemoveButton.Caption := ‘&Remover’;
pw.RemoveAllButton.Caption := ‘Remover
&Tudo’;
pw.OKButton.Caption := ‘&OK’;
pw.CancelButton.Caption := ‘&Cancelar’;
pw.ShowModal;
finally
pw.Free;
end;
end;
Observações
As senhas adicionadas nesta caixa de diálogo são
adicionadas na sessão (TSession) atual. Isto é útil
quando colocamos senha em tabelas Paradox, ou
mesmo quando trabalhamos com banco de dados Client
Servidor, e queremos que o usuário digite a senha de
acesso. Se não fizermos desta forma, nem adicionarmos
via programação as senhas necessárias, esta caixa de
diálogo será mostrada quando o programa tentar abrir
uma tabela com senha. A grande vantagem aqui é que
podemos traduzir os Caption’s dos componentes.
189 - Truncar valores reais para
apenas n casas decimais
{ Às vezes você precisa considerar apenas duas casas
de valores reais, mas o Delphi não oferece algo pronto
para isto. Se usarmos funções como Round que vem
com o Delphi, o valor será arredondado (e não
truncado). Com Round() o valor abaixo será 135.55 (e
não 135.54) com duas casas decimais.}
ValorReal := 135.54658;
{ Somente a parte inteira - nenhuma casa
decimal }
X := Trunc(ValorReal); // X será 135
{ Duas casas }
X := Trunc(ValorReal * 100) / 100; // X
será 135.54
{ Três casas }
X := Trunc(ValorReal * 1000) / 1000; // X
será 135.546
Observações
Isto pode não funcionar se ValorReal for muito alto. Isto
por causa da multiplicação que poderá estourar a
capacidade do tipo em uso. Lembre-se: os tipos reais
aceitam valores muuuiiiito altos.
190 - Excluir todos os registros de
uma tabela (como DELETE ALL do
Clipper)
procedure tbDBDeleteAll(const DataSet:
TDataSet);
begin
with DataSet do
while RecordCount > 0 do
Delete;
end;

{ Chame-a como nos exemplos abaixo: }


tbDBDeleteAll(Table1);
ou
tbDBDeleteAll(Query1);
Observações
Se houver um filtro ou range ativo, somente os registros
filtrados serão excluídos. Portanto é diferente de
Table1.EmptyTable. Esta função poderá ser chamada no
evento BeforeDelete do Table (ou Query) principal em
um formulário mestre-detalhe para excluir os itens (da
parte detalhe).
191 - Saber se o sistema está
usando 4 dígitos para o ano
{ Para não correr o risco de surpresas desagradáveis, é
melhor que seu programa em Delphi verifique se o
Windows está ajustado para trabalhar com 4 dígitos
para o ano. Assim seu programa pode alertar o usuário
quando o ano estiver sendo representado com apenas 2
dígitos. A função abaixo retorna true se estiver ajustado
para 4 dígitos.}
function Is4DigitYear: Boolean;
begin
result:=(Pos(‘yyyy’,ShortDateFormat)>0);
end;
192 - Imprimir caracteres
acentuados diretamente para a
impressora
{ Usando comandos da impressora podemos fazer isto
de uma forma bastante simples. Quando enviamos o
caractere ASCII número 8 (oito) para a impressora, a
cabeça de impressão retrocede uma posição, pois este
caractere é o BackSpace. Então podemos imprimir a
letra sem acento e, sem seguida, voltar e imprimir o
acento desejado. Vejamos um exemplo:
- Coloque um botão no form;
- Altere o evento OnClick deste botão conforme abaixo:
}
procedure TForm1.Button2Click(Sender:
TObject);
var
F: TextFile;
begin
AssignFile(F, ‘LPT1’);
Rewrite(F);
try
{ Regra: caractere sem acento + chr(8) +
acento }
WriteLn(F, ‘Este e’ + #8 + ”” + ‘ um
teste.’);
WriteLn(F, ‘Acentuac’ + #8 + ‘,a’ + #8 +
‘~o.’);
WriteLn(F, ‘Vovo’ + #8 + ‘^’);
WriteLn(F, ‘U’ + #8 + ”” + ‘ltimo.’);
WriteLn(F, #12); // Eject
finally
CloseFile(F);
end;
end;
Observações
Usando este recurso, a acentuação não fica excelente,
mas melhora bastante.
193 - Imprimir texto justificado
com formatação na impressora
Epson LX-300
{ A impressora Epson LX-300 dispõe de um comando
que justifica o texto. Este recurso é interessante, pois
com ele podemos continuar a enviar os comandos de
formatação de caracteres como condensado, negrito,
italico, expandido, etc.
Para o exemplo abaixo:
- Coloque um botão no form;
- Altere o evento OnClick deste botão como abaixo: }
procedure TForm1.Button1Click(Sender:
TObject);
const
cJustif = #27#97#51;
cEject = #12;
{ Tamanho da fonte }
c10cpi = #18;
c12cpi = #27#77;
c17cpi = #15;
cIExpandido = #14;
cFExpandido = #20;
{ Formatação da fonte }
cINegrito = #27#71;
cFNegrito = #27#72;
cIItalico = #27#52;
cFItalico = #27#53;
var
Texto: string;
F: TextFile;
begin
Texto := c10cpi +
‘Este e um teste para impressora Epson
LX 300. ‘ +
‘O objetivo e imprimir texto justificado
sem deixar ‘ +
‘de usar formatacao, tais como: ‘ +
cINegrito + ‘Negrito, ‘ + cFNegrito +
cIItalico + ‘Italico, ‘ + cFItalico +
c17cpi + ‘Condensado (17cpi), ‘ + c10cpi
+
c12cpi + ‘12 cpi, ‘ + c10cpi +
cIExpandido + ‘Expandido.’ + cFExpandido
+
‘ Este e apenas um exemplo, mas voce
podera adapta-lo ‘ +
‘a sua realidade conforme a
necessidade.’;
AssignFile(F, ‘LPT1’);
Rewrite(F);
try
WriteLn(F, cJustif, Texto);
WriteLn(F, cEject);
finally
CloseFile(F);
end;
end;
Observações
Este recurso de justificação da Epson LX-300 pode ser
usado em qualquer linguagem de programação.
194 - Descobrir o código ASCII de
uma tecla
{ - Coloque um Label no form (Label1);
- Mude a propriedade KeyPreview do form para true;
- Altere o evento OnKeyDown do form como abaixo: }
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word;
Shift: TShiftState);
begin
Label1.Caption :=
Format(‘O código da tecla pressionada é:
%d’, [Key]);
end;
Observações
Para testar execute e observe o Label enquanto
pressiona as teclas desejadas.
195 - Usar eventos de som do
Windows
{ Evento Som Padrão }
MessageBeep(0); { ou Beep; }
{ Evento Parada Crítica }
MessageBeep(16);
{ Evento Pergunta }
MessageBeep(32);
{ Evento Exclamação }
MessageBeep(48);

{ Evento Asterisco }
MessageBeep(64);
196 - Trabalhar com Filter de
forma mais prática
Se você está habituado a usar este código no filter…
Table1.Filter := ‘Nome = ”’+ Edit1.Text +
””;
ou
Table1.Filter := ‘Data = ”’ +
DateToStr(Date) + ””;
Tente usar este:
Table1.Filter := ‘Nome = ‘ +
QuotedStr(Edit1.Text);
ou
Table1.Filter := ‘Data = ‘ +
QuotedStr(DateToStr(Date));
Observações
A função QuitedStr() coloca apóstrofos envolvendo a
string. Se houver um apóstrofo como parte da string, ela
o subtitui por dois apóstrofos, para que seja
corretamente interpretado.
197 - Reproduzir um arquivo WAV
Inclua na seção uses: MMSystem
PlaySound(‘C:\ArqSom.wav’, 1, SND_ASYNC);
Observações
Troque o nome do arquivo (C:\ArqSom.wav) pelo
arquivo desejado
198 - Copiar arquivos usando
curingas (*.*)
{ - Coloque um Button no Form;
- Altere o evento OnClick deste Button conforme
abaixo: }

procedure TForm1.Button2Click(Sender:
TObject);
var
SR: TSearchRec;
I: integer;
Origem, Destino: string;
begin
I := FindFirst(‘c:\Origem\*.*’,
faAnyFile, SR);
while I = 0 do begin
if (SR.Attr and faDirectory) <>
faDirectory then begin
Origem := ‘c:\Origem' + SR.Name;
Destino := ‘c:\Destino' + SR.Name;
if not CopyFile(PChar(Origem),
PChar(Destino), true) then
ShowMessage(‘Erro ao copiar ‘ + Origem +
‘ para ‘ + Destino);
end;
I := FindNext(SR);
end;
end;
Observações
No exemplo acima, se o arquivo já existir no destino, a
função falha (não copia). Para que a função possa
sobreescrever o arquivo destino (caso exista), altere o
último parâmetro de CopyFile para false. CUIDADO! Se
um arquivo for sobreescrito, estará perdido para sempre!
199 - Excluir arquivos usando
curingas (*.*)
{ - Coloque um Button no Form;
- Altere o evento OnClick do Button conforme abaixo: }
procedure TForm1.Button2Click(Sender:
TObject);
var
SR: TSearchRec;
I: integer;
begin
I := FindFirst(‘c:\Teste\*.*’,
faAnyFile, SR);
while I = 0 do begin
if (SR.Attr and faDirectory) <>
faDirectory then
if not DeleteFile(‘c:\Teste' + SR.Name)
then
ShowMessage(‘Não consegui excluir
c:\Teste' + SR.Name);
I := FindNext(SR);
end;
end;
Observações
No exemplo acima todos os arquivos do diretório
c:\Teste serão excluídos. CUIDADO! Arquivos excluídos
desta forma não vão para a lixeira.
200 - Definir a quantidade de
registros a ser impressa em uma
página do QuickReport
1. A forma mais simples consiste em alterar a altura
(Height) da banda Detail do nosso relatório de modo que
a altura total da página seja inferior a duas vezes a
altura da banda. Desta forma, cada registro será
impresso em uma nova página, teoricamente por falta
de espaço na página atual.
2. Uma outra forma mais sofisticada é usar o evento
AfterPrint da banda Detail. Nele testamos se ainda não
chegou no fim a tabela e, caso positivo, pedimos uma
nova página:
if not Table1.EOF then
QuickRep1.NewPage;
Deve existir outras alternativas, mas as duas anteriores
funcionaram bem nos testes realizados.
201 - Para que servem
OnGetEditMask, OnGetEditText e
OnSetEditText do TStringGrid
O evento OnGetEditMask ocorre quando entramos no
modo de edição. Neste momento podemos verificar em
qual linha/coluna se encontra o cursor e então, se
quiser, poderá especificar uma máscara de edição.
Exemplo:
procedure
TForm1.StringGrid1GetEditMask(Sender:
TObject; ACol, ARow: Integer; var Value:
String);
begin
if (ARow = 1) and (ACol = 1) then
Value := ‘(999) 999-9999;1;_’; //
Telefone
end;
O evento OnGetEditText ocorre também quando
entramos no modo de edição. Neste momento podemos
manipularmos o texto da célula atual (linha/coluna) e
então podemos simular algo tal como uma tabela onde
opções podem ser digitadas através de números.
Exemplo:
procedure
TForm1.StringGrid1GetEditText(Sender:
TObject; ACol, ARow: Integer; var Value:
String);
begin
if (ARow = 1) and (ACol = 2) then begin
if StringGrid1.Cells[ACol, ARow] =
‘Ótimo’ then
Value := ‘1’
else if StringGrid1.Cells[ACol, ARow] =
‘Regular’ then
Value := ‘2’
else if StringGrid1.Cells[ACol, ARow] =
‘Ruim’ then
Value := ‘3’;
end;
end;

O evento evento OnSetEditText ocorre quando saímos


do modo de edição. Neste momento podemos manipular
a entrada e trocar por um texto equivalente.
Normalmente usamos este evento em conjunto com o
evento OnGetEditText. Exemplo:
procedure
TForm1.StringGrid1SetEditText(Sender:
TObject; ACol, ARow: Integer; const Value:
String);
begin
if (ARow = 1) and (ACol = 2) then begin
if Value = ‘1’ then
StringGrid1.Cells[ACol, ARow] := ‘Ótimo’
else if Value = ‘2’ then
StringGrid1.Cells[ACol, ARow] :=
‘Regular’
else if Value = ‘3’ then
StringGrid1.Cells[ACol, ARow] := ‘Ruim’
end;
end;
Observações
Para testar o exemplo anterior crie um novo projeto e
coloque no Form1 um TStringGrid. Mude os três eventos
mencionados conforme os exemplos. Execute e
experimente digitar nas céluas 1 e 2 da primeira linha
(na parte não fixada, é claro!).
202 - Fazer a barra de título ficar
intermitente (piscante)
Inclua na seção uses: Windows
{ Coloque um TTimer no Form desejado. Define a
propriedade Interval do Timer para 1000 (1 segundo).
Modifique o evento OnTimer do Timer conforme abaixo:
}

procedure TForm1.Timer1Timer(Sender:
TObject);
begin
FlashWindow(Handle, true);
FlashWindow(Application.Handle, true);
end;
203 - Posicionar o cursor do mouse
em um controle
Inclua na seção uses: Windows
{ Digite a procedure abaixo imediatamente após a
palavra implementation no código do seu formulário. }
procedure MouseParaControle(Controle:
TControl);
var
IrPara: TPoint;
begin
IrPara.X := Controle.Left +
(Controle.Width div 2);
IrPara.Y := Controle.Top +
(Controle.Height div 2);
if Controle.Parent <> nil then
IrPara :=
Controle.Parent.ClientToScreen(IrPara);
SetCursorPos(IrPara.X, IrPara.Y);
end;
{ Para testar, coloque no Form um botão e
troque o name dele para btnOK e modifique
o evento OnShow do Form conforme abaixo: }
procedure TForm1.FormShow(Sender:
TObject);
begin
MouseParaControle(btnOk);
end;
Observações
A função “MouseParaControle” recebe um parâmetro do
tipo TControl. Isto significa que você poderá passar para
ela qualquer controle do Delphi, tais como: TEdit,
TButton, TSpeedButton, TPanel, etc. Pode ser até
mesmo o próprio Form.
204 - Mostrar o Hint para cada
coluna do StringGrid
Para testar o exemplo abaixo inclua no seu form um
componente StringGrid
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
Grids;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
procedure FormCreate(Sender: TObject);
procedure StringGrid1MouseMove(Sender:
TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
Col,Row : integer; // Declarar esta
variável
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// Evento OnCreate do Form
procedure TForm1.FormCreate(Sender:
TObject);
begin
StringGrid1.Hint := ‘0 0’;
StringGrid1.ShowHint := True;
end;
// Evento OnMouseMove do componente
StringGrid
procedure
TForm1.StringGrid1MouseMove(Sender:
TObject; Shift: TShiftState;
X, Y: Integer);
var r,c : integer;
begin
StringGrid1.MouseToCell(X, Y, C, R);
if ((Row <> r) or (Col <> c)) then
begin
Row := r; Col := c;
Application.CancelHint;
StringGrid1.Hint := ‘Linha:
‘+IntToStr(r)+#32+‘Coluna: ‘+IntToStr(c);
end;
end;
205 - Mudar o papel de parede 3
Para testar o exemplo abaixo inclua no seu form um
componente Button e no evento OnClick o código
abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0,
PChar(‘C:\windows\Arenito.bmp’),SPIF_SENDW
ININICHANGE);
end;
206 - Arquivos AVI e WAV em
tabelas
O exemplo abaixo demonstra como gravar um arquivo
.AVI ou .WAV dentro de um arquivo paradox. Mostra
também como reproduzir estes arquivos.
Para que o código abaixo funcione inclua em um Form
02 componentes Button, 01 componente Panel, 01
componente DBGrid, 01 componente Table, 01
componente DataSource e 01 componente OpenDialog.
Crie um arquivo Paradox com a seguinte estrutura:
Nome Tipo Tamanho
Codigo +
Nome A 100
Avi B

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, DBTables, ExtCtrls, MPlayer,
DBCtrls, Grids, DBGrids;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Table1: TTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Panel1: TPanel;
OpenDialog1: TOpenDialog;
Table1Codigo: TAutoIncField;
Table1Nome: TStringField;
Table1Avi: TBlobField;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var
Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var Form1: TForm1;
FileName : string;
MediaPlayer1 : TMediaPlayer;

implementation
{$R *.DFM}
{Esta função cria um arquivo temporário
para o sistema}
function GetTemporaryFileName : string;
{$IFNDEF WIN32}
const MAX_PATH = 144;
{$ENDIF}
var
{$IFDEF WIN32}
lpPathBuffer : PChar;
{$ENDIF}
lpbuffer : PChar;
begin
{Get the file name buffer}
GetMem(lpBuffer, MAX_PATH);
{$IFDEF WIN32}
{Get the temp path buffer}
GetMem(lpPathBuffer, MAX_PATH); {Get the
temp path}
GetTempPath(MAX_PATH, lpPathBuffer); {Get
the temp file name}
GetTempFileName(lpPathBuffer,‘tmp’,0,lpBuf
fer);
FreeMem(lpPathBuffer, MAX_PATH);
{$ELSE} {Get the temp file name}
GetTempFileName(GetTempDrive(‘C’),‘tmp’,0,
lpBuffer);
{$ENDIF} {Create a pascal string containg}
{the temp file name and return it}
result := StrPas(lpBuffer);
{Free the file name buffer}
FreeMem(lpBuffer, MAX_PATH);
end;
{Grava AVI ou Wav no arquivo PARADOX}
procedure TForm1.Button1Click(Sender:
TObject);
var FileStream: TFileStream; {para ler o
arquivo avi}
BlobStream: TBlobStream; {para salvar no
campo blob}
begin
Application.ProcessMessages;
Button1.Enabled := false;
Button2.Enabled := false;

if OpenDialog1.Execute then
FileStream :=
TFileStream.Create(OpenDialog1.FileName,fm
OpenRead);
Table1.Append;
Table1Nome.Value := OpenDialog1.FileName;
BlobStream :=
TBlobStream.Create(Table1AVI,
bmReadWrite);
BlobStream.Seek(0, soFromBeginning);
BlobStream.Truncate;
BlobStream.CopyFrom(FileStream,
FileStream.Size);
FileStream.Free;
BlobStream.Free;
Table1.Post;
Button1.Enabled := true;
Button2.Enabled := true;
end;
{Reproduz o que está gravado no campo
Blob}
procedure TForm1.Button2Click(Sender:
TObject);
var FileStream: TFileStream; {a temp file}
BlobStream: TBlobStream; {the AVI Blob}
begin
BlobStream :=
TBlobStream.Create(Table1AVI, bmRead);
if BlobStream.Size = 0 then
begin
BlobStream.Free;
Exit;
end;
MediaPlayer1.Close; {Reset the file name}
MediaPlayer1.FileName := ”; {Refresh the
play window}
MediaPlayer1.Display := Panel1;
Panel1.Refresh;
if FileName <> ” then
DeleteFile(FileName); {Get a temp file
name}
FileName := GetTemporaryFileName; {Create
a temp file stream}
FileStream :=
TFileStream.Create(FileName,fmCreate or
fmOpenWrite);
FileStream.CopyFrom(BlobStream,
BlobStream.Size); {Free the streams}
FileStream.Free; BlobStream.Free;
MediaPlayer1.FileName := filename;
MediaPlayer1.DeviceType := dtAviVideo;
MediaPlayer1.Open;
MediaPlayer1.Play;
end;
// Evento OnDestroy do Form
procedure TForm1.FormDestroy(Sender:
TObject);
begin
MediaPlayer1.Close;
MediaPlayer1.FileName := ”;
if FileName <> ” then
DeleteFile(FileName);
end;
// Evento OnShow do Form
procedure TForm1.FormShow(Sender:
TObject);
begin
MediaPlayer1 := TMediaPlayer.Create(self);
with MediaPlayer1 do
begin
Parent := self ;
Visible := False;
end;
Table1.Open;
end;
// Evento OnClose do Form
procedure TForm1.FormClose(Sender:
TObject; var Action: TCloseAction);
begin
Table1.Close;
end;
end.
207 - Copiar registros de uma
tabela para outra incluindo valores
NULL
Procedure TtableCopiaRegistro(Origem,
Destino: Ttable);
begin
with TabelaOrig do
begin
{Inicia um contador para os campos da
TabelaOrig}
for i := 0 to FieldCount -1 do
{Este if verifica se o campo da TabelaOrig
é NULL, se for, atribui seu valor ao campo
da TabelaDest}
if not Fields[i].IsNull then
TabelaDest.Fields[i].Assign(Fields[i]);
end; {end with}
end;
Este exemplo funcionará com todos tipos de campos se
você tiver acabado de criar a TabelaDest.
Para criar um dado valor NULL :
Fields[i].Clear
208 - Jogar uma imagem direto
para um campo da tabela
procedure TForm1.Button1Click(Sender:
TObject);
var BMP: TBitMap;
begin
BMP := TBitMap.Create;
if OpenPictureDialog1.Execute then
begin
if Table1.State in [dsInsert, dsEdit] then
begin
BMP.LoadFromFile(OpenPictureDialog1.FileNa
me);
Table1Graphic.Assign( BMP );
end;
end;
end;
209 - Retornar a coluna ativa do
DBGrid
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
Db, DBTables, Grids, DBGrids;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
Table1: TTable;
DataSource1: TDataSource;
procedure DBGrid1ColEnter(Sender:
TObject);
end;

var
Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.DBGrid1ColEnter(Sender:
TObject);
begin
Caption :=
DBGrid1.SelectedField.FieldName;
end;
210 - Imprimir em impressora
matricial em modo caracter
Procedure TForm1.Button1Click(Sender:
TObject);
var Arquivo : TextFile;
begin
AssignFile(Arquivo,‘LPT1’);
Rewrite(Arquivo);
Writeln(Arquivo,‘Teste de impressao -
Linha 0’);
Writeln(Arquivo,‘Teste de impressao -
Linha 1’);
Writeln(Arquivo,#27#15+‘Teste de Impressão
- Linha 2’);
Writeln(Arquivo,‘Teste de impressao -
Linha 3’);
Writeln(Arquivo,#27#18+‘Teste de Impressão
- Linha 4’);
Writeln(Arquivo,‘Teste de impressao -
Linha 5’);
Writeln(Arquivo,#12); // Ejeta a página
CloseFile(Arquivo);
end;
211 - Gravar imagem JPG em
tabela Paradox
Procedure Grava_Imagem_JPEG(Tabela:TTable;
Campo:TBlobField;
Foto:TImage; Dialog:TOpenPictureDialog);
var BS:TBlobStream;
MinhaImagem:TJPEGImage;
Begin
Dialog.InitialDir := ‘c:\temp’;
Dialog.Execute;
if Dialog.FileName <> ” Then
Begin
if not (Tabela.State in [dsEdit,
dsInsert]) Then
Tabela.Edit;
BS := TBlobStream.Create((Campo as
TBlobField), BMWRITE);
MinhaImagem := TJPEGImage.Create;
MinhaImagem.LoadFromFile(Dialog.FileName);
MinhaImagem.SaveToStream(BS);
Foto.Picture.Assign(MinhaImagem);
BS.Free;
MinhaImagem.Free;
Tabela.Post;
DBISaveChanges(Tabela.Handle);
End;
End;

procedure TForm1.Button1Click(Sender:
TObject);
begin
Grava_Imagem_JPEG(TbClientes,TbClientesCli
_Foto, Image1,
OpenPictureDialog1);
// TbClientes é o nome de alguma Tabela
// TbClientesCli_Foto é um variavel da
tabela do tipo Blob
// Image1 é um componente
// OpenPictureDialog1 é o componente para
abrir a figura
end;
212 - Ler imagem JPG da tabela
Paradox
Procedure Le_Imagem_JPEG(Campo:TBlobField;
Foto:TImage);
var BS:TBlobStream;
MinhaImagem:TJPEGImage;
Begin
if Campo.AsString <> ” Then
Begin
BS := TBlobStream.Create((Campo as
TBlobField), BMREAD);
MinhaImagem := TJPEGImage.Create;
MinhaImagem.LoadFromStream(BS);
Foto.Picture.Assign(MinhaImagem);
BS.Free;
MinhaImagem.Free;
End
Else
Foto.Picture.LoadFromFile(‘c:\temp\limpa.j
pg’);
End;

procedure TForm1.Button1Click(Sender:
TObject);
begin
Le_Imagem_JPEG(TbClientesCli_Foto,
Image1);
// TbClientesCli_Foto é um variavel da
tabela do tipo Blob
// Image1 é um componente
end;
213 - Como saber quantos dias tem
no mes
function TForm1.AnoBiSexto(Ayear:
Integer): Boolean;
begin
// Verifica se o ano é Bi-Sexto
Result := (AYear mod 4 = 0) and ((AYear
mod 100 <> 0) or
(AYear mod 400 = 0));
end;

function TForm1.DiasPorMes(Ayear, AMonth:


Integer): Integer;
const DaysInMonth: array[1..12] of Integer
= (31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31);
begin
Result := DaysInMonth[AMonth];
if (AMonth = 2) and AnoBiSexto(AYear) then
Inc(Result);
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
Label1.Caption :=
IntToStr(DiasPorMes(1999, 10));
end;
214 - Como saber se o ano é
bisexto
function TForm1.AnoBiSexto(Ayear:
Integer): Boolean;
begin
Result := (AYear mod 4 = 0) and ((AYear
mod 100 <> 0) or
(AYear mod 400 = 0));
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
if AnoBiSexto(1999) Then
ShowMessage(‘Ano de 1999 é Bisexto’)
Else ShowMessage(‘Ano de 1999 não é
Bisexto’);
end;
215 - Colocar o mes por extenso
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,
Dialogs,StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
function MesExtenso( Mes:Word ) : string;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.MesExtenso( Mês:Word ) :


string; const meses : array[0..11] of
PChar = (‘Janeiro’, ‘Fevereiro’, ‘Março’,
‘Abril’, ‘Maio’, ‘Junho’, ‘Julho’,
‘Agosto’, ‘Setembro’,‘Outubro’,
‘Novembro’, ‘Dezembro’);
begin
result := meses[mes-1];
End;

procedure TForm1.Button1Click(Sender:
TObject);
begin
label1.Caption := MesExtenso(3);
end;

end.
216 - Chamar um e-mail pelo Delphi
Uses Shellapi

procedure TForm1.Button1Click(Sender:
TObject);
var Mail : String;
begin
Mail := ‘mailto:lloydsoft@ieg.com.br’;
ShellExecute(GetDesktopWindow,‘open’,pchar
(Mail),nil,nil,sw_ShowNormal);
end;
217 - Imprimir em impressora
matricial em modo caracter via
Rede
// Esta rotina lê todas as impressoras instaladas no
windows
// e coloca dentro de um ComboBox e não se esqueça
de adicionar
// na cláusula uses a unit Printers

procedure TForm1.FormShow(Sender:
TObject);
var I : Integer;
begin
ComboBox1.Items.Clear;
For I:= 1 to Printer.Printers.Count do
Begin
if Pos(‘LPT’, printer.Printers.Strings[I-
1]) > 0Then
ComboBox1.Items.Add(‘LPT1’)
Else if Pos(‘\’,
printer.Printers.Strings[I-1]) > 0 Then
ComboBox1.Items.Add(Copy(printer.Printers.
Strings[I-1],
Pos(‘\’, printer.Printers.Strings[I-1]),
length(printer.Printers.Strings[I-1]) -
Pos(‘\’, printer.Printers.Strings[I-1]) +
1));
End;
End;
// e quando apertar o botao imprimir, o
evento pega qual a impressora
// que você escolheu atravéz do ComboBox e
Imprimi.
procedure TForm1.btImprimirClick(Sender:
TObject);
var I:Integer;
Arquivo : TextFile;
begin
AssignFile(Arquivo,ComboBox1.Value);
Rewrite(Arquivo);
WriteLn(Arquivo, ‘TESTE DE IMPRESSAO -
1’);
WriteLn(Arquivo, ‘TESTE DE IMPRESSAO -
2’);
WriteLn(Arquivo, ‘TESTE DE IMPRESSAO -
3’);
WriteLn(Arquivo, ‘TESTE DE IMPRESSAO -
4’);
CloseFile(Arquivo);
end;
218 - Link para WEB
Um procedure para você clicar no (label, menu, botão…)
a automaticamente abrir seu navegador padrão e
carregar a página determinada pelo link.
1º Declare o procedure na seção PUBLIC da unit.
procedure JumpTo(const aAdress: String);
2º Coloque a cláusula ShellAPI na uses no início da unit.
procedure TForm1.JumpTo(const aAdress:
String);
var
buffer: String;
begin
buffer := ‘http://’ + aAdress;
ShellExecute(Application.Handle, nil,
PChar(buffer), nil, nil, SW_SHOWNORMAL);
end;
procedure TForm1.Label1Click(Sender:
TObject);
begin
JumpTo(‘www.lloydsoft.hpg.ig.com.br’);
end;
219 - Configurar o Delphi para
acessar tabelas do Acess
Execute o BDE, abra a paleta CONFIGURATION, click
em Drivers, Native, MsAccess, uma janela de
configuração com várias opções será aberta. Configure
a DLL32 para IDDA032.DLL ACESS 95 ou
IDDA3532.DLL ACESS 97. Na opção SYSTEM
DATABASE, aponte para o arquivo System.mdw do
Acess que geralmente está no subdiretório
\Msoffice\Access. Salve a configuração e após isto é só
criar seu alias (se já houver algum criado, delete e
configure de novo). Com essa informação em mãos,
faça o programa não pedir o prompt de login (a da
senha), colocando um TDatabase no projeto. Escolha o
alias que você criou na propriedade AliasName. Altere
LoginPrompt para False. Na propriedade
DatabaseName, coloque um nome qualquer (servirá
como substituto do alias em todas as TTable e TQuery
que acessem esse BD). Altere a propriedade AliasName
de todas as TTables e TQueries que acessem essas
tabelas para o nome que você definiu em
DatabaseName no TDatabase.
220 - Emular o pressionamento de
uma tecla
keybd_event(65,0,0,0);
Será enviado o ‘A’ para o componente que estiver em
foco.
221 - Procurar arquivos
procedure TForm1.DirList( ASource :
string; ADirList : TStringList );
var
SearchRec : TSearchRec;
Result : integer;
begin
Result := FindFirst( ASource, faAnyFile,
SearchRec );
if Result = 0 then
while (Result = 0) do
begin
if (SearchRec.Name+’ ‘)[1] = ‘.’ then
{ Se pegou nome de SubDiretorio }
begin
Result := FindNext( SearchRec );
Continue;
end;
ADirList.Add( SearchRec.Name );
Result := FindNext( SearchRec );
end;
FindClose( SearchRec );
ADirList.Sort;
end;
Utilize a função assim:

procedure TForm1.Button1Click(Sender:
TObject);
var
contador: Integer;
lista: TStringlist;
begin
lista:= TStringlist.create;
DirList(‘C:\*.*’, lista);
end;
222 - Ligar/desligar a tecla Caps
Lock
Inclua na seção uses: Windows
{ Esta função liga/desliga Caps Lock, conforme o
parãmetro State }
procedure tbSetCapsLock(State: boolean);
begin
if (State and ((GetKeyState(VK_CAPITAL)
and 1) = 0)) or
((not State) and
((GetKeyState(VK_CAPITAL) and 1) = 1))
then
begin
keybd_event(VK_CAPITAL, $45,
KEYEVENTF_EXTENDEDKEY or 0, 0);
keybd_event(VK_CAPITAL, $45,
KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,
0);
end;
end;

{ Exemplos de uso: }
tbSetCapsLock(true); { Liga Caps Lock }
tbSetCapsLock(false); { Desliga Caps Lock
}
Observações
Aparentemente, podemos usar esta mesma técnica para
ligar/desligar Num Lock. Neste caso trocaríamos
VK_CAPITAL por VK_NUMLOCK. Por incrível que
pareça não funcionou (pelo menos no teste que fiz). E
tem mais: isto está na documentação do (R)Windows.
223 - Verificar se uma determinada
tecla está pressionada
Inclua na seção uses: Windows
{ Esta função retorna true se a tecla informada estiver
pressionada. False em caso contrário. }

function tbKeyIsDown(const Key: integer):


boolean;
begin
Result := GetKeyState(Key) and 128 > 0;
end;

{ Exemplos de uso: }

if tbKeyIsDown(VK_CONTROL) then
{ Tecla Ctrl pressionada }

if tbKeyIsDown(VK_MENU) then
{ Tecla Alt pressionada }

if tbKeyIsDown(VK_SHIFT) then
{ Tecla Shift pressionada }

if tbKeyIsDown(VK_F2) then
{ Tecla F2 pressionada }
Observações
Qualquer tecla pode ser verificada. Para isto basta saber
o código virtual (Virtual Key Code) da tecla.
224 - Fazer pesquisa incremental
Prob.: Gostaria de montar um formulário de pesquisa
com um DBGrid e um Edit de modo que, enquanto o
usuário digita um nome do Edit, o registro vai sendo
localizado no DBGrid. Como fazer?
- Crie um índice na tabela com campo a ser usado na
pesquisa.
Coloque no Form:
- Um DataSource
- Um Table
- Um DBGrid
- Um Edit
Altere as seguintes propriedades:
- DataSource1.DataSet = Table1
- Table1.DatabaseName = ‘NomeDoAlias’
- Table1.TableName = ‘NomeDaTabela’
- Table1.IndexFieldNames = ‘NomeDoCampo’
- Table1.Active = true
- DBGrid1.DataSource = DataSource1
Escreva a instrução abaixo no evento OnChange do
Edit:
Table1.FindNearest([Edit1.Text]);
Observações
Este exemplo considera que o campo seja tipo string.
Para outros tipos de campos pode ocorrer erro
dependendo dos valores digitados no Edit1.
225 - Implementar rotinas
assembly em Pascal
{ O Delphi permite a implementação de rotinas assembly
mescladas ao código Pascal. Não entrarei em detalhes
minuciosos, mas darei alguns exemplos básicos de
como implementar rotinas simples que retornam
números inteiros.}

{ Soma dois inteiros de 8 bits }


function Soma8(X, Y: byte): byte;
asm
mov al, &X
add al, &Y
end;

{ Soma dois inteiros de 16 bits }


function Soma16(X, Y: Word): Word;
asm
mov ax, &X
add ax, &Y
end;

{ Soma dois inteiros de 32 bits }


function Soma32(X, Y: DWord): DWord;
asm
mov eax, &X
add eax, &Y
end;

{ A chamada a estas funções são feitas da mesma


forma que chamamos uma função Pascal. Exemplo: }
var
A: byte;
begin
A := Soma8(30, 25); { A = 55 }
end;
226 - Alterar o nome de volume
(Label) de um disco
Inclua na seção uses: Windows
{ Da unidade C: }
SetVolumeLabel(‘c:', ‘NovoLabel’);
{ Da unidade atual: }
SetVolumeLabel(nil, ‘NovoLabel’);
227 - Evitar a proteção de tela
durante seu programa
Inclua na seção uses: Windows
{ Na seção “private” do Form principal acrescente: }
procedure AppMsg(var Msg: TMsg; var
Handled: Boolean);
{ Na seção “implementation” acrescente (troque TForm1
para o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var
Handled: Boolean);
begin
if (Msg.Message = wm_SysCommand) and
(Msg.wParam = sc_ScreenSave) then
Handled := true;
end;

{ No evento “OnCreate” do form principal, coloque: }


Application.OnMessage := AppMsg;
228 - Validar datas
try
StrToDate(Edit1.Text);
except
on EConvertError do
ShowMessage (‘Data Inválida!’);
end;
229 - Formatar CEP
{ Esta função forma CEP como: 99.999-999 }
function tbFormataCEP(const CEP: string):
string;
var
I: integer;
begin
Result := ”;
for I := 1 to Length(CEP) do
if CEP[I] in [‘0’..‘9’] then
Result := Result + CEP[I];
if Length(Result) <> 8 then
raise Exception.Create(‘CEP inválido.’)
else
Result :=
Copy(Result, 1, 2) + ‘.’ +
Copy(Result, 3, 3) + ‘-‘ +
Copy(Result, 6, 3);
end;
=== Para testar ===
- Coloque um Edit e um Button no form;
- No evento OnClick do Button coloque a instrução
abaixo:
Edit1.Text := tbFormataCEP(Edit1.Text);
Observações
Para formatar outros códigos como CPF, CGC, etc.,
pode-se usar a mesma idéia.
230 - Quantas Segundas tem num
mês
unit Unit1;

interface

uses SysUtils;

function UltimoDiaMes(Mdt: TDateTime) :


TDateTime;
function QtdDiaSemana(Mdt: TDateTime;
DiaSemana : Integer) : Integer;

implementation

function QtdDiaSemana(Mdt: TDateTime;


DiaSemana : Integer) : Integer;
{Mdt = qualquer dia do mes DiaSemana = dia
da semana procurado ( 1 a 7) retorna o
quantidade de dias}
var
ano, mes, UltimoDia : word;
mDtTemp : TDateTime;
I : Integer;
begin
MdtTemp := UltimodiaMes(Mdt);
Decodedate(MdtTemp, ano, mes,
UltimoDia);
MdtTemp := EncodeDate(ano,mes,1);
result := 0;
for I := 1 to UltimoDia do
begin
if DayOfWeek(Mdttemp) = DiaSemana then
Inc(Result);
MdtTemp := Mdttemp + 1;
end;
end;

function UltimoDiaMes(Mdt: TDateTime) :


TDateTime;
{ retorna o ultimo dia o mes, de uma data
fornecida}
var
ano, mes, dia : word;
mDtTemp : TDateTime;
begin
Decodedate(mDt, ano, mes, dia);
mDtTemp := (mDt - dia) + 33;
Decodedate(mDtTemp, ano, mes, dia);
Result := mDtTemp - dia;
end;

end.
231 - Retorna a quantidade de dias
uteis entre duas datas
function
DifDateUtil(dataini,datafin:string):intege
r;
var a,b,c:tdatetime;
ct,s:integer;
begin
if StrToDate(DataFin) < StrtoDate(DataIni)
then
begin
Result := 0;
exit;
end;
ct := 0;
s := 1;
a := strtodate(dataFin);
b := strtodate(dataIni);
if a > b then
begin
c := a;
a := b;
b := c;
s := 1;
end;
a := a + 1;
while (dayofweek(a)<>2) and (a <= b) do
begin
if dayofweek(a) in [2..6] then
begin
inc(ct);
end;
a := a + 1;
end;
ct := ct + round((5*int((b-a)/7)));
a := a + (7*int((b-a)/7));
while a <= b do
begin
if dayofweek(a) in [2..6] then
begin
inc(ct);
end;
a := a + 1;
end;
if ct < 0 then
begin
ct := 0;
end;
result := s*ct;
end;
232 - Como registrar um OCX
Digite “Regsvr.exe do OCX>” ou “Regsvr32.exe do
OCX>”
233 - Como usar recursos do word
uses
ComObj, ActiveX;

var
OldWord, NewWord: Variant;

function GetOrCreateObject (const


ClassName: string): IDispatch;
var
ClassID: TGUID;
Unknown: IUnknown;
begin
ClassID := ProgIDToClassID (ClassName);
if Succeeded (GetActiveObject (ClassID,
nil, Unknown)) then
OleCheck (Unknown.QueryInterface
(IDispatch, Result))
else
Result := CreateOleObject (ClassName);
end;

procedure TForm1.FormCreate(Sender:
TObject);
begin
OldWord := GetOrCreateObject
(‘Word.Basic’);
NewWord := GetOrCreateObject
(‘Word.Application’);
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
OldWord.FileNew;//criar um arquivo novo
OldWord.AppShow; //chamar a aplicação
OldWord.Insert (‘Mastering Delphi by
Pacal Votan’); //inserir o texto
end;

procedure TForm1.Button2Click(Sender:
TObject);
var
Document, Range: Variant;
begin
NewWord.Visible := True;
NewWord.Documents.Add;
// inserir texto
NewWord.Documents.Item(1).Range.
Text := ‘Mastering Delphi by Pacal
Votan’;
// get document and add paragraph
Document := NewWord.Documents.Item(1);
Document.Paragraphs.Add;
Document.Paragraphs.Add;
// selecionar o terceiro parqagrafo
Range :=
Document.Paragraphs.Item(3).Range;
Range.Text := ‘Hello, Delphi’;
Range.Bold := 1;
Range.Font.Size := 30;
// salvar o arquivo gerado
if SaveDialog1.Execute then
Document.SaveAs (WideString
(SaveDialog1.Filename), 0);
Document.SaveAs (FileName := WideString
(SaveDialog1.Filename),
FileFormat := 0, //formato nativo do
word
SaveNativePictureFormat := 1); // true
end;
234 - Bloqueio de palavras
use a função Pos.
sAux:=‘Nós usamos delphi!’;
if Pos(‘delphi’,sAux)>0 then
{faça alguma coisa};
235 - Esconder o icone da Barra de
Tarefas
//Insira estas linhas no onShow do seu
Aplicativo para que ele fique invisível
//na barra do menu Iniciar:

var
H : HWnd;
begin
H := FindWindow(Nil,‘Project1’); {troque
project1 pelo nome do seu projeto)
if H <> 0 then ShowWindow(H,SW_HIDE);
end;
236 - Texto Rotativo
procedure AngleTextOut(CV: TCanvas; const
sText: String; x, y, angle:integer);
var
LogFont: TLogFont;
SaveFont: TFont;
begin
SaveFont := TFont.Create;
SaveFont.Assign(CV.Font);
GetObject(SaveFont.Handle,
sizeof(TLogFont), @LogFont);
with LogFont do
begin
lfEscapement := angle *10;
lfPitchAndFamily := FIXED_PITCH or
FF_DONTCARE;
end; {with}
CV.Font.Handle :=
CreateFontIndirect(LogFont);
SetBkMode(CV.Handle, TRANSPARENT);
CV.TextOut(x, y, sText);
CV.Font.Assign(SaveFont);
SaveFont.Free;
end;
237 - Enviando caracteres para
outra aplicação
var
myHandle : THandle;
begin
myHandle:= FindWindow( ‘MyAppClass’,
‘MyAppCaption’);
if myHandle <> 0 then
PostMessage( myHandle, WM_KeyDown,
myCharCode, 0 );
end;
238 - Limitando a região de
movimentação do mouse
Inclua na seção uses: Windows
Coloque um botão no form e altera o evento OnClick
dele conforme abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
R: TRect;
begin
{ Pega o retângulo da área cliente do
form }
R := GetClientRect;
{ Converte as coordenadas do form em
coordenadas da tela }
R.TopLeft := ClientToScreen(R.TopLeft);
R.BottomRight :=
ClientToScreen(R.BottomRight);
{ Limita a região de movimentação do
mouse }
ClipCursor(@R);
ShowMessage(‘Tente mover o mouse para
fora da área cliente do Form’);
{ Libera a movimentação }
ClipCursor(nil);
end;
239 - Executar Internet Explorer
uses comobj;

procedure TForm1.logoClick(Sender:
TObject);
var ie : Variant;
begin
IE :=
CreateOleObject(‘InternetExplorer.Applicat
ion’);
IE.Visible := true;
IE.Navigate(‘www.lloydsoft.hpg.ig.com.br’
);
end;
240 - Enviar um email
smtp.postmessage.toAddress := ‘StringList
(por ex uma listbox’;
smtp.postmessage.FromAdreess := ‘ex:
meu_email@123.pt’;
smtp.userid := ‘ex: user@123.pt’
smtp.host := ‘ex: smtp@123.pt’
smtp.postmessage.subject := ‘Assunto’
smtp.postmessage.body := ‘Texto da
mensagem (stringlist)’

smtp.connect;
smtp.sendmail;
smtp.disconnect;
Contribuição:
O Anonymous.nick enviou um complemento explicando
melhor o procedimento para enviar um e-mail usando o
Delphi.
Fazer um aplicativo completo para manipulação de e-
mails é um tanto trabalhoso e não é o assunto desta
dica. Muitas vezes, porém, queremos apenas dar ao
nosso software a capacidade de enviar simples e-mails.
Isto é fácil, especialmente porque o Delphi5 nos oferece
o componente TNMSMTP (paleta FastNet) que faz
praticamente todo o trabalho para nós. Precisamos
apenas alterar algumas propriedades e chamar alguns
métodos para que a mensagem seja enviada. Vamos
para a prática:
1. Coloque um componente TNMSMTP no form.
2. Coloque um botão e no evento OnClick deste botão
escreva:
procedure TForm1.Button1Click(Sender:
TObject);
begin

{ Seu servidor SMTP }


NMSMTP1.Host := ‘smtp.servidor.com.br’;

{ Porta SMTP, **NÃO MUDE ISTO** }


NMSMTP1.Port := 25;

{ Nome de login do usuário }


NMSMTP1.UserID := ‘MeuLogin’;

{ Conecta ao servidor }
NMSMTP1.Connect;
{ Se ocorrer algum erro durante a
conexão com o servidor, avise! }
if not NMSMTP1.Connected then
raise Exception.Create(‘Erro de
conexão’);

with NMSMTP1.PostMessage do begin


{ Seu e-mail }
FromAddress :=
‘meuemail@meuserver.com.br’;

{ Seu nome }
FromName := ‘Meu Nome’;

{ E-mail do destinatário }
ToAddress.Clear;

ToAddress.Add(‘destinatario@servidor.com.b
r’);

{ Assunto da mensagem }
Subject := ‘Assunto da mensagem’;

{ Corpo da mensagem }
Body.Clear;
Body.Add(‘Primeira linha da mensagem’);
Body.Add(‘Segunda linha da mensagem’);
Body.Add(”); { Linha em branco }
Body.Add(‘Última linha da mensagem’);

{ Anexar arquivos(Se não quiser anexar


arquivos, apague as 3 linhas seguintes) }

Attachments.Clear;

{ Endereço do anexo }

Attachments.Add(‘c:\diretorio\arquivo.ext’
);

end;

{ Manda o e-mail }
NMSMTP1.SendMail;
{ Disconecta do servidor }
NMSMTP1.Disconnect;
end;

Pronto! É só fazer as adaptações necessárias e você


terá envio de e-mails em sua aplicação.
Observações:
Para enviar o mesmo e-mail para vários destinatário de
uma só vez basta adicionar os endereços de e-mails de
todos os destinatários em
NMSMTP1.PostMessage.ToAddress.
Complemento enviado por Anonymous.nick
241 - Listbox
Selecionar primeiro da lista:
combobox1.ItemIndex:=0;
Mostrar atual:
listbox1.items[listbox1.itemindex];
Adicionar:
ListBox1.Items.Add(ComboBox1.Text);
Apagar:
ListBox1.Items.Delete(ListBox1.ItemIndex);
242 - Capturar ecrã
var bitmap : tbitmap;
jpg : tjpegimage;
dc : hdc;
desktoprect : trect;
desktopcanvas : tcanvas;
x, y : integer;

begin
dc:=getdc(getdesktopwindow);
try
desktopcanvas:=tcanvas.create;
bitmap:=tbitmap.create;
jpg:=tjpegimage.create;
try
bitmap.Width:=320;
bitmap.Height:=240;
desktopcanvas.handle:=dc;
desktoprect:=rect(0,0,319,239);
bitmap.canvas.CopyRect(desktoprect,deskto
pcanvas,desktoprect);
img.Picture.Bitmap:=bitmap;

for y:=yy to yy+10 do


for x:=xx to xx+10 do
img.canvas.pixels[x,y]:=clwhite;

with jpg do
begin
compressionquality:=25;
assign(bitmap);
compress;
savetofile(‘data'+filename);
end;
finally
bitmap.free;
desktopcanvas.free;
end;
finally
releasedc(getdesktopwindow,dc);
end;
end;
243 - String Grid Colorido
unit
Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure StringGrid1DrawCell(Sender:
TObject; Col, Row: Longint;
Rect: TRect; State: TGridDrawState);
procedure FormClose(Sender: TObject; var
Action: TCloseAction);
procedure StringGrid1DblClick(Sender:
TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
procedure TForm1.Button1Click(Sender:
TObject);
var
C, R: Integer;
Value: Integer;
begin
{Encher o String Grid de valores
Inteiros e Ramdomicos}
Randomize;
for C := 1 to StringGrid1.ColCount-1 do
for R := 1 to StringGrid1.RowCount-1 do
begin
Value := Random(10) - 5;
StringGrid1.Cells[C,R] :=
IntToStr(Value);
StringGrid1.Objects[C,R] :=
Pointer(clBlack);
end;
end;

procedure
TForm1.StringGrid1DrawCell(Sender:
TObject; Col, Row: Longint;
Rect: TRect; State: TGridDrawState);
const
LM = 3; {each indiviual cell’s left
margin}
TM = 2; {each indiviual cell’s top
margin}
var
ptr: Pointer;
begin
{qualquer cor é armazenada no ponteiro
do objeto}
ptr := StringGrid1.Objects[Col, Row];
StringGrid1.Canvas.Font.Color :=
LongInt(ptr);
{deixe as filas fixas e as colunas fixas
em prata }
if gdFixed in State then
StringGrid1.Canvas.Brush.Color :=
clSilver;
{puxemos o destaque do modo seguinte
quando a celula for selecionada }
if gdSelected in State then
begin
StringGrid1.Canvas.Brush.Color :=
clHighlight;
StringGrid1.Canvas.Font.Color :=
clHighlightText;
end;
{finalmente, faça o desenho de celula
atual }
StringGrid1.Canvas.TextRect(Rect,
Rect.Left + LM, Rect.Top + TM,
StringGrid1.Cells[col,row]);
end;

procedure TForm1.FormClose(Sender:
TObject; var Action: TCloseAction);
var
C, R: Integer;
begin
for C := 1 to StringGrid1.ColCount-1 do
for R := 1 to StringGrid1.RowCount-1 do
begin
{faça os objetos de todos o grid apontar
a nada }
StringGrid1.Objects[C, R] := nil;
{se nós tivéssemos armazenado objetos no
grid, nós deveríamos os livrar assim:
StringGrid1.Objects[C, R].Free;}
end;
end;
procedure
TForm1.StringGrid1DblClick(Sender:
TObject);
begin
With StringGrid1 do
Case Random(4) of
0 : Objects[Col,Row] := Pointer(clRed);
1 : Objects[Col,Row] := Pointer(clLime);
2 : Objects[Col,Row] := Pointer(clBlue);
3 : Objects[Col,Row] :=
Pointer(clFuchsia);
end;
end;

end.
244 - Utilizar o MessageBox com
parâmetros
var
Button: Integer;
Mensagem1 : Array[0..79] of Char;
Mensagem2 : Array[0..79] of Char;
begin
StrPCopy(Mensagem1, Edit1.Text + ‘ ‘ +
Edit2.Text);
StrPCopy(Mensagem2, Edit3.Text + ‘ ‘ +
Edit4.Text);
Button := Application.MessageBox
(Mensagem2,Mensagem1, MB_YESNOCANCEL+
mb_DefButton1+MB_ICONQUESTION);
end;
245 - Cor em DbGrid
Coloque a propriedade defaultdrawdata do dbgrid em
FALSE
No evento onDrawColumnCell do seu grid coloque o
seguinte:

procedure
TForm1.DBGrid1DrawColumnCell(Sender:
TObject;
const Rect: TRect; DataCol: Integer;
Column: TColumn;
State: TGridDrawState);
begin
If table1PRAZO.Value > DATE then //
condição
Dbgrid1.Canvas.Font.Color:= clFuchsia; //
coloque aqui a cor desejada
Dbgrid1.DefaultDrawDataCell(Rect,
dbgrid1.columns[datacol].field, State);
end;
246 - Todos os programas que
estão em execução
01) Programas Abertos
Function EnumWindowsProc (Wnd: HWND; lb:
TListbox): BOOL; stdcall;
var caption: Array [0..128] of Char;
begin
Result := True;
if IsWindowVisible(Wnd) and
((GetWindowLong(Wnd, GWL_HWNDPARENT) = 0)
or
(HWND(GetWindowLong(Wnd, GWL_HWNDPARENT))
= GetDesktopWindow))and
((GetWindowLong(Wnd, GWL_EXSTYLE) and
WS_EX_TOOLWINDOW) = 0)
then
begin
SendMessage( Wnd, WM_GETTEXT,
Sizeof(caption),integer(@caption));
lb.Items.AddObject( caption,TObject( Wnd
));
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
EnumWindows( @EnumWindowsProc, integer(
listbox1 ));
end;
02) Programas Abertos (incluíndo os
ocultos)
Para listar (pegar) todas janelas abertas, deve-se usar a
funcao da API EnumWindows, que usa uma funcao
Callback, com dois parametros, um Handle para a janela
e um ponteiro. Voce pode usá-la com um códi-go
semelhante a este (Este lista as janelas abertas, mesmo
invisí-veis, em uma listbox):

function EnumWindowsProc(Wnd : HWnd;Form :


TForm1) : Boolean; Export; {$ifdef Win32}
StdCall; {$endif}
var
Buffer : Array[0..99] of char;
begin
GetWindowText(Wnd,Buffer,100);
if StrLen(Buffer) <> 0 then
Form.ListBox1.Items.Add(StrPas(Buffer));
Result := True;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
EnumWindows(@EnumWindowsProc,LongInt(Self)
);
end;
247 - Evitando o erro de Key
Violation
A dica abaixo apresenta o código para evitar que o
programa pare e envie uma mensagem padrão de erro
por Key Violation (Chave Primária).
Para isto, o código deve ser inserido no evento
OnPostError do componente de banco de dados (Table
ou Query).
Toda vez que ocorrer um erro de gravação no banco de
dados este evento será executado, sendo que na
variável de parâmetro “E” deste procedimento é
armazenado a mensagem que será apresentada na tela.
No caso de Key Violation a mensagem é exatamente
esta: “Key violation.”.
Para realizar um tratamento deste erro, testa-se se a
mensagem ocorrida é “Key violation.’, se for verdadeiro
o processo de gravação é abortado (Action := daAbort).
Código Completo:
Procedure TForm1.Table1PostError(DataSet:
TDataSet; E: EDatabaseError;var Action:
TDataAction);
Var
ErroMens :String;
begin
ErroMens := E.Message;
if ErroMens = ‘Key violation.’ then begin
ShowMessage(‘Chave Primária Inválida !’);
action := daAbort;
end;
end;
248 - Conferindo se o processador
da máquina é 386, 486 ou Pentium
Comentário :
A função abaixo implementa uma rotina que através da
função GetSystemInfo retorna se o processador
instalado na sua máquina é um 386, 486 ou Pentium.
Se o seu processador não for nenhum destes
apontados, a função retorna que seu processador é
desconhecido.
Obs: Para ver o resultado desta rotina, ponha um
componente Button no formulário, dê um duplo clique no
mesmo e insira o código descrito abaixo da função.
Código Completo:
function Info: String;var SysInfo:
TSystemInfo;
begin
GetSystemInfo(SysInfo);
case SysInfo.dwProcessorType of
386 : result := ‘Processador 80386’;
486 : result := ‘Processador 80486’;
586 : result := ‘Processador Pentium’;
else
result := Format(‘Processado desconhecido
(%d)’, [SysInfo.dwProcessorType]);
end;
end;
Como Usar:
procedure TForm1.Button1Click(Sender:
TObject);
begin
Showmessage(‘Nesta máquina temos :’+
Info);
end;
249 - Apagar um subdiretório
Inclua a unit SHELLAPI na clausula uses do seu form.

procedure DeleteDir( hHandle : THandle;


Const sPath : String );
var
OpStruc: TSHFileOpStruct;
FromBuffer, ToBuffer: Array[0..128] of
Char;
begin
fillChar( OpStruc, Sizeof(OpStruc), 0 );
FillChar( FromBuffer, Sizeof(FromBuffer),
0 );
FillChar( ToBuffer, Sizeof(ToBuffer), 0 );
StrPCopy( FromBuffer, sPath);
With OpStruc Do
Begin
Wnd:= hHandle;
wFunc:=FO_DELETE;
pFrom:= @FromBuffer;
pTo:= @ToBuffer;
fFlags:= FOF_NOCONFIRMATION;
fAnyOperationsAborted:=False;
hNameMappings:=nil;
//lpszProgressTitle:=nil;
End;
ShFileOperation(OpStruc);
end;

Utilize a função assim:

procedure TForm1.Button1Click(Sender:
TObject);
begin
DeleteDir( Self.Handle,‘C:\TESTE’);
end;
250 - Abrir arquivos com aplicativo
associado
Inclua a unit SHELLAPI na clausula uses do seu form.

procedure TForm1.ExecFile(F: String);


var
r: String;
begin
case ShellExecute(Handle, nil, PChar(F),
nil, nil, SW_SHOWNORMAL) of
ERROR_FILE_NOT_FOUND: r := ‘The specified
file was not found.’;
ERROR_PATH_NOT_FOUND: r := ‘The specified
path was not found.’;
ERROR_BAD_FORMAT: r := ‘The .EXE file is
invalid (non-Win32 .EXE or error in .EXE
image).’;
SE_ERR_ACCESSDENIED: r := ‘Windows 95
only: The operating system denied access
to the specified file.’;
SE_ERR_ASSOCINCOMPLETE: r := ‘The filename
association is incomplete or invalid.’;
SE_ERR_DDEBUSY: r := ‘The DDE transaction
could not be completed because other DDE
transactions were being processed.’;
SE_ERR_DDEFAIL: r := ‘The DDE transaction
failed.’;
SE_ERR_DDETIMEOUT: r := ‘The DDE
transaction could not be completed because
the request timed out.’;
SE_ERR_DLLNOTFOUND: r := ‘Windows 95 only:
The specified dynamic-link library was not
found.’;
SE_ERR_NOASSOC: r := ‘There is no
application associated with the given
filename extension.’;
SE_ERR_OOM: r := ‘Windows 95 only: There
was not enough memory to complete the
operation.’;
SE_ERR_SHARE: r := ‘A sharing violation
occurred.’;
else
Exit;
end;
ShowMessage(r);
end;

Utilize a função assim:

procedure TForm1.Button1Click(Sender:
TObject);
begin
ExecFile(‘c:\windows\ladrilhos.bmp’);
end;
251 - Inserindo uma Imagem no
Formulário
A dica abaixo apresenta o código para implementação
da função para inserir uma imagem no fundo do
formulário.
A função permite que se especifique as coordenadas da
imagem e qual o arquivo que contém a imagem.
Através do componente TBitMap é possível criar uma
figura dinamicamente e especificar qual será a imagem,
através do método LoadFromFile.
Para desenhar a imagem usa-se o componente
Tcanvas, através do método Draw, que desenha um
gráfico nas coordenadas especificadas.
Código Completo:
declara após o type junto aos outros procedimentos!
Procedure
Desenha(figura:String;H,V:Integer);

Procedure
TForm1.Desenha(figura:String;H,V:Integer);
Var
Imagem :TBitMap;
begin
Imagem := TBitMap.Create;
Try
Imagem.LoadFromFile(Figura);
Canvas.Draw(H,V,Imagem);
Except
ShowMessage(‘ Arquivo não foi localizado
!’);
end;
end;
ExemploQuando o botão for clicado, uma imagem será
inserida no formulário, nas coordenadas (10,20);
procedure TForm1.Button1Click(Sender:
TObject);
begin
Desenha(‘c:\windows\bolhas.bmp’,10,20);
end;
252 - Número de cores suportadas
pelo seu Monitor
A dica abaixo apresenta o código para implementação
de uma função que retorne o número de cores
suportadas pelo monitor.
A função se baseia na utilização de uma API do
Windows, chamada GETDC.
A função GETDC deve ser seguida sempre da função
ReleaseDC , a fim de restaurar as características da
propriedade selecionada.
Através da função GETDC é possível definir quais as
características de contexto do monitor que desejamos
manipular, no caso abaixo, define-se a característica de
resolução.( GETDC(0) ).
Código Completo:
Function QdeCores : integer;var h : HDC;
begin
Result := 0; try h := GetDC( 0 );
Result :=1 shl ( GetDeviceCaps( h, PLANES
) * GetDeviceCaps( h, BITSPIXEL ));
finally
ReleaseDC( 0, h );
end;
end;
253 - Verificando se uma
determinada fonte esta instalada
A função abaixo implementa uma rotina para testar se
determinada fonte esta instalada no windows.
Para evitar que a fonte a ser testada seja escrita com
espaços em branco indevidos, usa-se a função Trim
para retirar os espaços em branco.
Código Completo:
Function
FonteExiste(Fonte:STring):Boolean;
begin
with Screen.Fonts do
Result := IndexOf(Trim(Fonte)) > 0;
end;
Exemplo:
Procedure
TForm1.Button1Click(Sender:Tobject);
begin
If FonteExiste(‘Times New Roman’) then
ShowMessage(‘ Fonte já existe !’) Else
ShowMessage(‘ Fonte Inexistente !’);
end;
254 - Listando os campos da tabela
num Memo
A implementação da função abaixo permite inserir os
campos de uma tabela num componente TMemo.
Para que a função funcione é necessário que as units
StdCtrls e DbTables tenham sido declaradas.
Os campos que serão listados, são aqueles que foram
declarados através da operação de duplo clique no
componente Table e opção ADD Fields.
Código Completo:
Procedure ListaCampos(TB:Ttable;M:Tmemo);
Begin
M.Lines.Assign(TB.ListField);
End;
Exemplo:
Procedure
TForm1.Button1Click(Sender:TObject);
Begin
ListaCampos(Table1,Memo1);
end;
255 - Imprimindo o conteúdo de um
Memo
// Adicione a Unit Printers na cláusula do
seu Form
uses Printers;

O código abaixo implementa uma função para imprimir o


conteúdo de um componente Memo.
Para que seja feita a impressão, o código cria um
arquivo texto de impressão (MemoFile :TextFile), com o
objetivo de armazenar as linhas existentes no memo.
Neste arquivo são armazenadas todas as linhas
existentes no memo.
O código completo:
Procedure
TForm1.Memo_Print(Conteudo:TStrings);
Var
MemoFile :TextFile;
P :Integer;
Begin AssignPrn(MemoFile);
Rewrite(MemoFile);
For P := 0 to Conteudo.Count-1 do
Writeln(MemoFile,Conteudo.Strings[P]);
CloseFile(MemoFile);
end;
Exemplo :
Procedure
Tform1.Button1Click(Sender:TObject);
begin
MemoPrint(Memo1.Lines);
end;
2ª Dica
Imprimindo o conteúdo de um
TMemo ou um TListBox?
A procedure abaixo recebe um objeto do tipo TStrings
como paramêtro e imprime o seu conteúdo na
impressora padrão. Pelo fato de ela usar uma TStrings,
a procedure irá trabalhar com qualquer tipo de
componente que contenha uma propriedade do tipo
TStrings, como um TDBMemo ou um TListBox.

// Adicione a Unit Printers na cláusula do


seu Form
uses Printers;

procedure ImpStrings(Strings: TStrings);


var Prn: TextFile;
i: Word;
begin
AssignPrn(Prn);
try
Rewrite(Prn);
try
for i := 0 to Strings.Count -1 do
writeln(Prn, Strings.Strings[i]);
finally
CloseFile(Prn);
end;
except
on EInOutError do
MessageDlg(‘Erro na impressão do texto.’
mtError, [mbOK], 0);
end;
end;
3ª Dica
Para imprimir o conteúdo de um TMemo ou um
TListbox, use o seguinte código:
PrintStrings(Memo1.Lines);
ou
PrintStrings(Listbox1.Items);
256 - Verificando o tipo de Drive
Verificando o tipo de Drive
O código abaixo implementa uma função para testar
qual o tipo de drive da unidade especificada.
Para isto, é necessário utilizar uma função de API do
windows chamada GetTypeDrive.
Esta função retorna valores default que indicam o tipo
de drive selecionado.
(Drive_Removable,Drive_Fixed,Drive_Remote,Drive_Cd
Rom,Drive_RamDisk)
Código Completo:
Function Tipo_Drive(Drive:Char):String;
Const
Drive_Removable = 2;
Drive_Fixed = 3;
Drive_Remote = 4;
Drive_CdRom = 5;
Drive_RamDisk = 6;
var
Tipo: byte;
begin
Tipo := GetDriveType(PChar(Drive + ‘:'));
Case Tipo of
0: Result := ‘Indeterminado’;
1: Result := ‘Inexistente ‘;
2: Result := ‘Removível’;
3: Result := ‘Fixo’;
4: Result := ‘Rede’;
5: Result := ‘CD-ROM’;
6: Result := ‘RAM Disk’;
else Result := ‘ Erro’;
End;
end;
257 - Como tocar sons no auto-
falante interno do PC
Unit Sounds;

interface

uses SysUtils, Windows, Classes, StdCtrls;

procedure Sound(Freq : Word);

implementation

procedure SetPort(address, Value:Word);


var
bValue: byte;
begin
bValue := trunc(Value and 255);
asm
mov dx, address
mov al, bValue
out dx, al
end;
end;

function GetPort(address:word):word;
var
bValue: byte;
begin
asm
mov dx, address
in al, dx
mov bValue, al
end;
GetPort := bValue;
end;
procedure Sound(Freq : Word);
var
B : Byte;
Value: Word;
begin
if Freq > 18 then
begin
Freq := Word(1193181 div LongInt(Freq));
B := Byte(GetPort($61));
if (B and 3) = 0 then
begin
SetPort($61, Word(B or 3));
SetPort($43, $B6);
end;
SetPort($42, Freq);
SetPort($42, Freq shr 8);
end
else
begin
Value := GetPort($61) and $FC;
SetPort($61, Value);
end;
end;
end.
258 - Apagando todos os registros
da tabela
Para apagar os registros de uma tabela utiliza-se a
função delete.
Através de um comando de repetição (While) é possível
excluir todos os registros da tabela, usando como flag a
quantidade de registros existentes na tabela
(RecordCount > 0).
Código Completo:
Procedure ApagarTodosReg(Origem:TDataSet);
Begin
With Origem do
While RecordCount > 0 do
Delete;
End;
Como Usar:
ApagarTodosReg(Table1);
ou ApagarTodosReg(Query1);
259 - Como desenhar um Bitmap
num form
var
Form1: TForm1;
Bmp: TBitmap;
implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender:
TObject);
begin
Bmp:=TBitmap.Create;

Bmp.Loadfromfile(‘c:\windows\nuvens.bmp’);
end;

procedure TForm1.TForm1.FormPaint(Sender:
TObject);
begin
Canvas.Draw(50,50,Bmp);
end;

procedure TForm1.FormClose(Sender:
TObject; var Action: TCloseAction);
begin
Bmp.Free;
end;
260 - Evitando caracteres com
acento
A função abaixo pega um string informada como
parâmetro e retira todas as letras acentuadas
substituindo-as por letras correspondentes sem acento.
function AnsiToAscii ( str: String ):
String;
var
i: Integer;
begin
for i := 1 to Length ( str ) do
case str[i] of
‘á’: str[i] := ‘a’;
‘é’: str[i] := ‘e’;
‘í’: str[i] := ‘i’;
‘ó’: str[i] := ‘o’;
‘ú’: str[i] := ‘u’;
‘à’: str[i] := ‘a’;
‘è’: str[i] := ‘e’;
‘ì’: str[i] := ‘i’;
‘ò’: str[i] := ‘o’;
‘ù’: str[i] := ‘u’;
‘â’: str[i] := ‘a’;
‘ê’: str[i] := ‘e’;
‘î’: str[i] := ‘i’;
‘ô’: str[i] := ‘o’;
‘û’: str[i] := ‘u’;
‘ä’: str[i] := ‘a’;
‘ë’: str[i] := ‘e’;
‘ï’: str[i] := ‘i’;
‘ö’: str[i] := ‘o’;
‘ü’: str[i] := ‘u’;
‘ã’: str[i] := ‘a’;
‘õ’: str[i] := ‘o’;
‘ñ’: str[i] := ‘n’;
‘ç’: str[i] := ‘c’;
‘Á’: str[i] := ‘A’;
‘É’: str[i] := ‘E’;
‘Í’: str[i] := ‘I’;
‘Ó’: str[i] := ‘O’;
‘Ú’: str[i] := ‘U’;
‘À’: str[i] := ‘A’;
‘È’: str[i] := ‘E’;
‘Ì’: str[i] := ‘I’;
‘Ò’: str[i] := ‘O’;
‘Ù’: str[i] := ‘U’;
‘Â’: str[i] := ‘A’;
‘Ê’: str[i] := ‘E’;
‘Î’: str[i] := ‘I’;
‘Ô’: str[i] := ‘O’;
‘Û’: str[i] := ‘U’;
‘Ä’: str[i] := ‘A’;
‘Ë’: str[i] := ‘E’;
‘Ï’: str[i] := ‘I’;
‘Ö’: str[i] := ‘O’;
‘Ü’: str[i] := ‘U’;
‘Ã’: str[i] := ‘A’;
‘Õ’: str[i] := ‘O’;
‘Ñ’: str[i] := ‘N’;
‘Ç’: str[i] := ‘C’;
end;
Result := str;
end;
261 - Executando uma chamada
para a Conexão Dial-Up
Executando uma chamada para a Conexão Dial-Up
Insira um objeto do tipo Button definindo sua
propriedade name para Button1.
implementation
uses Registry;
{$R *.DFM}
procedure TForm1.Button1Click(Sender:
TObject);
Var
Conexao, Executa, Conecta : string;
Dialup : Pchar;
reg : TRegIniFile;
begin
reg :=
TRegIniFile.create(‘RemoteAccess');
Conexao :=
reg.ReadString(”,‘Default’,”);
reg.free;
Executa:=‘rundll32.exe rnaui.dll,RnaDial
‘; {executavel e biblioteca do windows}
Conecta:=Executa+Conexao; {concatena
comando e nome da conexão}
Dialup:=Pchar(Conecta); {transforma
string em caracter para ser aceita pela
função}
winexec(Dialup,sw_show);
end;
262 - Capturar informações do
ambiente DOS
No exemplo abaixo deve ser incluído no objeto TForm
um objeto do tipo Button, um objeto do tipo StringGrid e
um objeto do tipo ListBox.

type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
StringGrid1: TStringGrid;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}

// Evento OnClick do objeto Button


procedure TForm1.Button1Click(Sender:
TObject);
var
Env : PChar;
i : Integer;
S : String;
PosEq : Integer;
begin
Env := GetEnvironmentStrings;
With ListBox1,StringGrid1 do
begin
While Env^ <> #0 do
begin
Items.Add(StrPas(Env));
Inc(Env,StrLen(Env)+1);
end;
RowCount := Items.Count;
for i := 0 to Pred(Items.Count) do
begin
PosEq := Pos(=,Items[i]);
Cells[0,i] := Copy(Items[i],1,PosEq-1);
Cells[1,i] :=
Copy(Items[i],PosEq+1,Length(Items[i]));
end;
end;
end;
263 - Capturar a data da BIOS (
Basic Input Output System ) do
computador
Insira um objeto do tipo Button com a propriedade name
definica como Button1 e um objeto do tipo Label com a
propriedade definida como Label1.
procedure TForm1.Button1Click(Sender:
TObject);
begin
Label1.Caption := ‘Data da Bios:
‘+String(PChar(Ptr($FFFF5)));
end;
264 - Manda o Form para frente
begin
SetWindowPos(Form1.handle, HWND_TOPMOST,
Form1.Left, Form1.Top,Form1.Width,
Form1.Height, 0); // HWND_NOTOPMOST normal
end;

++Facil
SetForegroundWindow(handle);
265 - Form com um furo da pra ve
atraz
var
Region, Region2 : hrgn;
begin
Form1.FormStyle:= fsStayOnTop;
Region :=
CreaterectRgn(0,0,width,height);
Region2 :=
CreateEllipticRgn(30,30,100,100);
CombineRgn(region, region, region2,
RGN_DIFF);
SetWindowRgn(handle, region, true);
end;
266 - Abrir as configurações do
Vídeo do Painel de Controle
WinExec(‘RunDLL32.exe
Shell32.DLL,Control_RunDLL Desk.cpl’,
SW_Show)
Os outros itens do Painel de Controle podem ser
acessados mudando-se o nome do arquivo .cpl,
exemplo:
- Modem.cpl
- Netcpl.cpl
267 - Simular o pressionamento de
uma combinação de teclas
ex: Ctrl+F2
Inclua na seção uses: Windows
{ Mantém pressionada CTRL }
keybd_event(VK_CONTROL, 0,
KEYEVENTF_EXTENDEDKEY or 0, 0);

{ Pressiona F2 }
keybd_event(VK_F2, 0, 0, 0);

{ Libera (solta) CTRL }


keybd_event(VK_CONTROL, $45,
KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,
0);
Observações
Neste exemplo pressionamos Ctrl+F2. Não se esqueça
das teclas que precisam manter pressionadas: Ctrl, Alt,
Shift.
268 - Alterar o ícone do botão
iniciar do Windows
Variáveis globais do form:
var
Form1: TForm1;
Iniciar : hWnd;
OldBitmap : THandle;
NewImage : TPicture;

No Oncreate do Form:

procedure TForm1.FormCreate(Sender:
TObject);
begin
NewImage:=TPicture.create;
NewImage.LoadFromFile(‘C:\Delphi3\Images\D
EFAULT\OutOpen.BMP’);
Iniciar :=
FindWindowEx(FindWindow(‘Shell_TrayWnd’,ni
l),0,‘Button’,nil);
OldBitmap:=SendMessage(Iniciar,BM_SetImage
,0,NewImage.Bitmap.Handle);
end;

No OnDestroy
procedure TForm1.FormDestroy(Sender:
TObject);
begin
SendMessage(Iniciar,BM_SetImage,0,OldBitma
p);
NewImage.Free;
end;
269 - Inverter os botões do mouse
Dica :
{ Para inverter: }
SwapMouseButton(true);

{ Para voltar ao normal: }


SwapMouseButton(false);
270 - Clicar com o mouse
{O exemplo abaixo simula o pressionamento
da tecla do botão esquerdo do mouse em uma
determinada posição da tela. No exemplo
serão utilizados dois botões (Button1 e
Button2), ao clicar no Button2 será
executado o onClick do Button1 como se o
mouse tivesse clicado sobre ele }

procedure TForm1.Button1Click(Sender:
TObject);
begin
ShowMessage(‘Button 1 clicked’);
end;

procedure TForm1.Button2Click(Sender:
TObject);
var
Pt : TPoint;
begin
Application.ProcessMessages;
{Obtém o point no centro do Button1}
Pt.x := Button1.Left + (Button1.Width div
2);
Pt.y := Button1.Top + (Button1.Height div
2);
{Converte Pt para as coordenadas da tela }
Pt := ClientToScreen(Pt);
Pt.x := Round(Pt.x * (65535 /
Screen.Width));
Pt.y := Round(Pt.y * (65535 /
Screen.Height));
{Move o mouse}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_MOVE, Pt.x, Pt.y, 0, 0);
{Simula o pressionamento do botão esquerdo
do mouse}
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_LEFTDOWN, Pt.x, Pt.y, 0, 0);
{ Simula soltando o botão esquerdo do
mouse }
Mouse_Event(MOUSEEVENTF_ABSOLUTE or
MOUSEEVENTF_LEFTUP, Pt.x, Pt.y, 0, 0);
end;
271 - Executar algo antes de
minimizar
Primero, capturamos a menssagem, adicionando esta
linha na declaração private do form:
type
TForm1 = class(TForm)
private
{Esta linha}
procedure WMSysCommand(var Msg:
TWMSysCommand); message WM_SYSCOMMAND;
end;
Na implementation, colocamos a procedure:
procedure TForm1.WMSysCommand(var Msg:
TWMSysCommand);
begin
if (Msg.CmdType = SC_MINIMIZE) or
(Msg.CmdType = SC_MAXIMIZE) then
MessageBeep(0);
DefaultHandler(Msg);
end;
272 - Esconder icones do desktop
ShowWindow(FindWindow(nil,‘Program
Manager’),SW_HIDE);
Para mostrar :
ShowWindow(FindWindow(nil,‘Program
Manager’),SW_SHOW);
273 - Senha em tabelas
Senha em tabelas
Colocar componete session (Guia dataset)
sessio1.addpassword(‘senha’)
table1.active:= true
OBS: no databasedekstop programar a opcao password
security
274 - Rodar videos em um panel
begin
if opendialog1.execute then
begin
mediaplayer1.filename:=
opendialog1.filename;
mediaplayer1.open;
mediaplayer1.Perform
(wm_lbuttondown,0,$00090009);
mediaplayer1.Perform
(wm_lbuttonup,0,$00090009);
end;
end;
275 - Sql por campo edit
pesquisando pelo nome
query1.active := false;
query1.sql.clear;
query1.sql.add(‘select * from teste where
nome = ”’ + edit1.Text + ‘”’);
query1.active:= true;
276 - Sql relacionada com a
primeira letra
query1.active := false;
query1.sql.clear;
query1.sql.add(‘select * from estrucpr
where upper(portugues)like “LETRA%” ‘);
query1.active:= true;
PRIMEIRA LETRA “LETRA%”
ULTIMA LETRA “%LETRA”
QUE CONTENHA A LETRA “%LETRA%”
277 - Fazer um campo memo ocupar
2 páginas
EVENTO : OnStartPage DA QUICKRAP
if frmpesquisa.DBMEMOProtResp.CanFocus >
QRDBRichText1.CanFocus then
QRDBRichText1.AutoStretch:= true ;
278 - Procura com mais de um
Banco de Dados
edit1.text:= dbcombobox1.Text;
QueryPrinc.active := false;
QueryPrinc.sql.clear;
QueryPrinc.sql.add(‘select * from estrucpr
where portugues = ”’ + edit1.Text + ‘”’);
QueryPrinc.active:= true;

if DBcodEl.text=DBcodEl.text then
edit2.Text:= DBcodEl.Text;

QuerySin.active := false;
QuerySin.sql.clear;
QuerySin.sql.add(‘ select * from sinonimo
where sin_est_id = ”’ + edit2.text + ‘
”’);
QuerySin.active:= true;

if DBcodEl.text=DBcodEl.text then
edit3.Text:= DBcodEl.Text;

QueryPropFis.active := false;
QueryPropFis.sql.clear;
QueryPropFis.sql.add(‘select * from
FIQU_PRO where fiqu_id = ”’ + edit3.Text +
‘”’);
QueryPropFis.active:= true;
279 - Senhas Aleatórias

procedure TForm1.Button1Click(Sender:
TObject);
var
i:integer;
const
str=‘1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ’
;
max=6;
begin
Edit1.Text:=”;
for i:=1 to max do
Edit1.Text:=Edit1.Text+str[random(length(s
tr))+1];
end;
end.
280 - Configurações internacionais
Normalmente o Delphi pega os formatos de data/hora,
moeda e formato numérico da Configuração
Internacional do Painel de Controle. Isto pode levar a
erros quando avaliando datas, numeros ou listas. Para
evitar estes erros, voce pode mudar as constantes
definidas no Delphi, como DecimalSeparator,
ShortDateFormat e outros desta maneira:
DecimalSeparator := ‘.’;
ShortDateFormat := ‘mm/dd/yy’;
Isto terá precedência sobre a configuração padrão. Para
uma lista completa das variáveis, procure em Currency
Formatting Variables na ajuda do Delphi.,
281 - Desenhando com tipos
diferentes de linhas
O Windows permite desenhar linhas onde cada pixel é
outro tipo de primitiva ou desenho com a função
LineDDA. Ela precisa de uma função “callback”, que
será chamada quando um pixel deve ser desenhado. Ali
podem ser postas as rotinas de desenho. A rotina a
seguir desenha um retângulo a cada 4 pixels:
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
public
DrawNow : Integer;
end;

var
Form1: TForm1;

procedure DrawPoint(x,y : Integer;lpData :


LParam); stdcall;

implementation

{$R *.DFM}

procedure DrawPoint(x,y : Integer;lpData :


LParam);
begin
with TObject(lpData) as TForm1 do begin
if DrawNow mod 4 = 0 then
Canvas.Rectangle(x-2,y-2,x+3,y+3);
Inc(DrawNow);
end;
end;
procedure TForm1.FormCreate(Sender:
TObject);
begin
DrawNow := 0;
end;

procedure TForm1.FormPaint(Sender:
TObject);
begin
LineDDA(0,0,Width,Height,@DrawPoint,Intege
r(Self));
end;
end.
282 - Desabilitando o Splash
Screen do Report Smith
1 - Localize o arquivo RS_RUN.INI (no diretório do
Windows);
2 - Na seção [ReportSmith] inclua a linha seguinte:
ShowAboutBox=0
3 - Na seção [RS_RunTime] inclua a linha seguinte:
ShowAboutBox=0
4 - Não se esqueça de distribuir com o seu aplicativo o
referido arquivo INI.
283 - Verificar se o registro está
travado
Inclua a unit DBITYPES na clausula uses do seu form.
function TForm1.IsRecordLocked(Table: TTable;
ByAnyone: boolean): Boolean;
var
Locked: BOOL;
hCur: hDBICur;
rslt: DBIResult;
begin
Table.UpdateCursorPos;
// Is the record locked by the current
session…
Check(DbiIsRecordLocked(Table.Handle,
Locked));
Result := Locked;
// If the current session does not have a
lock and the ByAnyone varable is
// set to check all sessions, continue
check…
if (Result = False) and (ByAnyone = True)
then
begin
// Get a new cursor to the same record…
Check(DbiCloneCursor(Table.Handle, False,
False, hCur));
try
// Try and get the record with a write
lock…
rslt := DbiGetRecord(hCur, dbiWRITELOCK,
nil, nil);
if rslt <> DBIERR_NONE then
begin
// if an error occured and it is a lock
error, return true…
if HiByte(rslt) = ERRCAT_LOCKCONFLICT then
Result := True
else
// If some other error happened, throw an
exception…
Check(rslt);
end
else
// Release the lock in this session if the
function was successful…
Check(DbiRelRecordLock(hCur, False));
finally
// Close the cloned cursor…
Check(DbiCloseCursor(hCur));
end;
end;
end;

Utilize a função assim:

procedure TForm1.Button1Click(Sender:
TObject);
begin
If IsRecordLocked(Table1,True) then
Showmessage(‘Registro Travado!’);
end;
284 - Cursor customizado
Criar um arquivo de recurso com o cursor (vamos
chamá-lo de teste.res)
Vamos chamar o recurso de CUR_1
Coloque {$R teste.res} na seção implementation

procedure InsereCursor(Num : Smallint);


begin
Screen.Cursors[Num]:=
LoadCursor(hInstance, PChar(‘CUR_1’));
Screen.Cursor := Num;
end;
285 - Dica impressora matricial
Primeiro utilize somente fontes courier, tamanho 10, no
report especifique que a unidade inves de ser inches
sera caracter e adicione uma impressora fabricantes
generico somente texto.
Na hora de imprimir selecione esta impressora e pronto !
Isso deve resolver seu problema.
286 - Retorna a cor de um
componente no formato string
procedure TForm1.BitBtn1Click(Sender:
TObject);
begin
// Retorna a cor do form
Caption := ColorToString(Form1.Color);
// Muda a cor do form
Form1.Color := StringToColor(‘clBlack’);
end;
287 - Retornar o nome do usuário
que esta com a tabela Exclusiva
procedure TForm1.BitBtn1Click(Sender:
TObject);
begin
try
Table1.Close;
Table1.Exclusive := True;
Table1.Open;
except on E:EDBEngineError do
if E.Errors[0].ErrorCode = 10243 then
begin
ShowMessage(‘Mensagem de
erro’+E.Errors[0].Message );
ShowMessage( ‘Arquivo com
erro’+E.Errors[1].Message );
ShowMessage( ‘Nome do usuario’+
E.Errors[2].Message );
end
end;
end;
288 - Mostrar as fontes TrueType
Instaladas no Windows
Para testar o exemplo abaixo inclua em seu formulário
um componente ListBox, um componente Label e um
componente
ListBox.
// Evento OnClick do componente LisBox
procedure TForm1.ListBox1Click(Sender:
TObject);
begin
{ Atribui a propriedade Caption do
componente Label o nome da fonte
selecionada apenas para visualização}
Label1.Caption :=
ListBox1.Items[ListBox1.ItemIndex];
{ Atribui ao componente Label1 na
propriedade Name da propriedade Font o
nome da fonte selecionada para que o
componente Label para utilizar a mesma
fonte }
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;
289 - Como criar um contador de
página para um relatório
desenvolvido no QuickReport 2.0

var
Form1: TForm1;
i : integer;
implementation
{$R *.DFM}

procedure TForm1.Button1Click(Sender:
TObject);
begin
i := 0 ;
QuickRep1.Prepare;
QrLabel2.Caption := IntToStr(i);
QuickRep1.Preview;
end;

procedure
TForm1.QuickRep1StartPage(Sender:
TQuickRep);
begin
i := i + 1;
Form2.Label1.caption := IntToStr(i);
end;
290 - Como retornar a uma lista os
campos indexados de um tabela
procedure TForm1.Button1Click(Sender:
TObject);
var
i : integer;
begin
Table1.IndexDefs.Update;
ListBox1.Items.add
(‘******** Índice Primário ********’);
for i:=0 to Table1.IndexDefs.Count-1 do
begin
if Table1.IndexDefs.Items[i].Options =
[ixPrimary..ixUnique] then
ListBox1.Items.add(Table1.IndexDefs.Items[
I].Fields)
else
begin
ListBox1.Items.add(”);
ListBox1.Items.add
(‘**** Índice Secundário ****’);
Listbox1.Items.Add(Table1.IndexDefs.Items[
I].Name);
end;
end;
end;
291 - Como definir seu próprio
hotkey
Primeiro fixe a propriedade KeyPreview do Form para
TRUE
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word;
Shift: TShiftState);
begin
if (ssCtrl in Shift) and (chr(Key) in
[‘A’, ‘a’]) then
ShowMessage(‘Ctrl-A’);
end;
292 - Transformando ícone (*.ico)
em bitmap (*.bmp)

VAR
Pic : TPicture;
TI : TIcon;
BEGIN
TI := TIcon.Create;
TI.Handle := ExtractIcon(HInstance,
FileNameBuf, 0);
Pic := TPicture.Create;
Pic.Icon := TI;
Image1.Picture := Pic; {TImage}
BitBtn1.Glyph := TBitmap.Create;
WITH BitBtn1.Glyph DO
BEGIN
width := TI.Width;
Height := TI.Height;
Canvas.Draw(0, 0, Pic.Icon);
END;
END;
293 - Transferindo o conteúdo de
um memo para um memofield
Var
t: TTable;
Begin
t := TTable.create(self);
with t do
begin
DatabaseName := ‘MyAlias’; {personal
alias}
TableName := ‘MyTbl.db’;
open;
edit;
insert;
fieldByName(‘TheField’).assign(memo1.lines
); {This is it!}
post; {required!!!}
close;
end;
end;
294 - Mudar o foco do campo em
um Dbgrid
Modificando o foco de um DBGrid
DBGrid1.SelectedIndex:=2; { Vai para a 3a
coluna }
295 - Como tirar os espaços no
início e no final de uma string
Function Trim(J:String):String; Export;
Begin
While J[Length(J)]=#32 do Dec(J[0]);
If Length(J)>1 then
While (J[1]=’ ‘) do
Begin
Delete(J,1,1);
If Length(J)<=1 then J:=”;
end;
Result:=J;
end;
296 - Como colocar uma coluna do
DBGrid em maiuscula
procedure TForm1.DBGrid1KeyPress(Sender:
TObject; var Key: Char);
begin
if DBGrid1.SelectedField.FieldName=‘NOME’
THEN
Key := AnsiUpperCase(Key)[Length(Key)];
end;
297 - Simular Print Screen
Uma coisa que pode ser muito útil em suporte a
distância, ou até mesmo pra outros objetivos, é a
realização de um “print-scrren” coisa que muitas vezes
um usuário não dá conta de realizar e fica complicado,
de certa maneira, explicar por telefone. Por este motivo
criamos uma rotininha que simula a tecla PrintScreen. A
baixo a rotina de como realizar tal processo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
keybd_event(VK_PRINT, 0, 0, 0);
keybd_event(VK_PRINT, 0, KEYEVENT_KEYUP,
0);
end;

Obs: Tentei a dica sitada logo acima e não deu certo!!!


Procurei ajuda no Help do delphi e encontrei essa logo
abaixo e funcionaou (estou usando PENTIUM III 128
Ram, Win98 e Delphi 4)
Simular Print Screen 2
keybd_event(vk_snapshot,0, 0, 0); {Tela
Toda}
keybd_event(vk_snapshot,1, 0, 0); {Janela
Ativa}
298 - Resolvendo Problemas do
Print-Setup do QuickReport
{Quando executa o PrintSetup do Preview e você está
trabalhando com papel Personalizado, o QuickReport
perde a configuração do Papel Personalizado,
colocando o PaperSize de Custom para Letter. Para
resolver o problema guarde o valor da propriedade
PaperSize e do Length em variáveis e no evento
BeforePrint você atribui o valor da variável para o
QuickReport novamente, dessa forma resolve o
problema. Veja exemplo }

Uses
qrprntr

var
Form1: TForm1;
cPaperSize : TQRPaperSize;
nLength : Extended;

implementation
{$R *.DFM}

procedure TForm1.Button1Click(Sender:
TObject);
begin
cPapersize := QuickRep1.Page.PaperSize;
nLength := QuickRep1.Page.Length;
QuickRep1.Preview;
end;

procedure
TForm1.QuickRep1BeforePrint(Sender:
TQuickRep;
var PrintReport: Boolean);
begin
QuickRep1.Page.PaperSize := cPaperSize;
QuickRep1.Page.Length := nLength;
end;
299 - Caption do BitBtn com várias
linhas
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons;

type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
procedure TForm1.FormCreate(Sender:
TObject);

var
R : TRect;
N : Integer;
Buff : array[0..255] of Char;
begin
with BitBtn1 do
begin
Caption := ‘Várias linhas no caption de um
botão’;
Glyph.Canvas.Font := Self.Font;
Glyph.Width := Width - 6;
Glyph.Height := Height - 6;
R := Bounds(0, 0, Glyph.Width, 0);
StrPCopy(Buff, Caption);
Caption := ”;
DrawText(Glyph.Canvas.Handle,
Buff,StrLen(Buff),R,
DT_CENTER or DT_WORDBREAK or DT_CALCRECT);
OffsetRect(R,(Glyph.Width - R.Right) div
2,
(Glyph.Height - R.Bottom) div 2);
DrawText(Glyph.Canvas.Handle, Buff,
StrLen(Buff), R,
DT_CENTER or DT_WORDBREAK);
end;
end;

end.
300 - Alterar fonte do hint
Para testar este exemplo inclua no seu form alguns
componentes. Nestes componentes coloque
informações na propriedade Hint de cada componente e
altere a propriedade ShowHint para True.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure MyShowHint(var HintStr: string;
var CanShow: Boolean;
var HintInfo: THintInfo);
end;

var
Form1: TForm1;

implementation
{$R *.DFM}

// Função que irá alterar a fonte do Hint


procedure TForm1.MyShowHint(var HintStr:
string;
var CanShow: Boolean;
var HintInfo: THintInfo);
var i : integer;
begin
for i := 0 to Application.ComponentCount -
1 do
if Application.Components[i] is
THintWindow then
with
THintWindow(Application.Components[i]).Can
vas do
begin
Font.Name := ‘Arial’;
Font.Size := 18;
Font.Style := [fsBold];
HintInfo.HintColor := clWhite;
end;
end;

// Evento OnCreate do Form


procedure TForm1.FormCreate(Sender:
TObject);
begin
// Ativa a função que irá alterar o
formato do Hint
Application.OnShowHint := MyShowHint;
end;
301 - Ocultar/Mostrar o Relógio na
Barra de Tarefas
Ocultar
ShowWindow( FindWindowEx(FindWindowEx(
FindWindow(‘Shell_TrayWnd’, nil), HWND(0),
‘TrayNotifyWnd’, nil), HWND(0),
‘TrayClockWClass’, nil), Sw_Hide);
Mostrar
ShowWindow( FindWindowEx(FindWindowEx(
FindWindow(‘Shell_TrayWnd’, nil), HWND(0),
‘TrayNotifyWnd’, nil), HWND(0),
‘TrayClockWClass’, nil), Sw_Show);
302 - Caixa Mista
function CaixaMista (mNome: string):
string; var
tam,pos1,pos2 : integer ;
pal : string;
begin
tam := Length(mNome);
mNome := TrimRight(mNome) + ‘ ‘;
mNome := AnsiUpperCase(mNome);
while True do
begin
pos1:=POS( ‘ ‘ , mNome) ;
if pos1 = 0 then
break;
pal := Copy(mNome,1,pos1) ;
pos2 := pos(pal, ‘ DA - DAS - DE - DO -
DOS ‘);
If pos2 > 0 then
pal :=AnsiLowerCase (pal)
else
pal:=Copy(pal,1,1) +
AnsiLowerCase(Copy(pal,2,tam)) ;
result := result + pal ;
mNome := copy(mNome,pos1+1,tam)
end;
end;

Exemplo:
Coloque este comando no evento de saida de
foco de um edit
Edit1.Text :=CaixaMista(Edit1.Text) ;

DIGITANDO ASSIM
JOSÉ JORNANDO DE CARVALHO JÚNIOR
Ficará Assim
José Jornando de Carvalho Júnior
303 - Justificar Texto
function
Justifica(mCad:string;mMAx:integer):string
;
var
mPos,mPont,mTam,mNr,mCont:integer;
mStr:string;
begin
mTam:=Length(mCad);
if mTam>=mMax then
Result:=copy(mCad,1,mMax)
else
mStr:=”;
mCont:=0;
mPont:=1;
mNr:=mMax-mTam;
while mCont<mNr do
begin
mPos:=pos(mStr,copy(mCad,mPont,100));
if mPos=0 then
begin
mStr:=mStr+’ ‘;
mPont:=1;
continue;
end
else
begin
mCont:=mCont+1;
Insert(‘ ‘,mCad,mPos+mPont);
mPont:=mPont+mPos+length(mStr);
end;
Result:=mCad;
end;
end;

EX.:
Memo1.lines[i]:=justifica(memo1.lines[i]
{String},60 {Nº de caracteres possiveis da
linha});
304 - Código gerador de senha
procedure TForm1.Button1Click(Sender:
TObject);
var
i:integer;
const
str=‘1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ’
;
max=6;
begin
Edit1.Text:=”;
for i:=1 to max do
Edit1.Text:=Edit1.Text+str[random(length(s
tr))+1];
end;
305 - Espaço maior no RichEdit
SendMessage(RichEdit1.Handle,
EM_EXLIMITTEXT, 0, $FFFFFF);
a depender da suar versão do delphi use
SendMessage(RichEdit1.Handle,
EM_LIMITTEXT, 0, $FFFFFF);
306 - Como criar novas tabela a
partir de consulta SQL
Para criar tabelas permanentes do resultado de uma
query faça o seguinte:
Query1.Open
DBIMakePermanent(Query1.Handle, ‘Nome-
Da-Tabela.db’, True);
Query1.Close;
Utilize BDE na Clausula USES para utilizar a função
DBIMakePermanent
307 - Código sequencial automático
Você manda o caminho (Alias “C:\Windows”), nome da
tabela (tabela.db) e o campo primário (código por ex) e
ele autoincrementa, se quiser usar formatação é só
colocar.
Function AutoIncrementoManual(Const
pAlias:String; pTabela:String;
pCampo:String):Integer;
var
vQry : tQuery;
int : integer;
begin
vQry := tQuery.Create(Application);
with vQry do begin
DatabaseName := pAlias;
SQL.Add(‘Select Max(‘ + pCampo +’) as
Proximo’);
SQL.Add(‘From ‘+ pTabela);
Open;
int:= FieldByName(‘Proximo’).asInteger +
1;
Result := int;
free;
end; {with vQry}
end;
308 - Encriptar/Desencriptar
strings
Esta função permite encriptar e desencriptar strings. O
código de encriptação é bastante simples, por isso pode
ser melhorado, sendo este apenas um exemplo de como
fazê-lo em Delphi.
function EnDecryptString(StrValue :
String; Chave: Word) : String;
var
I: Integer;
OutValue : String;
begin
OutValue := ”;
for I := 1 to Length(StrValue) do
OutValue := OutValue +
char(Not(ord(StrValue[I])-Chave));
Result := OutValue;
end;
Exemplo de utilização:
Iniciar um novo projecto, copiar a função para uma unit,
colocar três TEdit (Edit1, Edit2, Edit3) e dois TButton
(Button1 e Button2) na form.
No evento OnClick do Button1 deve chamar a função,
em que os parâmetros de entrada são o texto do Edit1 e
uma chave de encriptação do tipo word.
procedure TForm1.Button1Click(Sender:
TObject);
begin
Edit2.text:=EnDecryptString(Edit1.text,
236);
end;
No evento OnClick do Button2 deve chamar a função
EnDecryptString, em que os parâmetros de entrada são
o texto encriptado do Edit2 a chave de encriptação
usada para encriptar a string.
procedure TForm1.Button2Click(Sender:
TObject);
begin
Edit3.text:=EnDecryptString(Edit2.text,
236);
end;
2ª Dica
Função para criptografar uma
String
A função Criptografia pode ser usada para criptografar a
senha acesso ao sistema. Ela é usada nos dois
sentidos, para criptografar e descriptografar, desde que
seja usada a mesma chave nas duas operações. “mStr”
é a String que vai ser criptografada e “mChave” é a
String que sera usada como base para fazer a
criptografia.
function Criptografia(mStr, mChave:
string): string;
var
i, TamanhoString, pos, PosLetra,
TamanhoChave: Integer;
begin
Result := mStr;
TamanhoString := Length(mStr);
TamanhoChave := Length(mChave);
for i := 1 to TamanhoString do
begin
pos := (i mod TamanhoChave);
if pos = 0 then
pos := TamanhoChave;
posLetra := ord(Result[i]) xor
ord(mChave[pos]);
if posLetra = 0 then
posLetra := ord(Result[i]);
Result[i] := chr(posLetra);
end;
end;
3ª Dica
Encripitando uma string
program Crypt;
uses WinCRT;
const
C1 = 52845;
C2 = 22719;
function Encrypt(const S: string; Key:
Word): string;
var
I: byte;
begin
Result[0] := S[0];
for I := 1 to Length(S) do
begin
Result[I] := char(byte(S[I]) xor (Key shr
8));
Key := (byte(Result[I]) + Key) * C1 + C2;
end;
end;
function Decrypt(const S: string; Key:
Word): string;
var
I: byte;
begin
Result[0] := S[0];
for I := 1 to Length(S) do
begin
Result[I] := char(byte(S[I]) xor (Key shr
8));
Key := (byte(S[I]) + Key) * C1 + C2;
end;
end;
var
S: string;
begin
Write(‘>’);
ReadLn(S);
S := Encrypt(S, 12345);
WriteLn(S);
S := Decrypt(S, 12345);
WriteLn(S);
end.
Encripitando uma string (2)
function Encrypt( Senha:String ): String;
Const
Chave : String = ‘Jesus’;
Var
x,y : Integer;
NovaSenha : String;
begin
for x := 1 to Length( Chave ) do
begin
NovaSenha := ”;
for y := 1 to Length( Senha ) do
NovaSenha := NovaSenha + chr(
(Ord(Chave[x]) xor Ord(Senha[y])));
Senha := NovaSenha;
end;
result := Senha;
end;
309 - Encriptar/Desencriptar
arquivos
Este procedimento permite encriptar e desencriptar
arquivos de qualquer tipo. O código de encriptação é
bastante simples, por isso pode ser melhorado, sendo
este apenas um exemplo de como fazê-lo em Delphi.
procedure EnDecryptFile(INFName, OutFName
: String; Chave : Word);
var
InMS, OutMS : TMemoryStream;
I : Integer;
C : byte;
begin
InMS := TMemoryStream.Create;
OutMS := TMemoryStream.Create;
try
InMS.LoadFromFile(INFName);
InMS.Position := 0;
for I := 0 to InMS.Size - 1 do
begin
InMS.Read(C, 1);
C := (C xor not(ord(chave shr I)));
OutMS.Write(C,1);
end;
OutMS.SaveToFile(OutFName);
finally
InMS.Free;
OutMS.Free;
end;
end;
Exemplo de utilização:
Iniciar um novo projecto, copiar o procedimento
EnDecryptFile para uma unit, colocar dois TButton
(Button1 e Button2) na form.
No evento OnClick do Button1 deve chamar o
procedimento, em que os parâmetros são o a path do
arquivo a encriptar, a path para onde o arquivo deve ser
encriptado e uma chave de encriptação.
procedure TForm1.Button1Click(Sender:
TObject);
begin
EnDecryptFile(‘c:\arquivo.txt’,
‘c:\arquivo1.txt’, 12);
end;
No evento OnClick do Button2 deve chamar o
procedimento, em que os parâmetros são o a path e o
nome do arquivo encriptado, a path e o nome para onde
o arquivo deve ser desencriptado e a chave de
encriptação usada para encriptar o arquivo original.
procedure TForm1.Button2Click(Sender:
TObject);
begin
EnDecryptFile(‘c:\ficheiro1.txt’,
‘c:\ficheiro2.txt’, 12);
end;
Agora verifique se o arquivo c:\arquivo.txt é igual ao
arquivo c:\arquivo2.txt, se é então correu tudo bem!
310 - Colocar os bitmaps na dll
Por vezes, quando iniciamos um projecto, temos uma
preocupação: fazer uma aplicação pequena. Bem, a
solução pode passar por colocar todos os bitmaps que
vamos utilizar numa dll. Então vamos lá começar:
Deve usar o Image Editor, criar uma nova Resource File
(.res), neste ficheiro vamos colocar os bitmaps e icons
(ambos funcionam da mesma forma) que queremos na
nossa aplicação, clique com a tecla direita do rato na
nova resource file e crie um novo bitmap, depois
desenhe ou cole do clipboard um bitmap, finalmente
guarde o ficheiro com o nome images.res. Depois disto
estar feito vá ao IDE do Delphi e no File menu clique
New… e escolha DLL depois cole o código abaixo, não
se esqueça de adicionar uma unit vazia ao projecto.
Guarde o projecta da dll no mesmo directório do ficheiro
image.res, finalmente faça o build da dll (não se
esqueça, que não se pode correr (executar) uma dll!)
Código da Dll:
library ImageRes; {nome da dll}
uses DummyUnit; {DummyUnit é uma unit
vazia, que é necessária}
{$R images.res} {nome da resource file,
que deve estar no mesmo caminho da dll}
begin
end.
Código da DummyUnit:
unit DummyUnit;
interface
implementation
end.
Usar os bitmaps que estão na dll:
Estão aqui alguns exemplos como extrair os bitmaps da
dll:
procedure
TForm1.SpeedButton1Click(Sender:TObject);
var
MyHandle :THandle;
Bmp : TBitmap;
begin
MyHandle := LoadLibrary(‘ImageRes.DLL’);
{nome da dll construida acima}
Bmp := TBitmap.Create;
Bmp.Handle := LoadBitmap(MyHandle,
‘BITMAP1’); {Bitmap1 é o nome do bitmap
criado no ficheiro image.res}
SpeedButton1.Glyph.Handle :=
LoadBitmap(MyHandle,‘BITMAP1’); {Carrega o
Bitmap1 para o glyph do SpeedButton1}
Canvas.Draw(0,0,Bmp); {Desenha o bitmap no
canvas da form}
Image1.picture.bitmap:=Bmp; {Carrega o
bitmap para o componente Timage}
Bmp.Free;
end;
311 - Teclas mágicas para
trabalhar mais rápido
Esta dica não tem código, são apenas alguns shortcuts
do teclado que permitem aumentar o rendimento do seu
trabalho no IDE do Delphi.

Seleccione as linhas que quer alinhar à


direita, depois pressione as teclas
Ctrl+Shift+i
Ctrl+Shift ao mesmo tempo e a tecla i para
cada espaço à direita.
Seleccione as linhas que quer alinhar à
esquerda, depois pressione as teclas
Ctrl+Shift+u
Ctrl+Shift ao mesmo tempo e a tecla u para
cada espaço à esquerda.
á alguma vez necessitou de fazer o
cut/copy a uma coluna de código?
Alt+seleção Pressione a tecla Alt e ao mesmo tempo
seleccione com o rato ou as teclas o texto
que pretender.
Seleccione os vários componentes de uma
Shift+Mouse form ao pressionar a tecla shift e ao clicar
nos componentes a seleccionar.
Move nas várias direcções o componente
Ctrl+Setas
seleccionado.
Aumenta ou diminui o tamanho do
Shift+Setas
componente seleccionado.
312 - Procurar Strings numa
ListBox
Quando pretendemos procurar uma determinada
palavra no Help de um programa, escrevemos as
primeiras letras da palavra a procurar e o Help vai
seleccionar a palavra mais parecida com a que
digitamos.Este pequeno exemplo demonstra como fazer
isso em Delphi. Primeiro deve criar um projecto novo,
inserir um TEdit(Edit1) e um ListBox(ListBox1), depois
pode inserir várias strings na ListBox. No evento
onChange do Edit1 deve colar o código abaixo.Quando
correr o programa deve digitar no Edit as primeiras
letras da palavra a procurar, e repare como a palavra
mais parecida é automaticamente seleccionada na
ListBox.
procedure TForm1.Edit1Change(Sender:
TObject);
var
S : Array[0..255] of Char;
begin
StrPCopy(S, Edit1.Text);
with ListBox1 do
ItemIndex := Perform(LB_SELECTSTRING, 0,
LongInt(@S));
end;
313 - DbGrid Zebrado
O exemplo abaixo mostra como deixar cada linha do
componente DBGrid de uma cor diferente, dando assim
um efeito zebrado. O controle é feito no evento
OnDrawColumnCell.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, Db,
DBTables, Grids, DBGrids, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
DBGrid1: TDBGrid;
Table1: TTable;
DataSource1: TDataSource;
procedure DBGrid1DrawColumnCell(Sender:
TObject; const Rect: TRect; DataCol:
Integer; Column: TColumn; State:
TGridDrawState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;

implementation
{$R *.DFM}

procedure
TForm1.DBGrid1DrawColumnCell(Sender:
TObject; const Rect: TRect; DataCol:
Integer; Column: TColumn; State:
TGridDrawState);
begin
If odd(Table1.RecNo) then
begin
DBGrid1.Canvas.Font.Color:= clWhite;
DBGrid1.Canvas.Brush.Color:= clGreen;
end
else
begin
DBGrid1.Canvas.Font.Color:= clBlack;
DBGrid1.Canvas.Brush.Color:= clWhite;
end;
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.Canvas.TextOut(Rect.Left+2,Rect.To
p,Column.Field.AsString);
end;
314 - Enviar relatório do
Quickreport para TXT
Uses QRExport

{ Utilize o componente QRTextFilter }


procedure TForm1.Button4Click(Sender:
TObject);
begin
{ Exemplo 1 }
QuickRep1.ExportToFilter(TQRAsciiExportFil
ter.Create(‘C:\REPORT.TXT’));

{ Exemplo 2 }
QuickRep1.ExportToFilter(TQRHTMLDocumentFi
lter.Create(‘C:\REPORT.htm’));
QuickRep1.ExportFilter.Free;
end;

Agradescimentos a WebMaster pela pequena


correção
315 - Como retornar a cor de um
pixel de uma imagem
{Para testar o exemplo inclua em um form um
componente Image e inclua neste componente Image
uma imagem qualquer. Inclua o código abaixo no evento
OnMouseMove.}
procedure TForm1.Image1MouseMove(Sender:
TObject; Shift: TShiftState; X,Y:
Integer);
begin
// Retornar a cor
Caption :=
ColorToString(Image1.Canvas.Pixels[X,Y]);
{ Retornar o número da cor }
Caption := Caption + ‘ -
‘+IntToStr(ColorToRGB(Image1.Canvas.Pixels
[X,Y]));
end;
Esta dica foi testada com uma imagem de formato BMP
316 - Criando uma barra de status
Para criar uma barra de status realmente útil,
primeiramente coloque um componente TStatusBar (que
está na paleta Win32) no seu form (vou explicar
completo porque vários programadores não o conhecem
e usam Panels para isso). Clique com o botão direito no
StatusBar1 e escolha Panels Editor. Clique Add e pronto
(se quiser colocar mais divisões - para colocar um
relógio, por exemplo, é só clicar Add mais vezes).
Apesar de muitos colocarem mensagens em StatusBars
no evento OnMouseMove dos componentes, o melhor
modo que eu conheço para isso é usando Hints.
Primeiramente altere a propriedade ShowHint para True.
Depois digite o que vai aparecer no seguinte formato:
Texto que vai aparecer junto ao mouse|Texto que vai
aparecer no StatusBar (onde | é Shift + \).
Nota:
* No texto que aparecer junto ao mouse, coloque uma
frase pequena (ex: Imprimir). No texto que vai aparecer
no StatusBar, coloque um texto mais explicativo (ex:
Imprimir o relatório de vendas do mês atual).
* Caso você queira que não apareça nenhum texto junto
ao mouse (ou seja, só no StatusBar), cuide para que o
primeiro caracter de Hint seja o caracter “|” (sem aspas).
No evento OnCreate do form, coloque o seguinte
comando:
Application.OnHint := ShowHint;
Crie uma procedure na seção private do form a
procedure ShowHint. Na seção implementation, coloque:
procedure TForm1.ShowHint(Sender:
TObject);
begin
StatusBar1.Panels[0].Text := GetLongHint
(Application.Hint);
end;
E pronto.
317 - Abreviando Nomes
function AbreviaNome(Nome: String):
String;
var
Nomes: array[1..20] of string;
i, TotalNomes: Integer;
begin
Nome := Trim(Nome);
Result := Nome;
{Insere um espaço para garantir que
todas as letras sejam testadas}
Nome := Nome + #32;
{Pega a posição do primeiro espaço}
i := Pos(#32, Nome);
if i > 0 then
begin
TotalNomes := 0;
{Separa todos os nomes}
while i > 0 do
begin
Inc(TotalNomes);
Nomes[TotalNomes] := Copy(Nome, 1, i
- 1);
Delete(Nome, 1, i);
i := Pos(#32, Nome);
end;
if TotalNomes > 2 then
begin
{Abreviar a partir do segundo nome,
exceto o último.}
for i := 2 to TotalNomes - 1 do
begin
{Contém mais de 3 letras? (ignorar
de, da, das, do, dos, etc.)}
if Length(Nomes[i]) > 3 then
{Pega apenas a primeira letra do
nome e coloca um ponto após.}
Nomes[i] := Nomes[i][1] + ‘.’;
end;
Result := ”;
for i := 1 to TotalNomes do
Result := Result + Trim(Nomes[i])
+ #32;
Result := Trim(Result);
end;
end;
end;
318 - Acessando Membros
Protegidos de um Objeto
Normalmente, você não pode acessar membros
protegidos de um objeto. Mas Delphi deixa você acessar
membros protegidos se o objeto foi definido na mesma
unit. Assim, você pode definir um objeto derivado e fazer
a mudança de tipo onde quer usar o membro protegido.
Seria algo assim:
THackControl = class(TCustomEdit)
end;
Depois de definir esta classe, você pode acessar todos
membros protegidos de TCustomEdit, com ebjetos de
classe derivadas com um código como esse:
THackControl(MyEdit).Color := clBlack;
319 - Alterando a fonte de
determinado registro em um DBGrid
Para trocar a fonte de um DBGrid, utilize a rotina
abaixo no evento OnDrawDataCell:
if Tabela.FieldByName (‘Salario’).Value >=
10000 then
begin
DbGrid1.Canvas.Font.Color := clRed;
DbGrid1.Canvas.Font.Style := [fsBold];
end;
DbGrid1.DefaultDrawDataCell(Rect, Field,
State);
No caso, somente os registros com salário maior que
R$ 10.000,00 ficarão com cor vermelha e em negrito.
Nota: Não é necessário mover o ponteiro da tabela
para colorir os registros.
320 - Apagar arquivos via MS-DOS
WinExec(‘Command.com /c Del
c:\temp\*.tmp’, 0)
321 - armazenado num Blop
Os campos do Tipo TBlobField, tem metodos que
permitem que sejam armazenados dados contidos em
arquivos, ou em um Stream…
No primeiro caso (dos arquivos), o codigo seria algo
como:
TBlobField(SuaTabela.FieldByName(‘SeuCampo
’)).LoadFromFile(‘NomedoArquivo’);
No segundo caso, poderia ser feito um exemplo com o
TRichEdit:
var
Stream : TMemoryStream;
begin
Stream := TMemoryStream.Create;
try
RichEdit1.Lines.SaveToStream(Stream);
Stream.Seek(0,soFromBeginning);
TBlobField(SuaTabela.FieldByName(‘SeuCampo
’)).LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
Ambos os exemplos, assumem que a tabela ja’ estaria
em modo de Edicao ou de Insercao.
322 - Array de Edit boxes
Procedure DoSomethingWithEditControls;
Var
K: Integer;
EditArray: Array[0..99] of Tedit;
begin
Try
For K:= 0 to 99 do
begin
EditArray[K]:= TEdit.Create(Self);
EditArray[K].Parent:= Self;
SetSomeOtherPropertiesOfTEdit;
Left:= 100; Top:= K*10;
OnMouseMove:= WhatToDoWhenMouseIsMoved;
end;
DoWhateverYouWantToDoWithTheseEdits;
Finally
For K:= 0 to 99 do EditArray[K].Free;
end;
323 - Arredondando valores
procedure RoundDecimal(var AValue: double;
Const ADecimal: integer);
var
strValue : string;
begin
strValue :=
FloatToStrF(AValue,ffFixed,18,ADecimal);
AValue := StrToFloat(strValue);
end;
324 - Centralizando uma string
Function Center(StrX : string; IntX :
ShortInt) : string;
begin
Center := Middle (StrX, IntX,
EspacoBranco);
end;
325 - Chamando Help
coloque o seguinte codigo em um botão ou menu:
Application.HelpFile:=‘SeuHelp.hlp’;
Application.helpcomand(HELP_CONTENTS,0);
funciona para qualquer arquivo de help…
Complemento feito por Thiago Alves
Cavalcante:
Application.HelpFile:=‘SeuHelp.hlp’;
Application.HelpCommand(parametros, 0);

Parâmetros:
HELP_CONTENTS - chama o arquivo de Help como se tivesse
dado um duplo-clique no arquivo .hlp
HELP_FINDER - Chama o help a partir do menu Conteúdo.
HELP_QUIT - Desativa o Help.

Agradecimento especial ao Tiago e também ao


Rodolfo que mandou uma correção igual ao do
Tiago!
Valeu!
326 - Colocando bitmaps num
ComboBox
Ajuste a propriedade Style do ComboBox para
csOwnerDrawVariable.
var
Form1: TForm1;
Bmp1, Bmp2, Bmp3: TBitmap;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender:
TObject);
begin
Bmp1:=TBitmap.Create;
Bmp1.Loadfromfile(‘c:\chip16.bmp’);
Bmp2:=TBitmap.Create;
Bmp2Loadfromfile(‘c:\zoom.bmp’);
Bmp3:=TBitmap.Create;
Bmp3Loadfromfile(‘c:\disk.bmp’);
ComboBox1.Items.AddObject(‘Chip’,Bmp1);
ComboBox1.Items.AddObject(‘Zoom’,Bmp2);
ComboBox1.Items.AddObject(‘Disk’,Bmp3);
end;

procedure
TForm1.ComboBox1DrawItem(Control:
TWinControl; Index: Integer; Rect: TRect;
State: TOWnerDrawState);
var
Bitmap: TBitmap;
Offset: Integer;
begin
with (Control as TComboBox).Canvas do
begin
FillRect(Rect); Bitmap:=
TBitmap(ComboBox1.Items.Objects[index]);
BrushCopy(Bounds(Rect.Left + 2, Rect.Top +
2, Bitmap.Width,
Bitmap.Height), Bitmap, Bounds(0, 0,
Bitmap.Width, Bitmap.Height), clRed);
Offset: Bitmap.width + 8;
TextOut(Rect.Left + Offset, Rect.Top,
ComboBox1.Items[index]);
end;
end;

procedure
TForm1.ComboBox1MeasureItem(Control:
TWinControl; Index: Integer; var Height:
Integer);
begin
Height:=20;
end;
327 - Colocando uma barra de
progresso para o batchmove
1 - No form, coloque um componente TDataSource.
2 - Na propriedade DataSet do TDataSource inserido,
coloque a tabela de origem, ou seja,
“DataSource1.DataSet:=BatchMove1.Source;”
3 - Utilize o evento OnChangeData do TDataSource p/
acompanhar o processo de cópia.
Lembre-se que antes disso você deverá utilizar a
propriedate RecordCount da tabela de origem para
saber o total de registros que serão copiados.
Lembre-se também que a cada registro lido, o evento
OnChangeData é chamado, portanto, é através desse
evento que você poderá acompanhar o
processo de cópia, e por exemplo, atualizar uma barra
de porcentagem.
328 - Colocar automaticamente a
senha em tabelas Paradox
Coloque o seguinte antes de abrir a tabela :
Table1.DBSession.AddPassword(‘senha_da_tab
ela’);
329 - Como evitar a mensagem de
erro Key Violation
Inclua a unit DBITYPES na clausula uses do seu form.
procedure TForm1.Table1PostError(DataSet:
TDataSet; E: EDatabaseError; var Action:
TDataAction);
begin
if EDBEngineError(E).Errors[0].ErrorCode =
9729 then
ShowMessage(‘Registro já existe!’);
Action:= daAbort;
end;
330 - Como Trocar o Cursor do
Mouse
Existem vários cursores no Delphi (crDefault é o cursor
padrão, crHourGlass é a ampulheta, crHandPoint é a
“mãozinha”, etc). Para alterá-lo, basta escolher um na
propriedade Cursor do componente em que você quer
mudar o cursor (troque no form para trocar o do form
inteiro). Mas, se você quiser colocar um cursor diferente,
siga os procedimentos abaixo:
Na seção interface da unit que contém o form, coloque
as seguintes linhas:
const
crSeuCursor = 1; // Tem que ser um valor
maior que 0 (zero)
No evento OnCreate do form, digite as seguintes linhas:
Screen.Cursors [crSeuCursor] :=
LoadCursorFromFile (‘Cursor.ani’);
// O cursor pode ser dos tipos comum
(*.cur) ou animado (*.ani)
// Lembre-se: o arquivo tem que estar na
mesma pasta do programa
// ou digite o nome do caminho dele.
Na hora de trocar de cursor, use o seguinte comando:
Objeto.Cursor := crSeuCursor;
onde Objeto é o nome do objeto que vai ter o cursor
alterado (o form, por exemplo).
331 - Configurando a Rede em
Win95/Win98 com Delphi
Vamos exemplificar com 3 máquinas, 1 servidor
chamado SERV e 2 máquinas clientes.Claro que isto
pode ser incrementado de acordo com suas
necessidades:
No servidor: diretório real D:\SISTEMA\DADOS
compartilhe o subdiretório D:\SISTEMA\DADOS como
um recurso chamado Servidor_Hno
Inclua no AUTOEXEC.BAT : Subst H:
D:\SISTEMA\DADOS
Nas máquinas clientes: mapear drive de rede H: como
\SERV1\Servidor_HNo no fim deste processo voce terá
o drive H: como sendo o seu Drive de rede para o
Sistema, este drive estará presente em todas as
máquinas e pode ser utilizado como seu NET DIR.
No BDE Configuration: NET DIR: H: (Para o driver
Paradox)
Em seu Alias: Path: H:\DADOS\
Em System: Local Share: True
Depois disto você configura o BDE de forma igual em
todas as máquinas da rede.
332 - Configurando RedeNovell
NetWare com Delphi
Configurar uma rede Novell para trabalhar com Delphi é
muito facíl, mais facíl que uma rede ponto a ponto como
Windows 95.
Primeiro precisamos de um diretório onde será criado o
NET FILE do Paradox, normalmente um diretório
partindo da raiz do servidor será o suficiente, vamos
usar o drive padrão da Novell para exemplificar o caso:
F: <— drive da rede
F:\NETDIR <— o diretório do NET FILE
Para o diretório onde serão armazenados os arquivos do
seus sistema não é necessário nenhum cuidado
especial, podemos assumir alguma configuração como a
que segue:
F:\SISTEMA\DADOS <— diretório de dados
Para quem trabalha todos os dias com uma rede Novell,
existe uma armadilha que pode causar umas noites mal
dormidas:
Uma das coisas que muitos tentam para economizar um
pouco do HD local, é colocar o executável na rede, sem
grandes problemas, desde que você tenha um cuidado
básico.
Sempre que você executa um programa que trata com
base Paradox, o PRIVATE DIR fica sendo o diretório
onde este executavél se encontra, no caso de você
colocar este executável em um diretório da rede para
ser acessado por muitos, como fica este diretório P
Para resolver este problema voce deve
“programaticamente” alterar oPrivate Dir para um
diretório local, para isso você tem de adicionar as
seguintes linhas de código ao iniciar a sua aplicação:
Session.PrivateDir := ‘C:\WINDOWS\TEMP’;
Para ter acesso a Session você tem de incluir a unit DB
na clausula Uses do seu projeto.
Este cuidado pode prevenir várias travadas sem razão
aparente em redes Novell.
333 - Convertendo nomes longos
para nomes curtos
Para converter um nome longo de arquivo para um
nome curto (e vice-versa), use as seguintes funções (a
primeira retorna um nome curto e a segunda um nome
longo):
function GetShortFileName (const Arquivo :
String) : String;
var
aTmp : array [0..255] of char;
begin
if GetShortPathName (PChar (Arquivo),
aTmp, sizeof (aTmp) - 1) = 0 then
Result := Arquivo
else
Result := StrPas (aTmp);
end;

function GetLongFileName (const Arquivo :


String) : String;
var
aInfo : TSHFileInfo;
begin
if SHGetFileInfo (PChar(Arquivo), 0,
aInfo, sizeof (aInfo), SHGFI_DISPLAYNAME)
<>0 then
Result := String (aInfo.szDisplayName)
else
Result := Arquivo;
end;
334 - Adicionando a soma de Fields
no QRExpression do QuickReport
QRExpr1.Expression := Sum(Field1);
QRExpr2.Expression := Sum(Field2);
QRExpr3.Expression := Sum(Field1+Field2);
335 - Criando e apagando TFields
em Run-Time
procedure TForm1.btnCriaFieldClick(Sender:
TObject);
var T: TStringField;
begin
if qryCliente.Active then
qryCliente.Close;
T := TStringField.Create(Self);
T.fieldName := ‘cli_Nome’;
T.FieldKind := fkData;
T.DisplayLabel := ‘Nome do Cliente’;
T.Visible := True;
T.Name := qryCliente.Name + T.FieldName;
T.Index := qryCliente.FieldCount;
T.DataSet := qryCliente;
qryCliente.FieldDefs.UpDate;
qryCliente.Open;
end;

procedure
TForm1.btnApagaFieldClick(Sender:
TObject);
var TC: TComponent;
begin
TC :=
FindComponent(‘qryClientecli_Nome’);
if not (TC = nil) then
begin
qryCliente.Close;
TC.Free;
qryCliente.Open;
end;
end;
336 - Alterando parcialmente o
conteúdo da prop.SQL de uma
Query
Vamos supor que você tenha uma instrução SQL em
uma Query como a seguinte:
SELECT IDCliente, cli_Nome, cli_DataNasc,
cli_Sexo
FROM Cliente
WHERE ( IDCliente < 1000 )
AND ( cli_Sexo = ‘M’ ) (*)
ORDER BY cli_Nome
Para alterar somente a quarta(*) linha do SQL você
pode fazer assim:
with qryCliente do
begin
if Active then Close;
SQL[3] := ‘AND ( cli_UF = ‘ES’) OR (
cli_UF = ‘RJ’ )’; // ou SQL[3] := ‘ ‘;
Open;
end;
337 - Como fazer uma unit como
biblioteca
COMO FAZER DCU PARA SERVIR COMO
BIBLIOTECA DE FUNCOES E COMO FAZER PARA
QUE OUTRO PROGRAMA ENXERGUE-AS.
PRIMEIRO:
PARA FAZER UMA UNIT DE FUNCOES, VOCÊ TEM
QUE COMPILA-LA PARA GERAR A EXTENSÃO DCU.
PARA FAZER COM QUE ELA VIRE UMA BIBLIOTECA
DE FUNÇÕES ELA TEM QUE TER A EXTENSÃO DCU.
SEGUNDO:
VOCÊ NÃO VAI CONSEGUIR COMPILAR UMA UNIT
SE ELA ESTIVER SOZINHA, ISTO PORQUE O DELPHI
SÓ COMPILA PROJETOS E COMO UNIT NÃO É
PROJETO A OPÇÃO DE COMPILAÇÃO NÃO ESTARÁ
DISPONÍVEL. PORTANTO, ABRA UM PROJETO
QUALQUER, OU MESMO CRIE UM ALEATORIO E
ABRA UMA NOVA UNIT, É NESTA UNIT E NÃO A DO
PROJETO QUE VOCÊ CRIARÁ TODAS AS SUAS
FUNÇÕES. DEPOIS DISTO ENTÃO VOCÊ
ABANDONA O FORM E SÓ VAI USAR A UNIT.
TERCEIRO:
QUANDO VOCÊ ABRIR A UNIT, ESTA VIRÁ SOMENTE
COM O NOME, INTERFACE, IMPLEMENTATION E
END..
EXEMPLO:
Unit unit1;
Interface
Implementation
End.
QUARTO:
PARA VOCÊ CRIAR UMA FUNÇÃO O
PROCEDIMENTO É IGUAL Á UNIT COMUM, MAS
PARA QUE ELA SEJA ENXERGADA POR OUTROS
PROGRAMAS PRECISA SER DECLARADA ABAIXO
DA INTERFACE E ABAIXO DE POSSIVEIS USES
NECESSÁRIOS AS SUAS FUNÇÕES.
EXEMPLO DE UMA UNIT DE FUNÇÕES:
unit ufuncoes; //NOME DA UNIT

interface

uses // CLASSES NECESSÁRIAS ÁS FUNÇÕES


ABAIXO, NAS SUAS TALVEZ PRECISE DE OUTRAS
SysUtils, WinTypes, WinProcs, Messages,
Classes, Graphics, Controls,Dialogs,
StdCtrls, Grids, DBGrids;

function data(vdata:string):boolean; //
DECLARAÇÃO DAS FUNÇÕES OU PROCEDURES

procedure cor(grade:tdbgrid;color:tcolor);
// PARA PODEREM SER ENXERGADAS POR OUTRAS
UNITS.
// COLOQUE OS MESMOS CABEÇALHOS DA SUA
FUNÇÀO

implementation // AQUI QUE VOCÊ VAI CRIAR


AS SUAS FUNÇÕES, NÃO SE ESQUEÇA O QUE
CRIAR AQUI, TERÁ QUE DECLARAR EM CIMA
SENÃO NENHUMA OUTRA UNIT AS ENXERGARÁ.

function data(vdata:string):boolean;
begin
try
StrToDate(vdata);
data:=true;
except
MessageDlg(‘Data Inválida !!’ ,
mtInformation, [mbOk], 0);
data:=false;
end;
end;

procedure cor(grade:tdbgrid;color:tcolor);
// muda a cor para preto para todas as
colunas de qualquer dbgrid
var
i:integer;
numcampos:integer;
begin
numcampos:=grade.FieldCount;
{subtraio -1 aqui embaixo porque as
colunas começam de zero}
for I := 0 to numcampos-1 do // COLOCA AS
23 COLUNAS COM COR PRETA
grade.columns[i].font.color:=color;
end;
end.
QUINTO:
PARA QUALQUER UNIT ENXERGAR ESTAS DUAS
FUNÇÕES ACIMA, É NECESSÁRIO QUE VOCÊ
COLOQUE ESTA UNIT NO DIRETORIO DO SEU
PROGRAMA QUE VAI UTILIZÁ-LA E DEPOIS É SÓ
COLOCÁ-LA NA USES DA UNIT QUE FARÁ O USO
DAS MESMAS. APÓS ISTO É SÓ CHAMAR AS
FUNÇÕES QUE NELA CONSTEM QUE
FUNCIONARÃO PERFEITAMENTE, INCLUSIVE
PODEM SER DEBUGADAS, O DEBUG ENTRARÁ NA
UNIT DAS FUNÇÕES SE VOCÊ FOR TECLANDO F7.
338 - Como imprimir com codigo
fonte
unit animais; {exemplo de impressao com
codigo fonte do arquivo exemplo de delphi
chamado animais. mostra como aumentar a
fonte, mudar a fonte, mudar a grossura da
linha, imprimir uma reta, imprimir
caracteres e dados}

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
DBCtrls, ExtCtrls, Grids, DBGrids, Db,
DBTables, ExtDlgs, StdCtrls,printers,
ComCtrls, Buttons, Outline, DirOutln;

type
TForm1 = class(TForm)
dtanimais: TTable;
dsanimais: TDataSource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DBImage1: TDBImage;
Imprime: TBitBtn;
dtanimaisNAME: TStringField;
dtanimaisSIZE: TSmallintField;
dtanimaisWEIGHT: TSmallintField;
dtanimaisAREA: TStringField;
dtanimaisBMP: TBlobField;
procedure ImprimeClick(Sender: TObject);
procedure FormKeyPress(Sender: TObject;
var Key: Char);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
pag:integer;
linha:integer;

implementation

{$R *.DFM}

//ESTA PROCEDURE AVALIA A TECLA


PRESSIONADA, SE FOR ESC O EVENTO DO FORM
FORMKEYPRESS SERÁ ACIONADO E ENTÃO
ABORTARÁ A IMPRESSÃO. PARA ISTO VOCÊ
PRECISA IR NO EVENTO FORMKEYPRESS DO FORM
E CLICAR SOBRE ELE.

procedure TForm1.FormKeyPress(Sender:
TObject; var Key: Char);
begin
if (Key=VK_ESCAPE) and (Printer.Printing)
then
begin
Printer.Abort;
MessageDlg(‘Impressão abortada’,
mtInformation, [mbOK],0);
end;
end;

// ESTA PROCEDURE É O CABEÇALHO DO


RELATÓRIO E É CHAMADO NO INICIO DA
IMPRESSÃO LOGO APÓS O BEGINDOC.

procedure cabrelat;
begin
inc(pag,1); // INCREMENTA NA VARIAVEL PAG
+1
printer.canvas.pen.width:=9; {expessura do
traco}
INC(LINHA,80); // INCREMENTA NA VARIAVEL
LINHA +80
printer.canvas.textout(3700,LINHA,‘PAG:
‘+INTTOSTR(PAG));
INC(LINHA,80);
printer.canvas.moveto(4000,LINHA); {moveto
e lineto funcionam como coluna inicial e
final}
printer.canvas.lineto(5,LINHA); {traco da
coluna 5 ate a 4000 em pixels, varia de
impressora p/impressora}
INC(LINHA,5);
printer.canvas.font.size:=14; {tamanho da
fonte}
printer.canvas.textout(3,LINHA,NOME); {O
PRINTER.CANVAS.TEXTOUT, imprime dados ou
caracteres}
printer.canvas.textout(1400,
linha,TAMANHO);
printer.canvas.textout(2300, linha,PESO);
printer.canvas.textout(3100, linha,AREA);
INC(LINHA,120);
printer.canvas.moveto(4000,LINHA);
printer.canvas.lineto(5,LINHA);
INC(LINHA,10);
printer.canvas.font.size:=12;
end;

// ESTA PROCEDURE É O RODAPÉ DO RELATÓRIO


E É CHAMADO NO FINAL DA IMPRESSÃO.

procedure rodape;
begin
INC(LINHA,80);
printer.canvas.font.style:=[fsitalic];
{tipos de fonte: fsBold, fsItalic,
fsUnderline, fsStrikeOut);}
printer.canvas.textout(4000,LINHA,‘CONTINU
A’);
INC(LINHA,80); {font.color := clred;}
printer.canvas.pen.width:=9; {espessura da
linha}
printer.canvas.moveto(4000,linha);
printer.canvas.lineto(5,linha);
printer.canvas.font.style:=[]; {estilo da
linha}
printer.newpage;
linha:=30;
end;

procedure TForm1.ImprimeClick(Sender:
TObject);

VAR
nnumero: integer;
begin
{dtanimais.setkey;}
cancela.visible:=true;
{torna visivel o botao de cancelar no
form}
form1.refresh;
{faz o form mostrar o botao cancela, sem o
refresh nao adianta colocar o botao de
cancela visivel}
nnumero:=0;
pag:=0;
linha:=30;
printer.begindoc; {inicializa a
impressora}
CABRELAT;
dtanimais.first;
while not (dtanimais.eof) do
begin
printer.canvas.textout(3,
linha,dtanimaisname.text);// IMPRIME OS
CAMPOS DO ARQUIVO
printer.canvas.textout(1800,
linha,dtanimaissize.text); {campo size}
printer.canvas.textout(2500,
linha,dtanimaisweight.text);{campo weight}
printer.canvas.textout(3100,
linha,dtanimaisarea.text); {campo area}
inc(linha,120); { o inc() incrementa
pixels e aqui esta incrementando 120}{
entre um registro e outro}
dtanimais.next; {pula registro}
application.processmessages; {Sem isso nao
adianta clicar no botao cancela}
if not printer.printing then {caso tenha
abortado a impressao num click}
{o printer ja nao estara imprimindo, entao
entrara aqui}
exit;
inc(nnumero,1);
if linha>=3400 then
BEGIN
RODAPE;
CABRELAT;
END;
if dtanimais.eof then
begin
printer.canvas.pen.width:=9;
INC(LINHA,80);
printer.canvas.moveto(4000,LINHA);
printer.canvas.lineto(5,LINHA);
INC(LINHA,60);
printer.canvas.font.name:=‘arial’;
printer.canvas.font.size:=10;
printer.canvas.textout(5,linha,‘TOTAL DE
ANIMAIS:’);
printer.canvas.textout(1000,linha,INTTOSTR
(NNUMERO));
INC(LINHA,100);
printer.canvas.moveto(4000,LINHA);
printer.canvas.lineto(5,LINHA);
printer.canvas.font.size:=14;
printer.enddoc;
end;
end;
if printer.printing then
printer.enddoc;
dtanimais.first; {retorno ao inicio da
tabela}
end;
end.
339 - Dicas de DbGrid
TROCAR O NOME NO TITULO DE
CADA CAMPO
1 Clique duas vezes sobre o dbgrid, isto fará aparecer
uma janela, nesta janela clique com o botão direito do
mouse e selecione add fields., todos os campos
aparecerão.
2 Para mudar o nome do titulo de cada campo,
selecione o campo desejado e no object inspector vá na
propriedade title, clique no sinal de mais que se
encontra no lado esquerdo da propriedade, nas opções
que aparecerem mude a propriedade caption, o que
você escrever aqui, ficará no titulo.
COLOCAR O DBGRID EM ORDEM
DO TITULO CLICADO
1 No evento ontitleclick, criar uma variavel chamada
campo, campo então receberá a coluna clicada, para
depois a query fazer o order by pelo campo escolhido.
procedure
Tconscli.gradeprocessosTitleClick(Column:
TColumn);
var
campo:string;
begin
campo:=column.fieldname; // CAMPO RECEBE O
NOME DA COLUNA CLICADA,
application.processmessages; // para
considerar algo que aconteça no dbgrid
durante a entrada nesta procedure
qrCLIENTES.sql.clear; // LIMPA A QUERY
qrCLIENTES.sql.add(‘select * from div1
order by ‘+campo); // ESCREVE O SELECT COM
O ORDER BY
if not QRCLIENTES.Prepared then
QRCLIENTES.Prepare;
QRCLIENTES.Open; // ABRE A QUERY COM A
ORDEM ESCOLHIDA.
End;
column.Font.color:=clblue; // COLOCAR A
COLUNA NA COR DESEJADA
BUSCA RECURSIVA NO DBGRID
1 Colocar o dbgrid em modo de leitura.
2 Criar uma variavel publica chamada letras no inicio do
form;
3 Clicar no evento onkeypress do dbgrid e fazer isto
abaixo:
letras:=letras+uppercase(key); // acumula
as letras digitadas
QRclientes.LOCATE(CAMPO,LETRAS,
[loPartialKey]); // Efetua a procura
4 Para zerar a variavel letras, basta escolher um evento
de click ou de tecla pressionada e inserir:
letras:=;
Minha dica fica para o evento onkeydown com isto:
IF (KEY=38) or (key=40) then // avalio se
é seta para cima ou para baixo;
letras:=”;
end;
e no evento oncelclick colocar isto:
letras:=;
Desta forma quando clicar na célula ou teclar seta para
cima ou para baixo a variavel letras zerará.
TROCAR O TAB PELO ENTER NO
DBGRID

no evento onKeyDown do DBGrid:

begin
case key of
13 : Key := 9;
end;
end;
340 - Para colocar um back ground
nos forms
Coloque um TImage no seu formulário, escolha uma
Picture e deixe a propriedade Visible = False.
Depois, no evento OnPaint do Form, use o seguinte
código:
for i:= 0 to Round(Width/Image1.Width) do
for j := 0 to Round(Height/Image1.Height)
do
Canvas.Draw(i*Image1.Width,j*Image1.Height
,Image1.Picture.Graphic);
Caso utilize um BitMap, pode substituir o
Image1.Picture.graphic por Image1.BitMap.
341 - Como indexar um vetor
Veja o exemplo:
for x := 1 to 10 do
for y := 1 to 10 do
if array[x] < array[y] then begin
varaux := array[y];
array[y] := array[x];
array[x] := varaux;
end;
Consiste no seguinte para cada item do vetor vc verifica
todos os outros, se for menor faz a troca.
Simples não?
A fução aSort do clipper encapsula este processo pra
vc.
342 - Como formatar data para
exibição por extenso
O Delphi permite formatar datas para apresentação por
extenso de forma bastante simples. Vejamos os
seguintes exemplos:
Para formatar a data 18/03/1999, podemos utilizar:
No create do form colocar
Shortdateformat:=

dddd, dd/mm/yyyy = Quinta, 18/03/1999


dd/mmm/yyyy = 18/Mar/1999
dddd, dd” de “mmmm” de “yyyy = Quinta, 18
de Março de 1999
dd” de “mmmm” de “yyyy, dddd = 18 de Março
de 1999, Quinta
343 - Como converter DBF para
Paradox e Acess paar Paradox
A) ACCESS PARA PARADOX
DIGAMOS QUE VOCÊ TENHA UM BANCO DE DADOS
EM ACCESS CHAMADO DISCOTECA.MDB E QUE
NELE TENHA VÁRIAS TABELAS, VAMOS
CONVERTER APENAS UMA, QUE NO NOSSO
EXEMPLO SE CHAMA: AUTORES, E QUE SE
QUISESSEMOS CONVERTER OUTRAS O
PROCEDIMENTO SERIA EXATAMENTE O MESMO.
Abra o database desktop e crie um alias chamado
DISCO, informe o drive desejado como ACCESS, veja
bem é ACCESS e não microsoft access drive, tá legal
???, depois no campo database que se abriu bem
abaixo, indique o diretorio onde se encontra o banco do
access exemplo: c:\discoteca\dados\discoteca.mdb,
para testar e ver se está correto clique no botão conectt,
se der algum erro é porque não existe o caminho ou o
arquivo mdb informado no campo database.
Uma vez que conectou, feche o alias e vá em file no
menu da database desktop, clique em new e depois em
sql file, na janela que se abre digite select * from
autores, uma vez que digitou a instrução, clique no
botão Query que está em cima há direita, ele tem um
ponto de interrogação preto, bom depois de clicar se
abrirá uma tela, bem no meio tem table type com duas
opções: PARADOX E DBASE, ESCOLHA PARADOX,
depois vá onde está table name bem no meio da tela,
digite o diretório e o nome do arquivo que quer que
receba a tabela do access convertida, pronto, quando
fizer isso ela já estará convertida, com o nome que você
deu com extensão db. Ou seja você tem uma tabela
paradox com os dados que estavam em autores dentro
do banco do access.
B) DBF PARA PARADOX
Abrir o database desktop, abra uma nova qbe e procure
o diretorio onde está o dbf.
Uma vez escolhido, clique nele, aparecerá um retangulo
como quadrinhos ao lado de cada campo, clique no
primeiro quadrado que marcará todos automaticamente.
Feito isso clique na paleta onde está escrito Query e vá
em propriedades, aparecerá um form onde você pode
escolher entre paradox ou dbase, escolha paradox e
logo embaixo digite o diretorio e o nome da tabela que
voce quer criar, tecle o raizinho para rodar a query que
então ele converterá para paradox.
344 - Como acrescentar
caracteristicas em um objeto
Categoria : Banco de Dados
Dica :
Para visualizar uma imagem em um DBGrid, você vai ter
que criar um descendente dele que aceite essas figuras.
O código está abaixo:
unit DBPicGrd;

interface

uses
DBGrids, DB, DBTables, Grids, WinTypes,
Classes, Graphics;

type
TDBPicGrid = class (TDBGrid)
protected
procedure DrawDataCell(const Rect: TRect;
Field: TField; State:
TGridDrawState); override;
public
constructor Create (AOwner : TComponent);
override;
published
property DefaultDrawing default False;
end;

procedure Register;

implementation

constructor TDBPicGrid.Create (AOwner :


TComponent);
begin
inherited Create (AOwner);
DefaultDrawing := False;
end;

procedure TDBPicGrid.DrawDataCell (const


Rect: TRect; Field: TField;
State: TGridDrawState);
var
bmp : TBitmap;
begin
with Canvas do
begin
FillRect(Rect);
if Field is TGraphicField then
try
bmp := TBitmap.Create;
bmp.Assign (Field);
Draw (Rect.Left, Rect.Top, bmp);
finally
bmp.Free;
end
else
TextOut (Rect.Left, Rect.Top, Field.Text);
end;
end;

procedure Register;
begin
RegisterComponents (‘Custom’,
[TDBPicGrid]);
end;
end.
345 - Como acessar pelo Delphi,
tabelas no Acess
Primeiro crie um alias apontando para o diretorio onde
está o arquivo mdb do access, este apontamento deve
ser testado clicando no botão connectt. Se funcionar,
pode fechar salvando o novo alias. Caso contrário
verifique se o diretório está correto e se o arquivo mdb
existe neste diretório.
Bem, após isso, vá no delphi, abra um projeto novo,
coloque um componente tdatabase, uma query, um
datasource e um dbgrid. Após isso clique duas vezes no
componente tdatabase, após clicar, aparecerá um
formulário, informe o nome que deseja dar ao database
em name, em alias name, clique na seta e escolha o
alias criado anteriormente, depois clique em defaults, se
quiser uma senha para acesso ao banco, procure a
palavra PASSWORD dentro da janela que foi
preenchida com comandos quando você clicou em
defaults, e digite a senha desejada, se não quiser senha
deixe em branco. Após fazer isto, clique em OK. Bem,
agora vá em propriedades do tdatabase e clique em
conectt, ele vai pedir um usuário e uma senha, se não
colocou password, basta clicar em ok que ele se
conectará e caso tenha uma password digite-a. Uma vez
conectado, vá na query, na propriedade strings, coloque
a instrução SELECT acessando a tabela que está dentro
do arquivo MDB. Veja bem, não é para colocar o arquivo
mdb mas sim uma ou mais das tabelas que estão dentro
do MDB. Depois disso na propriedade database,
escolha o nome que deu ao seu database, se você fez
tudo correto, o nome dele tem que estar na lista. Bom,
agora active a query. Após isso vá no datasource e
conecte-o á query, e depois vá no dbgrid e sete o
datasource para o datasource criado. Se fez tudo
correto e se a tabela tiver dados, você os verá no dbgrid.
346 - Extarir palavra que está sob
o cursor
function RECharIndexByPos(RichEdit:
TRichEdit; X, Y: Integer): Integer;
{ retorna a posição absoluta do caracter
para um conjunto de coordenadas do cursor}
var
P: TPoint;
begin
P := Point(X, Y);
Result := SendMessage(RichEdit.Handle,
EM_CHARFROMPOS, 0, longint(@P));
end;

function REExtractWordFromPos(RichEdit:
TRichEdit; X, Y: Integer): string;
{ X, Y - coordenadas num controle rich
edit }
{retorna a palavra sob a posição corrente
do cursor}
var
BegPos, EndPos: Integer;
begin
BegPos := RECharIndexByPos(RichEdit, X,
Y);
if (BegPos < 0) or
(SendMessage(RichEdit.Handle,EM_FINDWORDBR
EAK,WB_CLASSIFY,BegPos) and
(WBF_BREAKLINE or WBF_ISWHITE) <> 0 ) then
begin
result:=”;
exit;
end;
if SendMessage(RichEdit.Handle,
EM_FINDWORDBREAK, WB_CLASSIFY, BegPos- 1)
and
(WBF_BREAKLINE or WBF_ISWHITE) = 0 then
BegPos := SendMessage(RichEdit.Handle,
EM_FINDWORDBREAK,
WB_MOVEWORDLEFT, BegPos);
EndPos := SendMessage(RichEdit.Handle,
EM_FINDWORDBREAK,
WB_MOVEWORDRIGHT, BegPos);
Result :=
TrimRight(REGetTextRange(RichEdit, BegPos,
EndPos - BegPos));
end;
347 - Como extrair o primeiro nome
de uma pessoa
Para pegar o primeiro nome de uma pessoa, crie a
seguinte função:
function PrimeiroNome (Nome : String) :
String;
var
PNome : String;
begin
PNome := ”;
if pos (‘ ‘, Nome) <> 0 then
PNome := copy (Nome, 1, pos (‘ ‘, Nome) -
1);
Result := PNome;
end;
348 - Criar atalho no desktop
Coloque essas units na seção implementation :
uses ShlObj, ActiveX,ComObj, Registry;
Por último, crie uma procedure que faça o trabalho:
procedure CreateShortcut (FileName,
Parameters, InitialDir, ShortcutName,
ShortcutFolder : String);
var
MyObject : IUnknown;
MySLink : IShellLink;
MyPFile : IPersistFile;
Directory : String;
WFileName : WideString;
MyReg : TRegIniFile;
begin
MyObject :=
CreateComObject(CLSID_ShellLink);
MySLink := MyObject as IShellLink;
MyPFile := MyObject as IPersistFile;
with MySLink do
begin
SetArguments(Parameters);
SetPath(PChar(FileName));
SetWorkingDirectory(PChar(InitialDir));
end;
MyReg :=
TRegIniFile.Create(‘Software\MicroSoft\Win
dows\CurrentVersion\Explorer’);
Directory := MyReg.ReadString (‘Shell
Folders’,‘Desktop’,”);
WFileName := Directory + ‘' + ShortcutName
+ ‘.lnk’;
MyPFile.Save (PWChar (WFileName), False);
MyReg.Free;
end;
349 - Imprimir com precisão
milimétrica
O objeto Canvas que está na classe Printer é uma
ferramenta que ajuda muito a imprimir qualquer tipo de
dados, sejam eles texto ou gráficos. O problema é que a
largura e a altura são determinadas em pixels, e esses
valores variam de acordo com a resolução da
impressora. Para converter de milímetros para pixels,
use as funções abaixo, sendo que MMtoPixelX é para a
resolução horizontal e MMtoPixelY é para a resolução
vertical (porque na impressora é possível uma resolução
como 1440x720 dpi - 1440 dpi para a horizontal e 720
dpi para a vertical, por exemplo):
function MMtoPixelX (MM : Integer) :
Longint;
var
mmPointX : Real;
PageSize, OffSetUL : TPoint;
begin
mmPointX := Printer.PageWidth /
GetDeviceCaps(Printer.Handle,HORZSIZE);
Escape
(Printer.Handle,GETPRINTINGOFFSET,0,nil,@O
ffSetUL);
Escape
(Printer.Handle,GETPHYSPAGESIZE,0,nil,@Pag
eSize);
if MM > 0 then
Result := round ((MM * mmPointX) -
OffSetUL.X)
else
Result := round (MM * mmPointX);
end;

function MMtoPixelY (MM : Integer) :


Longint;
var
mmPointY : Real;
PageSize, OffSetUL : TPoint;
begin
mmPointY := Printer.PageHeight /
GetDeviceCaps(Printer.Handle,VERTSIZE);
Escape
(Printer.Handle,GETPRINTINGOFFSET,0,nil,@O
ffSetUL);
Escape
(Printer.Handle,GETPHYSPAGESIZE,0,nil,@Pag
eSize);
if MM > 0 then
Result := round ((MM * mmPointY) -
OffSetUL.Y)
else
Result := round (MM * mmPointY);
end;
350 - Como alterar o caption da
janela de preview do quickreport
Para mudar o título da barra de título da janela de
Preview de seus relatórios, use o seguinte comando:
QRPrinter.PreviewCaption := ‘Visualização
do Relatório’;
351 - Como Instalar RXLIB Para
Delphi 5.x:
1) Rode o RXINST.EXE para instalar os arquivos
necessários (acho que isso
você já fez)
––––––––––––––––––––––––––––––––-
Obs : Veja a observação abaixo :
If you have Delphi 5 Professional or Standard Edition,
deactivate the
conditional define {$DEFINE DCS} in the RX.INC file
before compiling the
library.
––––––––––––––––––––––––––––––––-

2) Depois disso vá em File/Open e abra o arquivo


RXCTL5.DPK e compile ele.
Repita a operação para os arquivos RXDB5.DPK e
RXBDE5.DPK (tem que ser nessa
ordem).

3) Feche os 3 arquivos sem salvar.

4) Verifique também se os arquivos rxbde5.bpl, rxctl5.bpl


e rxdb5.bpl estão
no seu Windows/System.

5) Vá novamente em File/Open e abra o arquivo


DCLRX5.DPK. Compile e instale
esse arquivo. Isso já vai criar uma nova guia no Delphi.
Repita a operação
para os arquivos DCLRXDB5.DPK e DCLRXBD5.DPK
(mais uma vez a ordem é
importante).

Feito isso as 3 guias foram criadas. Feche os arquivos


sem salvar.

6) Vá em Tools/Environment Option/Library. Na opção


Library path inclua o
diretório aonde estão os .pas e .dcu da RxLib (é o
diretório Units dentro da
arvore da Rx).
351 - Verificação de PIS
function vpis(Dado: String):boolean;
var
i,wsoma,wm11,wdv,wdigito: integer;
begin
if Trim(Dado) <> ” then
begin
wdv := StrToInt(copy(Dado,11,1));
wsoma := 0;
wm11 := 2;
for i := 1 to 10 do
begin
wsoma := wsoma + (wm11 *
StrToInt(Copy(Dado,11 -i, 1)));
if wm11 < 9 then
wm11 := wm11+1
else
wm11 := 2;
end;
wdigito := 11 - (wsoma mod 11);
if wdigito > 9 then
wdigito := 0;
if wdv = wdigito then
begin
Application.MessageBox(‘Valor
válido!’,‘Aviso !’, mb_IconStop+mb_ok);
vpis := True;
end
else
begin
Application.MessageBox(‘Valor informado
não é válido!’, ‘Atenção!’,
mb_IconStop+mb_ok);
vpis := false;
end;
end;
end;
353 - Imprimindo com o Bloco de
Notas
WinExec(‘NotePad.exe /p c:\FileName.txt’,
0)
354 - Estado de uma tabela
if Table1.State in [dsInsert, dsEdit] then
begin
//seus comandos
end;
355 - Adicionando uma nova fonte
no Windows
Coloque o código abaixo no OnClick de um botão:
AddFontResource(PChar(‘c:\MyFonts\Monospac
.ttf’));
Troque o nome do arquivo do exemplo anterior pelo
nome desejado. Arquivos de fonte possuem uma das
seguintes extensões: FON, FNT, TTF, FOT.
356 - Alternando Bitmaps no Fundo
de um Form
Escrito por Robert Vivrette - RobertV@mail.com
do Undu.Com
Um leitor perguntou recentemente sobre imagens de
fundo em Forms…. Apesar de já se ter escrito diversos
artigos sobre este tópico, sua questão tinhas algumas
novidades. Primeiramente, ele desejava que o fundo se
alternasse periodicamente entre diferente
Essencialmente, a solução para isto seria a aplicação de
outros artigos similares. Em primeiro lugar, para resolver
a questão de se ter diversas imagens, os bitmaps
devem ser carregados em um array quando o Form for
criado. A mudança periódica da imagem s
Finalmente, para tratar do assunto “não leia as imagens
do disco”, recorremos aos resources. Um arquivo de
resource é apenas um caminho para empacotar muito
bem qualquer tipo de dados que será anexado ao
executável durante o processo de Linkedição. Para o
BITMAP1 BITMAP IMAGE1.BMP
BITMAP2 BITMAP IMAGE2.BMP
BITMAP3 BITMAP IMAGE3.BMP
BITMAP4 BITMAP IMAGE4.BMP
BITMAP5 BITMAP IMAGE5.BMP
A primeira parte de cada linha é o identificador que você
utilizará no código para capturar uma imagem em
particular. A segunda parte é o tipo de resource (neste
caso, bitmap). E a última parte é o nome do arquivo que
deve ser utilizado para a imagem. Ist
{$R MYBMPS.RES}
Quando o executável está sendo linkeditado (um passo
antes da compilação), o resource será automaticamente
anexado ao executável. Para carregar as imagens do
resource no array de bitmaps no programa, fiz
simplesmente:
for a := 1 to NumBmps do
begin
Bmps[a] := TBitmap.Create;
Bmps[a].LoadFromResourceName(hInstance,‘BI
TMAP’+IntToStr(a));
end;
É basicamente isto… A seguir a listagem da Unit
principal:
unit Unit1a;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
const
NumBmps = 5;
type
TForm1 = class(TForm)
Timer1: TTimer;
Edit1: TEdit;
CheckBox1: TCheckBox;
ListBox1: TListBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
Bmps : Array[1..NumBmps] of TBitmap;
SelectedBmp : Integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{$R MYBMPS.RES}
procedure TForm1.FormCreate(Sender:
TObject);
var
a : Integer;
begin
for a := 1 to NumBmps do
begin
Bmps[a] := TBitmap.Create;
Bmps[a].LoadFromResourceName(hInstance,‘BI
TMAP’+IntToStr(a));
end;
SelectedBmp := 1;
end;
procedure TForm1.FormDestroy(Sender:
TObject);
var
a : Integer;
begin
for a := 1 to NumBmps do Bmps[a].Free;
end;
procedure TForm1.FormPaint(Sender:
TObject);
var
x,y,w,h : Integer;
begin
w := Bmps[SelectedBmp].Width;
h := Bmps[SelectedBmp].Height;
for x := 0 to (Width div w) do
for y := 0 to (Height div h) do
Canvas.Draw(x*w,y*h,Bmps[SelectedBmp]);
end;
procedure TForm1.Timer1Timer(Sender:
TObject);
begin
Inc(SelectedBmp);
if SelectedBmp > NumBmps then SelectedBmp
:= 1;
Paint;
end;
end.
357 - Atualizando as informações
em ambiente de rede
Acessando a mesma tabela concorrente com outra
estação ou outro objeto Query,Table, etc
a) Crie procedure para uso no evento OnActivate
procedure TForm1.FormRefresh(Sender:
TObject);
begin
Table1.Refresh;

TableN.Refresh;
end;
b) No evento OnActivate do formulário acrescente a
linha
Application.OnActivate := FormRefresh;
c) No evento OnShow do formulário acrescente a linha
FormRefresh(Sender);
d) No evento OnAfterPost de cada objeto TTable
acrescente as linhas
Table.FlushBuffers;
FormRefresh(Self);
358 - BookMarks
Bookmarks permitem ao programador “memorizar” um
determinado local da tabela para que possa retornar
mais tarde, é muito simples e fácil de usar já que
existem apenas três métodos que lhe permitem utilizar
este recurso.
Para marcar um determinado local em uma tabela
necessitamos criar uma nova instância de TBookmark e
executar o método GetBookMark de um TTable.
var
bmLocalImportante : TBookmark;
begin
bmLocalImportante := table.GetBookMark;
Para retornar a este local em particular a qualquer
momento deve- se utiliza o método GotoBookMark(),
este método recebe como parâ- metro o TBookmark
recebido como retorno de GetBookMark.
table1.GotoBookMark(bmLocalImportante);
Após utilizar o Bookmark para o que desejar é
importante que a memória utilizada por este recurso,
seja novamente liberada para o sistema, para executar
esta operação utilize o método FreeBookMark.
table1.FreeBookMark(bmLocalImportante);
Podem ser criados vários Bookmarks para uma mesma
tabela, sendo este número limitado apenas pela
quantidade de memória livre no equipamento.
Mas cuidado com o uso indevido deste recurso, cada
instancia de TBookMark reserva uma determinada
porção de memória que só será novamente liberada
para ser reutilizada após a execução de um
FreeBookmark.
Se vários Bookmarks forem criados e não liberados
podem comprometer a execução do programa.
359 - Centralizando o formulário no
centro da área do windows
var
r : TRect;
osv : TOSVersionInfo;
begin
osv.EdwOSVersionInfoSize := sizeof(osv);
GetVersionEx(osv);
if osv.dwPlatformId =
VER_PLATFORM_WIN32_WINDOWS then
begin
SystemParametersInfo(SPI_GETWORKAREA, 0,
@r, 0);
Left := ((r.right - r.left) - Width) div
2;
Top := ((r.bottom - r.top) - Height) div
2;
end
else
begin
Left := (GetSystemMetrics(SM_CXSCREEN) -
Width) div 2;
Top := (GetSystemMetrics(SM_CYSCREEN) -
Height) div 2;
end;
end;
360 - Colocando BMP’s em
StringGrids
with StringGrid1.Canvas do
begin
{…}
Draw(Rect.Left, Rect.Top,
Image1.Picture.Graphic);
{…}
end;
361 - Consultando entre datas
utilizando SQL
If DateTimePicker2.Date <
DateTimePicker1.Date Then
begin
ShowMessage(‘Intervalo de datas inválido,
a data inicial é maior que a data
final!’);
DateTimePicker2.Date :=
DateTimePicker1.Date;
end
Else
begin
Inicio := DateToStr(DateTimePicker1.Date);
Final := DateToStr(DateTimePicker2.Date);
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Text := ‘SELECT
Nome,Empresa,FoneRes,FoneCom,Mala FROM
Contatos WHERE Data >=:pInicial and
Data<=:pFinal ORDER BY Nome’;
Query1.ParamByName(‘pInicial’).AsDateTime
:= StrToDate(Inicio);
Query1.ParamByName(‘pFinal’).AsDateTime :=
StrToDate(Final);
Query1.Prepare;
Query1.Open;
DBGrid3D1.SetFocus
end;
Label3.Caption := ‘Total de contatos: ‘ +
IntToStr(Query1.RecordCount)
362 - Convertendo PCHAR para
STRING
Var
sWinDir: AnsiString;
nTam: Integer;
Begin
nTam := MAX_PATH;
SetLength(sWinDir,nTam);
GetWindowsDirectory( PChar( sWinDir ),
nTam )
SetLength(sWinDir,nTam);
End;
Pronto, pode usar o sWinDir como qualquer outra String
ou utiliza a função STRPAS
363 - Convertendo valor
Hexadecimal para Inteiro
function HexToInt(const HexStr: string):
longint;
var
iNdx: integer;
cTmp: Char;
begin
Result := 0;
for iNdx := 1 to Length(HexStr) do
begin
cTmp := HexStr[iNdx];
case cTmp of
‘0’..‘9’: Result := 16 * Result +
(Ord(cTmp) - $30);
‘A’..‘F’: Result := 16 * Result +
(Ord(cTmp) - $37);
‘a’..‘f’: Result := 16 * Result +
(Ord(cTmp) - $57);
else
raise EConvertError.Create(‘Illegal
character in hex string’);
end;
end;
end;

Complemento enviado por murilosh@bol.com.br


A dica que está no DTDelphi para converter hexadecimal para inteiro é
meio complicada. Aqui está a mais simples rotina para fazer isto.
function HexToInt(Hex: string): integer;
begin
Result := StrToInt(‘$’ + Hex);
end;
Ela só pega o hexadecimal, adiciona o caracter ‘$’ e converte para inteiro!
Por MuriloSH
364 - Convertendo valores de
Campos
No delphi podemos ler um campo armazenado numa
tabela, alterando seu tipo, ou seja, podemos ler um
campo numérico, por exemplo, como um campo string, e
vice-versa. Este recurso é útil e prático, pois permite
maior agilidade e menos programação.
Exemplo:
Se quisermos converter um campo numérico armazendo
em Tabela1 para string, armazenando-o na variável S,
podemos fazer o seguinte:
S:=tabela1.camponumerico.asstring;
Pode-se utilizar as seguintes conversões:
Asboolean - Converte para valores booleanos (lógicos)
AsDateTime - Converte para Data/Hora
AsFloat - Converte para valores numéricos de ponto
flutuante
AsInteger - Converte para valors numéricos inteiros
AsString - Converte para strings de caracteres
365 - Copiando arquivos de
diretório para diretório
procedure CopyDir(const cFrom, cTo :
string);
var
OpStruc : TSHFileOpStruct;
frombuf, tobuf : array[0..128] of Char;
begin
FillChar(frombuf, Sizeof(frombuf), 0);
FillChar(tobuf, Sizeof(tobuf), 0);
StrPCopy(frombuf, cFrom);
StrPCopy(tobuf, cTo);
with OpStruc do
begin
Wnd := Application.Handle;
wFunc := FO_COPY;
pFrom := @frombuf;
pTo := @tobuf;
fFlags := FOF_NOCONFIRMATION or
FOF_RENAMEONCOLLISION;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end; // with
ShFileOperation(OpStruc);
end; // CopyDir
366 - Copiando arquivos usando o
Shell do Windows
Coloque no uses: ShellApi
{ - Coloque um botão no form e altere o
evento OnClick deste botão conforme
abaixo:}
procedure TForm1.Button1Click(Sender:
TObject);
var
Dados: TSHFileOpStruct;
begin
FillChar(Dados,SizeOf(Dados), 0);
with Dados do
begin
wFunc := FO_COPY;
pFrom := PChar(‘c:\teste\*.txt’);
pTo := PChar(‘a:');
fFlags:= FOF_ALLOWUNDO;
end;
SHFileOperation(Dados);
end;
Observações:
Esta forma de copiar arquivos oferecem várias
vantagens. O Shell avisa para pôr um próximo disco
quando o atual estiver cheio. Mostra a barra de
progresso. Pode copiar arquivos usando máscara de
uma forma extremamente simples.
367 - Criando Alias de Banco de
Dados no código
Exemplo para arquivo .dbf e .db :
1. Crie um novo projeto.
2. Coloque os seguintes comoponentes no form:
Tdatabase, Ttable, Tdatasource, Tdbgride Tbutton.
3. Dê um duplo clique no Tdatabase para entrar no
Database propriety editor.
4. Configure o Database Name para ‘MeuAlias’ .
5. Selecione ‘STANDARD’ para Drive Name.
6. Clique no botão Default. Ele automaticamente
adicionará um PATH= na área de parâmetros.
7. Configure o PATH= para C:\DELPHI\DEMOS\DATA.
8. Clique no botão OK para fechar a caixa de diálogo.
9. Configure a proporiedade DatabaseName do Ttable
para ‘MeuAlias’.
10.Configure a proporiedade Dataset do TDatasource
para ‘Table1’.
11.Configure a proporiedade DataSource do Tdbgrid
para ‘Datasource1’.
12.Coloque o seguinte código no evento Onclick do
TButton:
Procedure
TForm1.Button1Click(Sender:Tobjetc);
begin
Table1.TableName := ‘CUSTOMER’;
Table1.Active := true;
End;
Uma alternativa para os passos 1-11: Coloque o
seguinte código no evento OnClick do TButton:
Procedure
TForm1.Button1Click(Sender:Tobjetc);
begin
Database1.DataBaseName := ‘MeuAlias’;
Database1.DriverName := ‘STANDART’;
Database1.Params.Clear;
Database1.Params.Add(‘PATH=C:\DELPHI\DEMOS
\DATA’);
Table1.DatabaseName := ‘MeuALias’;
Table1.TableName := “CUSTOMER’
Table1.Active := true;
DataSource1.Dataset := Table1;
DBGrid1.DataSource := Datasource1;
End;
368 - Criando componentes em
tempo de execução
procedure TForm1.BotaoCriaOnClick(Sender :
TObject);
Var
Button : TButton;
begin
Button := TButton.Create(Form);
with Button do
begin
Parent := Form;
height := 32;
width := 128;
caption := ‘Click em mim!’;
left := (Form.ClientWidth - width) div 2;
top := (Form.ClientHeight - height) div 2;
end;
end;
369 - Criando cores personalizadas
[sistema RGB]
Coloque um TButton no form e coloque o seguinte
código no evento OnClick:
procedure TForm1.Button1Click(Sender:
TObject);
var
Vermelho, Verde, Azul: byte;
MinhaCor: TColor;
begin
Vermelho := 0;
Verde := 200;
Azul := 150;
MinhaCor := TColor(RGB(Vermelho, Verde,
Azul));
Form1.Color := MinhaCor;
end;
A quantidade de cada cor primária é um número de 0 a
255. Observe que a cor retornada pela função RGB()
está no formato do Windows (ColorRef), é por isto que
fiz a conversão TColor(RGB(…)).
370 - Criando uma barra de status
completa
Para testar o exemplo abaixo inclua um componente
StatusBar, um componente Timer.
No componente StatusBar vá até a propriedade Panels
e adicione 3 panels.
Na propriedade Interval do componente Timer informe o
valor 500.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
ComCtrls, ExtCtrls;
type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormKeyPress(Sender: TObject;
var Key: Char);
procedure FormKeyDown(Sender: TObject; var
Key: Word; Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// Evento OnCreate do Form
procedure TForm1.FormCreate(Sender:
TObject);
begin
Timer1Timer(Self);
end;
// Evento OnTimer do componente Timer
procedure TForm1.Timer1Timer(Sender:
TObject);
begin
StatusBar1.Panels[0].Text :=
TimeToStr(Time);
if GetKeyState(VK_NUMLOCK) = 1 then
StatusBar1.Panels[1].Text := ‘Num lock:
ON’
else
StatusBar1.Panels[1].Text := ‘Num lock:
OFF’;
if GetKeyState(VK_CAPITAL) = 1 then
StatusBar1.Panels[2].Text := ‘Caps lock:
ON’
else
StatusBar1.Panels[2].Text := ‘Caps lock:
OFF’;
end;
// Evento OnKeyPress do Form
procedure TForm1.FormKeyPress(Sender:
TObject; var Key: Char);
begin
Timer1Timer(Self);
end;
// Evento OnKeyDown do Form
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word; Shift:
TShiftState);
begin
Timer1Timer(Self);
end;
371 - Deletando um Diretório
procedure DelTree(const RootDir : String);
var
SearchRec : TSearchRec;
begin
Try
ChDir(RootDir); {Caminho Especificado}
FindFirst(‘*.*’,faAnyFile,SearchRec);
Erc := 0;
while Erc = 0 do
begin
if ((SearchRec.Name <> ‘.’ ) and
(SearchRec.Name <> ‘..’)) then
begin
if (SearchRec.Attr and faDirectory>0) then
begin
{Achou o diretório e ira apagar seus
arquivos}
DelTree(SearchRec.Name);
end
else
begin
{Achou um arquivo. Apagar ou não}
end;
end;
Erc := FindNext (SearchRec);
{ Erc igual a zero se o FindNext obtiver
sucesso, senão erro do DOS}
Application.ProcessMessages;
end;
finally
if Length(RootDir) > 3 then
ChDir(‘..’);
end;
end;
372 - Descobrindo se há impressora
instalada
try
// Set printer so, for get information
JustTest := Printer.Orientation;
IsPrinterSetup := true;
except
on EPrinter do IsPrinterSetup := false;
end;
if not IsPrinterSetup then
begin
SayAboutIt;
ExitProgram;
End;
373 - Descobrindo se o aplicativo
está minimizado
Coloque no uses: Windows
if IsIconic(Application.Handle) then
{ Minimizado }
else
{ Não minimizado }
Observações:
Pode-se verificar qualquer janela (form). Só um
lembrete:
Quando clicamos no botão de minimizar do form
principal, na verdade ele é oculto e o Application é que é
minizado.
374 - Descobrindo se um form já
está criado
Bem saber se um form já esta ou não criado, melhor
dizer instanciado, não é um problema muito crítico,
abaixo pode-se ver uma unit padrão criada com um form
vazio no Delphi, esta unit alem de declarar o nova
classe TForm1 cria também uma variável Form1 do Isto
é muito importante que seja observado, uma variável
para um tipo “FORM” nada mais é que um ponteiro, ou
seja ela apenas mostra em que local da memória está a
instancia do seu form, enquanto o seu form não existir
este ponteiro deve apontar para lugar
unit Unit1
interface
uses SysUtils, WinTypes, WinProcs,
Messages, Classes, Graphics, Controls,
Forms, Dialogs;
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var Form1: TForm1;
implementation
{$R *.DFM}
end.
Partindo deste princípio podemos verificar se um form
foi ou não instanciado verificando o valor guardado em
FORM1, se este valor for diferente de “NIL” significa que
o Form já foi instanciado…
Bem a coisa não é assim tão simples, imagine que um
amigo mudou-se para São Paulo e lhe passou seu novo
endereço, você recebe e anota em sua agenda,. depois
de dois meses ele resolve que não quer mais morar em
São Paulo e vai embora, ok o fato de seu amig
A forma mais limpa e automática para se contornar este
problema nos obriga acodificar o seguinte no evento
OnDestroy do Form :
procedure TForm1.FormDestroy(Sender:
TObject);
begin
Form1 := nil;
end;
Assim, quando o “FORM1” for destruído ele apaga o seu
endereço junto.
Assim quando for instanciar um form utilize a seguinte
verificação:
if Form2 = nil then
Form2 := TForm2.Create(Self);
Form2.Show;…
Interessante que o Show quando um form já esta criado
tem o efeito de umBringToFront.
Bem tudo isso resolve parte do problema, a outra parte
tem de ser resolvida por você estruturando o seu
programa de forma aos controles funcionem de acordo.
1 - Este controle não funciona para forms com múltiplas
instancias, a não ser que você crie uma variável para
cada instancia.
Pessoalmente eu nunca usei isso, se um form pode ter
múltiplas instancias em MDI então controle por
ActiveMDIChild e se for SDI então não sei porque ter
mais de uma instancia.
2 - Quando for criar um novo form não crie variáveis
desnecessariamente, utilize a variável que já esta sendo
criada na unit do Form.
Ex: Dados FORM1 e FORM2
Apenas FORM1 está no AUTO-CREATE. Quando no
uses de FORM1 for referenciada a unit UNIT2 a variável
FORM2 estará acessível, use-a.
FORM2 := TFORM2.CREATE(SELF);
3 - Quando um Form é mostrado com ShowModal este
tipo de controle não se aplica já que será impossível
mostrar qualquer outro form.
375 - Descobrindo se um form já
está criado 2
Quando um form ou outro objeto não existe, ou seja,
ainda não foi criado, a variável usada para instanciar o
objeto está “nil”. Exemplo:
form1 := Tform1.create();
A variável form1 passa a ter um valor diferente de nil.
Logo, faça o teste:
If form1 = nil then
{form não criado ainda ou já foi fechado}
Lembre-se de fazer o form1, no seu evento close,
receber nil.
form1 := nil;
Assim ele estará fechado e não existirá mais. Teste este
exemplo e verá.
376 - Descobrindo se um objeto
tem uma determinada propriedade
uses Typinfo
if GetPropInfo(DataSet, ‘TableName’) <>
nil then
ShowMessage(‘Objeto TTable’);
377 - Descobrindo se uma janela
(form) está maximizada
Coloque no uses: Windows
if IsZoomed(Form1.Handle) then
{ Form1 está maximizado }
else
{ Form2 NÃO está maximizado }
378 - Detectando e Finalizando o
screen saver
Primeiro verifique se o protetor de tela está em
execução
Function IsScreensaverRunning: Boolean;
var
old: Bool;
begin
SystemParametersInfo(
SPI_SCREENSAVERRUNNING, 0, @old, 0 );
Result := old;
If old Then
Begin
SystemParametersInfo(
SPI_SCREENSAVERRUNNING, 1, @old, 0 );
End; { If }
end;
Se estiver em execução simule o pressionamento de
uma tecla
keybd_event( VK_SPACE, MapVirtualkey(
VK_SPACE, 0 ), 0, 0);
keybd_event( VK_SPACE, MapVirtualkey(
VK_SPACE, 0 ), KEYEVENTF_KEYUP, 0);
379 - Exibindo solicitação de senha
do banco dados personalizada
Coloque no uses: DbPwDlg
{ Coloque um botão no form e escreve seu
evento OnClick como abaixo }
procedure TForm1.Button1Click(Sender:
TObject);
var
pw: TPasswordDialog;
begin
pw := TPasswordDialog.Create(Self);
try
pw.Caption := ‘Banco de Dados’;
pw.GroupBox1.Caption := ‘Senha’;
pw.AddButton.Caption := ‘&Adicionar’;
pw.RemoveButton.Caption := ‘&Remover’;
pw.RemoveAllButton.Caption := ‘Remover
&Tudo’;
pw.OKButton.Caption := ‘&OK’;
pw.CancelButton.Caption := ‘&Cancelar’;
pw.ShowModal;
finally
pw.Free;
end;
end;
Observações:
As senhas adicionadas nesta caixa de diálogo são
adicionadas na sessão (TSession) atual. Isto é útil
quando colocamos senha em tabelas Paradox, ou
mesmo quando trabalhamos com banco de dados Client
Servidor, e queremos que o usuário digite a senha de
aces
380 - Exibindo corretamente o
conteúdo dos campos boolean
Chame o fields editor da tabela onde eles existirem,
adicione os campos e na propriedade DisplayValues
informe a string Sim;Nao. Com isso, também será
permitido informar ‘S’ para true e ‘N’ para false.
381 - Exibindo o diálogo About do
Windows
Coloque no uses: Shellapi
{ About padrão do Windows }
ShellAbout(Handle, ‘Windows’, ”, 0);
{ Personalizada }
ShellAbout(Handle, ‘NomePrograma’,
‘Direitos autorais reservados a’#13’Fulano
de Tal’, Application.Icon.Handle);
382 - Exibindo ou compararando
data de arquivos
procedure TForm1.Button1
var
TheFileDate: string;
Fhandle: integer;
begin
FHandle := FileOpen(YourFileName, 0);
try
TheFileDate :=
DateTimeToStr(FileDateToDateTime(FileGetDa
te(FHandle)));
finally
FileClose(FHandle);
end;
end;
383 - Exportando Relatório do
QuickReport para HTML, DOC, TXT
ou XLS
Na clausula uses, acrescente a unit QRExport
Exportando para HTML:
QuickReport.ExportToFilter(TQRHTMLDocument
Filter.Create(‘c:\teste.html’));
Exportando para DOC ou TXT:
QuickReport.ExportToFilter(TQRAsciiExportF
ilter.Create(‘c:\teste.doc’));
Exportando para XLS:
QuickReport.ExportToFilter(TQRXLSFilter.Cr
eate(‘c:\teste.xls’));
Atenção : Esta dica foi testada utilizando o Delphi 4 com
o QuickReport 3.05, pode ser que em outras versões do
Delphi ou do QuickReport, possa vir a não funcionar

OBS: A dica não funciona em todas as versões do


Quickreport
384 - Fazendo cálculo de horas
var
hora1: TDateTime;
hora2: TDateTime;
total: TDateTime;
begin
hora1 := StrToTime(Edit1.Text);
hora2 := StrToTime(Edit2.Text);
total := Hora2 - Hora1;
Label1.Caption :=
FormatDateTime(‘hh:nn:ss’,total);
end;
385 - Fazendo sua aplicação
executar sem apresentar o form
principal
program Project1;
uses
Forms,Windows,
Unit1 in ‘Unit1.pas’ {Form1};
{$R *.RES}
begin
Application.Initialize;
Application.ShowMainForm := False; <====
aqui.
Application.CreateForm(TForm1, Form1);
Showwindow(application.handle,sw_hide);
<== Este oculta da TaskBar
Application.Run;
end.
386 - Fazendo um Pack em arquivos
PARADOX
Uses Bde

procedure TForm1.ParadoxPack(Table :
TTable);
var
TBDesc : CRTblDesc;
hDb: hDbiDb;
TablePath: array[0..dbiMaxPathLen] of
char;
begin
Table.Open;
FillChar(TBDesc,Sizeof(TBDesc),0);
with TBDesc do
begin
StrPCopy(szTblName,Table.TableName);
StrPCopy(szTblType,szParadox);
bPack := True;
end;
hDb := nil;
Check(DbiGetDirectory(Table.DBHandle,
True, TablePath));
Table.Close;
Check(DbiOpenDatabase(nil, ‘STANDARD’,
dbiReadWrite, dbiOpenExcl,nil,0, nil,
nil, hDb));
Check(DbiSetDirectory(hDb, TablePath));
Check(DBIDoRestructure(hDb,1,@TBDesc,nil,n
il,nil,False));
Table.Open;
end;

Exemplo de Uso:ParadoxPack(Table1);
387 - Fazendo uma impressão
direta
procedure Say(Nlin,Ncol: Integer;Var
LinhaAtual: Integer; Var Arquivo:
Text;Texto: Variant);
{Função para impressão de linhas em um
relatório}
var
X: Integer;
begin
Write(Arquivo,#13);
If Nlin<>LinhaAtual then
begin
for X :=LinhaAtual to (Nlin-1) do
begin
WriteLn(Arquivo,”);
LinhaAtual:=LinhaAtual+1;
end;
end;
If Ncol>0 then
begin
For X:=0 to Ncol do
begin
Write(Arquivo,’ ‘);
end;
end;
If LinhaAtual >=63 then { 63 É O NÚMERO DA
ÚLTIMA LINHA ANTES DO RODAPÉ}
begin
For X:=63 to 67 do { 67 É A QUANTIDADE DE
LINHAS POR PÁGINA }
begin
Writeln(Arquivo,”);
LinhaAtual:=1;
end;
end;
Write(Arquivo,Texto);
end;
procedure TForm1.Button1Click(Sender:
TObject);
var
ArqPrn: TextFile;
LinhaAtual: Integer;
begin
LinhaAtual:=0;
AssignFile(ArqPrn,‘LPT1’);
ReWrite(ArqPrn);
Say(00,00,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(01,01,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(02,00,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(03,03,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(04,00,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(05,03,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(06,00,LinhaAtual,ArqPrn,‘Wincomp
Informática Ltda’);
Say(07,04,LinhaAtual,ArqPrn,123456789);
Say(08,00,LinhaAtual,ArqPrn,123456789);
Say(09,00,LinhaAtual,ArqPrn,123456789);
CloseFile(ArqPrn);
end;
388 - Fazendo uma janela filha de
outra sem usar MDI
procedure TForm1.CreateParams(var Params:
TCreateParams);
begin
inherited CreateParams(Params); { call the
inherited first }
with Params do
begin
Style := Style or WS_CHILD; { add a style
flag }
WndParent := Application.MainForm.Handle;
end;
end;
389 - Finalizando todas as tarefas
procedure
TForm1.ButtonKillAllClick(Sender:
TObject);
var
pTask : PTaskEntry;
Task : Bool;
ThisTask: THANDLE;
begin
GetMem (pTask, SizeOf (TTaskEntry));
pTask^.dwSize := SizeOf (TTaskEntry);
Task := TaskFirst (pTask);
while Task do
begin
if pTask^.hInst = hInstance then
ThisTask := pTask^.hTask
else
TerminateApp (pTask^.hTask, NO_UAE_BOX);
Task := TaskNext (pTask);
end;
TerminateApp (ThisTask, NO_UAE_BOX);
end;
390 - Como incrementar 1 mês
numa data
IncMonth(Data, 1);
No exemplo, a variável Data é do tipo TDateTime.

obs: para decrementar basta usar assim:


IncMonth(Data, -1);
391 - Como obter informações do
S.O. (Nome, Versão, Compilação)
Vamos à função :
unit sobreManager;
interface
uses Windows, SysUtils, Classes, Graphics,
Forms, Controls, StdCtrls, Buttons,
ExtCtrls;
type
TfrmSobreManager = class(TForm)
btnOK: TButton;
ProductName: TLabel;
Version: TLabel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Copyright: TLabel;
Panel1: TPanel;
Image2: TImage;
GroupBox1: TGroupBox;
Bevel1: TBevel;
stOSVersao: TStaticText;
stOSBuilder: TStaticText;
stOS: TStaticText;
stOSService: TStaticText;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmSobreManager: TfrmSobreManager;
implementation

{$R *.DFM}
// VERIFICA E APRESENTA AS INFORMAÇÕES do
SISTEMA OPERACIONAL
procedure
TfrmSobreManager.FormCreate(Sender:
TObject);
var
verInfo : TOsVersionInfo;
str : String;
I : Word;
begin
verInfo.dwOSVersionInfoSize :=
SizeOf(TOSVersionInfo);
if GetVersionEx(verInfo) then begin
stOSVersao.Caption := ‘Versão : ‘+
IntToStr(verInfo.dwMajorVersion) +
IntToStr(verInfo.dwMinorVersion);
OSBuilder.Caption := ‘Compilação :
‘+IntToStr(verInfo.dwBuildNumber);
str := ‘Sistema Operacional : ‘;
case verInfo.dwPlatformId of
VER_PLATFORM_WIN32s : stOS.Caption := str
+‘Windows 95’;
VER_PLATFORM_WIN32_WINDOWS : stOS.Caption
:= str +‘Windows 95 Osr2 / 98’;
VER_PLATFORM_WIN32_NT : stOS.Caption :=
str +‘Windows NT’;
end;
str := ”;
for I := 0 to 127 do
str := str + verInfo.szCSDVersion[I];
stOSService.Caption := ‘Informações
Adicionais : ‘+ str;
end
end;
end.
392 - Unit com varias funções de
datas
unit FaCDate;
{** Criada em 24/07/1999 - Baseada em
necessidades genericas de tratamento de
datas ** Autor : Fabio Camara}
interface
uses
Forms, Dialogs, Messages, WinProcs,
SysUtils, Classes,
Graphics, ExtCtrls, Controls;

Type {Tipos criados}


TSemestre = record
Mes, Ano : Word;
end;
Semestre = array[0..5] of TSemestre;

function
ReturnSixMonth(Actual:TDateTime):Semestre;
function
NameMonth(Mes:Word;Abrev:Boolean):string;
function DataExtenso(Data:TDateTime):
string;
function DataValida(StrD: string):
boolean;
function
PrimeiroDiaUtil(Data:TDateTime):TDateTime;
function IsWeekEnd(dData : TDateTime) :
boolean;

implementation

function
ReturnSixMonth(Actual:TDateTime):Semestre;
{Retorna 6 meses atrás da data enviada, de
mes em mes}
var
d,m,y : word;
i : byte;
Data : TDateTime;
begin
for i := 6 downto 1 do begin
Data := Actual - (30 * i);
DecodeDate(Data,y,m,d);
Result[i].Mes := m;
Result[i].Ano := y;
end;
end;

function
NameMonth(Mes:Word;Abrev:Boolean):String;
{Retorna o nome de um mês abreviado ou
não}
const
NameL : array [1..12] of String[9] =
(‘JANEIRO’,‘FEVEREIRO’,‘MARÇO’,‘ABRIL’,
‘MAIO’,‘JUNHO’,‘JULHO’,‘AGOSTO’,
‘SETEMBRO’,‘OUTUBRO’,‘NOVEMBRO’,
‘DEZEMBRO’);
begin
if (Mes in [1..12]) then
if Abrev then
Result := Copy(NameL[Mes],1,3)
else
Result := NameL[Mes];
end;

function DataExtenso(Data:TDateTime):
String;
{Retorna uma data por extenso}
var
NoDia : Integer;
DiaDaSemana : array [1..7] of String;
Meses : array [1..12] of String;
Dia, Mes, Ano : Word;
begin
{ Dias da Semana }
DiaDasemana [1]:= ‘Domingo’;
DiaDasemana [2]:= ‘Segunda-feira’;
DiaDasemana [3]:= ‘Terçafeira’;
DiaDasemana [4]:= ‘Quarta-feira’;
DiaDasemana [5]:= ‘Quinta-feira’;
DiaDasemana [6]:= ‘Sexta-feira’;
DiaDasemana [7]:= ‘Sábado’;
{ Meses do ano }
Meses [1] := ‘Janeiro’;
Meses [2] := ‘Fevereiro’;
Meses [3] := ‘Março’;
Meses [4] := ‘Abril’;
Meses [5] := ‘Maio’;
Meses [6] := ‘Junho’;
Meses [7] := ‘Julho’;
Meses [8] := ‘Agosto’;
Meses [9] := ‘Setembro’;
Meses [10]:= ‘Outubro’;
Meses [11]:= ‘Novembro’;
Meses [12]:= ‘Dezembro’;
DecodeDate (Data, Ano, Mes, Dia);
NoDia := DayOfWeek (Data);
Result := DiaDaSemana[NoDia] + ‘, ‘ +
IntToStr(Dia) + ‘ de ‘ + Meses[Mes]+ ‘
de ‘ + IntToStr(Ano);
end;

function DataValida(StrD: string):


Boolean;
{Testa se uma data é valida}
begin
Result := true;
try
StrToDate(StrD);
except
on EConvertError do Result:=False;
end;
end;

function
PrimeiroDiaUtil(Data:TDateTime):TDateTime;
{Retorna data do primeiro dia Util do mes,
de uma data informada}
var Ano, Mes, Dia : word;
DiaDaSemana : Integer;
begin
DecodeDate (Data, Ano, Mes, Dia);
Dia := 1;
DiaDaSemana := DayOfWeek(Data);
if DiaDaSemana in [1,7] then
Dia := 2;
Result := EncodeDate(Ano, Mes, Dia);
end;

function IsWeekEnd(dData : TDateTime) :


boolean;
{Verifica se uma data informada cai em um
final de semana}
begin
if DayOfWeek(dData) in [1,7] then
result := true
else
result := false;
end;
end.
393 - Consulta SQL que usa a data
do sistema
Problema:
Preciso fazer uma consulta com SQL que me retorne
todos os registros em que o valor de um campo do tipo
data seja igual ou anterior à dada do sistema. Como
fazer?
Solução:
Query.Close;
Query.SQL.Text := ‘select * from Tabela
where CampoData <= :Hoje’;
Query.ParamByName(‘Hoje’).AsDate := Date;
Query.Open;
Observações
Este exemplo foi testado com tabelas Paradox, mas
deve funcionar na maioria dos bancos de dados com
pouca ou nenhuma alteração
394 - Imprimindo Forms
O exemplo a seguir é um procedimento para imprimir
um form. Para imprimir o form, basta informar o nome do
mesmo como parâmetro: PrintForm(Form1). Antes de
imprimir, a cor atual do form é salva em OldColor e
alterada para clWhite (frm.Color := clWhite), para evitar
gasto excessivo de tinta da impressora (ou tonner).
PrintForm
uses
Windows, SysUtils, Printers, Forms,
Graphics, Controls, Classes;
.
.
.
procedure PrintForm(frm: TForm);
var
bmp: TBitMap;
x, y, WDPI, HDPI: Integer;
OldColor: TColor;
begin
Screen.Cursor := crHourGlass;
OldColor := frm.Color;
frm.Color := clWhite;
frm.Update;
bmp := frm.GetFormImage;
with Printer do
begin
Orientation := poLandscape;
BeginDoc;
HDPI := PageHeight div 8;
WDPI := PageWidth div 8;
x := PageWidth - Round(WDPI * 0.4);
{0.4” margem direita}
y := PageHeight - Round(HDPI * 0.5);
{0.5” Altura do rodapé}
Canvas.StretchDraw(Rect(0, 0, x, y),
bmp);
EndDoc;
end;
bmp.Free;
frm.Color := OldColor;
Screen.Cursor := crDefault;
end;
395 - O Enigma da propriedade
filter do TTable
Sei que em muitos casos, manipular uma propriedade
no Object Inspector é uma tarefa simples, que não exige
muito do desenvolvedor, mas quando a necessidade é
ativa-las em RunTime (tempo de execução), a
complexidade aumenta consideravelmente.
Revisando um pouco, a propriedade filter recebe um
valor do tipo string, e ao acionar a propriedade filtered
para true, aplica-se uma filtragem na tabela relacionada,
colocando disponíveis apenas os registros que
satisfazem a condição do filtro. Por exemplo: Colocamos
na propriedade filter de um Ttable (via Object Inspector)
a seguinte regra - state = ‘CA’ - Onde state é o nome do
campo da tabela relacionada e CA é a condição de filtro.
Notem que CA esta entre aspas, e é justamente este o
problema, em tempo de execução temos que passar os
valores entre aspas. E se estamos passando em
RunTime, é porque queremos permitir a flexibilidade de
um filtro ser escolhido pelo usuário do sistema, agora
como vamos passar uma variável para a propriedade
filter que possua aspas? É notório que o compilador
trata valores entre aspas do seu código como valores
string. Pronto, descobrimos o enigma, vamos agora
desvendá-lo.
A primeira alternativa que veio a minha cabeça para
resolver este problema, foi imaginar passar aspas dentro
de aspas, criando um código que considerei bizarro.
Var
Texto : String;
Begin
Table1.Filter := ‘state = ‘+””+Texto+””;
Table1.Filtered := True;
End;
Funcionar, funcionou, mas não me conformei com este
monstro. Continuei pensando e tive a idéia de
concatenar strings com o caractere AscII
correspondente a aspas, acredito que visualmente ainda
não era o ideal, porém era menos grotesco e mais fácil
de outros programadores entenderem.
Var
Texto : String;
Begin
Table1.Filter := ‘state = ‘+#39+Texto+#39;
Table1.Filtered := True;
End;
Continuei conjugando a frase: “Funcionar, funcionou,
mas não estou ainda 100% satisfeito”. Sou um fã
incondicional do bom e velho Pascal, e simplesmente
não aceitaria este tipo de “gambiarra” para solucionar
este enigma. De posse do manual de Object Pascal,
comecei a procurar uma solução mais condizente com a
categoria do Delphi (Nota do Autor: Categoria muito alta,
pois afirmo que o Delphi é a melhor linguagem de
desenvolvimento que já conheci). A noite foi virando
madrugada, o café foi acabando, a determinação ainda
estava forte quando li: QuotedStr. Sabia antes de ler sua
definição que havia encontrado a solução, minha
palpitação não se enganava. Vamos testar:
Var
Texto : String;
Begin
Table1.Filter := ‘state =
‘+QuotedStr(Texto);
Table1.Filtered := True;
End;
Um sorriso tomou conta de minha face, sabia que o
meu velho amigo Pascal não ia me decepcionar, afinal
somos amigos a 6 anos, e defendo ele com unhas e
dentes, como realmente deve ser um amigo fiel.
Aproveito para lembrar que você pode também colocar
filtros parciais, como por exemplo:
Var
Texto : String;
Begin
Texto := ‘F*’;
Table1.Filter := ‘state =
‘+QuotedStr(Texto);
Table1.Filtered := True;
End;
Neste exemplo, todos os estados iniciados pela letra ‘F’
seriam mostrados em seu DataControls/DBGrid.
396 - Permitir cancelar processo
demorado
Problema:
Em determinadas partes no programa existem
processos que podem demorar vários minutos para
serem concluídos. Muitas vezes o usuário desiste e
deseja cancelar o processamento. Como permitir este
cancelamento?
Solução:
Em aplicativos para Windows é comum, em
processamentos demorados, o programa mostrar uma
janela de diálogo avisando que o processo pode levar
um tempo extra. Nesta mesma janela normalmente
coloca-se também um botão “Cancelar” que dá ao
usuário a opção aguardar ou desistir do processo. Para
fazer isto em um aplicativo Delphi, siga os passos
abaixo:
- Vamos considerar em nosso exemplo que o
processamento ocorre na unit do Form1.
- Declare, na seção public do Form1, uma variável
boolean.
public;
Cancelar: boolean;
- Crie um novo form (vou chamá-lo de Form2);
- Coloque um botão neste novo form. Programe o
OnClick deste botão conforme abaixo:
Form1.Cancelar := true;
- Na parte onde ocorre o loop do processamento
demorado coloque algo como:
try
{ Antes de começar o processamento }
Form2.Caption := ‘Processamento
demorado…’;
Form2.Show;
{ No início do loop “Cancelar” precisa
ser false }
Cancelar := false;
{ Aqui inicia o loop do processamento
demorado }
while {…} do begin
{ … Processa algo aqui… }
{ Permite que o programa processe
mensagens do Windows }
Application.ProcessMessages;
{ Se a variável “Cancelar” foi alterada
para true… }
if Cancelar then begin
ShowMessage(‘Operação cancelada pelo
usuário.’);
Break; { Sai do loop }
end;
end;
finally
Form2.Close;
end;
Observações
Não se esqueça de que o Form1 precisa usar Form2 e
vice-versa.
397 - Descobrir se uma data é fim
do mês
Inclua na seção uses: SysUtils
{ Esta função retorna true se a data passada como
parâmetro é fim de mês. Retorna false caso contrário. }
function tbFimDoMes(const Data:
TDateTime): boolean;
var
Ano, Mes, Dia: Word;
begin
DecodeDate(Data +1, Ano, Mes, Dia);
Result := Dia = 1;
end;
398 - Obter o tipo de dado de um
valor no Registro do Windows
Inclua na seção uses: Registry, Dialogs
- Coloque um botão no form;
- Altere o evento OnClick do botão conforme abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
const
cRegPath =
‘System\CurrentControlSet\control\FileSyst
em’;
cRegValue = ‘ACDriveSpinDown’;
var
Reg: TRegistry;
S: string;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey(cRegPath, false) then
begin
case Reg.GetDataType(cRegValue) of
rdUnknown: S := ‘Tipo Desconhecido’;
rdString: S := ‘String’;
rdExpandString: S := ‘ExpandString’;
rdInteger: S := ‘Inteiro’;
rdBinary: S := ‘Binário’;
end;
ShowMessage(S);
end else
ShowMessage(‘Erro ao abrir chave do
Registro’);
finally
Reg.Free;
end;
end;
Observações
A unit Dialogs foi acrescentada no uses somente para
podermos usar a procedure ShowMessage.
399 - Programar meu aplicativo
para abrir arquivos a partir do
Windows Explorer
Inclua na seção uses: Registry
Problema:
Criei um editor de textos no Delphi. Agora gostaria que o
Windows Explorer usasse este editor para abrir arquivos
com a extensão .dpg e .dan. Como fazer?
Solução:
Para fazer isto será necessária a criação de algumas
chaves no Registro do Windows. O exemplo abaixo cria
todas as chaves necessárias.
- Coloque um TButton e no evento OnClick dele coloque
o código abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.LazyWrite := false;
{ Define o nome interno (ArquivoDaniel)
e uma legenda que aparecerá no Windows
Explorer (Arquivo do Daniel) }
Reg.OpenKey(‘ArquivoDaniel’, true);
Reg.WriteString(”, ‘Arquivo do Daniel’);
Reg.CloseKey;
{ Define o comando a ser executado quando
abrir um arquivo pelo Windows Explorer
(NomeDoExe %1). O símbolo %1 indica que o
arquivo a ser aberto será passado como
primeiro parâmetro para o aplicativo -
ParamStr(1). }

Reg.OpenKey(‘ArquivoDaniel\shell\open\comm
and’, true);
Reg.WriteString(”, ParamStr(0) + ‘ %1’);
{ NomeDoExe %1 }
Reg.CloseKey;
{ Define o ícone a ser usado no Windows
Explorer:
0 - primeiro ícone do EXE
1 - segundo ícone do EXE, etc }
Reg.OpenKey(‘ArquivoDaniel\DefaultIcon’,
true);
Reg.WriteString(”, ParamStr(0) + ‘,0’);
{ 0 = primeiro ícone }
Reg.CloseKey;
{ Define as extensões de arquivos que
serão abertos pelo meu aplicativo }
{ *.dpg }
Reg.OpenKey(‘.dpg’, true);
Reg.WriteString(”, ‘ArquivoDaniel’);
Reg.CloseKey;
{ *.dan }
Reg.OpenKey(‘.dan’, true);
Reg.WriteString(”, ‘ArquivoDaniel’);
Reg.CloseKey;
finally
Reg.Free;
end;
end;
- Coloque um TMemo;
- No evento OnShow do Form coloque o código abaixo:
procedure TForm1.FormShow(Sender:
TObject);
begin
{ Se o primeiro parâmetro for um nome de
arquivo existente… }
if FileExists(ParamStr(1)) then
{ Carrega o conteúdo do arquivo no memo
}
Memo1.Lines.LoadFromFile(ParamStr(1));
end;
*** Para testar ***
- Execute este programa;
- Clique no botão para criar as chaves no Registro do
Windows;
- Feche o programa;
- Crie alguns arquivos com as extensões .dpg e .dan;
- Vá ao Windows Explorer e procure pelos arquivos
criados;
- Experimente dar um duplo-clique sobre qualquer dos
arquivos com uma das extensões acima.
Observações
Existem outros recursos que poderão ser configurados.
Porém, para começar, este já é um bom exemplo.
400 - Consultar por mês de um
campo data
Problema:
Tenho um cadastro de clientes com Codigo, Nome,
DataNasc, etc.
Preciso fazer uma consulta onde apareceão apenas os
clientes que fazem aniversário em determinado mês.
Como fazer?
Solução:
Use uma Query como abaixo:
- Coloque no form os seguintes componentes:
* TQuery
* TDataSource
* TDBGrid
* TEdit
* TButton
- Altere as propriedades dos componentes como abaixo:
* Query1.DatabaseName = (alias do BDE)
* DataSource1.DataSet = Query1
* DBGrid1.DataSource = DataSource1
- Coloque o código abaixo no evento OnClick de
Button1:
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add(‘select * from dCli’);
Query1.SQL.Add(‘where extract(month from
DataNasc) = :Mes’);
Query1.ParamByName(‘Mes’).AsInteger :=
StrToInt(Edit1.Text);
Query1.Open;
- Execute. Digite um número de 1 a 12 no Edit e clique
no botão.
Observações
Os números de 1 a 12 representam, respectivamente,
os meses de Janeiro a Dezembro. Este exemplo foi
testado com Delphi4, BDE5 e tabela Paradox7.
401 - Criando tabelas via SQL
Inclua na seção uses: dbTables
- Coloque um TButton no form;
- Escreve no OnClick do Button como abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
Q: TQuery;
begin
Q := TQuery.Create(Application);
try
Q.DatabaseName := ‘SF’;
with Q.SQL do begin
Add(‘Create Table Funcionarios’);
Add(‘( Codigo AutoInc,’);
Add(‘ Nome Char(30),’);
Add(‘ Salario Money,’);
Add(‘ Depto SmallInt,’);
Add(‘ Primary Key (Codigo) )’);
end;
Q.ExecSQL;
finally
Q.Free;
end;
end;
Observações
Este exemplo foi testado com banco de dados Paradox,
porém deverá funcionar em vários outros bancos de
dados com pouca ou nenhuma alteração.
402 - Obter nomes dos campos de
uma tabela
Inclua na seção uses: dbTables, Classes, Forms
A função abaixo obtém os nomes de todos os campos
de uma tabela do banco de dados.
procedure tbGetFieldNames(const DBName,
TblName: string;
List: TStringList);
var
I: integer;
begin
List.Clear;
with TTable.Create(Application) do
try
DatabaseName := DBName;
TableName := TblName;
with FieldDefs do begin
Update;
for I := 0 to Count -1 do
List.Add(Items[I].Name);
end;
finally
Free;
end;
end;
=== Exemplo de uso ===
- Coloque um TMemo e um TButton no Form;
- Coloque o código abaixo no evento OnClick do Button:
procedure TForm1.Button1Click(Sender:
TObject);
var
List: TStringList;
begin
List := TStringList.Create;
try
tbGetFieldNames(Edit1.Text, Edit2.Text,
List);
Memo1.Lines.Assign(List);
finally
List.Free;
end;
end;
403 - Nomeando um relatório no
spool de impressão do Windows
Inclua na seção uses: Printers
Problema:
Quando mandamos imprimir no Windows, normalmente
o nome do documento aparece na fila de impressão
(spool). Como fazer com que aplicativos feitos em
Delphi se comporte desta forma? Ou seja, como nomear
meus relatórios feitos em Delphi?
Solução:
Antes de enviar seu relatório, faça assim:
Printer.Title := ‘Nome do relatório’;
Observações
Esta solução aplica-se perfeitamente aos relatórios
feitos usando o objeto Printer. Nos casos de geradores
de relatórios, estes provavelmente possuem uma
propriedade equivalente.
404 - Impedir que o form seja
arrastado para fora das margens da
tela
- Na seção Private declare a procedure abaixo:
private
procedure WMMove(var Msg: TWMMove);
message WM_MOVE;
- Abaixo da palavra implementation escreva a procedure
abaixo:
procedure TForm1.WMMove(var Msg: TWMMove);
begin
if Left < 0 then
Left := 0;
if Top < 0 then
Top := 0;
if Screen.Width - (Left + Width) < 0
then
Left := Screen.Width - Width;
if Screen.Height - (Top + Height) < 0
then
Top := Screen.Height - Height;
end;
Para testar:
- Execute o programa e tente arrastar o form para fora
das margens da tela e veja o que acontece.
405 - Mostrar mensagem mesmo
que esteja no Prompt do DOS
Inclua na seção uses: Windows
Problema:
Fiz um programa que mostra mensagens de lembrete
quando é chegada determinada data/hora. Porém
quando o usuário vai para o Prompt do MS-DOS em
modo tela cheia, a mensagem não aparece. O que devo
fazer?
Solução:
Antes de mostrar a mensagem, coloque sua aplicação
na frente das demais.
SetForegroundWindow(Application.Handle);
ShowMessage(‘Teste’);
406 - Criar sub-diretório no
diretório do EXE
Inclua na seção uses: FileCtrl, SysUtils
Problema:
Gostaria de criar um sub-diretório dentro do diretório
onde se encontra o EXE de minha aplicação. Como
fazer?
Solução:
Primeiramente vamos conhecer algumas funções do
Delphi que precisaremos usá-las:
ParamStr(Indice) - Retorna valores passados na linha
de comando quando executamos o programa. Se o valor
de Indice for 0 (zero) será retornado o caminho+nome
do EXE.
ExtractFilePath(NomeArq) - Retorna o caminho (path)
do nome de arquivo informado.
Exemplo:
S := ‘C:\NomeDir\Programa.exe’;
ExtractFilePath(S); { retorna:
‘C:\NomeDir' }
DirectoryExists(CaminhoDir) - Retorna true se o
diretório informado existe. False em caso contrário.
CreateDir(CaminhoDir) - Tenta criar o diretório
informado.
Se conseguir, retorna true. Caso contrário retorna false.
Agora que sabemos como trabalham estas funções,
vamos escrever uma função que precisamos para criar
um sub-diretório conforme proposto.
function CriaSubDir(const NomeSubDir:
string): boolean;
var
Caminho: string;
begin
Caminho := ExtractFilePath(ParamStr(0))
+ NomeSubDir;
if DirectoryExists(Caminho) then
Result := true
else
Result := CreateDir(Caminho);
end;
Exemplo de uso:
- Chame a função no evento OnCreate do form:
procedure TForm1.FormCreate(Sender:
TObject);
begin
if not CriaSubDir(‘MeuSubDir’) then
ShowMessage(‘Não foi possível criar o
sub-diretório MeuSubDir.’);
end;
407 - Enviar comandos de rolagem
vertical para um TMemo
Inclua na seção uses: Windows
Problema:
Gostaria que o meu programa rolasse automaticamente
o conteúdo de um TMemo, simulando o deslizamento da
barra de rolagem vertical. Isto é possível no Delphi?
Solução:
Sim. Utilizando mensagens do Windows isto é fácil.
Vejamos algums exemplos:
SendMessage(Memo1.Handle, WM_VSCROLL,
SB_PAGEDOWN, 0);
Onde:
Memo1.Handle = manipulador da janela do Memo1.
WM_VSCROLL = Mensagem do Windows - rolagem
vertical.
SB_PAGEDOWN = Comanndo de rolagem - página para
baixo.
Outros exemplos:
{ Página para cima }
SendMessage(Memo1.Handle, WM_VSCROLL,
SB_PAGEUP, 0);
{ Linha para baixo }
SendMessage(Memo1.Handle, WM_VSCROLL,
SB_LINEDOWN, 0);
{ Linha para cima }
SendMessage(Memo1.Handle, WM_VSCROLL,
SB_LINEUP, 0);
Observações
Além desta técnica existem API’s do Windows que
fazem um trabalho equivalente.
408 - Criar form sem título que
possa ser arrastado
Problema:
Fazer um relógio num form é fácil. Porém gostaria que
esse orm não possuísse a barra de título, mas que o
usuário ainda pudesse arrastá-lo com o mouse. Isto é
possível no Delphi?
Solução:
Sim, é possível e é fácil. Siga os passos abaixo:
- Crie um novo projeto;
- Mude as seguintes propriedades do Form1:

BorderStyle = bsNone, FormStyle =


fsStayOnTop,

- Coloque um Label;
- Coloque um Timer;
- Altere o evento OnTimer do Timer1 conforme abaixo:

procedure TForm1.Timer1Timer(Sender:
TObject);
begin
Label1.Caption := TimeToStr(Time);
end;
- Altere o evento OnCreate do Form1 conforme abaixo:
procedure TForm1.FormCreate(Sender:
TObject);
begin
Width := 80;
Height := 40;
Label1.Left := 10;
Label1.Top := 10;
end;
- Vá na seção private do Form1 e declare a procedure
abaixo:
private
procedure WMNCHitTest(var Msg:
TMessage);
message WM_NCHitTest;
public
{ Public declarations }
end;
- Vá na seção implementation e escreva a procedure
abaixo:
implementation
{$R *.DFM}
procedure TForm1.WMNCHitTest(var Msg:
TMessage);
begin
if GetAsyncKeyState(VK_LBUTTON) < 0 then
Msg.Result := HTCAPTION
else
Msg.Result := HTCLIENT;
end;
- Execute e experimente arrastar form com o mouse.
Observações
Para fechar este aplicativo pressione Alt+F4. Uma
alternativa mais elegante é colocar um menu local
(PopupMenu) com um comando para fechar.
409 - Definir data/hora de um
arquivo
Inclua na seção uses: SysUtils
{ Esta função altera a data e hora de um
arquivo. Se obter sucesso retorna true,
caso contrário retorna false. }
function DefineDataHoraArq(NomeArq:
string; DataHora: TDateTime): boolean;
var
F: integer;
begin
Result := false;
F := FileOpen(NomeArq, fmOpenWrite or
fmShareDenyNone);
try
if F > 0 then
Result := FileSetDate(F,
DateTimeToFileDate(DataHora)) = 0;
finally
FileClose(F);
end;
end;
{ Exemplo de uso 1: Usa a data atual do sistema (Now) }
if DefineDataHoraArq(‘c:\teste\logo.bmp’,
Now) then
ShowMessage(‘Data/Hora do arquivo
definida com sucesso.’)
else
ShowMessage(‘Não foi possível definir
data/hora do arquivo.’);

{ Exemplo de uso 2: Usa uma data fixa }


var
DataHora: TDateTime;
begin
{ Define a data para 5-Fev-1999 e a hora
para 10:30 }
DataHora := EncodeDate(1999, 2, 5) +
EncodeTime(10, 30, 0, 0);
if
DefineDataHoraArq(‘c:\teste\logo.bmp’,
DataHora) then
ShowMessage(‘Data/Hora do arquivo
definida com sucesso.’)
else
ShowMessage(‘Não foi possível definir
data/hora do arquivo.’);
end;
410 - Ocultar/exibir o cursor do
mouse
Inclua na seção uses: Windows
- Escreva a função abaixo:
function MouseShowCursor(const Show:
boolean): boolean;
var
I: integer;
begin
I := ShowCursor(LongBool(true));
if Show then begin
Result := I >= 0;
while I < 0 do begin
Result := ShowCursor(LongBool(true)) >=
0;
Inc(I);
end;
end else begin
Result := I < 0;
while I >= 0 do begin
Result := ShowCursor(LongBool(false)) <
0;
Dec(I);
end;
end;
end;
- Exemplos de uso:
MouseShowCursor(false); { Oculta o cursor
}
MouseShowCursor(true); { Exibe o cursor }
411 - Executar um programa e
aguardar sua finalização antes de
continuar
Inclua na seção uses: Windows
{ Esta função faz isto. }
function ExecAndWait(const FileName,
Params: string;
const WindowState: Word): boolean;
var
SUInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
begin
{ Coloca o nome do arquivo entre aspas.
Isto é necessário devido aos espaços
contidos em nomes longos }
CmdLine := ‘”’ + Filename + ‘”’ +
Params;
FillChar(SUInfo, SizeOf(SUInfo), #0);
with SUInfo do begin
cb := SizeOf(SUInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := WindowState;
end;
Result := CreateProcess(nil,
PChar(CmdLine), nil, nil, false,
CREATE_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(Filename)),
SUInfo, ProcInfo);
{ Aguarda até ser finalizado }
if Result then begin
WaitForSingleObject(ProcInfo.hProcess,
INFINITE);
{ Libera os Handles }
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;
- Exemplo de uso:
ExecAndWait(‘c:\windows\notepad.exe’, ”,
SW_SHOW);
Observações
Não se esqueça de informar o caminho (path) do
arquivo completo. Esta função foi desenvolvida para
Delphi 32 bits (2, 3, 4,…).
412 - Adicionar o evento OnClick
do DBGrid
Problema:
Meu programa precisa processar algo quando o usuário
clicar no DBGrid em um determinado form. O problema
é que o DBGrid não possui o evento OnClick. É possível
adicionar este evento no DBGrid?
Solução:
É possível sim. Afinal é muito simples. Siga os passos
abaixo para resolver seu problema:
- Monte seu form normalmente, colocando o DBGrid e
demais componentes;
- Vá na seção “private” da unit e declare a procedure
abaixo:
private
procedure DBGridClick(Sender: TObject);
- Logo após a palavra “implementation”, escreva a
procedure:
implementation
{$R *.DFM}

procedure TForm1.DBGridClick(Sender:
TObject);
begin
ShowMessage(‘Clicou no DBGrid.’);
end;
- Coloque as instruções abaixo no evento OnCreate do
Form:
procedure TForm1.FormCreate(Sender:
TObject);
begin
DBGrid1.ControlStyle :=
DBGrid1.ControlStyle + [csClickEvents];
TForm(DBGrid1).OnClick := DBGridClick;
end;
- E pronto. Execute e teste.
Observações
O segredo principal desta dica está OnCreate do Form.
A primeira instrução ativa o evento OnClick. A segunda
instrução acessa o manipulador do evento OnClick. Para
isto precisamos tratar o DBGrid como se fosse Form,
pois o evento OnClick está declarado como protegido
(protected) na classe TDBGrid.
413 - Criar caixas de diálogo em
tempo de execução
Inclua na seção uses: Forms, StdCtrls, Buttons
A função abaixo demonstra a criação de uma caixa de
diálogo que pode ser usada para permitir ao usuário
digitar o seu nome:
{ Esta função retorna true se for
pressionado OK e false em caso contrário.
Se for OK, o texto digitado pelo usuário
será copiado para a variável Nome }
function ObterNome(var Nome: string):
boolean;
var
Form: TForm; { Variável para o Form }
Edt: TEdit; { Variável para o Edit }
begin
Result := false; { Por padrão retorna
false }
{ Cria o form }
Form := TForm.Create(Application);
try
{ Altera algumas propriedades do Form }
Form.BorderStyle := bsDialog;
Form.Caption := ‘Atenção’;
Form.Position := poScreenCenter;
Form.Width := 200;
Form.Height := 150;
{ Coloca um Label }
with TLabel.Create(Form) do begin
Parent := Form;
Caption := ‘Digite seu nome:’;
Left := 10;
Top := 10;
end;
{ Coloca o Edit }
Edt := TEdit.Create(Form);
with Edt do begin
Parent := Form;
Left := 10;
Top := 25;
{ Ajusta o comprimento do Edit de acordo
com a largura do form }
Width := Form.ClientWidth - 20;
end;
{ Coloca o botão OK }
with TBitBtn.Create(Form) do begin
Parent := Form;
{ Posiciona de acordo com a largura do
form }
Left := Form.ClientWidth - (Width * 2) -
20;
Top := 80;
Kind := bkOK; { Botão Ok }
end;
{ Coloca o botão Cancel }
with TBitBtn.Create(Form) do begin
Parent := Form;
Left := Form.ClientWidth - Width - 10;
Top := 80;
Kind := bkCancel; { Botão Cancel }
end;
{ Exibe o form e aguarda a ação do
usuário. Se for OK… }
if Form.ShowModal = mrOK then begin
Nome := Edt.Text;
Result := true;
end;
finally
Form.Free;
end;
end;
Para chamar esta função siga o exemplo abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
S: string;
begin
if ObterNome(S) then
Edit1.Text := S;
end;
Observações
Os componentes Label, Edit (var Edt) e BitBtn’s (botões)
não são destruídos explicitamente (Componente.Free).
Isto não é necessário, pois ao criá-los informei como
proprietário o Form (ex: TLabel.Create(Form)). Neste
caso, estes componentes são destruídos
automaticamente ao destruir o Form (Form.Free).
414 - Fechar um aplicativo com uma
mensagem de erro fatal
Inclua na seção uses: Windows
procedure TForm1.Button1Click(Sender:
TObject);
begin
FatalAppExit(0, ‘Erro fatal na
aplicação.’);
end;
Observações
A função FatalAppExit é uma API do Windows. Esta
mostra uma caixa de diálogo (normalmente branca) com
a mensagem passada no segundo parâmetro. Quando a
caixa de diálogo é fechada a aplicação é finalizada. O
evento OnCloseQuery dos forms não são chamados
quando usamos esta função.
415 - Criar um EXE que seja
executado apenas através de outro
EXE criado por mim
Inclua na seção uses: Windows
Problema:
Gostaria que um determinado programa (Prog1.EXE)
fosse executado apenas através de outro programa
(Prog2.EXE).
Solução:
Antes da linha “Application.Initialize;” de Prog1.dpr
(programa a ser chamado), coloque o código abaixo:
if ParamStr(1) <> ‘MinhaSenha’ then begin
{ Para usar ShowMessage, coloque Dialogs
no uses }
ShowMessage(‘Execute este programa
através de Prog2.EXE’);
Halt; { Finaliza }
end;

{ No Form1 de Prog2 (programa chamador)


coloque um botão e escreva o OnClick deste
botão como abaixo:}

procedure TForm1.Button1Click(Sender:
TObject);
var
Erro: Word;
begin
Erro := WinExec(‘Pro2.exe MinhaSenha’,
SW_SHOW);
if Erro <= 31 then { Se ocorreu erro… }
ShowMessage(‘Erro ao executar o
programa.’);
end;
Observações
Aqui o parâmetro passado foi ‘MinhaSenha’. Você
deverá trocar ‘MinhaSenha’ por algo que apenas você
saiba (uma senha). Caso uma pessoa conheça esta
senha, será possível chamar este programa passando-a
como parâmetro. Neste caso sua “trava” estará violada.
416 - Resolver “Internal error
near: IBCheck” do Interbase 5.1.1
Server no NT
Recebi esta mensagem do desenvolvedor Alexsando S.
Pimenta.
Como deve ser do interesse de outros desenvolvedores,
coloquei-a aqui:
==== Mensagem original ====
Olá Daniel,
Anote está solução, muitos tem o mesmo problema mas
não conseguem a solução tão facilmente como eu.
Look:
Problema:
Estou com um problemão. Trabalho com o NT 4
workstation Service Pack 3, Delphi 3 e Interbase 4.2.xxx.
E instalei o Interbase 5.1.1 Server nesta máquina. Até aí
tudo bem. Quando fui rodar a aplicação deram alguns
problemas de conversão do tipo de Dado. Analisando o
problema percebi que havia esquecido de instalar o
Client do Interbase. Foi aí que começaram os
problemas. Tentei instalar o client, porém o instalador
após preparar os arquivos de instalação mostrava a
seguinte mensagem e parava : Titulo da janela =
“Severe”, mensagem = “Internal error near: IBCheck”;
comecei a ler os manuais, em certo ponto aconselhava
desinstalar qualquer versão posterior do Interbase da
minha máquina. Foi então que desinstalei o Interbase
4.2.xxx (através do “Control Panel”, “Add/Remove
Programs”). Nova tentativa de instalar o client, o erro
persistia. Resolvi desinstalar (através do “Control Panel”,
“Add/Remove Programs”) todo o Interbase da minha
máquina e começar tudo de novo. Porém quando tentei
instalar novamente o Interbase Server, surpresa, o erro
apareceu novamente. Mas agora não havia interbase
instalado. Fui desinstalando Delphi, BDE, … e nada.
Entrei no Regedit, pois o desinstalador, normalmente,
faz o trabalho incompleto e é necessário excluir um
monte de lixo do Registry. Deparei com a seguintes
chaves:
hkey_local_machine\system\controlset001\enum\root\leg
acy_interbase_guard
hkey_local_machine\system\controlset001\enum\root\leg
acy_interbase
Tentei excluí-las, porém são chaves protegidas, e o
regedit não permitiu que eu excluísse-as.
Poderiam me dar uma solução para eu poder instalar o
Interbase em minha máquina?
Preciso disto com urgência.
Obrigado,
Alexsandro Pimenta
Xenon Software Comércio e Serviços Ltda
apepper@uol.com.br
Solução:
Sr. Alexsandro,
Esse erro: ‘Internal error near: IBCheck’ acontece
apenas em algumas máquinas NT 4.
Na hora da instalação, é criada uma chave com valor
errado.
Entre no registry do Windows e altere a opção, PATH de
binário para string, da chave:
HKEY_CURRENT_USER\Environment
Renata Oliva
Inprise Support Center
417 - Obtendo uma data acrescida
de xMeses
Function SomaMes (dData : TDateTime;
xMeses : Integer; lCorrido : boolean) :
TDateTime;
var
Ano, Mes, Dia : word;
DataAux : TDateTime;
begin
DecodeDate(dData, Ano, Mes, Dia);
Mes := Mes + xMeses;
Ano := Ano + (Mes DIV 12);
Mes := Mes mod 12;
DataAux := MenorDataValida (Ano, Mes,
Dia);
if not lCorrido Then
DataAux := DataAux - 1;
SomaMes := DataAux;
end;
418 - Separar (filtrar) caracteres
de uma string
{ Abaixo da palavra implementation digite:
}
type
TChars = set of Char;

function FilterChars(const S: string;


const ValidChars: TChars): string;
var
I: integer;
begin
Result := ”;
for I := 1 to Length(S) do
if S[I] in ValidChars then
Result := Result + S[I];
end;

{ Para usar a função:


- Coloque um botão no Form;
- Altere o evento OnClick deste botão
conforme abaixo: }

procedure TForm1.Button4Click(Sender:
TObject);
begin
{ Pega só letras }

ShowMessage(FilterChars(‘D63an*%i+/e68l13’
,
[‘A’..‘Z’, ‘a’..‘z’]));
{ Pega só números }

ShowMessage(FilterChars(‘D63an*%i+/e68l13’
, [‘0’..‘9’]));
end;
Observações
Se quizer usar este função em outras unit’s, coloque a
declaração do tipo TChars na seção interface. Coloque
aí também uma declaração da função FilterChars. E não
se esqueça da cláusula uses.
419 - Trabalhar com cores no
formato string
procedure TForm1.Button1Click(Sender:
TObject);
begin
{ Exibe as cores atuais dos Edit’s }
ShowMessage(ColorToString(Edit1.Color));
ShowMessage(ColorToString(Edit2.Color));
{ Altera as cores dos Edit’s }
Edit1.Color := StringToColor(‘clBlue’);
Edit2.Color :=
StringToColor(‘$0080FF80’);
end;
420 - Verificar se determinado
programa está em execução (Word,
Delphi, etc)
{ Coloque um Button no Form e altere o
evento OnClick deste como abaixo: }
procedure TForm1.Button1Click(Sender:
TObject);
begin
{ Verifica o Delphi }
if FindWindow(‘TAppBuilder’, nil) > 0
then
ShowMessage(‘O Delphi está aberto’)
else
ShowMessage(‘O Delphi NÃO está aberto’);

{ Verifica o Word }
if FindWindow(‘OpusApp’, nil) > 0 then
ShowMessage(‘O Word está aberto’)
else
ShowMessage(‘O Word NÃO está aberto’);

{ Verifica o Excell }
if FindWindow(‘XLMAIN’, nil) > 0 then
ShowMessage(‘O Excell está aberto’)
else
ShowMessage(‘O Excell NÃO está aberto’);
end;
Observações
Há uma margem de erro nesta verificação: pode haver
outros programas que possuam uma janela com os
mesmos nomes. Você mesmo pode criar aplicativos em
Delphi e, propositadamente, criar uma janela com um
destes nomes.
421 - Gerar uma tabela no Word
através do Delphi
Inclua na seção uses: ComObj
{ - Coloque um botão no Form;
- Altere o evento OnClick do botão
conforme abaixo: }

procedure TForm1.Button1Click(Sender:
TObject);
var
Word: Variant;
begin
{ Abre o Word }
Word :=
CreateOleObject(‘Word.Application’);
try
{ Novo documento }
Word.Documents.Add;
try
{ Adiciona tabela de 2 linhas e 3
colunas }
Word.ActiveDocument.Tables.Add(
Range := Word.Selection.Range,
NumRows := 2,
NumColumns := 3);
{ Escreve na primeira célula }
Word.Selection.TypeText(Text := ‘Linha
1, Coluna 1’);
{ Próxima célula }
Word.Selection.MoveRight(12);
{ Escreve }
Word.Selection.TypeText(Text := ‘Linha
1, Coluna 2’);
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := ‘Linha
1, Coluna 3’);
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := ‘Linha
2, Coluna 1’);
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := ‘Linha
2, Coluna 2’);
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := ‘Linha
2, Coluna 3’);
{ Auto-Formata }
Word.Selection.Tables.Item(1).Select; {
Seleciona a 1º tabela }
Word.Selection.Cells.AutoFit; { auto-
formata }
{ Imprime 1 cópia }
Word.ActiveDocument.PrintOut(Copies :=
1);
ShowMessage(‘Aguarde o término da
impressão…’);
{ Para salvar… }
Word.ActiveDocument.SaveAs(FileName :=
‘c:\Tabela.doc’);
finally
{ Fecha documento }
Word.ActiveDocument.Close(SaveChanges :=
0);
end;
finally
{ Fecha o Word }
Word.Quit;
end;
end;
Observações
Foram usados neste exemplo o Delphi4 e MS-Word97.
422 - Obter a quantidade de
registros total e visível de uma
tabela
Inclua na seção uses: DbiProcs
Os componentes TTable e TQuery possuem a
propriedade RecordCount que indicam a quantidade de
registros da tabela.
No entanto esta propriedade é dependente de filtros, ou
seja, se tivermos uma tabela com dez registros com
campo “Codigo” de 1 a 10 e aplicarmos o filtro mostrado
a seguir, a propriedade RecordCount retornará 5 e não
10.
Table1.Filter := ‘Codigo <= 5’;
Table1.Filtered := true;
Se quizermos obter a quantidade total de registros,
independentemente de filtros, devemos usar uma API do
BDE conforme abaixo:
var
Total: integer;
begin
Check(DbiGetRecordCount(Table1.Handle,
Total));
ShowMessage(‘Total de registros: ‘ +
IntToStr(Total));
end;
Observações
Para testar o exemplo acima, o Table1 precisa estar
aberto.
423 - Salvar/restaurar o tamanho e
posição de Form’s
{ Crie uma nova Unit conforme abaixo: }
unit uFormFunc;

interface
uses Forms, IniFiles, SysUtils, Messages,
Windows;

procedure tbLoadFormStatus(Form: TForm;


const Section: string);
procedure tbSaveFormStatus(Form: TForm;
const Section: string);

implementation

procedure tbSaveFormStatus(Form: TForm;


const Section: string);
var
Ini: TIniFile;
Maximized: boolean;
begin
Ini := TIniFile.Create(ChangeFileExt(
ExtractFileName(ParamStr(0)),’.INI’));
try
Maximized := Form.WindowState =
wsMaximized;
Ini.WriteBool(Section, ‘Maximized’,
Maximized);
if not Maximized then begin
Ini.WriteInteger(Section, ‘Left’,
Form.Left);
Ini.WriteInteger(Section, ‘Top’,
Form.Top);
Ini.WriteInteger(Section, ‘Width’,
Form.Width);
Ini.WriteInteger(Section, ‘Height’,
Form.Height);
end;
finally
Ini.Free;
end;
end;

procedure tbLoadFormStatus(Form: TForm;


const Section: string);
var
Ini: TIniFile;
Maximized: boolean;
begin
Maximized := false; { Evita msg do
compilador }
Ini := TIniFile.Create(ChangeFileExt(
ExtractFileName(ParamStr(0)),’.INI’));
try
Maximized := Ini.ReadBool(Section,
‘Maximized’, Maximized);
Form.Left := Ini.ReadInteger(Section,
‘Left’, Form.Left);
Form.Top := Ini.ReadInteger(Section,
‘Top’, Form.Top);
Form.Width := Ini.ReadInteger(Section,
‘Width’, Form.Width);
Form.Height := Ini.ReadInteger(Section,
‘Height’, Form.Height);
if Maximized then
Form.Perform(WM_SIZE, SIZE_MAXIMIZED,
0);
{ A propriedade WindowState apresenta
Bug.
Por isto usei a mensagem WM_SIZE }
finally
Ini.Free;
end;
end;
end.

{ Em cada formulário que deseja


salvar/restaurar:
- Inclua na seção uses: uFormFunc
- No evento OnShow digite:
tbLoadFormStatus(Self, Self.Name);
- No evento OnClose digite:
tbSaveFormStatus(Self, Self.Name);}
Observações
O arquivo INI terá o nome do executável e extensão INI
e será salvo no diretório do Windows. A palavra Self
indica o Form relacionado com a unit em questão.
Poderia ser, por exemplo, Form1, Form2, etc. Onde
aparece Self.Name poderá ser colocado um nome a sua
escolha. Este nome será usado como SectionName no
arquivo INI e deve ser idêntico no evento OnShow e
OnClose de um mesmo Form, porém para cada Form
deverá ser usado um nome diferente.
424 - Criando um campo lookup em
tempo de execução
uses
Forms, Classes, Controls, StdCtrls, Db,
DBTables, DBCtrls;
type
TForm1 = class(TForm)
Table1: TTable;
Table2: TTable;
Button1: TButton;
DBLookupComboBox1: TDBLookupComboBox;
DataSource1: TDataSource;
Table2Codigo: TFloatField; // Objeto campo
chave código usado pelo lookup
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender:
TObject);
var
Nome : string;
begin
with TStringField.Create(Table2) do
begin
FieldName := ‘MeuCampoLookup’;
FieldKind:= fkLookup;
DataSet := Table2;
Nome := Dataset.Name + FieldName;
KeyFields:= ‘Codigo’; //Campo Chave
LookUpDataset:= Table1;
LookUpKeyFields:= ‘Codigo’; //Campo Chave
LookUpResultField:= ‘Nome’; //Resultado da
campo lookup criado
DbLookupCombobox1.DataField:= FieldName;
DataSource1.DataSet:= Dataset;
Table2.FieldDefs.Add(Nome, ftString, 20,
false);
end;
DbLookupCombobox1.DataSource:=
Datasource1;
Table1.Active:= True;
Table2.Active:= True;
end;
end.
425 - Mostrar um Form de LogOn
antes do Form principal
{
* Crie um novo Projeto. Este certamente
terá o Form1.
* Adicione um novo Form (Form2).
* Coloque no Form2 dois botões TBitBtn.
* Mude a propriedade Kind do BitBtn1
para bkOK.
* Mude a propriedade Kind do BitBtn2
para bkCancel.
* Vá no menu “Project/Options” na aba
“Forms” e passe o
Form2 de “Auto-create Forms” para
“Available Forms”.
* Abra o arquivo Project.dpr (menu
Project/View Source).
* Altere o conteúdo deste arquivo
conforme abaixo:
}

program Project1;

uses
Forms, Controls,
Unit1 in ‘Unit1.pas’ {Form1},
Unit2 in ‘Unit2.pas’ {Form2};

{$R *.RES}

var
F: TForm2;

begin
F := TForm2.Create(Application);
try
if F.ShowModal = mrOK then begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
finally
F.Free;
end;
end.
Observações
O Form2 do exemplo é o Form de LogOn. Este deverá
ser preparado para que se possa escolher o usuário,
digitar a senha, etc.
426 - Saber se a impressora atual
possui determinada fonte
Inclua na seção uses: Printers
{ Coloque este código no OnClick de um
botão }
with Printer.Fonts do
if IndexOf(‘Draft 10cpi’) >= 0 then
ShowMessage(‘A impressora possui a
fonte.’)
else
ShowMessage(‘A impressora NÃO possui a
fonte.’);
Observações
Isto pode ser útil quando queremos usar fonte da
impressora quando for uma matricial ou fonte do
Windows quando for uma Jato de Tinta ou Laser.
427 - Saber se determinada Font
está instalada no Windows
{ Coloque este código no OnClick de um
botão }
with Screen.Fonts do
if IndexOf(‘Courier New’) >= 0 then
ShowMessage(‘A fonte está instalada.’)
else
ShowMessage(‘A fonte não está
instalada.’);
428 - Como importar dados de um
arquivo texto para uma Tabela
var
sArquivo: TextFile;
Entrada, sArq2: string;
iLinha: integer;
begin
tblCep.Open;
tblCepLoc.Open;
bCancelaImport := False;
AssignFile(sArquivo,
FileNameEdit1.FileName);
sArq2 :=
After(‘Cep_Loc.txt’,FileNameEdit1.FileName
);

iLinha := 0;
if FileNameEdit1.FileName =
‘C:\Download\Ceps\Cep_loc.txt’ then begin
// Arquivo de Localidades
RzProgressBar1.TotalParts := 0;
RzProgressBar1.TotalParts :=
NumLinhasArq(FileNameEdit1.FileName);

Reset(sArquivo);
Readln(sArquivo,Entrada);
while not Eoln(sArquivo) do begin
Inc(iLinha);
Readln(sArquivo,Entrada);

// 0 = Base Total e 2 = Inclusao


if (copy(Entrada,90,1) = ‘0’) or
(copy(Entrada,90,1) = ‘2’) then
begin
tblCepLoc.Append;
tblCepLoc.FieldByName(‘cep_ChvLocal’).AsSt
ring :=
copy(Entrada,1,6);
tblCepLoc.FieldByName(‘cep_Cidade’).AsStri
ng :=
copy(Entrada,7,60);
tblCepLoc.FieldByName(‘cep_UF’).AsString
:= copy(Entrada,75,2);
try
tblCepLoc.Post;
except
tblCepLoc.Cancel;
end;
end
else if (copy(Entrada,90,1) = ‘1’) then
begin // Exclusao
if tblCepLoc.Locate(‘cep_ChvLocal’,
copy(Entrada,1,6),
[loPartialKey]) then
tblCepLoc.Delete;
end
else if (copy(Entrada,90,1) = ‘3’) then
begin // Alteracao
if tblCepLoc.Locate(‘cep_ChvLocal’,
copy(Entrada,1,6),
[loPartialKey])
then begin
tblCepLoc.Edit;
tblCepLoc.FieldByName(‘cep_Cidade’).AsStri
ng :=
copy(Entrada,7,60);
tblCepLoc.FieldByName(‘cep_UF’).AsString
:=
copy(Entrada,75,2);
end;
try
tblCepLoc.Post;
except
tblCepLoc.Cancel;
end;
end;
RzProgressBar1.PartsComplete := iLinha;
Application.ProcessMessages;
if bCancelaImport then
Break;
end;
CloseFile(sArquivo);
end;
429 - Como Imprimir um arquivo
direto para a Impressora
AssignPrn(‘c:\leiame.txt’);
Como imprimir um arquivo PRN
No prompt do MS-DOS digite:
COPY IMPRESS.PRN PRN /B
430 - Como Usar ASSEMBLER com
Delphi
É fácil. Existem duas maneiras de vc trabalhar com ASM
no Delphi:
1 - Se toda a rotina form em ASM, crie a função com a
directiva assembler.
Dessa maneira, o compilador entenderá que toda a
função é escrita em assembler, e vc faz exatamente
isso, cria toda a função em ASM.
Ex.:
procedure MinhaFuncao(param1: integer);
assembler;
begin
(todo o código deve ser em assembler)
end;
2 - Se apenas parte da rotina for em ASM, use o bloco
asm .. end;
Ex.:
procedure MinhaFuncao(param1: integer);
begin
… (codigo em Object Pascal) …
asm
… (codigo em Assembler) …
end;
… (codigo em Object Pascal) …
end; // fim da rotina
Eu nao pretendo me aprofuncar muito em ASM, apenas
quero aprender a fazer algo como um loop ou um laço e
trabalhar com strings e matrizes…
Para fazer um loop basta definir um label e depois fazer
um salto para ele. ex.:
Loop_1:
xxxx
jmp Loop_1
O ASM não tem suporte para string e matriz, vc terá que
fazer isto na mão.
A forma mais simples de definir um string é o PChar do
delphi.
O PChar é uma sequencia de caracteres terminado com
o caracter nulo (#0 ).
Para trabalhar com matriz, vc terá que fazer o
endereçamento na mão.
> Estao se eu for ler todos os conceitos do ASM e todo
o material que tem por ai eu perderia muito tempo, entao
o melhor para resolver meu caso sao exemplos mesmo.
Se vc não quer “perder tempo” não utilize ASM, pois
qualquer coisa que vc for fazer é demorado para
implementar. Qualquer erro, por menor que seja, em
ASM pode travar a máquina.
Pesquisando por ai olha oque eu consegui fazer….
antes:
for x := 1 to length(dados) do begin
b := byte(dados[x]);
asm
mov dx,$17
mov al,b
out dx,al
end;
end;
agora:
asm
mov dx,$17
mov al,dados // string contendo as
informacoes
out dx,al
end;
pronto, minha rotina tem 50x mais velocidade e
funcionou com perfeicao…baixei uma apostila que
sitava alguns exemplos e resolvi dar uma tentada e deu
certo….
Bom um problema eu resolvi, faltam outros…hehehe
Quanto a problemas de travar, estou trabalhando em um
sistema grande que opera em maquinas de todos os
tipo, portanto tenho de montar rotinas complexas e
rapidas, isso me obriga a ir muitas vezes buscar ajuda
no ASM que tem me motrado muitas solucoes para
meus problemas de performance.
O meu maior problema e que nao posso pedir ao cliente
para trocar a maquina e sim eu tenho que me adaptar.
Bom, vom continuar estudando, se alguem tiver mais
material me mande que eu agradeco.
Gostaria de agradecer tambem a todos os emails que
foram enviados com este topico.
431 - Como Retornar Várias
informações Sobre a BIOS
Esta função retorna várias informações sobre a BIOS,
no formato String que você poderá facilmente jogar para
um memo usando o seguinte:
Memo1.Lines.Text := GetBiosInfoAsText;
O Memo apresentará todas as informações que a
função retirou sobre a BIOS.
Texto:
function GetBiosInfoAsText: string;
var
p, q: pchar;
begin
q := nil;
p := PChar(Ptr($FE000));
repeat
if q <> nil then begin
if not (p^ in [#10, #13, ‘ ‘..’~’ , ‘©’
, ‘¸’ ]) then begin
if (p^ = #0) and (p - q >= 8) then begin
Result := Result + TrimRight(String(q))
+ #13#10;
end;
q := nil;
end;
end else
if p^ in [‘!’..’~’ , ‘©’ , ‘¸’ ] then
q := p;
inc(p);
until p > PChar(Ptr($FFFFF));
Result := TrimRight(Result);
end;
432 - Quando der problema na
instalação do componente
- Com o D5 aberto, mudei a resolucao do video para 256
cores, mandei aplicar a mudanca e vi que a paleta do
D5 ficou normal, ou seja, exibindo os icones como
devem ser exibidos. Depois, eu voltei a resolucao para
milhoes de cores (como estava antes) e, para minha
surpresa, a paleta do D5 continuou normal.
Solução 01
- vá até o painel de controle/sistema/configurações
avançadas/gráficos/aceleração de hardware. Vá
diminuindo a aceleração e verifique se arrumou.
Solução 02 (Se sua placa mãe for
com video OnBoard)
- No setup do computador coloque a placa de video com
2 Mb. Não deixe 4 Mb nem 8 Mb. Isso resolveu meu
problema.
By Lloyd Dickinson
433 - Digito Verificador
Você deve multiplicar individualmente todos os
algarismos de um número requerido por uma sequência
númerica (9,8,7,..,2,9,8…) partindo do fim e repetindo a
sequência caso seja necessário. Soma os resultados da
multiplicação e divida tudo por onze. O resto dessa
divisão deverá ser o DV, mas se esse resto for maior do
que nove você deve subtrair esse resultado de onze.
Existem várias tabelas utilizadas hoje no mercado, a
mais usual é a 2..9 e depois a 2..7, sem contar outros
tipos de módulos.
Segue um exemplo simples com cinco algarimos:
Matrícula: 00113-9
=> (0*5) + (0*6) + (1*7) + (1*8) + (3*9) = 0 + 0 + 7 + 8 +
27 = 42
=> 42 mod 11 => DV é 9
//Calcula o digito verificador
function DV11(Matr : string): string;
{Calculo pelo módulo 11 - tabela 2..9}
var
X, Cont, Soma, DV, NMatr : integer;
begin
Cont := 5; Soma := 0;
For X := 1 to 5 do
begin
NMatr := StrToInt(Copy(Matr,Cont-4,1));
Soma := Soma + (NMatr * Cont);
Inc(Cont);
end;
DV := Soma mod 11;
if DV > 9 then DV := 11 - DV;
Result := IntToStr(DV);
end;
434 - O Delphi faz alguma coisa em
C++.
Voce pode abrir projetos do Delphi no builder que ele
converte, mas vice versa não.
Para usar codigo escrito em C++ no delphi voce
precisará gerar o .OBJ no Builder ou no Visual C++ e
em seguida incluir este .OBJ no seu projeto via diretiva
de compilaçao:
{$I filec.obj}
435 - Como enviar dados do Delphi
para o Excel
procedure
TFormCTEmbarque.SpeedButton1Click(Sender:
TObject);
var
Excel : Variant;
Linha:Integer;
begin
Excel :=
CreateOleObject(‘Excel.Application’);
Excel.Visible :=True;
{Excel.Workbooks.Add;}
Excel.WorkBooks.Open(‘\SERVIDOR\Cotacao\Ge
rar.xls’);
Excel.WorkBooks[1].Sheets[1].Cells[2,7]:=N
ow;
Excel.WorkBooks[1].Sheets[1].Cells[3,2]:=D
MCotacao.TBLiberaRemetente.Value;
Excel.WorkBooks[1].Sheets[1].Cells[3,5]:=D
MCotacao.TBLiberaColeta.Value +
‘-‘ +DMCotacao.TBLiberaUF_Coleta.Value;
Excel.WorkBooks[1].Sheets[1].Cells[4,2]:=D
MCotacao.TBLiberaDestinatario.Value;
Excel.WorkBooks[1].Sheets[1].Cells[4,5]:=D
MCotacao.TBLiberaDestino.Value +
‘-‘ +DMCotacao.TBLiberaUF_Destino.Value;
Excel.WorkBooks[1].Sheets[1].Cells[5,2]:=D
MCotacao.TBLiberaQuantidade.AsString;
Excel.WorkBooks[1].Sheets[1].Cells[5,5]:=D
MCotacao.TBLiberaFreteEmpresa.AsString;
Excel.WorkBooks[1].Sheets[1].Cells[5,7]:=D
MCotacao.TBLiberaContrato.AsString;
Excel.WorkBooks[1].Sheets[1].Cells[6,2]:=F
ormCTEmbarque.Edit2.Text;
Excel.WorkBooks[1].Sheets[1].Cells[6,5]:=F
ormCTEmbarque.Edit3.Text;
Excel.WorkBooks[1].Sheets[1].Cells[6,7]:=F
ormCTEmbarque.Edit4.Text;
Excel.WorkBooks[1].Sheets[1].Cells[7,2]:=D
MCotacao.TBLiberaObservacao.Value;
DmCotacao.QCTEmbarque.Open;
Linha:=10;
While not DMCotacao.QCTEmbarque.Eof do
Begin
Excel.WorkBooks[1].Sheets[1].Cells[Linha,2
]:=DMCotacao.QCTEmbarqueCTRC.Value;
Excel.WorkBooks[1].Sheets[1].Cells[Linha,3
]:=DMCotacao.QCTEmbarqueNotaFiscal.Value;
Excel.WorkBooks[1].Sheets[1].Cells[Linha,4
]:=DMCotacao.QCTEmbarquePeso.Value;
Excel.WorkBooks[1].Sheets[1].Cells[Linha,5
]:=DMCotacao.QCTEmbarquePlaca.Value;
Excel.WorkBooks[1].Sheets[1].Cells[Linha,6
]:=DMCotacao.QCTEmbarqueData.Value;
DmCotacao.QCTEmbarque.Next;
Linha:=Linha+1;
end;
Excel.WorkBooks[1].SaveAs(‘\SERVIDOR\Cotac
ao\Controle.xls’);
DMCotacao.TBCotacao.Refresh;
end;
436 - Virtual keys
vk_LButton = $01;
vk_RButton = $02;
vk_Cancel = $03;
vk_MButton = $04; { NOT contiguous with L
& RBUTTON }
vk_Back = $08;
vk_Tab = $09;
vk_Clear = $0C;
vk_Return = $0D;
vk_Shift = $10;
vk_Control = $11;
vk_Menu = $12;
vk_Pause = $13;
vk_Capital = $14;
vk_Escape = $1B;
vk_Space = $20;
vk_Prior = $21;
vk_Next = $22;
vk_End = $23;
vk_Home = $24;
vk_Left = $25;
vk_Up = $26;
vk_Right = $27;
vk_Down = $28;
vk_Select = $29;
vk_Print = $2A;
vk_Execute = $2B;
vk_SnapShot = $2C;
vk_Copy = $2C {not used by keyboards }
vk_Insert = $2D;
vk_Delete = $2E;
vk_Help = $2F;
{vk_A thru vk_Z are the same as their
ASCII equivalents: ‘A’ thru ‘Z’ }
{ vk_0 thru vk_9 are the same as their
ASCII equivalents: ‘0’ thru ‘9’ }
vk_NumPad0 = $60;
vk_NumPad1 = $61;
vk_NumPad2 = $62;
vk_NumPad3 = $63;
vk_NumPad4 = $64;
vk_NumPad5 = $65;
vk_NumPad6 = $66;
vk_NumPad7 = $67;
vk_NumPad8 = $68;
vk_NumPad9 = $69;
vk_Multiply = $6A;
vk_Add = $6B;
vk_Separator = $6C;
vk_Subtract = $6D;
vk_Decimal = $6E;
vk_Divide = $6F;
vk_F1 = $70;
vk_F2 = $71;
vk_F3 = $72;
vk_F4 = $73;
vk_F5 = $74;
vk_F6 = $75;
vk_F7 = $76;
vk_F8 = $77;
vk_F9 = $78;
vk_F10 = $79;
vk_F11 = $7A;
vk_F12 = $7B;
vk_F13 = $7C;
vk_F14 = $7D;
vk_F15 = $7E;
vk_F16 = $7F;
vk_F17 = $80;
vk_F18 = $81;
vk_F19 = $82;
vk_F20 = $83;
vk_F21 = $84;
vk_F22 = $85;
vk_F23 = $86;
vk_F24 = $87;
vk_NumLock = $90;
vk_Scroll = $91;
437 - Validando número de cartão
de crédito
Function ValidCartao(const s:string):
Boolean;
Var
Valor, Soma, Multiplicador, Tamanho, i :
Integer;
begin
Result := False;
Multiplicador := 2;
Soma := 0;
Tamanho := Length (AllTrim (S));
For i := 1 to Tamanho - 1 do
begin
Try
Valor := StrToInt (Copy (S, i, 1)) *
Multiplicador;
Except
Valor := 0;
End;
Soma := Soma + (Valor DIV 10) + (Valor mod
10);
if Multiplicador = 1 Then
Multiplicador := 2
else
Multiplicador := 1;
end;
if IntToStr ((10 - (Soma mod 10)) mod 10)
= Copy (S, Tamanho, 1) Then
Result := True;
end;
438 - Utilizando o registro do
Windows
O registro do Windows é uma alternativa aos já
conhecidos arquivos .INI para a gravação de variáveis
diversas, porém, com muito mais recursos. Acessá-lo é
muito fácil, veja como:
Primeiro você deve incluir a unit Registry à cláusula
uses da seção interface da unit onde você for utilizá-lo.
Depois, crie uma variável do tipo TRegistry;
As chaves do registro tem estrutura semelhante a uma
árvore de diretórios, portanto, chamadas do tipo
Software\Microsoft\CurrentConfig são perfeitamente
válidas.
Daí por diante, você poderá ler e gravar diversas chaves
e valores no registro do Windows (recomenda-se fazer a
operação em um bloco protegido, para evitar problemas
durante o processamento).
Ao criar um objeto do tipo TRegistry, o root padrão é
sempre o HKEY_CURRENT_USER.
Para alterá-lo, utilize:
r.RootKey := [root key desejado];
onde [root key desejado] é o root que se deseja
conectar, como por exemplo HKEY_LOCAL_MACHINE.
Então r.RootKey := HKEY_LOCAL_MACHINE conecta
ao root diferente do padrão.
Exemplo:
unit Exemplo;
interface
uses SysUtils, WinTypes, WinProcs,
Messages, Dialogs, Forms,Controls,
Classes, StdCtrls, Registry;
type
// conjunto de tipos de valores
TKeyType = (ktString, ktBoolean,
ktInteger, ktCurrency, ktDate, ktTime);
// função exemplo
Function ReadAppKey(const Key: String;
KeyType: TKeyType; DefValue: Variant):
Variant;
Procedure WriteAppKey(const Key: String;
const Value: Variant; KeyType: TKeyType);
implementation
Function ReadAppKey(const Key: String;
KeyType: TKeyType; DefValue: Variant):
Variant;
var r: TRegistry;
begin
// cria o objeto TRegistry
r := TRegistry.Create;
// conecta ao root diferente do padrão
r.RootKey := HKEY_LOCAL_MACHINE;
try
// abre a chave (no root selecionado)
// o segundo parâmetro True, indica que se
a chave não existir, a operação de
abertura poderá criá-la.
r.OpenKey(‘Software' + Application.Title,
True);
Result := DefValue;
// testa se existe o valor que se deseja
ler.
// note que, para verificar a existência
de chaves, utilizados KeyExists([chave]) e
para verificar a existência de conjunto de
//chaves de uma chave, utilizamos
ValueExists([valor])
if r.ValueExists(Key) then
begin
case KeyType of
// lê o valor da chave em formato String
ktString: Result := r.ReadString(Key);
// lê o valor da chave em formato Boolean
ktBoolean: Result := r.ReadBool(Key);
// lê o valor da chave em formato Integer
ktInteger: Result := r.ReadInteger(Key);
// lê o valor da chave em formato Currency
(moeda)
ktCurrency: Result := r.ReadCurrency(Key);
// lê o valor da chave em formato
TDateTime (data)
ktDate: Result := r.ReadDate(Key);
// lê o valor da chave em formato
TDateTime (hora)
ktTime: Result := r.ReadTime(Key);
end;
end;
finally
// destroy o objeto criado
r.Free;
end;
end;
Procedure WriteAppKey(const Key: String;
const Value: Variant; KeyType: TKeyType);
var r: TRegistry;
begin
// cria o objeto TRegistry
r := TRegistry.Create;
// conecta ao root diferente do padrão
r.RootKey := HKEY_LOCAL_MACHINE;
try
// abre a chave (no root selecionado)
r.OpenKey(‘Software' + Application.Title,
True);
case KeyType of
// grava o valor da chave em formato
String
ktString: r.WriteString(Key, Value);
// grava o valor da chave em formato
Boolean
ktBoolean: r.WriteBool(Key, Value);
// grava o valor da chave em formato
Integer
ktInteger: r.WriteInteger(Key, Value);
// grava o valor da chave em formato
Currency (moeda)
ktCurrency: r.WriteCurrency(Key, Value);
// grava o valor da chave em formato
TDateTime (Data)
ktDate: r.WriteDate(Key, Value);
// grava o valor da chave em formato
TDateTime (Hora)
ktTime: r.WriteTime(Key, Value);
end;
finally
r.Free;
end;
end;
end.
439 - Usando TList e Record como
Array
Em Clipper costumava-se utilizar arrays de tamanho
variavel para uma infinidade de coisas, como em Delphi
não é possível redimencionar um array então temos de
implementar esta solução de forma mais complexa e
mais poderosa.
Primeiro usamos um record para simular as colunas, a
grande vantagem aqui é que um record pode conter
dados de diversos tiposde dados.
type
PLinha = ^TLinha;
TLinha = record
coluna1 : string;
coluna2 : string;
coluna3 : string;
coluna4 : string;
end;
Foi criado um tipo PLinha que será um ponteiro para
TLinha, esta jogada funciona muito bem para programas
que devem trabalhar com uma grande quantidade de
dados em memória, já que as informações serão
armazenadas fora do segmento de dados de seu
programa,
Crie um TList para guardar todos os itens, ele será o seu
array de tamanho variavel.
TList.create;
Sem grandes problemas, só não vá criar vários, voce só
precisa de um.
Para incluir um novo elemento na lista:
procedure TForm1.Button1Click(Sender:
TObject);
var
LocalLinha : PLinha;
begin
LocalLinha := New(PLinha);
LocalLinha^.coluna1 := ‘item1’;
LocalLinha^.coluna2 := ‘item2’;
LocalLinha^.coluna3 := ‘item3’;
LocalLinha^.coluna4 := ‘item4’;
DisplayRecord(MLinha.Add(LocalLinha));
end;
A função New() reserva memória para um novo
elemento do tipo passado como parâmetro e retorna um
ponteiro para esse local.
Para acessar os dados de um item em particular:
procedure TForm1.DisplayRecord(Const
LocalRecord: integer);
var
LocalLinha : PLinha;
begin
LocalLinha := MLinha.items[LocalRecord];
edit1.text := LocalLinha^.coluna1;
edit2.text := LocalLinha^.coluna2;
edit3.text := LocalLinha^.coluna3;
edit4.text := LocalLinha^.coluna4;
end;
Você não deve esquecer que esta trabalhando com
ponteiros.
Quando terminar de usar os dados tem de limpar a
memória que usou, abaixo segue uma função genérica
que vai funcionar com qualquer TList.
Procedimento que limpa uma TList:
procedure EmptyTList(Var AList: TList);
var
intContador: integer;
begin
for intContador:= (AList.Count-1) Downto 0
do
begin
Dispose(AList.Items[intContador]);
AList.Delete(intContador);
end;
end;
A função Dispose() libera a memória reservada pelo
New().
E depois de limpar, destrua(TList.free).
440 - Usando o objeto Sender
internamente a um evento ou a uma
procedure ou função que você criar
with Sender as TButton do
begin

end;
Para chamadas a partir de objetos diferentes:
if Sender is TButton then
with Sender as TButton do
begin

end;
else if Sender is TLabel then
with Sender as TButton do
begin

end;
end; {if}
441 - Tratando erros no banco de
dados
procedure AppException(Sender: TObject; E:
Exception);

implementation

procedure TChamado.AppException(Sender:
TObject; E: Exception);
var j: Integer;
Msg: String;
begin
Warning1.Hide;
if E is EDBEngineError then
begin
with EDBEngineError(E), Errors[0] do
if ErrorCode = 9734 then // Has Details
ShowMessage(‘Este registro não pode ser
removido, outros arquivos precisam dele.’)
else
if ErrorCode = 9729 then //11756 then //
Key Violation (o nro do codigo está
errado)
ShowMessage(Format(‘Ocorreu um erro no
banco de dados: código %d.’, [ErrorCode]))
else
if ErrorCode = 11270 then // another .NET
file
ShowMessage(‘Diretório controlado por
outro arquivo .NET, verifique configuração
do Banco de Dados.’)
else
if ErrorCode = 9733 then // Master record
missing
ShowMessage(‘Registro Master não
encontrado.’)
else
if ErrorCode = 9734 then // Master has
details
ShowMessage(‘Este registro não pode ser
removido, ele está sendo usado pelo
Fireman.’)
else
if ErrorCode = 8708 then // Record/Key
deleted
ShowMessage(‘Este registro foi removido
por outro Operador.’)
else
if ErrorCode = 10241 then // alredy in use
- // Copy usado para pegar o nome do
usuário
with Errors[2] do
ShowMessage(Format(‘Este registro está
sendo usado pelo Operador: ”%s”.’,
[Copy(Message, 7, 20)]))
else // Outros
begin
for j := 0 to ErrorCount -1 do // Loop
para pegar todas as linhas das msg de erro
with Errors[j] do
Msg := Msg + Message + #13;
ShowMessage(Format(‘EDBEngineError %d:
%s’, [ErrorCode, Msg]))
end
end
else
if E is EConvertError then
begin
with EConvertError(E) do
if Pos(‘date and time’, Message) > 0 then
ShowMessage(‘Informe uma data e hora
válida.’)
else
if Pos(‘is not a valid time’, Message) > 0
then
ShowMessage(‘Informe uma hora válida.’)
else
if Pos(‘is not a valid date’, Message) > 0
then
ShowMessage(‘Informe uma data válida.’)
else
Application.ShowException(E);
end
else
Application.ShowException(E);
end; // AppException
442 - Tirando os botões Load e
Save do Preview do QuickReport
no evento OnCreate do relatório:
With QRPrinter Do
begin
EnableOpenBtn := False;
EnableSaveBtn := False;
end;
443 - Substituindo os botões do
DBNavigator
A linha de comando para substituir um comando do
DBNavigator é a seguinte:
DBNavigator.BtnClick(nb####);
onde #### será:
first = vai para o primeiro registro;
prior = move o ponteiro para o registro anterior;
next = move o ponteiro para o proximo registro;
last = vai para o último registro;
insert = insere um novo registro na tabela;
delete = apaga o registro atual;
edit = edita o registro atual;
post = confirma a edição ou inserção de um novo
registro;
cancel = cancela a operação (edit, insert);
refresh = re-le a tabela de registros;
444 - Significados dos componentes
da RXLIB
TRxDBLookupCombo
Permite a pesquisa incremental através de uma lista
lookup permitindo que o usuário veja a lista se
movimentando enquanto ele digita. A propriedade
Lookup Source pode se referir a um componente Ttable,
TQuery, TQBEQuery ou outro TDataset válido.
TRxDBLookupList
Idêntico à TRxDBLookupCombo, porém em uma lista.
TRxDBCombobox
É um descendente de TDBCombobox que permite que
os valores mostrados em sua lista sejam diferentes, em
“display” dos que realmente estão armazenados no
Banco de Dados.
TRxDBGrid
É um excelente componente que permite mudar a cor de
fundo e fonte de cada célula individualmente ou de
colunas e linhas inteiras para melhor visualização.
Mostra ícones para campos OLE, GRAPHICS e BLOB.
Permite também a classificação por campos clicando-
TDStatusLabel
Mostra o estado de um DATASET ou o registro corrente
em uma tabela Paradox ou Dbase.
TDateEdit e TDBDateEdit
Permitem que o usuário digite diretamente um data ou
exibem um calendário popup-up para a escolha da
mesma.
TQBEQuery
Faz com que uma aplicação DELPHI possa uar o Query-
by-example no estilo paradox. Permite também a
inserção e atualização de registros em Queries.
TRxQuery
É um descendente de TQuery que suporta macros em
seus textos SQL similares aos parâmetros, ou seja,
aumenta o poder de suas consultas.
TSQLScript
Permite o uso de múltiplos textos SQL em uma Query.
TRxDBFilter
Encapsula a habilidade do BDE filtrar registros
localmente.
TDBProgress
Exibe o progresso de operações do BDE em drivers
IDAPI que suportam funções de callback.
TDBIndexCombo
Exibe uma lista mais compreensível ao usuário de todos
os índices de uma tabela.
TBDItems, TDatabaseItems,
TTableItems
Listas preenchidas com informações ativas do BDE (lista
dos banco de dados, lista das tabelas, lista dos campos,
etc.)
TDBSecurity
Provê interface para as caixas de diálogo de LOGIN e
CHANGE PASSWORD.
TRxDBRichEdit
Permite ao usuário guardar dados RTF em um campo
MEMO.
TAnimatedImage
Animação de bitmaps “bitmap por bitmap”. Permite o
carregamento de cursores animados do Windows.
TClipboardViewer
Permite que o usuário visualize o conteúdo da área de
transferência.
TCurrencyEdit
Edição de valores monetários e números formatados.
TPicClip
Representa uma coleção de bitmaps em um só arquivo
e permite o acesso por índice.
TFormPlacement
Permite que o usuário salve e carrega automaticamente
informações como tamanho, posição e estado da janela
em arquivos INI ou no REGISTRY.
TFormStorage
Permite que qualquer propriedade Published de
qualquer componente em um form possa ser salva ou
restaurada de um arquivo INI ou do REGISTRY.
TPageManager
Útil para a criação de caixas de diálogo para wizards e
experts.
TColorComboBox
Permite que uma cor seja escolhida de uma lista.
TFontComboBox
Permite que uma fonte seja escolhida de uma lista.
TRxLabel
Um label mais incrementado.
TTextListBox
Um descendente de TListBox com scrollbar horizontal
automática quando necessário.
TRxSplitter
Separa dois controles em run-time permitindo um
controle melhor sobre uma interface.
TRxSlider e TRxSwitch Slider e
Switch
(Botões de liga/desliga) com capacidades diversas de
visualização e utilização.
TRxSpinEdit e TRxSpinButton
Super speedbar com uma interface de tempo de
desenvolvimento igual à speedbar do Delphi. Permite a
customização em run-time de seus botões guardando e
restaurando suas posições em arquivos .INI ou do
REGISTRY. Permite botões como o do I.E.
TcomboEdit, TDateEdit,
TFileNameEdit, TDirectoryEdit
TEdits com botões para seleção de datas, nomes de
arquivos, diretórios ou dados customizados.
TMemoryTable
Implementa tabelas em memória e ainda permite
deleção de registros.
TRxCheckListBox
Uma listbox com checkboxes adicionais.
TrxSpeedButton
SpeedButton com um visual igual ao dos botões do
Internet Explorer e menu Drop-Down.
TRxTimerList
Um timer com capacidade de gerenciar vários eventos
em diferentes intervalos.
TSecretPanel
Permite visualizar um texto em modo scroll, podendo-se,
inclusive, determinar a velocidade que o texto sobe no
painel.
TRxDice
Gera um número aleatório, como se estivesse sorteando
um dado.
TRxcalculator
Componente que é uma calculadora.
TRxTrayIcon
Importante componente quando queremos que nossa
aplicação apareça no TRAY SYSTEM BAR, no canto
direito da barra de tarefas.
445 - Selecionando um formulário
coberto por um componente
Pressione e mantenha pressionada a tecla shift
enquanto dá um clique sobre um componente já
selecionado. Isso eliminará a seleção sobre o
componente e selecionará o formulário por default se
este for o único formulário selecionado.
446 - Selecionando registros órfãos
via SQL
SELECT DISTINCTROW [table1].[field1],
[table1].[field2] FROM table1 LEFT JOIN
table2 ON [table1].[field1] = [table2].[1]
WHERE ([table2].[1] Is Null);
447 - Salvando e Restaurando uma
Tstringgrid
Procedure SaveGrid;
var
f:textfile;
x,y:integer;
begin
assignfile (f,‘NomeArquivo’);
rewrite (f);
writeln (f,stringgrid.colcount);
writeln (f,stringgrid.rowcount);
For X:=0 to stringgrid.colcount-1 do
For y:=0 to stringgrid.rowcount-1 do
writeln (F, stringgrid.cells[x,y]);
closefile (f);
end;

Procedure LoadGrid;
var
f:textfile;
temp,x,y:integer;
tempstr:string;
begin
assignfile (f,‘NomeArquivo’);
reset (f);
readln (f,temp);
stringgrid.colcount:=temp;
readln (f,temp);
stringgrid.rowcount:=temp;
For X:=0 to stringgrid.colcount-1 do
For y:=0 to stringgrid.rowcount-1 do
begin
readln (F, tempstr);
stringgrid.cells[x,y]:=tempstr;
end;
closefile (f);
end;
448 - Retirando acentos de uma
string
function RemoveAcento(Str:String): String;
Const
ComAcento =
‘àâêôûãõáéíóúçüÀÂÊÔÛÃÕÁÉÍÓÚÇÜ’;
SemAcento =
‘aaeouaoaeioucuAAEOUAOAEIOUCU’;
Var
x : Integer;
Begin
For x := 1 to Length(Str) do
if Pos(Str[x],ComAcento)<>0 Then
Str[x] :=
SemAcento[Pos(Str[x],ComAcento)];
Result := Str;
end;
449 - Removendo a barra de
rolagem vertical do DBGrid
Para remover a barra de rolagem vertical de
componente TDBGrid, você precisa apenas criar um
novo componente herdado da classe TDBGrid e
reescrever o método paint.
No método Paint você usará a API do Windows
SetScrollRange definindo o tamanho máximo e mínimo
do scroll para zero (isto desabilitará a exibição da barra
de scroll).
E então acione o inherited paint para que o objeto novo
possa ser desenhado.
O código abaixo mostra uma Unit criada de uma
instância do componente TDBGrid e que não possui a
barra de rolagem vertical.
unit Newgrid;
interface
uses
WinTypes, WinProcs, Classes, DBGrids;

type
TNoVertScrollDBGrid = class(TDBGrid)

protected
procedure Paint; override;
end;

procedure Register;

implementation

procedure TNoVertScrollDBGrid.Paint;
begin
SetScrollRange(Self.Handle, SB_VERT, 0, 0,
False);
inherited Paint;
end;

procedure Register;
begin
RegisterComponents(‘Data Controls’,
[TNoVertScrollDBGrid]);
end;
end.
450 - Como reduzir o tempo e
carga de um programa
É comum acontecer um sensível aumento do tempo de
carga de um aplicativo desenvolvido em Delphi à
medida que este aplicativo cresce e adquire mais e mais
formulários. Às vezes o tempo de carga se torna
totalmente insuportável.
Os programas se tornam lentos principalmente devido à
grande quantidade de formulários que são criados e
inicializados logo no início da execução do programa.
Antes de ser efetivamente utilizado, todo formulário
precisa ser criado. A criação do formulário
Sempre que você adiciona um novo formulário ao
sistema, o IDE do Delphi providencia código para que
ele seja criado automaticamente. Isto simplifica a vida
do programador que não precisará se preocupar com
este detalhe.
O aumento do tempo de carga do aplicativo pode ser
resolvido pela simples remoção do código que o Delphi
gerou para a criação do formulário. Entretanto isto cria
um problema. Antes de efetivamente mostrar o
formulário na tela (ou antes de usar e/ou altera
Para remover o código que o Delphi criou
automaticamente, selecione Project|Options no menu.
Selecione a aba ‘Forms’. Aponte para um dos
formulários e clique no botão ‘>’. Isto faz com que o
formulário passe do painel ‘Auto-create forms’ para o
painel ‘Av
Se você quer saber onde está este código, clique em
View|Units (ou use Ctrl-F12) e selecione o seu projeto
na lista de units que aparecerá. O código que cria
formulários é algo mais ou menos como se segue:
Application.CreateForm(TForm1, Form1);
Cada formulário auto-criado terá uma linha como esta.
Quando o formulário passa para o painel de ‘Available
forms’, a linha correspondente é removida. Você
também pode simplesmente remover a linha
manualmente, usando o editor de textos.
Tipicamente usar um formulário significa mostrá-lo na
tela. Isto é feito invocando-se os métodos Show ou
ShowModal do formulário conforme o estilo do
aplicativo. Agora que o formulário não é mais criado
automaticamente, isto se torna um pouco mais complic
if Form1 = nil then
Form1 := TForm1.Create ( Application );
Form1.Show; { ou Form1.ShowModal; }
Alternativamente você poderia escrever assim:
if Form1 = nil then
Application.CreateForm ( TForm1, Form1 );
Form1.Show; { ou Form1.ShowModal; }
O efeito é o mesmo, mas eu, pessoalmente, prefiro a
primeira forma.
Você deve ter extremo cuidado ao usar esta técnica. Se
você tirar o código de criação automática do formulário e
tentar executar o Show ou ShowModal você vai receber
um erro do tipo ‘Access violation’. Tome cuidado e faça
isto um formulário por vez.
Atenção! Não faça isto para o seu formulário principal. O
formulário principal precisa ser o primeiro formulário a
ser criado. Assim é melhor mantê-lo como auto-criado.
Esta técnica efetivamente ‘distribui’ o tempo de carga e
inicialização do aplicativo pela execução do programa.
Os formulários agora são carregados ‘sob-demanda’.
Formulários nunca utilizados nunca serão criados. Isto
também melhora o uso de memória.
451 - Obtendo o próximo dia útil
caso a data informada caia em um
fim de semana
Function ProximoDiaUtil (dData :
TDateTime) : TDateTime;
begin
if DayOfWeek(dData) = 7 then
dData := dData + 2
else
if DayOfWeek(dData) = 1 then
dData := dData + 1;
ProximoDiaUtil := dData;
end;
452 - Obtendo o último dia útil
caso a data informada caia em um
fim de semana
Function DiaUtilAnterior (dData :
TDateTime) : TDateTime;
begin
if DayOfWeek(dData) = 7 then
dData := dData - 1
else
if DayOfWeek(dData) = 1 then
dData := dData - 2;
DiaUtilAnterior := dData;
end;
453 - Obtendo o nº de ocorrências
de uma string ‘T’ dentro de outra
‘S’
Function Occurs(T, S : ShortString) :
Byte;
Var
P : Byte;
Begin
Result := 0;
P := Pos (T, S);
while P > 0 do
begin
Inc (Result);
S := Copy (S, P + Length (T), 255);
P := Pos (T, S);
end;
End;
454 - Obtendo o nome das tabelas
de um determinado alias
procedure TForm1.Button1Click(Sender:
TObject);
begin
try
S := TStringList.Create;
GetTableNames(‘Nome_do_Alias’,’*.db’,False
, False, S);
Memo1.Text:=S.Text;
finally
S.Free;
end;
end;
455 - Obtendo o indice de um
componente em tempo de execução
function IndexInParent(vControl:
TControl): integer;
var
ParentControl: TWinControl;
begin
ParentControl := TForm(vControl.Parent);
if (ParentControl <> nil) then
begin
for Result := 0 to
ParentControl.ControlCount - 1 do
begin
if (ParentControl.Controls[Result] =
vControl) then Exit;
end;
end;
Result := -1;
end;
456 - Obtendo o extenso do mês
passado por parâmetro
Function MesExtenso (xMes : Variant) :
string;
Var
Dia, Mes, Ano : Word;
begin
Mes := 0;
Case VarType (xMes) of
VarDate : DecodeDate (xMes, Ano, Mes,
Dia);
VarString :
Try
Mes := StrToInt (xMes);
Except
End;
else
Try
Mes := Round (xMes);
Except
End;
end;
case Mes of
1: Result := ‘Janeiro’;
2: Result := ‘Fevereiro’;
3: Result := ‘Março’;
4: Result := ‘Abril’;
5: Result := ‘Maio’;
6: Result := ‘Junho’;
7: Result := ‘Julho’;
8: Result := ‘Agosto’;
9: Result := ‘Setembro’;
10: Result := ‘Outubro’;
11: Result := ‘Novembro’;
12: Result := ‘Dezembro’;
else
Result := ”;
end;
end;
457 - Obtendo o extenso de uma
data informada
Function DataExtenso (dData : TDateTime) :
string;
var
Ano, Mes, Dia : word;
begin
DecodeDate(dData, Ano, Mes, Dia);
DataExtenso := StrZero(Dia,2,0) + ‘ de ‘ +
MesExtenso(Mes) + ‘ de ‘ + IntToStr(Ano);
end;

Function MesExtenso (xMes : Variant) :


string;
Var
Dia, Mes, Ano : Word;
begin
Mes := 0;
Case VarType (xMes) of
VarDate : DecodeDate (xMes, Ano, Mes,
Dia);
VarString :
Try
Mes := StrToInt (xMes);
Except
End;
else
Try
Mes := Round (xMes);
Except
End;
end;
case Mes of
1: Result := ‘Janeiro’;
2: Result := ‘Fevereiro’;
3: Result := ‘Março’;
4: Result := ‘Abril’;
5: Result := ‘Maio’;
6: Result := ‘Junho’;
7: Result := ‘Julho’;
8: Result := ‘Agosto’;
9: Result := ‘Setembro’;
10: Result := ‘Outubro’;
11: Result := ‘Novembro’;
12: Result := ‘Dezembro’;
else
Result := ”;
end;
end;
Exemplo:
Label1.caption:=DataExtenso(now);
458 - Obtendo data do primeiro dia
util do mês
Function FirstDayOfMonth (Data :
TDateTime; lSabDom : Boolean) : TDateTime;
var
Ano, Mes, Dia : word;
DiaDaSemana : Integer;
begin
DecodeDate (Data, Ano, Mes, Dia);
Dia := 1;
if lSabDom Then
begin
DiaDaSemana := DayOfWeek (Data);
if DiaDaSemana = 1 Then
Dia := 2
else
if DiaDaSemana = 7 Then
Dia := 3;
end;
FirstDayOfMonth := EncodeDate (Ano, Mes,
Dia);
end;
459 - Obtendo a versão e outras
informações do BDE
Com esta rotina abaixo, você poderá obter as seguintes
informações do BDE:
ENGINE VERSION
INTERFACE LEVEL
VERSION DATE
VERSION TIME
function TForm1.VersaoBDE(SysVerList:
TStringList): SYSVersion;
var
Month, Day, iHour, iMin, iSec: Word;
Year: SmallInt;
begin
Check(DbiGetSysVersion(Result));
if (SysVerList <> nil) then
begin
with SysVerList do
begin
Clear;
Add(Format(‘ENGINE VERSION=%d’,
[Result.iVersion]));
Add(Format(‘INTERFACE LEVEL=%d’,
[Result.iIntfLevel]));
Check(DbiDateDecode(Result.dateVer, Month,
Day, Year));
Add(Format(‘VERSION DATE=%s’,
[DateToStr(EncodeDate(Year, Month,
Day))]));
Check(DbiTimeDecode(Result.timeVer, iHour,
iMin, iSec));
Add(Format(‘VERSION TIME=%s’,
[TimeToStr(EncodeTime(iHour, iMin, iSec
div 1000, iSec div 100))]));
end;
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
var
S : TStringList;
Ver : SYSVersion;
begin
S:=TStringList.Create;
Ver:=VersaoBDE(S);
Memo1.Text:=S.Text;
end;
460 - Obtendo a versão da tabela
unit Dbutils;
interface
uses
DbTables;
function DbGetVersion(table: TTable):
LongInt;
implementation
uses
Db, DbiProcs, DbiTypes, {DbiErrs,}
SysUtils
function DbGetVersao(table: TTable):
LongInt;
var
hCursor : hDBICur;
tableDesc: TBLFullDesc;
cName : array[0..255] of Char;
begin
{ make c-string copy table name }
StrPCopy(cName, table.TableName);
Check(DbiOpenTableList(table.DBHandle,
True, False, cName, hCursor));
Check(DbiGetNextRecord(hCursor, dbiNOLOCK,
@tableDesc, nil));
Result := tableDesc.tblExt.iRestrVersion;
Check(DbiCloseCursor(hCursor));
end;
end.
461 - Obtendo a próxima palavra
após os espaços determinados por
‘BlankToSkip’
Function NextWord (S : ShortString;
BlankToSkip, Mode : Byte) : ShortString;
Var
PosAnt, PosFin : Integer;
Begin
if Mode = mdAscend Then
PosFin := 1
else
PosFin := Length (S);
Inc (BlankToSkip);
Repeat
PosAnt := PosFin;
PosFin := NextPosWord (S, PosFin, Mode);
Dec (BlankToSkip);
Until (BlankToSkip = 0) or (PosFin = 0);
if BlankToSkip > 0 Then
Result := ”
else
begin
if PosFin = 0 Then
if Mode = mdAscend Then
PosFin := Length (S) + 1;
if Mode = mdAscend Then
Result := StripChar (Copy (S, PosAnt,
PosFin - PosAnt), EspacoBranco,
ReplaceRight)
else
Result := StripChar (Copy (S, PosFin + 1,
PosAnt - PosFin), EspacoBranco,
ReplaceLeft);
end;
End;
462 - Obtendo a Posição Inicial da
Próxima palavra após o caracter
indicado por ‘InitPos’
Function NextPosWord (S : ShortString;
InitPos, Mode : Byte) : Byte;
Var
I : Integer;
Begin
InitPos := Min (Max (InitPos, 1),
Length(S));
if Mode = mdDescend Then
I := -1
else
I := 1;
while ((InitPos <= Length(S)) And (InitPos
> 0) And (S[InitPos] <> ‘ ‘)) Do
Inc (InitPos, I);
while ((InitPos <= Length(S)) And (InitPos
> 0) And (S[InitPos] = ‘ ‘)) Do
Inc (InitPos, I);
if InitPos > Length (S) Then
InitPos := 0;
NextPosWord := InitPos;
End;
463 - Obtendo a posição da
enésima ocorrência da string ‘T’ na
string ‘S’
Function OccurPos (T, S : ShortString; N :
Byte) : Byte;
Var
Op, P, I : Byte;
Begin
I := 0;
Op := 0;
P := Pos (T, S);
While P > 0 Do
Begin
Inc (Op);
if Op = N Then
Begin
OccurPos := I + P;
Exit;
End;
Inc(I, P + Length(T) - 1);
P := Pos (T, Copy (S, I + 1, 255));
End;
OccurPos := 0;
end;
464 - Obtendo a maior data
anterior a uma data inválida
Function MenorDataValida (Ano, Mes, Dia :
Word) : TDateTime;
Var
Continua : Boolean;
DataAux : TDateTime;
begin
Continua := True;
DataAux := date;
while Continua do
Try
DataAux := EncodeDate (Ano, Mes, Dia);
Continua := False;
Except
Dec (Dia);
End;
MenorDataValida := DataAux;
end;
465 - Obtendo a lista de Aliases
disponíveis
Tudo que você precisa é de um componente TSession,
TListBox e uma StringList.
Defina a propriedade SessionName do TSession para
‘Session’.
Utilize o seguinte código:
procedure TForm1.Button1Click(Sender:
TObject);
var
MyStringList: TStringList;
i: integer;
begin
MyStringList := TStringList.Create;
Session.GetAliasNames(MyStringList);
for I := 0 to MyStringList.Count - 1 do
ListBox1.Items.Add(MyStringList[I]);
end;
Utilize o Help do TSession e consulte seus métodos
para ver por exemplo como capturar o diretório ou
caminho de um Alias com o método ‘GetAliasParams’.
Contruibuição do Claudio
// Procedure Modificada

procedure TForm1.Button1Click(Sender: TObject);


begin
Session.GetAliasNames(ListBox1.Items);
end;

Muito mais fácil, não achas???


466 - Obtendo a data do último dia
do mês, ou último dia útil, de uma
data informada
Function LastDayOfMonth (Data : TDateTime;
lSabDom : Boolean) : TDateTime;
var
Ano, Mes, Dia : word;
AuxData : TDateTime;
DiaDaSemana : Integer;
begin
AuxData := FirstDayOfMonth (NextMonth
(Data), False) - 1;
if lSabDom Then
begin
DecodeDate (Auxdata, Ano, Mes, Dia);
DiaDaSemana := DayOfWeek (AuxData);
if DiaDaSemana = 1 Then
Dia := Dia - 2
else
if DiaDaSemana = 7 Then
Dec (Dia);
AuxData := EnCodeDate (Ano, Mes, Dia);
end;
LastDayOfMonth := AuxData;
end;
467 - Mudando o foco para o
próximo controle
SendMessage(Form1.Handle,WM_NEXTDLGCTL,0,0
);
468 - Mudando a fonte de um menu
Para mudar o fonte de um menu você deve esquecer o
Menu Designer e criar os itens usando a função da API
AppendMenu, utilizando o parâmetro
MF_OWNERDRAW, no evento OnCreate da Form.
Então use as mensagens WM_MEASUREITEM e
WM_DRAWITEM para desenhar os menu
469 - Movimentando o ponteiro do
mouse sem a intervenção do usuário
Para movimentar o ponteiro do mouse sem intervenção
do usuário, deve-se usar um TTimer e colocar o
seguinte código em seu evento OnTimer:
var
pt:tpoint;
begin
getcursorpos(pt);
pt.x := pt.x + 1;
pt.y := pt.y + 1;
SetCursorPos(pt.x,pt.y);
if pt.x>=screen.width-1 then
setcursorpos(0,pt.y);
if pt.y>=screen.height-1 then
setcursorpos(pt.x,0);
end;
470 - Mostrando um formulário
Modal usando Show
Um exemplo disso é quando você está mostrando um
diálogo do progresso de uma operação.
O problema é que se você usa ShowModal todo o
código da operação deve estar contido no form do
diálogo de progresso.
Para evitar isso use DisableTaskWindows and
EnableTaskWindows.
Desta form seu diálogo vai agir como um formulário
Modal e ao mesmo tempo permite executar o form da
operação que está em progresso no diálogo.
procedure TForm1.ShowProgressDlg;
var
WindowList: Pointer;
begin
// Desabilita todos os formulários com
exceção de FrmProgress
WindowList :=
DisableTaskWindows(FrmProgress.Handle);
try
FrmProgress.Show;
// Início do loop que executa a operação
FrmProgress.ProgressBar1.Position :=
FrmProgress.ProgressBar1.Position + 1;
// Fim do loop
finally
// Reabilita todos os formulários
EnableTaskWindows(WindowList);
FrmProgress.Close;
end; // try
end; // ShowProgressDlg
471 - Mostrando a lista de último
acesso dos arquivos aberto
ultimamente
unit Uultimoacesso;
{object Form1: TForm1
Left = 230
Top = 186
Width = 435
Height = 167
Caption = ‘Ultimo Acesso’
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = ‘Arial’
Font.Style = []
PixelsPerInch = 96
TextHeight = 18
object Label1: TLabel
Left = 6
Top = 11
Width = 53
Height = 18
Caption = ‘Arquivo’
end
object Label2: TLabel
Left = 6
Top = 58
Width = 101
Height = 18
Caption = ‘Último Acesso’
end
object EdArquivo: TEdit
Left = 6
Top = 28
Width = 281
Height = 26
TabOrder = 0
end
object BtSeleciona: TButton
Left = 226
Top = 82
Width = 87
Height = 31
Caption = ‘Seleciona’
TabOrder = 1
OnClick = BtSelecionaClick
end
object EdUltimoAcesso: TEdit
Left = 6
Top = 82
Width = 204
Height = 26
TabOrder = 2
end
object ODSelecionaArquivo: TOpenDialog
Left = 352
Top = 8
end
end
}
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
EdArquivo: TEdit;
BtSeleciona: TButton;
Label1: TLabel;
Label2: TLabel;
EdUltimoAcesso: TEdit;
ODSelecionaArquivo: TOpenDialog;
procedure BtSelecionaClick(Sender:
TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.BtSelecionaClick(Sender:
TObject);
var
FileHandle : THandle;
LocalFileTime : TFileTime;
DosFileTime : DWORD;
LastAccessdTime : TDateTime;
FindData : TWin32FindData;
NomeArquivo : array[0..255] of char;
begin
if OdSelecionaArquivo.Execute then
begin
EdArquivo.Text :=
OdSelecionaArquivo.FileName;
StrPCopy(NomeArquivo,OdSelecionaArquivo.Fi
leName);
FileHandle := FindFirstFile(NomeArquivo,
FindData);
if FileHandle = INVALID_HANDLE_VALUE then
begin
Windows.FindClose(Handle);
if (FindData.dwFileAttributes and
FILE_ATTRIBUTE_DIRECTORY) = 0 then
begin
FileTimetoLocalFileTime(FindData.ftLastWri
teTime, LocalFileTime);
FileTimeToDosDateTime(LocalFileTime,
LongRec(DosFileTime).Hi,
LongRec(DosFileTime).Lo);
LastAccessdTime :=
FileDateToDateTime(DosFileTime);
EdUltimoAcesso.Text :=
DateTimeToStr(LastAccessdTime);
end;
end;
end;
end;
end.
472 - Montando um Banco de Dados
Cliente/Servidor
DILEMA
Quando colocar comandos SQL estaticamente
armazenados no servidor ou definidos no cliente? A
resposta a esta questão é relativa, e dependerá das
características de cada aplicação. Comandos de criação
de banco de dados, tabelas, teste de faixa de valores p
DICAS:
Configuração do Servidor de Banco (Interbase, no BDE
Configuration-IDAPI32.CFG, ou outro, no seu respectivo
programa de configuração) para dados em português.
Isto inclui as horas, datas e valores numéricos em
decimais.
Criação do alias de Banco de Dados no BDE
Configuration. Este alias é o nome usado nas aplicações
Delphi para referenciar um dado Banco de Dados .GDB
(Interbase)
Criação do usuário principal do Banco de Dados no
Interbase Server Manager.
Criação do Banco de Dados: CREATE DATABASE (via
WISQL).
Criação das Tabelas1
* CREATE TABLE (via Database Desktop). Deve-se
preencher, para cada campo das Tabelas: Nome,
Tipo/Faixa de Valores, Valor Requerido ou não, Valor
Default (somente Paradox), Chave/Não (somente
Paradox). Alguns destes dados podem vir de Attribute
Sets defin
* Criar Índices relacionados com as Tabelas. O nome do
índice é formado: (ou
<TABELA_NOME&IACUTE;NDICEpara índices
formados por mais de um campo).
* Definir a Integridade Referencial (via relacionamento
de Chave(s) Estrangeira(s)) entre as Entidades
(Tabelas) (somente Paradox). Criar sempre a Entidade
Principal e depois a Secundária (aquela que recebe a
Chave Estrangeira); qualquer valor da Chave Es
Criação de domínios (tipos padrões a partir dos quais
pode-se definir campos de várias tabelas), através do
CREATE DOMAIN. Com isso, a modificação do tipo é
feita somente uma vez.
Para as Tabelas que possuem número seqüencial como
Chave Primária, criar um gerador automático (CREATE
GENERATOR/CREATE TRIGGER), definindo um tipo
“Auto-Increment like Paradox”. Use SET GENERATOR
TO quando já existem valores até na Tab
Criação de triggers para operações de deleção que
envolvam integridade referencial entre tabelas.
Chave Primária: PRIMARY KEY ().
Chave Estrangeira:
ALTER TABLE
ADD CONSTRAINT
FOREIGN KEY ()
REFERENCES ;
Checagem de faixa de valores válidos para campos:
ADD CONSTRAINT
CHECK ()
Valores Default: ADD DEFAULT
Para operações repetitivas sobre uma Tabela, usar SQL
disparado no Delphi (ExecSQL), ao invés de código puro
Delphi. Com isso, processa-se os dados em bloco, com
um único lock no Banco de Dados, ao invés de efetuar a
operação por registro.
Criação de Stored Procedures, quando possível.
Criação de Views e Grant Permissions. Com isso, não é
necessário uma tabela de usuários, pois os mesmos são
cadastrados no Interbase Server Manager e suas
permissões de acesso são dadas pelo comando
GRANT.
Após a definição completa do BD através de SQL, salvar
os comandos SQL em um arquivo de criação automática
de BD(.SQL).
Criação de Dicionários de Dados (com seus campos
TField), que definem padronizações para vários campos
de diferentes tabelas (via Database Explorer).
Criação de Data Modules no IDE. Cada Data Module
possui um conjunto de tabelas e queries de um contexto
do sistema.
Criação de máscaras no IDE; criar “Máscaras Exemplo
para Língua Portuguesa”.
Definição de MinValue/MaxValue dos campos no IDE.
Definição de componentes TQuery para a interação C/S
no IDE.
DEFINIÇÕES:
Trigger: procedimento SQL disparado sobre evento na
tabela.
Stored Procedures: procedimentos pré-compilados SQL.
São mais eficientes do que enviar um texto SQL para o
Servidor de Banco de Dados.
Views: visões sobre uma ou mais tabelas em conjunto.
Otimiza o processamento sobre as mesmas e facilita o
controle de acesso e permissões (Grant Permissions).
473 - Lendo e gravando arquivos de
texto
Existem vários métodos em Delphi para gravar arquivos
texto a partir de informações gravadas em bases de
dados ou para ler arquivos texto e armazená-los em
bases de dados. Esta dica apresenta um destes
métodos: o uso de TextFiles.
TextFile é um tipo de dado pré-definido no Delphi e
corresponde ao tipo Text do Turbo Pascal e do Object
Pascal.
Inicialmente para acessar um arquivo de texto, você
precisa definir uma variável tipo TextFile, no local que
você achar mais apropriado, da seguinte forma:
var arq: TextFile;
Vamos precisar também de uma variável tipo string para
armazenar cada linha lida do arquivo:
var linha: String;
Antes de se iniciar a leitura do arquivo, precisamos
associar a variavel TextFile com um arquivo fisicamente
armazenado no disco:
AssignFile ( arq, ‘C:\AUTOEXEC.BAT’ );
Reset ( arq );
A rotina AssignFile faz a associação enquanto Reset
abre efetivamente o arquivo para leitura. AssignFile
corresponde à Assign do Turbo Pascal. Em seguida é
necessário fazer uma leitura ao arquivo, para isto
utilizaremos a procedure ReadLn:
ReadLn ( arq, linha );
O comando acima lê apenas uma linha de cada vez,
assim precisamos de um loop para efetuar várias
leituras até que o arquivo acabe. Para verificar o fim do
arquivo, utilizaremos a função Eof:
while not Eof ( arq ) do
Agora uma rotina quase completa para fazer a leitura de
um arquivo texto. Esta rotina recebe como parâmetro o
nome do arquivo que será lido:
procedure percorreArquivoTexto (
nomeDoArquivo: String );
var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Reset ( arq );
ReadLn ( arq, linha );
while not Eof ( arq ) do
begin
{ Processe a linha lida aqui. }
{ Para particionar a linha lida em
pedaços, use a função Copy. }
ReadLn ( arq, linha );
end;
CloseFile ( arq );
end;
E também uma rotina quase completa para gravação de
um arquivo texto. Esta rotina recebe como parâmetro o
nome do arquivo que será gravado e uma tabela
(TTable) de onde os dados serão lidos:
procedure gravaArquivoTexto (
nomeDoArquivo: String; tabela: TTable );
var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Rewrite ( arq );
tabela.First;
while not tabela.Eof do
begin
Write ( arq, AjustaStr (
tabela.FieldByName ( ‘Nome’ ).AsString, 30
) );
Write ( arq, FormatFloat ( ‘00000000.00’,
tabela.FieldByName ( ‘Salario’ ).AsFloat )
);
WriteLn ( arq );
tabela.Next;
end;
CloseFile ( arq );
end;
Note nesta segunda rotina, a substituição de Reset por
Rewrite logo após o AssignFile. Rewrite abre o arquivo
para escrita, destruindo tudo que houver lá
anteriormente .
Note também o uso de Write e WriteLn para gravar
dados no arquivo texto.
Finalmente note o uso de AjustaStr e FormatFloat para
garantir que campos string e numericos sejam gravados
com um número fixo de caracteres. FormatFloat é uma
rotina do próprio Delphi enquanto AjustaStr está definida
abaixo:
function AjustaStr ( str: String; tam:
Integer ): String;
begin
while Length ( str ) < tam do
str := str + ‘ ‘;
if Length ( str ) > tam then
str := Copy ( str, 1, tam );
Result := str;
end;
O uso da função AjustaStr é fundamental quando você
estiver gravando arquivos texto com registros de
tamanho fixo a partir de bases de dados Paradox que
usualmente não preenchem campos string com espaços
no final.
474 - Lendo e Escrevendo dados
binários no Registro do Windows
Coloque no uses: Registry
Coloque no Form:
- três edits;
- dois botões.
Logo abaixo da palavra implementation declare:
type
{ Declara um tipo registro }
TFicha = record
Codigo: integer;
Nome: string[40];
DataCadastro: TDateTime;
end;
- Escreva o evento OnClick do Button1 conforme abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
var
Reg: TRegistry;
Ficha: TFicha;
begin
{ Coloca alguns dados na variável Ficha }
Ficha.Codigo := StrToInt(Edit1.Text);
Ficha.Nome := Edit2.Text;
Ficha.DataCadastro :=
StrToDate(Edit3.Text);
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre uma chave (path). Se não existir
cria e abre. }
Reg.OpenKey(‘Cadastro\Pessoas', true);
{ Grava os dados (o registro) }
Reg.WriteBinaryData(‘Dados’, Ficha,
SizeOf(Ficha));
finally
Reg.Free;
end;
end;
- Escreva o evento OnClick do Button2 conforme abaixo:
procedure TForm1.Button2Click(Sender:
TObject);
var
Reg: TRegistry;
Ficha: TFicha;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Se existir a chave (path)… }
if Reg.KeyExists(‘Cadastro\Pessoas’) then
begin
{ Abre a chave (path) }
Reg.OpenKey(‘Cadastro\Pessoas’, false);
{ Se existir o valor… }
if Reg.ValueExists(‘Dados’) then
begin
{ Lê os dados }
Reg.ReadBinaryData(‘Dados’, Ficha,
SizeOf(Ficha));
Edit1.Text := IntToStr(Ficha.Codigo);
Edit2.Text := Ficha.Nome;
Edit3.Text :=
DateToStr(Ficha.DataCadastro);
end else
ShowMessage(‘Valor não existe no
registro.’)
end else
ShowMessage(‘Chave (path) não existe no
registro.’);
finally
Reg.Free;
end;
end;
Observações:
Qualquer tipo de dado pode ser gravado e lido de forma
binária no registro do Windows. Para isto você precisa
saber o tamanho do dado. Para dados de tamanho fixo,
use SizeOf(). Lembrete: não grave dados muito
extensos no Registro do Windows (ex: imagens),
475 - Invertendo uma string
Function ReverseStr (S : ShortString) :
ShortString;
var
I : Integer;
begin
Result := ”;
For I := Length(S) DownTo 1 Do
Result := Result + S[I];
end;
476 - Instalando componentes
Para se instalar componentes são utilizados três tipos
de arquivos diferentes:
· Os arquivos de extensão .pas ou .dcu são usados
geralmente para se instalar apenas um componente.
· Já os arquivos de extensão .dpk (pacote de
componentes) são geralmente usados para se instalar
vários componentes
ao mesmo tempo.
Antes de iniciarmos, você deverá copiar todos os
arquivos do componente para o diretório LIB que se
encontra no diretório do Delphi. Se os arquivos do
componente não forem copiados para este diretório a
instalação poderá não dar certo.
Para se instalar apenas um componente basta clicar no
menu Component | Install Compoment, clicar no botão
Browse…
selecionar o diretório LIB que se encontra no diretório do
Delphi e selecionar o arquivo de extensão .pas ou .dcu.
Em seguida irá aparecer uma tela chamada Package. O
arquivo do componente escolhido aparecerá na lista
abaixo.
Selecione-o e clique em Compile ou Install.
Se tudo correr bem, aparecerá uma mensagem da
confirmação.
Para remover basta selecionar o componente desejado
e clicar no botão Remove.
Já para se instalar pacotes de componentes é mais fácil.
Basta clicar no menu File | Open… e selecionar o tipo
de arquivo com extensão .dpk. A janela Package
aparecerá e basta clicar em Compile ou Install.
Instalando componentes 2
1º - Verificar se o componente tem o código fonte
(*.PAS). Se sim, fora as pouquíssimas exceções, ele
pode ser instalado em qualquer versão do Delphi. Caso
contrário verificar em que versão o componente
compilado (*.DCU) pode ser instalado.
Componentes compilados não podem ser instalados em
mais de uma versão do Delphi. Cada componente
compilado só pode ser instalado em um Delphi com a
mesma versão.
2º- Agora que você já sabe a versão do seu
componente, execute o Delphi e execute:
Delphi 1.x / 2.x: Menu Component, Install Component,
selecione o componente e OK
Delphi 3.x / 4.x: Menu Component, Install Component,
selecione o componente, selecione o package e OK.
No Delphi 3 em diante surgiram os packages que são
“pacotes” de componentes. Por exemplo, eu tenho
vários componentes grafico, então eu reuno todos os
componentes para gráficos e coloco dentro de uma
package com nome “GRAFICO”.
As packages também tem versões compiladas ou não.
A versão compilada tem a extensão (*.DPL), e assim
como os componentes, não pode ser alterada.
A versão não compilada tem a extensão (*.DPK), pode
ser alterada, isto é você pode adicionar ou remover os
componentes dela.
477 - Imprimir no Delphi como no
DOS “a mesma fonte”
No evento de onbeforeprint, faça
QuickReport1.font.name:=‘Draft 10Cpi’;
478 - Imprimindo um bitmap
utilizando TPrinter
As vezes, quando utilizados os médoto Draw e
StretchDraw da propriedade Canvas do objeto TPrinter,
a imagem não é impressa, para corrigir isto, utilize esta
procedure, que passando como parâmetros a instância
Printer.Canvas, Margem Esquerda, Margem Superior
procedure .DrawImage( Canvas : TCanvas; X,
Y, Width, Height : Integer; ABitmap :
TBitmap);
var
Header, Bits : Pointer;
HeaderSize : Integer;
BitsSize : Longint;
begin
GetDibSizes( ABitmap.Handle, HeaderSize,
BitsSize );
Header := AllocMem( HeaderSize );
Bits := AllocMem( BitsSize);
try
GetDib( ABitmap.Handle, ABitmap.Palette,
Header^, Bits^);
StretchDIBits(Canvas.Handle,X,Y,Width,Heig
ht,0,0,ABitmap.Width,ABitmap.Height,Bits,
TBitmapInfo(Header^),DIB_RGB_COLORS,SRCCOP
Y);
finally
FreeMem( Header, HeaderSize);
FreeMem( Bits, BitsSize );
end;
end;
479 - Fazendo um Web Browser
Para construir um Internet browser, coloque um Panel
com alinhamento ao topo de seu form.
Dentro do panel, insira um Combobox e um Button ou
um Bitbtn.
Da nova paleta de componentes internet, pegue um
componente HTML e alinhe-o na area cliente restante
de seu form.
Use o combobox para escrever o endereço do site
internet que você quer visitar. Use o button para entrar
na página, você também pode dar um evento
onkeypress para o Combobox e usar o enter para
acessar a página, adicione a seguinte linha de código ao
butt
HTML.RequestDoc(Combobox1.Text);
Está pronto o seu browser, agora só falta incrementar.
Para facilitar seu controle de navegação, crie um Panel
alinhado na parte de baixo do form e use um label para
mostrar a pagina que está sendo visitada. Use a
propriedade URL e o evento OnDoRequestDoc para
mostrar o status da conecção.
label1.caption := ‘Contacting ‘ +URL;
O combobox serve para guardar uma lista de todas as
páginas web que você visitou. No evento
OnBeginRetrieval do controle HTML, insira o seguinte
código:
with ComboBox1 do
if Items.IndexOf(HTML1.URL)<0 then
Items.Add(HTML1.URL);
Text := HTML1.URL;
SelectAll;
480 - Exibindo caixa de diálogo
personalizada de solicitação de
senha do banco dados
Coloque no uses: DbPwDlg
{Coloque um botão no form e escreve seu
evento OnClick como abaixo}
procedure TForm1.Button1Click(Sender:
TObject);
var
pw: TPasswordDialog;
begin
pw := TPasswordDialog.Create(Self);
try
pw.Caption := ‘Banco de Dados’;
pw.GroupBox1.Caption := ‘Senha’;
pw.AddButton.Caption := ‘&Adicionar’;
pw.RemoveButton.Caption := ‘&Remover’;
pw.RemoveAllButton.Caption := ‘Remover
&Tudo’;
pw.OKButton.Caption := ‘&OK’;
pw.CancelButton.Caption := ‘&Cancelar’;
pw.ShowModal;
finally
pw.Free;
end;
end;
Observações:
As senhas adicionadas nesta caixa de diálogo são
adicionadas na sessão (TSession) atual. Isto é útil
quando colocamos senha em tabelas Paradox, ou
mesmo quando trabalhamos com banco de dados Client
Servidor, e queremos que o usuário digite a senha de
aces
481 - Evitando que o Form seja
redimensionado
type
TForm1 = class(TForm)
private
{ Private declarations }
procedure WMGetMinMaxInfo(var Msg:
TWMGetMinMaxInfo); message
WM_GETMINMAXINFO;
procedure WMInitMenuPopup(var Msg:
TWMInitMenuPopup); message
WM_INITMENUPOPUP;
procedure WMNCHitTest(var Msg:
TWMNCHitTest); message WM_NCHitTest;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.WMGetMinMaxInfo(var Msg:
TWMGetMinMaxInfo);
begin
inherited;
with Msg.MinMaxInfo^ do
begin
ptMinTrackSize.x:= form1.width;
ptMaxTrackSize.x:= form1.width;
ptMinTrackSize.y:= form1.height;
ptMaxTrackSize.y:= form1.height;
end;
end;
procedure TForm1.WMInitMenuPopup(var Msg:
TWMInitMenuPopup);
begin
inherited;
if Msg.SystemMenu then
EnableMenuItem(Msg.MenuPopup, SC_SIZE,
MF_BYCOMMAND or MF_GRAYED)
end;
procedure TForm1.WMNCHitTest(var Msg:
TWMNCHitTest);
begin
inherited;
with Msg do
if Result in [HTLEFT, HTRIGHT, HTBOTTOM,
HTBOTTOMRIGHT,HTBOTTOMLEFT,
HTTOP,HTTOPRIGHT, HTTOPLEFT] then
Result:= HTNOWHERE
end;
482 - Enviando combinação de
teclas para o buffer do teclado
// Exemplo : PostKeyEx32(Ord(‘A’),
[ssCtrl], false);
// Envia Ctrl+A para o controle que tiver
o foco.
// Key : virtual keycode da tecla a
enviar. Para caracteres
// imprimíveis informe o código ANSI
(Ord(CHARACTER)).
// Shift : estado das teclas
modificadoras.
// Shift, Control, Alt, Mouse Buttons.
// SpecialKey: normalmente deve ser False.
Informe True se
// a tecla desejada for, por exemplo, do
teclado numérico.
procedure PostKeyEx32(Key: Word; const
Shift: TShiftState; SpecialKey: boolean);
type
TShiftKeyInfo = Record
shift: Byte;
vkey : Byte;
End;
byteset = Set of 0..7;
const
ShiftKeys: array [1..3] of TShiftKeyInfo =
((shift: Ord(ssCtrl); vkey: VK_CONTROL ),
(shift: Ord(ssShift); vkey: VK_SHIFT ),
(shift: Ord(ssAlt); vkey: VK_MENU ));
var
Flag: DWORD;
bShift: ByteSet absolute shift;
i: Integer;
begin
for i := 1 to 3 do begin
if shiftkeys[i].shift in bShift then
Keybd_Event(ShiftKeys[i].vkey,
MapVirtualKey(ShiftKeys[i].vkey, 0), 0,
0);
end; // for
if SpecialKey Then
Flag := KEYEVENTF_EXTENDEDKEY
else
Flag := 0;
Keybd_Event(Key, MapvirtualKey(Key, 0),
Flag, 0);
Flag := Flag or KEYEVENTF_KEYUP;
Keybd_Event(Key, MapvirtualKey(Key, 0),
Flag, 0);
for i := 3 DownTo 1 do
begin
if ShiftKeys[i].shift in bShift then
Keybd_Event(shiftkeys[i].vkey,
MapVirtualKey(ShiftKeys[i].vkey, 0),
KEYEVENTF_KEYUP, 0);
end; // for
end; // PostKeyEx32
483 - Como criar uma figura do
tipo marca d’ água
procedure TForm1.Button1Click(Sender:
TObject);
var
X, Y : Integer;
begin
brush.style := bsClear;
for y:=0 to image1.height-1 do
for x:=0 to image1.width-1 do
begin
if (x mod 2)=(y mod 2) then
image1.canvas.pixels[x,y]:=clWhite;
end;
end;
484 - Bloqueando um arquivo em
ambiente de rede
Quando você programar visando uma rede e quiser
bloquear um arquivo, é só chamar o metodo “Edit” da
Tabela que estiver usando.
Exemplo:
Table1.edit;
Se o registro já estiver bloqueado, ocorrerá um erro,
então você deve fazer o seguinte :
try { para verificar o erro }
Table1.edit;
exception on TDBEngineError do { o erro..}
MensageDlg(‘Registro ja esta sendo
usado…!’,mtInformation,[ mbOk ],0 );
end;
Nao use o DBNavigation
485 - Recuperar a Velocidade da
CPU
Esta interessante função recupera a velocidade de
processamento aproximada da CPU:
const
ID_BIT=$200000; // EFLAGS ID bit

function GetCPUSpeed: Double;


const
DelayTime = 500;
var
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
begin
try
PriorityClass :=
GetPriorityClass(GetCurrentProcess);
Priority :=
GetThreadPriority(GetCurrentThread);

SetPriorityClass(GetCurrentProcess,
REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread,THREAD_
PRIORITY_TIME_CRITICAL);

Sleep(10);
asm
dw 310Fh // rdtsc
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;

SetThreadPriority(GetCurrentThread,
Priority);
SetPriorityClass(GetCurrentProcess,
PriorityClass);

Result := TimerLo / (1000.0 * DelayTime);


except end;
end;
No evento OnClick, basta atribuir a saída da função a
uma string:
procedure TForm1.Button1Click(Sender:
TObject);
var cpuspeed:string;
begin
cpuspeed:=Format(‘%f MHz’, [GetCPUSpeed]);
edit1.text := cpuspeed;
end;
486 - Utilizando o
Dblookupcombobox
O componente DBLookupComboBox é utilizado para
selecionar registros de uma tabela e gravar em outra
tabela.
As propriedades necessárias para a utilização são:
DataSource - Ligar a DataSource da Tabela ao qual vai
receber o valor do registro selecionado;
DataField - Ligar o campo de ligação entre as duas
tabelas, ao qual vai receber o valor do registro
selecionado;
ListSource - Ligar a DataSource da Tabela ao qual vai
Ter o registro selecionado;
ListField - Ligar o campo que será listado quando o
usuário abrir a janela para seleção do registro;
KeyField - Ligar o campo de ligação entre as duas
tabelas, ao qual terá o seu valor enviado para gravação.
O campo de ligação entre as duas tabelas pode ser um
campo código, pois é este campo que manterá os
valores iguais entre as duas tabelas.
487 - Adicionar horas
function AdicionaHora(TimeAdd: Integer) :
String;
{Adiciona à hora atual um numero de horas
determinado. Caso este numero seje
negativo, ele subtrairá da hora atual}
Var
Horas,Min,SomaHoras,SomaMin : Integer;
S, S1 : String;
begin
Horas :=
Strtoint(Copy(TimetoStr(Time),1,2))+
TimeAdd;
Min :=
Strtoint(Copy(TimetoStr(Time),4,2))+
TimeAdd ;
SomaHoras := SomaHoras+Horas;
SomaMin := SomaMin + Min;
If SomaMin > 59 Then
begin
if SomaMin mod 60 = 0 Then
begin
Somahoras := Somahoras+(Somamin div 60);
Somamin := 0;
end
else
begin
SomaHoras := SomaHoras + (SomaMin div
60);
SomaMin := SomaMin mod 60;
end;
end;
If Somamin = 0 Then
begin
S := ‘00’;
end
else
begin
S := InttoStr(Somamin);
end;
If Length(InttoStr(SomaHoras)) = 1 Then
begin
S1 := Concat(‘0’,InttoStr(Somahoras));
end
else
begin
S1 := InttoStr(Somahoras);
end;
Result := Concat(S1,’:’,S,’:00’);
end;
488 - Checa se o Simbolo da UF é
Valido
function ChecaEstado(Dado : string) :
boolean;
const
Estados =
‘SPMGRJRSSCPRESDFMTMSGOTOBASEALPBPEMARNCEP
IPAAMAPFNACRRRO’;
var
Posicao : integer;
begin
Result := true;
if Dado <> ” then
begin
Posicao := Pos(UpperCase(Dado),Estados);
if (Posicao = 0) or ((Posicao mod 2) =
0) then
begin
Result := false;
end;
end;
end;
489 - Testa se seu processador
pentium tem o Bug fatal
function CheckPentium: integer;
const
tstBugVal1: single = 4195835.0;
tstBugVal2: single = 3145727.0;
var
Answer: double;
begin
{$U-}
Answer := tstBugVal1 / tstBugVal2;
{$U+}
if tstBugVal1 - Answer * tstBugVal2 > 1.0
then
begin
CheckPentium := 0;
end
else
begin
CheckPentium := 1;
end;
end;
490 - Como verificar se falta algum
edit para preencher
function CheckForBlankText : Boolean ;
// Declare-a na clausula Private do form
//
var
n : LongInt ;
begin
Result := false ;
for n := 0 to ( ComponentCount - 1 ) do
begin
if ( components[n].ClassType = TEdit )
then
begin
if TEdit (components[n]).text = ” then
begin
Result := true ;
Exit;
end;
end ;
end ;
End;
491 - Como gerar um clone de um
programa
function CloneProgram(sExecutableFilePath
: string ): string;
var
pi: TProcessInformation;
si: TStartupInfo;
begin
FillMemory( @si, sizeof( si ), 0 );
si.cb := sizeof( si );
CreateProcess(Nil, PChar(
sExecutableFilePath ), Nil, Nil, False,
NORMAL_PRIORITY_CLASS,Nil, Nil, si, pi );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
end;
492 - Como criar um arquivo de
Backup muito feio mais eficiente
procedure TFormCopia.BitBtn1Click(Sender:
TObject);
var
I: Integer;
begin
Database1.Connected:=True; // Database
para controle
Table2.DatabaseName:=DirectoryListBox1.Dir
ectory; // Seleciona local de destino da
cópia
with Session1 do
begin
Active:=True;
GetTableNames(‘AliasName’,’*.*’,True,True,
Memo1.Lines); // Retorna o nome das
tabelas
end;
for I:= 0 to Memo1.Lines.Count - 1 do
begin
Table1.TableName:=Memo1.Lines[I]; //
Tabela origem
Table2.TableName:=Memo1.Lines[I]; //
Tabela destino
BatchMove1.Execute;
end;
end;
Para efetuar a restauração:
procedure
TFormRestaura.BitBtn1Click(Sender:
TObject);
var I: Integer;
begin
Database1.Connected:=True;
Table2.DatabaseName:=DirectoryListBox1.Dir
ectory; // Origem da restauração
with Session1 do
begin
Active:=True;
GetTableNames(Table2.DatabaseName,’*.*’,Tr
ue,True,Memo1.Lines); // Retorna nomes das
tabelas
end;
for I:= 0 to Memo1.Lines.Count - 1 do
begin
Table1.TableName:=Memo1.Lines[I]; //
Tabela origem
Table2.TableName:=Memo1.Lines[I]; //
Tabela destino
BatchMove1.Execute;
end;
end;
//Após restaurar por este método, você
deve recriar os índices.
493 - Como ler código de barras
Crie um Edit e no evento OnChange coloque a seginte
rotina
procedure TForm1.Edit1Change(Sender:
TObject);
begin
try
// Crie um indice secundário para o campo
de código de Barras
Tabela.IndexFieldNames := ‘nome do campo
de Código de Barra ‘;
Tabela.Editkey;
Tabela.FindNearest([Edit1.Text]);
Tabela.Refresh;
except on
EDBEngineError do MessageDlg(‘Erro na
busca! Tente novamente.’, mtError,
[mbOK], 0);
end
end;
Este procedimento executa uma busca na tabela que vc
quer
494 - Como desenhar figuras no
desktop
//mas você pode também, usar textos ou
outros por exemplo…
var
sc: Tcanvas;
begin
sc := TCanvas.Create;
try
sc.Handle:=GetDC(0);
sc.Brush.Style := bsClear;
sc.Draw(6,6,Tela.Picture.Graphic);
ReleaseDC(0, sc.handle);
finally
sc.free;
end;
495 - Para você mudar as imagens
do DbNavigator
Para você mudar as imagens do DbNavigator
//abra o seguinte arquivo no Image Editor do Delphi e
modifique as imagens como quizer.
“C:Arquivos de
programas\Borland\Delphi4\Lib\dbctrls.res”
496 - Quantas Palavras existem?
function CountedWords(const
WordText:String):Integer;
// deve ser declarada na clausua Var da
unit:
// KeyCharsSet: set of Char = [ ‘.’, ‘,’,
””, ‘;’, ‘:’, ‘ ‘,#13,#10,#9 ];
var
i: Integer;
F1,F2: boolean;
begin
result := 0;
for i := 1 to length(WordText)-1 do
begin
F1 := not( WordText[i] in KeyCharsSet)
F2 := not( WordText[i+1] in KeyCharsSet)
if (F1 and not F2) or ((i =
length(WordText)-1)and F2) then
begin
result := result + 1;
end;
end;
if(length(WordText)=1)and Not( WordText[1]
in KeyCharsSet) then
begin
result := 1;
end;
end;
497 - Exporta uma imagem de um
TImage para um arquivo no formato
WMF
procedure
ExportaBMPtoWMF(Imagem:TImage;Dest:Pchar);
var
Metafile : TMetafile;
MetafileCanvas : TMetafileCanvas;
DC : HDC;
ScreenLogPixels : Integer;
begin
Metafile := TMetafile.Create;
try
DC := GetDC(0);
ScreenLogPixels := GetDeviceCaps(DC,
LOGPIXELSY);
Metafile.Inch := ScreenLogPixels;
Metafile.Width :=
Imagem.Picture.Bitmap.Width;
Metafile.Height :=
Imagem.Picture.Bitmap.Height;
MetafileCanvas :=
TMetafileCanvas.Create(Metafile, DC);
ReleaseDC(0, DC);
try
MetafileCanvas.Draw(0, 0,
Imagem.Picture.Bitmap);
finally
MetafileCanvas.Free;
end;
Metafile.Enhanced := FALSE;
Metafile.SaveToFile(Dest);
finally
Metafile.Destroy;
end;
end;
498 - Converte hora (formato
HH:MM) para minutos
Function HoraToMin(Hora: String): Integer;
begin
Result := (StrToInt(Copy(Hora,1,2))*60) +
StrToInt(Copy(Hora,4,2));
end;
499 - Como Visualizar arquivos ARJ
function ConverterAtributos (A: Integer):
String;
begin
Result:= ‘–W’;
if A and faArchive <> 0 then
Result[1]:= ‘A’;
if A and faSysFile <> 0 then
Result[2]:= ‘S’;
if A and faHidden <> 0 then
Result[3]:= ‘H’;
if A and faReadOnly <> 0 then
Result[4]:= ‘R’;
end;
procedure TFormPrincipal.BotaoAbrirClick
(Sender: TObject);
var
P : Integer;
Info: TInfoArj;
Arj : TArj;
begin
if OpenDialog.Execute then begin
Caption:= OpenDialog.FileName;
Arj := TArj.Create;
Arj.LoadFromFile (OpenDialog.FileName);
Lista.Items.Clear;
Lista.Items.BeginUpdate;
for P:= 0 to Arj.Lista.Count-1 do begin
Info:= Arj.Buscar (P);
with Lista.Items.Add do begin
Caption:= Arj.Lista.Strings[P];
SubItems.Add (IntToStr
(Info.Descompactado));
SubItems.Add (IntToStr (Info.Compactado));
SubItems.Add (DateTimeToStr
(Info.Modificado));
SubItems.Add (ConverterAtributos
(Info.Attributos));
SubItems.Add (IntToHex (Info.CRC, 8));
end;
end;
Lista.Items.EndUpdate;
Arj.Free;
end;
end;
500 - Visualizar aruqivos
compactados CAB
procedure TFormPrincipal.BotaoAbrirClick
(Sender: TObject);
var
K : Integer;
N : Integer;
Info: pInfoCabinet;
Nome: String;
Path: String;
begin
SetCurrentDir (‘D:TempCab’);
if OpenDialog.Execute then begin
N := 0;
Cabinet:= TCabinet.Create;
Cabinet.LoadFromFile
(OpenDialog.FileName);
Lista.Items.BeginUpdate;
Lista.Items.Clear;
Lista.ViewStyle:= vsReport;
for K:= 0 to Cabinet.Lista.Count-1 do
begin
Nome:= Cabinet.ExtrairNomePath
(Cabinet.Lista.Strings[K], Path);
if Nome <> ” then
with Lista.Items.Add do begin
Inc (N);
Caption:= Nome;
Info := pInfoCabinet
(Cabinet.Lista.Objects[K]);
if Info <> nil then
with Info^ do begin
SubItems.Add (IntToStr (Descompactado));
SubItems.Add (DateTimeToStr (Modificado));
SubItems.Add (Path);
end;
end;
end;
Lista.Items.EndUpdate;
Caption:= OpenDialog.FileName + ‘ - ‘ +
IntToStr (N) + ‘ arquivo(s)’;
Cabinet.Free;
end;
end;
501 - Replace Str
function ReplaceStr
(Text,oldstring,newstring:string):string;
var atual, strtofind, originalstr:pchar;
NewText:string;
lenoldstring,lennewstring,m,index:integer;
begin //ReplaceStr
NewText:=Text;
originalstr:=pchar(Text);
strtofind:=pchar(oldstring);
lenoldstring:=length(oldstring);
lennewstring:=length(newstring);
Atual:=StrPos(OriginalStr,StrtoFind);
index:=0;
while Atual<>nil do
begin //Atual<>nil
m:=Atual - OriginalStr - index + 1;
Delete(NewText,m,lenoldstring);
Insert(newstring,NewText,m);
inc(index,lenoldstring-lennewstring);

Atual:=StrPos(Atual+lenoldstring,StrtoFind
);
end; //Atual<>nil
Result:=NewText;
end; //ReplaceStr
502 - Abrir tabelas paradox
protegidas por senha
Existem diversos aplicativos na internet capazes de
descobrir as senhas de tabelas paradox a partir de um
erro das tabelas… mas pra que usar um aplicativo
desses se vc pode usar estas senhas masters que
funcionam com qualquer tabela paradox protegida por
senha!!
Para PARADOX 7.0 -> “jIGGAe” ou “cupcdvum”
Para PARADOX 5.0 -> “jIGGAe” ou “cupcdvum”
Para PARADOX 4.0 (DOS) -> “nx66ppx”
Aproveitem!
503 - Drag e Drop com o Windows
Explorer
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,
Dialogs, ComCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
PROCEDURE FileIsDropped ( VAR Msg :
TMessage ) ; Message WM_DropFiles ;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
uses
shellapi;
{$R *.DFM}

procedure TForm1.FormCreate(Sender:
TObject);
begin
DragAcceptFiles( Handle,True ) ;
end;

procedure TForm1.FileIsDropped ( VAR Msg :


TMessage ) ;
var
hDrop : THandle ;
fName : ARRAY[0..254] OF CHAR ;
NumberOfFiles : INTEGER ;
fCounter : INTEGER ;
Names : STRING ;
begin
hDrop := Msg.WParam ;
NumberOfFiles :=
DragQueryFile(hDrop,-1,fName,254);
Names := ” ;
for fCounter := 1 TO NumberOfFiles DO
BEGIN
DragQueryFile(hDrop,fCounter,fName,254);
// Aqui obtem-se o nome de todos os
arquivos selecionados no Explorer
Names := Names + #13#10 + fName ;
end;

ShowMessage(‘Selecionados
‘+IntToStr(NumberOfFiles) + ‘ Nomes : ‘ +
Names );
DragFinish ( hDrop);
end;
504 - Mudando o texto de um edit
no evento OnChange
Se o texto de um TEdit for mudado no seu evento
OnChange, este even-to será chamado recursivamente
até acabar com o espaço de pilha. Pa-ra fazer isso,
deve-se setar o evento OnChange para NIL antes de
mu-dar o texto, voltando ao original depois, desta
maneira:
procedure Edit1Change(Sender : TObject);
begin
Edit1.OnChange := NIL;
if Edit1.Text = ‘Texto’ then
Edit1.Text := ‘Novo Texto’;
Edit1.OnChange := Edit1Change;
end;
Esta dica também vale para evento OnValidate.
505 - Desabilitando um RadioButton
Num RadioGroup
TRadioButton(RadioGroup1.Controls[1]).Enab
led := False;
506 - Obter o tipo de um drive
Inclua na seção uses: Windows, Dialogs
{ - Coloque um edit (Edit1) e um botão no
form;
- Altere o OnClick do botão conforme
abaixo: }

procedure TForm1.Button1Click(Sender:
TObject);
var
S: string;
Tipo: byte;
begin
Tipo := GetDriveType(PChar(Edit1.Text[1] +
‘:'));
case Tipo of
0: S := ‘Tipo indeterminado’;
1: S := ‘Drive não existe’;
DRIVE_REMOVABLE: S := ‘Disco removível’;
DRIVE_FIXED: S := ‘Disco Fixo’;
DRIVE_REMOTE: S := ‘Unidade de rede’;
DRIVE_CDROM: S := ‘CD-ROM’;
DRIVE_RAMDISK: S := ‘RAM Disk’;
else
S := ‘Erro’;
end;
ShowMessage(S);
end;

{ Para pegar o tipo da unidade atual


troque…}
Tipo := GetDriveType(PChar(Edit1.Text[1] +
‘:'));
{ por }
Tipo := GetDriveType(nil);
Observações
Para testar digite a letra do drive no Edit1 e clique no
botão. A unit Dialogs foi colocada no uses apenas por
causa da procedure ShowMessage. Para exibir todas as
unidades existentes e seus res-pectivos tipos, use a
função tbGetDrives (da pergunta 64) em con-junto com
este exemplo.
507 - Executar um arquivo com
extenção *.lnk
uses ShellApi;
procedure TForm1.Button1Click(Sender:
TObject);
begin
ShellExecute(0,nil,‘C:\WINDOWS\START
MENU\DELPHI\Delphi3.lnk’ ,nil, nil,
SW_SHOWNORMAL);
end;
508 - Gravando e reproduzindo as
teclas digitadas no delphi
Se você escrever uma quantidade grande de código,
provavelmente passará por uma situação, na qual será
necessário gravar as teclas pressionadas e reproduzi-
las algumas vezes. Isto pode ser feito no ambiente IDE
do Delphi, digitando-se [Ctrl][Shift][R] para se co-meçar
a gravar. A partir de então todas as teclas que forem
pres-sionadas estarão sendo deveidamente registradas
na sequência em que a digitação ocorreu. Para se parar
de gravar é só digitar no-vamente [Ctrl][Shift][R]. E para
reproduzir de uma única vez a se-quência digitada
pressione [Ctrl][Shift][P].
Obs: Isto somente funciona com o “default keymapping”.
Para saber que tipo de keymapping você está utilizando,
verifique na opção {Environment Optiosn} do menu
{Tools}, o valor definido no “Editor Speedsetting
Combobox”, da aba “Editor”.
509 - Tipo de Conexão
function TipoConexao:boolean;
var
flags: dword;
begin
Result :=
InternetGetConnectedState(@flags, 0);
if Result then begin
showmessage(‘Conexão a Internet está
Ativa’);
if (flags and INTERNET_CONNECTION_MODEM)
= INTERNET_CONNECTION_MODEM then
showmessage(‘Conexão por modem’);
if (flags and INTERNET_CONNECTION_LAN) =
INTERNET_CONNECTION_LAN then
showmessage(‘Conexião por lan’);
if (flags and INTERNET_CONNECTION_PROXY)
= INTERNET_CONNECTION_PROXY then
showmessage(‘Conexião por proxy’);
if (flags and
INTERNET_CONNECTION_MODEM_BUSY)
=INTERNET_CONNECTION_MODEM_BUSY then
showmessage(‘modem ocupado’);
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
TipoConexao;
end;

Talvez não funcione no Delphi 3


510 - Sender - Objeto
O Sender representa o nome do objeto que está
chamando tal evento. Adicione 3 botões e modifique
seus nomes ( Name ) : A, B, C. No evento onClick do
botão A
procedure TForm1.AClick(Sender: TObject);
begin
if ( Sender = A ) then
ShowMessage(‘Botão A’);
if ( Sender = B ) then
ShowMessage(‘Botão B’);
if ( Sender = C ) then
ShowMessage(‘Botão C’);
end;
depois direcione o evento onClick dos outros botões B e
C para o evento onClick do botão A, execute e saia
clicando.
511 - Deletar com QUERY
QExclui.Close;
QExclui.Sql.Clear;
QExclui.SQL.Add(‘DELETE FROM TBEXEMPLO ‘ +
‘WHERE (TBEXEMPLO.CodigoP = :EdCodigoP)
AND ‘ +
‘(TBEXEMPLO.CodigoS = :EdCodigoS) ‘);
QExclui.PARAMBYNAME(‘EdCodigo’).AsInteger
:= 1;
QExclui.PARAMBYNAME(‘EdCodigoS’).AsInteger
:= 5;
QExclui.ExecSQL;
512 - Criar labels em tempo de
execução
procedure TForm1.Button1Click(Sender:
TObject);
Var
OLabel : TLabel;
begin
OLabel := TLabel.create(application);
OLabel.Parent := Form1;
OLabel.Name := ‘LABEL1’;
OLabel.Left := 10;
OLabel.Top := 10;
OLabel.font.Size := 20;
end;
513 - Insert em duas tabelas
procedure TForm1.Button1Click(Sender:
TObject);
begin
Try
With Query1 do
Begin
Close;
Sql.Clear;
Sql.Add(‘Insert Into tb_pai
(Cod_Orcamento,Cod_Aba,Cod_Atividades,Desc
ricao_Atividades,Cod_Mais)Select
Cod_Orcamento,Cod_Aba,Cod_Atividades,Descr
icao_Atividades,Cod_Mais>From
tb_orcamentos’);
Sql.Add(‘Where cod_orcamento = 6’);
ExecSql;
table2.refresh;
End
Except
Showmessage(‘Favor Selecionar
novamente’);
End
end;
514 - Vetor Dinâmico
01)
var
vetor_string_dinamico: array of string;
i: integer;
begin
setLength( vetor_string_dinamico, 10 );
for i := 0 to high(
vetor_string_dinamico) do begin
vetor_string_dinamico[ i ] := IntToStr(
i );
end;
02)
var
vetor_taluno: array of TAluno;
begin
setLength( vetor_tAluno, 5 );
vetor_tAluno[0] := TAluno.Create;
vetor_taluno[0].Codigo := valor;
03)
exemplo:
var
vetor_string_dinamico: array of string;
i: integer;
begin
setLength( vetor_string_dinamico, 10 );
for i := 0 to high(
vetor_string_dinamico) do begin
vetor_string_dinamico[ i ] := IntToStr(
i );
end;
04)

type
vetor_dinamico = array of TAluno;
var
vetor_aluno: vetor_dinamico;
515 - Tipos de Array
Um array é uma coleção ordenada de elementos do
mesmo tipo de dados, que faz uso de um índice para
dar acesso aos items da coleção. Arrays são úteis em
diversas situações. Como o índice permite acesso direto
aos elementos da lista, arrays fornecem um poderoso
mecanismo para se organizar dados. O exemplo a
seguir mostra como declarar uma array :
EXEMPLO 1:
Procedure Tform1.Button1Click (Sender:
Tobject) ;
var
Dias_de_Semana: array[1..7] of String ;

var
DiaNo: Integer;
DiadaSemana: String;

begin

{Inicializa o array com nomes dos dias


da semana }
Dias_de_Semana [1] := ‘Domingo’ ;
Dias_de_Semana [2] := ‘Segunda-feira’ ;
Dias_de_Semana [3] := ‘Terça-feira’ ;
Dias_de_Semana [4] := ‘Quarta-feira’ ;
Dias_de_Semana [5] := ‘Quinta-feira’ ;
Dias_de_Semana [6] := ‘Sexta-feira’ ;
Dias_de_Semana [7] := ‘Sábado’ ;

DiaNo :=DayOfWeek (Date) ; {Retorna o


número correspondente ao dia da semana da
data atual}
ShowMessage(‘ Hoje é ‘ + Dias_de_Semana
[DiaNo] ) ;
…………………………………………………………………………….
 EXEMPLO 2: Uso do comando FOR
O comando For deve ser usado sempre que se souber
com antecedência quantas vezes o laço deverá ser
executado. Como ilustração vamos resolver o seguinte
problema :

No baile Funk encontram-se quatro garotas (Juliana,


Natália, Carolina e Adriana) e quatro rapazes
(Guilherme, Neto, Leonardo e Eduardo). Pede-se :
quantos - e quais - pares podem ser formados com essa
turma ?

Para resolver:
Crie uma nova Aplicação (File | New Application)
Acrescente um ListBox
Acrescente um Button
Dê dois cliques sobre o Button e acrescente o código :

procedure TForm1.Button1Click(Sender:
TObject);
var
ElasList : array[1..4] of String [10] ;
ElesList : array[1..4] of String[10];
i , j : integer;
begin
ElasList[1] := ‘Juliana’ ;
ElasList[2] := ‘Natália’ ;
ElasList[3] := ‘Carolina’ ;
ElasList[4] := ‘Adriana’ ;
ElesList[1] := ‘Guilherme’ ;
ElesList[2] := ‘Neto’ ;
ElesList[3] := ‘Leonardo’ ;
ElesList[4] := ‘Eduardo’ ;
for i:=1 to 4 do
for j:=1 to 4 do
ListBox1.Items.Add(ElasList[i] + ‘
‘+ElesList[j]);
end;
end.
520 - Atribuindo a uma coluna do
StringGrid como só de leitura
if Col mod 2 = 0 then
grd.Options := grd.Options + [goEditing]
else
grd.Options := grd.Options - [goEditing];
521 - Chamar um programa e
esperar a finalização
Para executar um programa e esperar até esse
programa finalizar, use a rotina abaixo:
function Executa (Arquivo : String; Estado
: Integer) : Integer;
var
Programa : array [0..512] of char;
CurDir : array [0..255] of char;
WorkDir : String;
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
begin
StrPCopy (Programa, Arquivo);
GetDir (0, WorkDir);
StrPCopy (CurDir, WorkDir);
FillChar (StartupInfo, Sizeof
(StartupInfo), #0);
StartupInfo.cb := sizeof (StartupInfo);
StartupInfo.dwFlags :=
STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Estado;
if not CreateProcess (nil, Programa, nil,
nil, false, CREATE_NEW_CONSOLE or
NORMAL_PRIORITY_CLASS, nil, nil,
StartupInfo, ProcessInfo) then
Result := -1
else
begin
WaitForSingleObject (ProcessInfo.hProcess,
Infinite);
GetExitCodeProcess (ProcessInfo.hProcess,
Result);
end;
end;
Estado é o tipo de janela que aparecerá, que pode ser:
SW_SHOWNORMAL
Janela em modo normal
SW_MAXIMIZE
Janela maximizada
SW_MINIMIZE
Janela minimizada
SW_HIDE
Janela Escondida
522 - Colocar o cursor no final do
TEdit ao receber o foco
No evento OnEnter do TEdit coloque:
procedure TForm1.Edit1Enter(Sender:
TObject);
begin
Edit1.Selstart:= Length(Edit1.text);
end;
523 - Convertendo um número real
para string com 2 casas
ValorReal : Real;
ValorString : String;
ValorReal := 5;
ValorString :=
floattostrf(ValorReal,ffFixed,18,2);
524 - Como acrescentar dias uteis
a uma data
function Datafinal(dataini:tdatetime;
dias_uteis:integer):tdatetime;
//
// Retorna uma data acresçida de mais um
certo número de dias
// uteis descontando os fins de semana
//
var dw:integer;
begin
dw := DayOfWeek(dataini)-1;
result := dataini+dias_uteis+
((dias_uteis-1+dw) div 5)*2;
end;
525 - Como converter de decimal
para binario
function DecToBinStr(n: integer): string;
{Converte um numero decimal em binário}
var
S: string;
i: integer;
Negative: boolean;
begin
if n < 0 then
begin
Negative := true;
end;
n := Abs(n);
for i := 1 to SizeOf(n) * 8 do
begin
if n < 0 then
begin
S := S + ‘1’;
end
else
begin
S := S + ‘0’;
end;
n := n shl 1;
end;
Delete(S,1,Pos(‘1’,S) - 1);//remove
leading zeros
if Negative then
begin
S := ‘-‘ + S;
end;
Result := S;
end;
526 - Como converter decimal para
base especificada
function DecToBase( Decimal: LongInt;
const Base: Byte): String;
{converte um número decimal na base
especificada}
const
Symbols: String[16] =
‘0123456789ABCDEF’;
var
scratch: String;
remainder: Byte;
begin
scratch := ”;
repeat
remainder := Decimal mod Base;
scratch := Symbols[remainder + 1] +
scratch;
Decimal := Decimal div Base;
until ( Decimal = 0 );
Result := scratch;
end;
527 - Como converter decimal para
romanos
function DecToRoman( Decimal: LongInt ):
String;
{Converte um numero decimal em algarismos
romanos}
const
Romans: Array[1..13] of String = ( ‘I’,
‘IV’, ‘V’, ‘IX’, ‘X’, ‘XL’, ‘L’, ‘XC’,
‘C’, ‘CD’, ‘D’, ‘CM’, ‘M’ );
Arabics: Array[1..13] of Integer =( 1, 4,
5, 9, 10, 40, 50, 90, 100, 400, 500, 900,
1000);
var
i: Integer;
scratch: String;
begin
scratch := ”;
for i := 13 downto 1 do
while ( Decimal >= Arabics[i] ) do
begin
Decimal := Decimal - Arabics[i];
scratch := scratch + Romans[i];
end;
Result := scratch;
end;
528 - Como desconectar unidade de
rede
Function
DesconectaRede(Letra:Pchar;Forcada:boolean
):String;
//
// Disconecta uma unidade mapeada via
programação
//
// Letra = Letra atribuida a unidade
// Forcada = Força o cancelamento do
mapeamento
//
begin
WNetCancelConnection2(Letra,0,Forcada);
Case GetLastError() of
1205: Result := ‘Não foi possível abrir
o perfil’;
1206: Result := ‘Perfil do usuário não
encontrado ou inválido’;
1208: Result := ‘Ocorreu um Erro
específico na rede’;
2138: Result := ‘Rede não encontrada ou
fora do ar’;
2250: Result := ‘Mapeamento inválido ou
não encontrado’;
2401: Result := ‘Existem muitos arquivos
abertos’;
else
Result := ‘Unidade disconectada com
sucesso’;
end;
end;
529 - Diferença entre duas horas
function DifHora(Inicio,Fim :
String):String;
{Retorna a diferença entre duas horas}
var
FIni,FFim : TDateTime;
begin
Fini := StrTotime(Inicio);
FFim := StrToTime(Fim);
If (Inicio > Fim) then
begin
Result :=
TimeToStr((StrTotime(‘23:59:59’)-
Fini)+FFim)
end
else
begin
Result := TimeToStr(FFim-Fini);
end;
end;
Observação incluída por um dos
usuários da DTDelphi sobre a dica
Acima:
Olá, meu nome é Paulo e já parabenizo pelas dicas
disponíveis em Delphi, que ajudam todos os
programadores desta linguagem.

Eu sempre recorro as dicas e idéias, quando deparamos


com algumas dúvidas e dificuldades.

Eu estava consultando as dicas sobre horas, depois de


ter feito rotinas de cálculos de horas, é ví que a dica 529
diminuiria um tempo se eu tivesse visto antes.

Se você achar importante, tenho uma observação sobre


esta dica. É que quando é calculado com a diferença de
24 horas o resultado é sempre xx:59:59, portanto para
que o resultado seja arredondado, é só acrescentar +
StrToTime(‘00:00:01) conforme abaixo.

Result := TimeToStr((StrTotime(‘23:59:59’)
+ StrToTime(‘00:00:01’) -Fini)+FFim

Espero estar ajudado em algo, um abraço

Paulo Cesar Cortez


530 - Tamanho de um Diretorio
function DirSize(Dir:string):integer;
{Retorna o tamanho de um diretório}
var
SearchRec : TSearchRec;
Separator : string;
DirBytes : integer;
begin
if Copy(Dir,Length(Dir),1)=’' then
begin
Separator := ”;
end
else
begin
Separator := ‘';
end;
if
FindFirst(Dir+Separator+’*.*’,faAnyFile,Se
archRec) = 0 then
begin
if
FileExists(Dir+Separator+SearchRec.Name)
then
begin
DirBytes := DirBytes + SearchRec.Size;

{Memo1.Lines.Add(Dir+Separator+SearchRec.N
ame);}
end
else if
DirectoryExists(Dir+Separator+SearchRec.Na
me) then
begin
if (SearchRec.Name<>’.’) and
(SearchRec.Name<>’..’) then
begin
DirSize(Dir+Separator+SearchRec.Name);
end;
end;
while FindNext(SearchRec) = 0 do
begin
if
FileExists(Dir+Separator+SearchRec.Name)
then
begin
DirBytes := DirBytes + SearchRec.Size;

{Memo1.Lines.Add(Dir+Separator+SearchRec.N
ame);}
end
else if
DirectoryExists(Dir+Separator+SearchRec.Na
me) then
begin
if (SearchRec.Name<>’.’) and
(SearchRec.Name<>’..’) then
begin
DirSize(Dir+Separator+SearchRec.Name);
end;
end;
end;
end;
FindClose(SearchRec);
end;
531 - Eliminar Caracteres de
Strings
function EliminaCaracteres (sTexto:
String; sCaracteres:Set of Char):String;
{Elimina de sTexto todos os caracteres
passados como parametro}
var
nPos, nTam: Integer;
begin
Result := ”;
nPos := 1;
nTam := Lenght(sTexto);
while nPos <= nTam do
begin
if not (sTexto[nPos] in sCaracteres)
then Result := Result +sTexto[nPos]
end;
end;
532 - Verificar se variavel está
vazia
function Empty(inString:String): Boolean;
{Testa se a variavel está vazia ou não}
Var
index : Byte;
Begin
index := 1;
Empty := True;
while (index <= Length(inString))and
(index <> 0) do
begin
if inString[index] = ‘ ‘ Then
begin
inc(index)
end
else
Begin
Empty := False;
index := 0
end;
end;
end;
533 - Executar o Windows Explorer
com parametros
function ExecExplorer(OpenAtPath: string;
OpenWithExplorer, OpenAsRoot: Boolean):
boolean;
//
// Executa o Windows Explorer a partir de
uma pasta
// especificada
//
// Requer a unit ShellApi
//
// ex: execExplorer(‘C:\Temp’, True,True);
//
var
s: string;
begin
if OpenWithExplorer then
begin
if OpenAsRoot then
s := ‘ /e,/root,”’ + OpenAtPath + ‘”’
else
s := ‘ /e,”’ + OpenAtPath + ‘”’;
end
else
s := ‘”’ + OpenAtPath + ‘”’;
result :=
ShellExecute(Application.Handle,PChar(‘ope
n’),PChar(‘explorer.exe’),PChar(s),nil,SW_
NORMAL) > 32;
end;
534 - Como Esvaziar uma Tabela
function EsvaziaTabela(Tabela : TTable):
Boolean;
// Esvazia a tabela passada como parametro
var
lExclusivo : boolean;
begin
Tabela.Active := False;
repeat
try
Tabela.Exclusive := True;
Tabela.Active := True;
Tabela.EmptyTable;
lExclusivo := True;
Break;
except
on EDatabaseError do
if MessageDlg(‘A tabela está sendo usada
por outro usuário. Tenta novamente ?’,
mtError,[mbOK, mbCancel], 0) <> mrOK then
begin
lExclusivo := False;
raise;
end;
end;
until False;
Result := lExclusivo;
end;
535 - Pegar informações de
Executavel
function FileVerInfo(const FileName:
string;var FileInfo: TStringList):
Boolean;
//
// Obtem diversas informações de um
arquivo executável
//
// Requer um StringList criado antes de
executar a função
// deve ser declarado na clausula Var no
inicio da Unit
// StrLst := TStringList.Create;
//
//
const

Key: array[1..9] of string =


(‘CompanyName’,
‘FileDescription’,
‘FileVersion’,
‘InternalName’,
‘LegalCopyright’,
‘OriginalFilename’,
‘ProductName’,
‘ProductVersion’,
‘Comments’);

KeyBr: array [1..9] of string =


(‘Empresa……………………..’,
‘Descricao……………………’,
‘Versao do Arquivo………..’,
‘Nome Interno……………….’,
‘Copyright……………………..’,
‘Nome Original do Arquivo.’,
‘Produto………………………..’,
‘Versao do Produto…………’,
‘Comentarios……………:’);
var
Dummy : THandle;
BufferSize, Len : Integer;
Buffer : PChar;
LoCharSet, HiCharSet : Word;
Translate, Return : Pointer;
StrFileInfo, Flags : string;
TargetOS, TypeArq : string;
FixedFileInfo : Pointer;
i : Byte;
begin
Result := False;
If not FileExists(FileName) then
begin
showmessage(‘Arquivo não encontrado’);
Result := False;
exit;
end;
BufferSize :=
GetFileVersionInfoSize(PChar(FileName),
Dummy);
if BufferSize <> 0 then
begin
GetMem(Buffer, Succ(BufferSize));
try
if GetFileVersionInfo(PChar(FileName),
0, BufferSize,Buffer) then
begin
if VerQueryValue(Buffer,
‘\VarFileInfo\Translation’, Translate,
UINT(Len)) then
begin
LoCharSet :=
LoWord(Longint(Translate^));
HiCharSet :=
HiWord(Longint(Translate^));
for i := 1 to 9 do
begin
StrFileInfo :=
Format(‘\StringFileInfo\0%x0%x\%s’,
[LoCharSet, HiCharSet, Key[i]]);
if
VerQueryValue(Buffer,PChar(StrFileInfo),
Return,UINT(Len)) then
begin
FileInfo.Add(KeyBr[i] + ‘: ‘ +
PChar(Return));
end;
end;
if
VerQueryValue(Buffer,’',FixedFileInfo,
UINT(Len)) then
with TVSFixedFileInfo(FixedFileInfo^) do
begin
Flags := ”;
if (dwFileFlags and VS_FF_DEBUG) =
VS_FF_DEBUG then
begin
Flags := Concat(Flags,’*Debug* ‘);
end;
if (dwFileFlags and VS_FF_SPECIALBUILD)
= VS_FF_SPECIALBUILD then
begin
Flags := Concat(Flags, ‘*Special Build*
‘);
end;
if (dwFileFlags and VS_FF_PRIVATEBUILD)
= VS_FF_PRIVATEBUILD then
begin
Flags := Concat(Flags, ‘*Private Build*
‘);
end;
if (dwFileFlags and VS_FF_PRERELEASE) =
VS_FF_PRERELEASE then
begin
Flags := Concat(Flags, ‘*Pre-Release
Build* ‘);
end;
if (dwFileFlags and VS_FF_PATCHED) =
VS_FF_PATCHED then
begin
Flags := Concat(Flags, ‘*Patched* ‘);
end;
if Flags <> ” then
begin
FileInfo.Add(‘Atributos: ‘ + Flags);
end;
TargetOS := ‘Plataforma (OS): ‘;
case dwFileOS of
VOS_UNKNOWN : TargetOS :=
Concat(TargetOS, ‘Desconhecido’);
VOS_DOS : TargetOS := Concat(TargetOS,
‘MS-DOS’);
VOS_OS216 : TargetOS := Concat(TargetOS,
‘16-bit OS/2’);
VOS_OS232 : TargetOS := Concat(TargetOS,
‘32-bit OS/2’);
VOS_NT : TargetOS := Concat(TargetOS,
‘Windows NT’);
VOS_NT_WINDOWS32, 4: TargetOS :=
Concat(TargetOS, ‘Win32 API’);
VOS_DOS_WINDOWS16: TargetOS :=
Concat(TargetOS, ‘16-bit Windows ‘,‘sob
MS-DOS’);
else
TargetOS := Concat(TargetOS, ‘Fora do
Padrão. Código: ‘, IntToStr(dwFileOS));
end;
FileInfo.Add(TargetOS);
TypeArq := ‘Tipo de Arquivo: ‘;
case dwFileType of
VFT_UNKNOWN : TypeArq :=
Concat(TypeArq,‘Desconhecido’);
VFT_APP : TypeArq :=
Concat(TypeArq,‘Aplicacao’);
VFT_DLL : TypeArq :=
Concat(TypeArq,‘Dynamic-Link Lib.’);
VFT_DRV : begin
TypeArq := Concat(TypeArq,‘Device driver
- Driver ‘);
case dwFileSubtype of
VFT2_UNKNOWN : TypeArq :=
Concat(TypeArq,‘Desconhecido’);
VFT2_DRV_PRINTER : TypeArq :=
Concat(TypeArq,‘de Impressao’);
VFT2_DRV_KEYBOARD : TypeArq :=
Concat(TypeArq,‘de Teclado’);
VFT2_DRV_LANGUAGE : TypeArq :=
Concat(TypeArq,‘de Idioma’);
VFT2_DRV_DISPLAY : TypeArq :=
Concat(TypeArq,‘de Vídeo’);
VFT2_DRV_MOUSE : TypeArq :=
Concat(TypeArq,‘de Mouse’);
VFT2_DRV_NETWORK : TypeArq :=
Concat(TypeArq,‘de Rede’);
VFT2_DRV_SYSTEM : TypeArq :=
Concat(TypeArq,‘de Sistema’);
VFT2_DRV_INSTALLABLE : TypeArq :=
Concat(TypeArq,‘Instalavel’);
VFT2_DRV_SOUND : TypeArq :=
Concat(TypeArq,‘Multimida’);
end;
end;
VFT_FONT : begin
TypeArq := Concat(TypeArq,‘Fonte - Fonte
‘);
case dwFileSubtype of
VFT2_UNKNOWN : TypeArq :=
Concat(TypeArq, ‘Desconhecida’);
VFT2_FONT_RASTER : TypeArq :=
Concat(TypeArq,‘Raster’);
VFT2_FONT_VECTOR : TypeArq :=
Concat(TypeArq,‘Vetorial’);
VFT2_FONT_TRUETYPE : TypeArq :=
Concat(TypeArq,‘TrueType’);
end;
end;
VFT_VXD : TypeArq :=
Concat(TypeArq,‘Virtual Device’);
VFT_STATIC_LIB: TypeArq :=
Concat(TypeArq,‘Static-Link Lib.’);
end;
FileInfo.Add(TypeArq);
end;
end;
end;
finally
FreeMem(Buffer, Succ(BufferSize));
Result := FileInfo.Text <> ”;
end;
end;
end;
536 - Verificar tipo de arquivo
function FileTypeName(const aFile:
String): String;
{Retorna descrição do tipo do arquivo.
Requer a unit ShellApi}
var
aInfo: TSHFileInfo;
begin
if
SHGetFileInfo(PChar(aFile),0,aInfo,Sizeof(
aInfo),SHGFI_TYPENAME)<>0 then
Result := StrPas(aInfo.szTypeName)
else begin
Result := ExtractFileExt(aFile);
Delete(Result,1,1);
Result := Result +’ File’;
end;
end;
537 - Converter qualquer variavel
em string
function Geracaracter(const v: variant):
string;
//
// Converte qualquer tipo de variavel em
String
//
begin
case TVarData(v).vType of
varEmpty: result := ‘Empty’;
varNull: result := ‘Null’;
varSmallInt: result := IntToStr(v);
varInteger: result := IntToStr(v);
varSingle: result := FloatToStr(v);
varDouble: result := FloatToStr(v);
varCurrency: result := FloatToStr(v);
varDate: result := DateToStr(v);
varVariant: result := FloatToStr(v);
varUnknown: result := ‘?’;
varByte: result := IntToStr(v);
varString: result := V;
end;
end;
538 - Calcular percentual de Valor
function
Gerapercentual(valor:real;Percent:Real):re
al;
// Retorna a porcentagem de um valor
begin
percent := percent / 100;
try
valor := valor * Percent;
finally
result := valor;
end;
end;
539 - Retorna Path de Browser
Padrão
function GetBrowser: String;
//
// Retorna o Path de seu Browser padrão
//
// Requer a Registry declarada na clausual
Uses da unit
//
var
Browser: String;
I: Integer;
Reg: TRegistry;
begin
Reg := TRegistry.Create;
with Reg do
begin
try
RootKey := HKEY_CLASSES_ROOT;
if not
OpenKey(‘http\shell\open\command’,False)
then
begin
Browser := ”;
end
else
begin
Browser := ReadString(”);
end;
CloseKey;
finally
Free;
Reg := nil;
end;
I := Pos(‘.exe’,LowerCase(Browser));
if I > 0 then
begin
Browser := Copy(Browser, 1, (I+3));
end;
I := Pos(‘”’,Browser);
while I > 0 do
begin
Delete(Browser,1,I);
I := Pos(‘”’,Browser);
end;
end;
Result := Browser;
end;
540 - Resgate de variaveis do
ambiente DOS
Function GetDOSEnvVar(const
VarName:String):String;
// Rotina de resgate das variáveis de
ambiente DOS
Var
Len:Integer;
pDosEnv:PChar;
Begin
result :=”;
Len := Length(VarName);
PDosEnv := GetEnvironmentStrings;
If (StrLIComp(PDosEnv, @VarName[1], Len) =
0) And (PDosEnv[Len] =’ ‘) Then
Begin
Result := StrPas(PDosEnv + Len + 1);
Break;
End;
Inc(PDosEnv, StrLen(PDosEnv) + 1);
End;
541 - Tipo de Executável
Function GetExetype( Const fname: String
): TExetype;
//
// Retorna o tipo de executável que é o
arquivo
// Ideal para testar se o executável está
corrompido
// ou imcompativel
//
// Exemplo:
//
// procedure TForm1.Button1Click(Sender:
TObject);
// type
// TExeStrings = Array [TExetype] of
String[30];
// const
// ExeStrings : TExeStrings = (‘Unknown
file type’, ‘Dos executable’, ‘Windows 16
bit executable’,‘Windows 32 bit
executable’);
// begin
// With OpenDialog1 Do
// If Execute Then
// begin
// Showmessage(ExeStrings[ GetExetype(
filename )]);
// end;
// end;
//
//
Var
signature: Word;
WinHdrOffset: Word;
fexe: TFileStream;
Begin
result := etUnknown;
try
fexe := TFileStream.Create( fname,
fmOpenRead or fmShareDenyNone);
try
fexe.ReadBuffer( signature,
Sizeof(signature));
If signature = $5A4D { ‘MZ’ } Then
Begin
result := etDOS;
fexe.Seek( $18, soFromBeginning );
fexe.ReadBuffer( WinHdrOffset,
Sizeof(WinHdrOffset));
If WinHdrOffset >= $40 Then
Begin
fexe.Seek( $3C, soFromBeginning );
fexe.ReadBuffer( WinHdrOffset,
Sizeof(WinHdrOffset));
fexe.Seek( WinHdrOffset, soFrombeginning
);
fexe.ReadBuffer( signature,
Sizeof(signature));
If signature = $454E { ‘NE’ } Then
begin
result := etWinNE;
end
else
begin
If signature = $4550 { ‘PE’ } Then
end;
result := etWinPE;
end; { If }
end; { If }
finally
fexe.Free;
end
except
end;
end;
542 - Path de Aplicativo associado
a uma extensão
function GetExe(Ext : string) : string;
//
// Retorna o path completo do aplicativo
que está associado
// ao arquivo cuja extensão você colocou
em Ext
//
// Exemplo:
//
// Showmessage(GetExe(‘txt’));
// Vai retornar: C:\Windows\Notepad.exe
//
var
reg: TRegistry; s : string;
I: integer;
begin
s := ”;
reg := TRegistry.Create;
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKey(‘.’ + ext +
‘\shell\open\command’,false) <> false then
begin
s := reg.ReadString(”);
reg.CloseKey;
end
else
begin
if reg.OpenKey(‘.’ + ext, false) <>
false then
begin
s := reg.ReadString(”);
reg.CloseKey;
if s <> ” then
begin
if reg.OpenKey(s +
‘\shell\open\command’,false) <> false then
begin
s := reg.ReadString(”);
end;
reg.CloseKey;
end;
end;
end;
if ((length(s) > 0) and (s[1] = ‘”’)) then
Delete(s, 1, 1);
i := pos(‘.EXE’,uppercase(S));
if I = 0 then
begin
Result := ”
end
else
begin
Result := copy(S, 1, i +3);
end;
end;
543 - Nome do Host da Conexão
Function GetHostName(strIPAddress :
String) : String;
//
// Retorna o Host onde seu TCP/IP está
conectado
//
// Requer a Winsock declarada na clausula
uses da unit
//
Var
strHost : String ;
pszIPAddress : PChar ;
pReturnedHostEnt : PHostEnt ;
InternetAddr : u_long ;
GInitData : TWSADATA ;
Begin
strHost := ”;
If WSAStartup($101, GInitData) = 0 then
Begin
pszIPAddress := StrAlloc( Length(
strIPAddress ) + 1 ) ;
StrPCopy( pszIPAddress, strIPAddress ) ;
InternetAddr := Inet_Addr(pszIPAddress)
;
StrDispose( pszIPAddress ) ;
pReturnedHostEnt := GetHostByAddr(
PChar(@InternetAddr),4, PF_INET );
try
strHost := pReturnedHostEnt^.h_name;
WSACleanup;
Result := strHost ;
except
Result := ‘Host inválido ou não
encontrado’;
end;
end;
end;
544 - Clone Monocromático de
BitMap
function CreateDisabledBitmap(FOriginal:
TBitmap; OutlineColor: TColor): TBitmap;
// Use-a assim:
// image2.picture.Bitmap :=
CreateDisabledBitmap(Image1.Picture.Bitmap
, clBtnFace);
const
ROP_DSPDxax = $00E20746;
var
MonoBmp: TBitmap;
IRect: TRect;
begin
IRect := Rect(0, 0, FOriginal.Width,
FOriginal.Height);
Result := TBitmap.Create;
try
Result.Width := FOriginal.Width;
Result.Height := FOriginal.Height;
MonoBmp := TBitmap.Create;
try
with MonoBmp do
begin
Assign(FOriginal);
{$IFDEF S_D3}
HandleType := bmDDB;
{$ENDIF}
Canvas.Brush.Color := clBlack;
if Monochrome then
begin
Canvas.Font.Color := clWhite;
Monochrome := False;
Canvas.Brush.Color := clWhite;
end;
Monochrome := True;
end;
with Result.Canvas do
begin
Brush.Color := OutlineColor;
FillRect(IRect);
Brush.Color := clBtnHighlight;
SetTextColor(Handle, clBlack);
SetBkColor(Handle, clWhite);
BitBlt(Handle, 1, 1, IRect.Right -
IRect.Left, IRect.Bottom - IRect.Top,
MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
Brush.Color := clBtnShadow;
SetTextColor(Handle, clBlack);
SetBkColor(Handle, clWhite);
BitBlt(Handle, 0, 0, IRect.Right -
IRect.Left, IRect.Bottom - IRect.Top,
MonoBmp.Canvas.Handle, 0, 0, ROP_DSPDxax);
End;
finally
MonoBmp.Free;
end;
except
Result.Free;
raise;
end;
end;
545 - Quantos fins de semana já
se passaram no corrente ano
function WeekNum(const TDT:TDateTime) :
Word;
var
Y,M,D:Word;
dtTmp:TDateTime;
begin
DecodeDate(TDT,Y,M,D);
dtTmp := EnCodeDate(Y,1,1);
Result := (Trunc(TDT-dtTmp)+
(DayOfWeek(dtTmp)-1)) DIV 7;
if Result = 0 then
begin
Result := 51
end
else
begin
Result := Result-1;
end;
End;
546 - Testa se a hora é antes de
Meio dia
function IsAM: Boolean;
begin
Result := Frac(Time) < 0.5
end;
547 - Habilita o “Autorun” para
CD-Rom
procedure SetCDAutoRun(AAutoRun:Boolean);
// Requer a Registry declarada na clausula
uses da unit
const
DoAutoRun : array[Boolean] of Integer =
(0,1);
var
Reg:TRegistry;
begin
try
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
if
Reg.KeyExists(‘SystemCurrentControlSetServ
icesClassCDROM’) then
begin
if
Reg.OpenKey(‘SystemCurrentControlSetServic
esClassCDROM’,FALSE) then
begin
Reg.WriteBinaryData(‘AutoRun’,DoAutoRun[AA
utoRun],1);
end;
end;
finally
Reg.Free;
end;
ShowMessage(‘Suas configurações terão
efeito apos reiniciar o computador.’);
end;
548 - Reindexando Indices 2
Quando cai a “Energia” e suas Tabelas perdem os
índices, esta rotina pode ser útil para restauração dos
índices.
Para usar você terá que adicionar os componentes:
Table
Database { se sua aplicação possuir este componente
pode usar o mesmo}
O componente Table a propriedade exclusive tem que
ser true. Senão não funciona.
Procedure Reindexar(DataBase : TDatabase;
Tabela : TTable);
var
List : TStrings;
i : Integer;
begin
try
Database.Connected:=true;
except
Raise;
Exit;
end;
List:=TStringList.create;
session.GetTableNames(DataBase.aliasName,
”, true, false,List);
for i:= 0 to List.Count - 1 do
begin
if (Entidade2) then
break;
application.ProcessMessages;
Tabela.close;
Tabela.TableName:=List[i];
Try
Tabela.open;
Check(dbiRegenIndexes(Tabela.Handle));
except
Raise;
end;
end;
List.Free;
Database.Connected:=false;
end;
Para executar a rotina você pode Incluir quando sua
aplicação esta sendo iniciada
Adicionando a seguinte linha.
No evento oncreate do Datamodulo
Reindexar(Dados,Table1); //Dados Nome imposto por
mim ao componente Database e Table1 o componente
inserido na aplicação.
Esta rotina tem solucinado muitos problema em rede
paradox, pois se esta rotina não funcionar ou funcionar
me mande um email para discutirmos sobre ela
by Rogério Falcão: ro_monteiro@bol.com.br
549 - Como achar um Modem e sua
porta
// unit PegaPorta;

{
COMO FUNCIONA!
Todas as informações sobre o modem
instalado estão contidas no registro do
Windows. Usando TRegistry podemos,
facilmente, ter acesso à essas
informações. Porém, dependendo do modem,
ele pode não especificar em qual porta
está instalado. Então devemos primeiro
descobrir quantas portas serial existem no
sistema, criar um Handle para receber a
Porta e depois fazer tentativas de
abertura em cada uma delas no modo
Leitura/Escrita (GENERIC_READ or
GENERIC_WRITE). Se tentarmos, por exemplo,
abrir a COM1 (que, geralmente, está o
mouse), não conseguiremos abrí-la e
retornará erro (INVALID_HANDLE_VALUE).
Podemos então manipular o retorno. A forma
ideal é criar um loop para que todas as
portas sejam checadas.

O Procedure abaixo, pega as informações


contida nas chaves:
HKEY_LOCAL_MACHINE....\SerialComm e
....\modem\0000
A chave ...modem\0000, refere-se ao
primeiro modem encontrado, caso existir
mais que um, este será ..\modem\0001,
0002… e assim por diante.
Veja bem, poderemos ir diretamente apenas
na chave do modem para saber em que porta
ele está instalado. Esta informação estará
na Subsecção “AttachedTO”, porém, nem
todos os modems registram esta informação.
Portando, o modo mais seguro, e eficaz, é
usar tentativas
de abertura como descrito abaixo.

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,
Dialogs,StdCtrls, Registry;

type
TForm1 = class(TForm)
ComboBox1: TComboBox;
Label1: TLabel;
Button1: TButton;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure PegaModem(porta: string);
procedure ComboBox1Change(Sender:
TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation

{$R *.DFM}

procedure TForm1.PegaModem(porta :
string);
var
FHandle : THandle;
Reg : TRegistry;
Lista : TStrings;
i : integer;
varPorta, varModelo : string;
begin
Reg :=TRegistry.Create;

//Procurar na secção…
Reg.RootKey :=HKEY_LOCAL_MACHINE;

//SubSecção onde estão as Portas de


comunicação disponíveis
if
Reg.OpenKey(‘\Hardware\DeviceMap\SerialCom
m’, false) then begin

//Cria a uma ‘lista’ das portas


encontradas (mouse, modem… etc..)
lista := TStringList.Create;

//Adiciona à ‘lista’ as portas encontradas


Reg.GetValueNames(lista);
for i := 0 to lista.count -1 do begin
if trim(porta) = ” then
begin
varPorta := Reg.ReadString(lista[i]);// Lê
nome da porta
combobox1.Items.Add(varPorta);
end
else
varPorta := porta;

{Cria o Handle para receber a(s) porta(s)


e faz tentativa de abertura em todas
encontradas, no modo leitura ou escrita
(modem) }
FHandle := CreateFile(
PChar(‘\.' + varPorta),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);

// Se for uma porta válida para modem…


if FHandle <> INVALID_HANDLE_VALUE then
begin
CloseHandle(FHandle); // Fecha o Handle e
a porta

//Pega o nome/modelo do modem instalado na


porta existente
if
Reg.OpenKey(‘\System\CurrentControlSet'+
‘Services\Class\Modem\0000', false)then
begin
varModelo := Reg.ReadString(‘Model’);
Label2.Caption := varModelo+’ - Instalado
na porta ‘+varPorta;
Combobox1.Text := varPorta;
end;
end
else
Label2.Caption := ‘Não há modem instalado
na porta ‘+varPorta;
end;
//Fecha e libera variáveis
Reg.CloseKey;
Lista.Free;
Reg.Free;
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
Close;
end;

procedure TForm1.FormCreate(Sender:
TObject);
var
porta : string;
begin
Combobox1.Clear;
PegaModem(porta);
end;

procedure TForm1.ComboBox1Change(Sender:
TObject);
var
porta : string;
begin
//Verificar se existe mais de um modem…
porta := combobox1.text;
PegaModem(porta);
end;

end.
550 - Nome da Impressora Padrão
function GetDefaultPrinterName : string;
//
// Retorna o nome da impressora padrão do
Windows
//
begin
if(Printer.PrinterIndex >= 0)then
begin
Result :=
Printer.Printers[Printer.PrinterIndex];
end
else
begin
Result := ‘Nenhuma impressora Padrão foi
detectada’;
end;
end;
551 - Verificar se Impressora esta
Conectada
A dica abaixo apresenta o código para implementação
de uma função para verificar se a impressora esta
conectada.
Para implementar esta função é necessário que o
código gerado manipule algumas interrupções da Bios
(Sistema Básico de Entrada e Saída) responsáveis pelo
controle da porta paralela (Interrupção $17).
A interrupção $17 utiliza dois registros ah e dx, o
registrador ah indica neste caso o acesso a porta
paralela e o registrador dx indica qual das portas será
testada, 0 para LPT1 e 1 para LPT2.
Para saber se a porta esta ligada (impressora
conectada) o resultado da operação de tratamento de
interrupção deve ser $80.
Código Completo:
Function OnLine(Porta:Word):Boolean;
Const
Portas :Byte = $02;
Var
Res :Byte;
Begin
{ Código em Assembler }
Asm
mov ah,Portas; {Requisita o acesso as
portas}
mov dx,Porta;{Define a porta de teste}
Int $17; {Chama a interrupção de
Impressora}
mov Res,ah; {Guarda em Res o resultado da
operação }
end;
Result := (Res and $80) = $80; {Testa o
valor de saída}
End;
552 - Exibindo as propriedades do
arquivo
A dica abaixo apresenta o código de implementação
para exibir na tela uma janela padrão Windows de
propriedades do arquivo.
Para implementar este procedimento é necessário
acrescentar a unit ShellAPI.As propriedades do arquivo
são armazenadas numa estrutura chamada
TShellExecuteInfo, que corresponde a um registro com
os campos: tamanho do arquivo (cbSize), atributos
(fMask), nome (lpFile) , shell (lpVerb) e modo de
apresentação da janela (nShow).O primeiro passo do
procedimento é zerar todas a propriedades da Shell (
FillChar(S,SizeOf(S),0) ), segundo passo é atualizar
estas propriedades (With S do ) em relação ao arquivo
indicado (Arq :String) e o terceiro passo é abrir a janela
de propriedades com os valores atualizados
(ShellExecuteEx(@S)).
Código Completo:
Procedure Propriedades(Arq:String);
Var
s:TShellExecuteInfo;
Begin
FillChar(S,SizeOf(S),0);
With S do Begin
cbSize := SizeOf(S);
fMask := SEE_MASK_FLAG_NO_UI or
SEE_MASK_INVOKEIDLIST or
SEE_MASK_NOCLOSEPROCESS;
wnd := Handle;
lpVerb := ‘properties’;
lpFile := Pchar(Arq);
nShow := sw_ShowNormal;
End;
ShellExecuteEx(@S);
End;
553 - Dicas Práticas
Incluir componentes.
Ao teclar “Alt”+“V” e posteriormente “C” será
apresentada a janela com a lista de componentes
disponíveis.
Se você digitar seta para baixo o virtual irá lendo os
componentes da lista. Se você já souber o componente
que deseja vá diretamente a ele digitando seu nome, por
exemplo: TButton, TEdit , TLabel, TPanel, TComboBox,
etc.
Ao Teclar ENTER o componente é inserido no centro do
Form.
Depois de teclar o ENTER o diálogo “Component List”
ainda não foi fechado e você pode inserir tantos
componentes quantos você selecionar.
Se permanecer no mesmo componente e for dando
“enter” este será adicionado no centro do form
consecutivamente, ou seja, se você estiver no tedit
serão colocados tedit1, tedit2, tedit3 etc, ou seja, tantos
tedit quantos “enter” forem dados.
Tomar cuidado com os componentes que podem
receber outros componentes em seu interior, tais como
TPanel e TGroupBox.
Para fechar o diálogo “Component List”, ou seja, sair da
lista de componentes, tecle ESC.
Propriedades de um Componente.
Para você chegar às propriedades de um componente a
partir do form no qual este esteja inserido, selecione o
componente desejado com o “tab” e, ao encontrá-lo,
tecle f11 que você chegará ao “Object Inspector”, ou
seja, na lista de propriedades de seu componente. Se
você não conhece as propriedades contidas na lista vá
com a seta para baixo ou para cima que serão lidas
todas as propriedades.
Caso você já conheça as propriedades de seu
componente e queira ir a uma específica tecle “tab” até
escutar “select on”. Estará aberto assim um campo para
você colocar o nome da propriedade que você queira ir
diretamente. Digamos que seja “caption”. Dependendo
de quantas propriedades existam começando com a
letra “c”, bastará você teclar “c” no “select on” para
chegar na “caption” e caso chegue em algo que não seja
a propriedade desejada, setas para baixo a encontrarão
rápidamente, já que você estará posicionado nas
propriedades começadas pela letra “c”.
Se você quiser trocar a característica da propriedade
escolhida vá teclando tab até escutar sua característica
atual. Vamos supor que esta seja “xxxxxx” e você queira
que seja “zzzzzz”. Depois de escutar “xxxxxx” tecle a
que você deseja e dê “enter”. A propriedade será
alterada. Para conferir tecle “tab” e escutará o “select
on” e, com outro “tab” a propriedade atual. Existem
propriedades que possuem caixas combinadas com
várias possibilidades de opções específicas: nesse caso
tecle “alt” e seta para baixo e você abrirá a caixa; depois
é só teclar seta para baixo para ir escutando as opções.
Ao encontrar a desejada tecle “enter” que esta estará
marcada para você.
Para voltar ao seu form tecle f12 até encontrar o título
de seu form. Ao encontrá-lo utilize o “tab” para encontrar
o próximo componente a ser trabalhado.
Obs: É bom que o amigo(a) sempre, antes de sair da
lista de propriedades (object inspector) para voltar ao
form, deixe a lista posicionada na propriedade “name”
para que no form você possa localizar com facilidade o
próximo componente a ser trabalhado.
Criar eventos para os componentes.
Em primeiro lugar, selecionar o componente que você
deseja através da tecla Tab no form. Ir para Object
Inspector (f11). Teclar “Control”+“TAB” para selecionar a
Orelha dos Eventos. O evento padrão do componente já
é selecionado automaticamente e será dito pelo VV . Se
você quiser outro evento que não seja o padrão tecle
“Tab” e digite o nome do evento que você deseja. Tecle
Tab novamente e estará no evento digitado, caso exista.
outra forma é simplesmente ir andando com a setinha
verticalmente (abaixo ou acima) e ir ouvindo os nomes
dos eventos da lista.
Para efetivamente codificar o evento tecle
Control+ENTER no evento selecionado e o Delphi já cria
um esqueleto de procedure para você entrar com o
código. A janela de edição é ativada e você já pode
digitar o código que deseja. Após inserir-lo lembre-se
sempre de teclar F11, Control+Tab e voltando assim
para a lista de propriedades (object Inspector) posicionar
novamente na propriedade “name” para que, voltando
para o form com f12 ter acesso fácil aos componentes
dando “tab”.
554 - Criação de DLLs
Esta é uma outra dúvida bastante freqüente que chega a nós. “Como posso
usar uma DLL ?”, “Como posso criar uma DLL ?”, “Ei, moço! Pra quê serve
uma DLL ?”
Pois bem, DLL ou Dynamic Link Libraries, permitem que um conjunto de
funções desenvolvidas em uma linguagem possam ser utilizadas em
programas desenvolvidos em outras linguagens.
Você pode, por exemplo, criar uma DLL em Delphi com um conjunto de
funções e utilizá-la em aplicativos desenvolvidos em C++ ou Visual Basic,
por exemplo. Agora, vamos começar criando uma DLL:

1. Selecione o item New do Menu File, para exibir a caixa de diálogo


New Items. Agora, selecione o item DLL e clique em OK, para gerar o
código principal da DLL, que se apresenta a seguir:

library Project1;

{ Important note about DLL memory


management: ShareMem must be the first
unit in your library’s USES clause AND
your project’s (select Project-View
Source) USES clause if your DLL exports
any procedures or functions that pass
strings as parameters or function results.
This applies to all strings passed to and
from your DLL—even those that are nested
in records and classes. ShareMem is the
interface unit to the BORLNDMM.DLL shared
memory manager, which must be deployed
along with your DLL. To avoid using
BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils, Classes;
begin
end.
Em muitas situações, inclusive esta, o arquivo DELPHIMM.DLL deve ser
distribuído junto à sua aplicação. Uma outra observação muito importante,
para que você possa escrever suas DLLs, você deve ter conhecimentos na
Linguagem Object Pascal.
Vamos continuar criando nossa DLL, pois é ela que iremos usar mais para
frente. Apenas como exemplificação, vamos criar uma função que receba
como parâmetros dois números reais e retorne o maior deles.

Function Max (a b : double ) : double ;


Export ; stdcall ;
begin
If (a > b) then Result :=a else Result :=
b ;
end ;

Export = indica que a função poderá ser chamada por outros aplicativos.
Stdcall = permite que aplicativos desenvolvidos em outras linguagens
façam chamadas à função.
Após serem feitas estas alterações e salvar o projeto com o nome
MAXDLL, nossa DLL ficará assim:

library Project1;

{ Important note about DLL memory


management: ShareMem must be the first
unit in your library’s USES clause AND
your project’s (select Project-View
Source) USES clause if your DLL exports
any procedures or functions that pass
strings as parameters or function results.
This applies to all strings passed to and
from your DLL—even those that are nested
in records and classes. ShareMem is the
interface unit to the BORLNDMM.DLL shared
memory manager, which must be deployed
along with your DLL. To avoid using
BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes;
function Max(a, b :
double):double:expert:stdcall:
begin
if (a > b) then result:= a else result :=
b;
end;

exports
Max index 1;
begin
end.

Você pode compilar uma DLL, assim como a um projeto no Delphi, e


distribuir livremente.
PS: Você não pode executar uma DLL pelo Delphi, através do RUN do
Menu Run, pois não se trata de uma aplicação.
Mais à frente, você perceberá que uma DLL pode usar formulários e
objetos definidos em outras unidades. Iremos, agora, chamar uma DLL, a
partir de outra aplicação.
Neste exemplo que iremos montar, iremos usar: um formulário, duas caixas
de texto (os quais o usuário irá digitar dois números reais), um botão de
comando.

unit usadll;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function Max(a, b :
double):double;stdcall;

var
Form1: TForm1;

implementation

{$R *.DFM}

function Max(a, b :
double):double;external ‘MaxDLL’;
procedure TForm1.Button1Click(Sender:
TObject);
var
x, y, resultado : double;
begin
x := StrToFloat(Edit1.Text);
y := StrToFloat(Edit2.Text);
resultado := Max(x,y);
ShowMessage(‘Valor Máximo ‘
+FloatToStr(resultado));
end;

end.
PS: A função Max está declarada na seção interface e implementada na
seção implementation, ou seja, a função está implementada em uma DLL.
Bem, mostramos como criar uma DLL simples e como fazer chamada de
uma DLL. Agora, iremos melhorar nossa DLL, fazendo com que ela exiba
um formulário qualquer em qualquer aplicação desenvolvida para Windows.
Equipe GDI: Alexandre Andrade e Wagner Santos Todos os direitos
reservados 2000
Copyright © 2000 GDI - All rights reserved
555 - Criando um componente Skin
Aqui iremos tratar da criação de um componente SKIN
como os do WINAMP. Para montar os SKINS devemos
utilizar um Bitmap e deixar as bordas do formulários
transparentes (ocultas).
A solução é bem simples, utilizando o componente
Timage, dê uma olhado no fonte:
unit SkinImage;
interface

uses
Windows, Messages, SysUtils, Classes,
Graphics,
Controls, Forms, Dialogs,
ExtCtrls;

type
TSkinImage = class(TImage)
private

protected
{ Protected declarations }
function BitmapToRegion(bmp: TBitmap) :
dword;
procedure OwnerShow(Sender : TObject);
public
constructor Create(AOwner : TComponent);
override;
published
{ Published declarations }
end;

procedure Register;

var
Ready : Boolean;

implementation

procedure Register;
begin
RegisterComponents(‘CLINICA DELPHI’,
[TSkinImage]);
end;

{ TSkinImage }

constructor TSkinImage.Create(AOwner:
TComponent);
begin
inherited Create(AOwner);
if NOT (csDesigning in ComponentState)
then
with TForm(AOwner) do
begin
BorderStyle := bsNone;
Self.Top := 0;
Self.Left := 0;
OnShow := OwnerShow;
end;
end;

function TSkinImage.BitmapToRegion(bmp:
TBitmap) : dword;
var ix,iy : integer; // loop nas variáveis
tc : TColor; // transparentColor
b1 : boolean; // está olhando o “real”
pixels (no transparent pixels)
c1 : cardinal; // ajusta a variável na
região
i1 : integer; // primeira posição real
em pixel
begin
Result := 0;
i1 := 0;
// memória do transparent color
tc := bmp.transparentColor and $FFFFFF;
with bmp.canvas do
// enquadrilhe por todas as linhas
for iy := 0 to bmp.height - 1 do
begin
b1 := False;
// esquadrinhe por todo o pixels nesta
linha
for ix:=0 to bmp.Width - 1 do
// feito nós acharmos o começo/final
seguidos em pixel
if (pixels[ix, iy] and $FFFFFF <> tc) <>
b1 then begin
// sim, e foi o último pixel,
// so nós podemos somar uma região de
estilo de linha…
if b1 then begin
c1:=CreateRectRgn(i1,iy,ix,iy+1);
if result<>0 then
begin
// Esta não é a primeira região
CombineRgn(Result, Result, c1, RGN_OR);
DeleteObject(c1);
// Esta é a primeira região
end
else
Result := c1;
end else i1 := ix;
// mude o modo e procura o primeiro ou
último pixel?
b1:=not b1;
end;
// o último pixel nesta fila era um
pixel real?
if b1 then begin
c1:=CreateRectRgn(i1, iy, bmp.width-1,
iy+1);
if (Result <> 0) then
begin
CombineRgn(Result, Result, c1, RGN_OR);
DeleteObject(c1);
end
else
Result := c1;
end;
end;
end;

procedure TSkinImage.OwnerShow(Sender:
TObject);
var
Region : HRGN;
begin
if NOT Ready then
begin
Ready := True;
Region :=
BitmapToRegion(Picture.Bitmap);
SetWindowRgn(TForm(Owner).Handle,
Region, True);
DeleteObject(Region);
end;
end;

initialization
Ready := False;
end.

” Digamos a primeira linha de nosso bitmap se parece:


000XXXXX00XXXXX000000XXXX000
0 -> Pixel Trasparente; X -> Pixel Colorido
Agora minha função passa por esta linha e cria uma
região de janela para cada fila de pixels. No exemplo,
nós adquiriríamos 3 regiões (4-8, 11-15, 22-25).
Nós fizemos o mesmo para todas as outras linhas no
Bitmap, e todas essas regiões.
556 - Armazanando sons, vídeos em
bancos de dados
Um dos recursos mais interessantes nos bancos de
dados atuais é a possibilidade de armazenar recursos
multimídia juntamente com outras informações. Dessa
forma, é possível criar registros com informações mais
ricas sobre um determinado assunto. Por exemplo,
pode-se armazenar informações sobre um funcionário
juntamente com a sua própria foto. No Paradox, por
exemplo, existe um tipo de campo destinado
especialmente para esse fim.
No entanto, as possibilidades vão muito além do que o
simples armazenamento de imagens. É possível
armazenar sons, filmes ou qualquer tipo de arquivo,
usando o “obscuro” campo BLOB (Binary Large Object),
que permite que qualquer arquivo seja “embutido” no
banco de dados. Na verdade, o conteúdo do arquivo não
é armazenado no registro em si, mas num arquivo
separado que é manipulado internamente pelo banco de
dados.
Trabalhar com esse tipo de campo no Delphi é muito
simples, mas não tão óbvio à primeira vista. A
manipulação de campos BLOB, diferentemente dos
campos comuns, não deve ser feita diretamente, mas
sim por meio do objeto TBlobField, descendente do
TField, que disponibiliza recursos especiais para esse
fim. Para isso, você deve sempre se referir ao campo
BLOB no código como sendo um TBlobField, utilizando
typecasting.
Vamos supor que você tenha um arquivo de som
MyWave.wav que será armazenado no campo “SOM” da
tabela “MyTable”. Para carregar o conteúdo do arquivo
no campo SOM, basta fazer assim:
TBlobField(MyTable.FieldByName(‘SOM’)).Loa
dFromFile(‘MeuWave.wav’);
Neste exemplo, você usou o recurso de typecasting para
manipular o campo como sendo um objeto TBlobField,
carregando o arquivo através do método LoadFromFile
que existe nesse objeto. Fácil, não é?
Se você quiser salvar o conteúdo do campo “SOM” no
arquivo “MyWaveCopy.wav”, basta fazer assim:
TBlobField(MyTable.FieldByName(‘SOM’)).Sav
eToFile(‘MyWaveCopy.60wav’);
Para remover o conteúdo do campo “SOM” (limpá-lo),
você também deve usar um método apropriado:
TBlobField(MyTable.FieldByName(‘SOM’)).Cle
ar;
Para saber se o campo SOM possui algum conteúdo,
use a propriedade IsNull:
with MyTable do
if not
TBlobField(FieldByName(‘SOM’)).IsNull then

TBlobField(FieldByName(‘SOM’)).SaveToFile(
‘MyWaveCopy.wav’);
A maneira mais simples de utilizar o conteúdo de um
campo BLOB já armazenado é primeiro gravá-lo
novamente em um arquivo em disco, usando o método
SaveToFile, e depois manipulá-lo normalmente. No caso
de um conteúdo em formato wave, por exemplo, você
deve primeiro gravá-lo num arquivo .wav, e então
reproduzí-lo através do TMediaPlayer ou pela função
SndPlaySound.
Usando os mesmos métodos, você também pode
armazenar e manipular filmes AVI, apresentações,
documentos, enfim, o que a sua imaginação mandar.
Mas tenha em mente que o armazenamento de arquivos
de som ou outros tipos vai aumentar consideravelmente
o tamanho do seu banco de dados, por isso esse
recurso deve ser utilizado com cuidado. Uma boa
medida para reduzir esse problema é compactar o
arquivo antes de armazená-lo. Para utilizá-lo depois,
basta gerar o arquivo novamente em disco e
descompactá-lo. Para saber quanto um campo BLOB
está ocupando num registro do seu arquivo, em bytes,
use a propriedade BlobSize:
TBlobField(MyTable.FieldByName(‘SOM’)).Blo
bSize;
Obs: Para armazenar imagens ou texto em formato
RichText (RTF), use os tipos GRAPHIC e FORMATED
MEMO do Paradox, que são destinados a esses tipos de
dados. O Delphi também possui objetos para a
manipulação desses campos: TGraphicField e
TMemoField, ambos descendentes do TBlobField.
557 - Usuario logado
function LogUser : String;
{Requer a unit Registry declarada na
clausula Uses da Unit}
var
Registro:TRegistry;
begin
Registro := TRegistry.Create;
Registro.RootKey := HKEY_LOCAL_MACHINE;
if Registro.OpenKey(‘Network\Logon’,
false) then
begin
result := Registro.ReadString(‘username’);
end;
Registro.Free;
end;
559 - Executando sons no PC-
Speaker
PlaySong(‘CCEC’); Onde: C = DO D = RE E = MI F = FA
G = SOL A = LA B = SI
unit MUSIC;

Interface

Uses Windows, Classes, Forms;

Procedure PlaySong (TuneString:string);


Const BaseOctave: Integer = 0;

Implementation

Const SharpOffset = 60; { Frequencias das


notas }
Const PitchArray: Array[1..120] of Word =
( 28, 31, 33, 37, 41, 44, 49, 55,
62, 65, 73, 82, 87, 98, 110, 123, 131,
147,
165, 175, 196, 220, 247, 262, 294, 330,
349, 392, 440, 494, 523, 587, 659,
698, 784, 880, 988, 1047, 1175, 1319,
1397,
1568, 1760, 1976, 2093, 2349, 2637, 2794,
3136, 3520, 3951, 4186, 4699,
5274, 5588, 6272, 32139, 9738, 1934,
39659, 29, 33, 35, 39, 44, 46, 52, 58, 65,
69, 78, 87, 92, 104, 117, 131,
139, 156, 175, 185, 208, 233, 262, 277,
311,
349, 370, 415, 466, 523, 554, 622, 698,
740, 831, 932, 1047, 1109, 1245,
1397, 1480, 1661, 1865, 2093, 2217, 2489,
2794, 2960, 3322, 3729, 4186, 4435, 4978,
5588, 5920, 6645, 35669, 33772,
1772, 18119);

Const Octave: Integer = 3; {Teceira Oitava


- Inicia com meio C}
GenNoteType: Integer = 4; {Quartas da
nota}
Tempo: Integer = 120; {120 batidas por
minuto}
PlayFrac: Byte = 7; {Normal - nota dura
7/8 do tempo}

Var vq: LongInt; TmpPitch: LongInt;

{ Grava um valor na porta de som }


procedure SetPort(address, value: Word);
var bValue: Byte;
begin
bValue := trunc(value and 255);
asm
MOV DX, address
MOV AL, bValue
OUT DX, AL
end;
end;

{ Pega o valor na porta de som }


function GetPort(address: Word): Word;
var bValue: Byte;
begin
asm
MOV DX, address
in AL, DX
MOV bValue, AL
end;
result := bValue;
end;
{ Encerra o som }
procedure NoSound;
var wValue: Word;
begin
wValue := GetPort($61);
wValue := wValue and $FC;
SetPort($61, wValue);
end;

{Gera um som com a frequencia informada }


procedure Sound(Freq: Word);
var B: Word;
begin
if Freq > 18 then
begin
Freq := Word(1193181 div LongInt(Freq));
B := GetPort($61);
if (B and 3) = 0 then
begin
SetPort($61, B or 3);
SetPort($43, $B6);
end;
SetPort($42, Freq);
SetPort($42, (Freq SHR 8));
end;
end;

{Da uma pausa por x msegundos }


procedure Delay(MSecs: Integer);
var FirstTickCount : LongInt;
begin
FirstTickCount:=GetTickCount;
repeat
Application.ProcessMessages;
until ((GetTickCount-FirstTickCount) >=
LongInt(MSecs));
end;
{Executa uma string no padrão musical PLAY
do basic }
Procedure PlaySong (TuneString:string);
Var PlayTime: LongInt; IdleTime: LongInt;
DotTime: LongInt; NoteTime :
LongInt; NoteType: Integer; PitchIndex:
Integer;
Position: Integer; Number : Integer; Code:
Integer; TuneStrLen: Integer;
Character: Char; PlayDone: Boolean;
Procedure NVal(Pos:integer; var v, code:
integer);
Var Posn:integer;
Begin
v := 0;
posn := Pos;
while (posn <= TuneStrLen) and
(TuneString[posn] in [‘0’..‘9’]) do
Begin
v := v*10 + ord(TuneString[posn]) - ord
(‘0’);
Inc(posn);
End;

code := posn - Pos + 1;


End;

Procedure CheckDots; {Existe ponto apos a


nota?}
Begin
While (Position <= TuneStrLen) and
(TuneString[Position] = ‘.’) do
Begin
DotTime := DotTime + DotTime div 2;
inc(Position)
End;
End;
Begin
PlayDone := False;
TuneStrLen := length(TuneString);
Position := 1;
Repeat NoteType := GenNoteType;
DotTime := 1000;
Character := upcase(TuneString[Position]);
Case Character Of
‘A’..‘G’ :
Begin PitchIndex :=
(ord(Character)-64)+Octave*7;
If (Character=‘A’) or (Character=‘B’) Then
PitchIndex := PitchIndex + 7;
inc(Position); {Bemol ou sustenido?}
if Position <= TuneStrLen then
case TuneString[Position] of
‘#’,’+’:
begin
PitchIndex := PitchIndex+SharpOffset;
inc(Position);
end;
‘-‘:
begin
PitchIndex :=PitchIndex+SharpOffset - 1;
inc(Position);
end;
End;
if (Position <= TuneStrLen) and
(TuneString[Position] in
[‘0’..‘9’]) then
begin
NVal(Position,NoteType,Code);
inc(Position, Code - 1)
end;
CheckDots; {Toca a nota}
NoteTime :=
Round(DotTime/Tempo/NoteType*240);
PlayTime := Round(NoteTime*PlayFrac/8);
IdleTime := NoteTime-PlayTime;
Sound(PitchArray[PitchIndex]);
Delay(PlayTime);
if IdleTime <> 0 then
begin
NoSound;
Delay(IdleTime)
end;
End;
‘L’ :{Duracao 1 - 64 }
Begin
NVal (Position+1,GenNoteType,Code);
if (GenNoteType < 1) or (GenNoteType > 64)
then
GenNoteType := 4;
inc(Position, Code);
End;
‘M’ : {“S” staccato,“L” legato,“N”
normal.}
Begin
if Position < TuneStrLen then
begin
Case upcase(TuneString[Position+1]) Of
‘S’ : PlayFrac := 6;
‘N’ : PlayFrac := 7;
‘L’ : PlayFrac := 8;
End;
inc(Position,2);
end;
End;
‘O’ :
Begin
NVal (Position+1,Octave,Code);
Octave := Octave+BaseOctave;
if Octave > 7 then
Octave := 3;
inc(Position, Code);
End;
‘P’ :
Begin
NoSound;
NVal (Position+1,NoteType,Code);
if (NoteType < 1) or (NoteType > 64)then
NoteType := GenNoteType;
inc(Position, Code);
CheckDots;
IdleTime := DotTime Div Tempo * (240 Div
NoteType);
Delay (IdleTime);
End;
‘T’ : {Tempo - number de batidas por
minuto (32 - 255)}
Begin
NVal (Position+1,Tempo,Code);
if(Tempo < 32) or (Tempo > 255) then
Tempo := 120;
inc(Position, Code);
End;
Else
inc(Position); {Ignora caracteresespurios}
End;
Until ((Position > TuneStrLen) Or
(PlayDone));
NoSound;
End;
End.
Obs: Para tocar alguma coisa, experimente os seguintes
frequências:
PlaySong(‘O2L16T155P8MSO1BBB8BBB8BBO2E8F#8
G#8O1BBB8BBO2E8G#G#F#8D#8O1B8BBB8BBB8BBO2E
8F#8G#8EG#’);
PlaySong(‘MLB4BMSAG#F#E8G#8E8O3BBB8BBB8BBO
4E8F#8G#8O3BBB8BBO4E8G#G#F#8D#8O3B8BBB8BBB
8BB’);
PlaySong(‘O4E8F#8G#8MLEG#B4BAG#F#MSE8G#8E8
P2’);
//Familia Adams; ==============
PlaySong(‘O3T220L8CDEFP4O0L4FP8FP8O3L8DEF#
GP4O1L4GP8GP8O3L8DEF#GP4DEF#GP4CDEFP4O1L4F
P8FP8’);
PlaySong(‘P4T187O3L8CF.AF.DO2B-.O3GP4FE.GE
.CO2A.O3FP4CF.AF.DO2B-.O3GP4FL64EFL8E.CD.E
FP4’);
PlaySong(‘O3T220L8CDEFP4O0L4FP8FP8O3L8DEF#
GP4O1L4GP8GP8O3L8DEF#GP4DEF#GP4CDEFP4O1L4F
P8FP8’);
PlaySong(‘P4T187O3L8CF.AF.DO2B-.O3GP4FE.GE
.CO2A.O3FP4CF.AF.DO2B-.O3GP4FL64EFL8E.CD.E
FP2’);
//Beverly Hills Cop =================
PlaySong(‘t125msl4o3fg#l8fl16fl8a#l8fd#l4f
l4o4cl8o3fl16fl8o4c#co3g#fo4cl8fo3l16fl8d#
l16d#l8cl8gl4fp2’);
PlaySong(‘t125msl4o3fg#l8fl16fl8a#l8fd#l4f
l4o4cl8o3fl16fl8o4c#co3g#fo4cl8fo3l16fl8d#
l16d#l8cl8gl4fp2’);
PlaySong(‘o1l4ffl8d#l16d#l8d#l8cd#l4ffp8l1
6fl8fcfl4c#c#l8d#l16d#l8d#d#d#fp2l8fco0l8a
#g#l4f’);
PlaySong(‘o1l4fl8d#l16d#l8d#l8cd#l4ffp8l16
fl8fcfl4c#c#l8d#l16d#l8d#d#d#fp2’);
//james bond theme ================
PlaySong(‘mll8t125O1b4ebo2c4o1eo2cc#4o1eo2
c#c4o1eo2cO1b4ebo2c4o1eo2cc#4o1eo2c#c4o1eo
2c’);
PlaySong(‘t150mno3ef#16f#16f#f#3o2eeemno3e
g16g16gg3o2f#F#F#mno3ef#16f#16f#f#3o2eee’)
;
PlaySong(‘mno3eg16g16gg3o2f#F#F#mno3ef#16f
#16f#f#3o2eeemno3eg16g16gg3o2f#F#e’);
PlaySong(‘mlo4d#o3b64o4dd2o2g64bf#64amlg24
b1P2’);
//Leave it to beaver ==================
PlaySong(‘MST190O2L8CL4FL8A>CDL8CCFL4DL8CD
L8CCFDGCCD’);
PlaySong(‘L8CCFL4DL8CDL8CCFDFP2’);
//London Bridge =============
PlaySong(‘MST190O2L8CL4FL8A>CDL8CCFL4DL8CD
L8CCFDGCCD’);
PlaySong(‘L8CCFL4DL8CDL8CCFDFP2’);
//My Darling Clementine
=====================
PlaySong(‘T120MNO2L8G.L16GL4GDL8B.L16BL4BG
L8GBO3L4DDL8CO2BL2AL8ABO3L4CCO2L8B.L16AL4B
GL8GB’);
PlaySong(‘L4ADL8F#.L16AL2GL8G.L16GL4GDL8B.
L16BL4BGL8GBO3L4D.L8DCO2BL2AL8ABO3L4CC’);
PlaySong(‘O2L8B.L16AL4BGL8GBL4ADL8F#.L16AL
2GL8G.L16GL4GDL8B.L16BL4BGL8GBO3L4DDL8C’);
PlaySong(‘O2BL2AL8ABO3L4CCP2’);
// The Entertainers ================
PlaySong(‘T120MNO3L8DD#EO4L4CO3L8EO4L4CO3L
8EO4L4C.P4P8L8CDD#ECDL4EL8O3BL4O4DCP4P4O3L
8DD#EL4’);
PlaySong(‘O4CO3L8EO4L4CO3L8EL4O4C.P4P4O3L8
AGF#AO4CL4EL8DCO3AO4L4DP4P4O3L8DD#EL4O4C’)
;
PlaySong(‘O3L8EO4L4CO3L8EO4L4C.P4P4L8CDD#E
CDL4EL8O3BO4L4DCP4P4L8CDECDL4EL8CDCECDL4E’
);
560 - Troca de tamanho do papel
Como diria Pearl Jam: “…It’s a Revolution Baby…”
Bem, agora vou mostrar como criar uma rotina para
troca automatica de papel, muito útil em casos de
empresas que possuem diversos tipos de “papélis”.
Você pode copiar o nosso exemplo completo agora:
TamPa.zip
Acompanhe a baixo o código principal com detalhes do
mesmo:
procedure MudaTamPapel(PaperSize, Comp,
Alt: integer);
var
ADevice, ADriver, APort: array[0..255] of
char;
DeviceMode: THandle;
M: PDevMode;
s: string;
begin
// Força o uso de Printer. Se esta linha
for removida, a primeira
// invocação falha. Bug da VCL
S :=
Printer.Printers[Printer.PrinterIndex];
// Pega dados da impressora atual
Printer.GetPrinter(ADevice, ADriver,
APort, DeviceMode);
// Pega um ponteiro para DEVMODE
M := GlobalLock(DeviceMode);
try
if M <> nil then
begin
// Muda tamanho do papel
M^.dmFields := DM_PAPERSIZE;
if PaperSize = DMPAPER_USER then
M^.dmFields := M^.dmFields or
DM_PAPERLENGTH or DM_PAPERWIDTH;
M^.dmPaperLength := Alt;
M^.dmPaperWidth := Comp;
M^.dmPaperSize := PaperSize;//
// Atualiza
Printer.SetPrinter(ADevice, ADriver,
APort, DeviceMode);
end;
finally
GlobalUnlock(DeviceMode);
end;
end;

function ImpressoraCorrente: string;


begin
Result :=
Printer.Printers[Printer.PrinterIndex];
end;

procedure TForm1.AtualizaPrn;
begin
StaticText1.Caption := ImpressoraCorrente;
end;

procedure TForm1.MostraTamPapel;
var
ADevice, ADriver, APort: array[0..255] of
char;
DeviceMode: THandle;
M: PDevMode;
s: string;
begin
// Força o uso de Printer. Se esta linha
for removida, a primeira
// invocação falha. Bug da VCL
S :=
Printer.Printers[Printer.PrinterIndex];
// Pega dados da impressora atual
Printer.GetPrinter(ADevice, ADriver,
APort, DeviceMode);
// Pega um ponteiro para DEVMODE
M := GlobalLock(DeviceMode);
if M <> nil then
MostraDevMode(M^);
end;

function
TForm1.PegaTamanhoPapel(dmPaperSize:
word): string;
begin
Result := ‘Desconhecido’;
// Verifica ALGUNS TAMANHOS POSSÍVEIS.
Existem outros, veja DEVMODE
case dmPaperSize of
DMPAPER_USER: Result := ‘Definido pelo
usuário’;
DMPAPER_LETTER: Result := ‘Letter, 8 1/2-
by 11-inches’;
DMPAPER_LEGAL: Result := ‘Legal, 8 1/2- by
14-inches’;
DMPAPER_A4: Result := ‘A4 Sheet, 210- by
297-millimeters’;
end;
end;

procedure TForm1.MostraDevMode(const M:
TDevMode);
begin
// Mostra o valor de alguns campos
with M do
begin
// Mostra nome da impressora
Memo1.Lines.Add(‘Nome:’ + dmDeviceName);
// Verifica se campo tamanho do papel esta
preenchido e mostra
if dmFields and DM_PAPERSIZE <> 0 then
Memo1.Lines.Add(PegaTamanhoPapel(dmPaperSi
ze));
if dmFields and DM_PAPERLENGTH <> 0 then
Memo1.Lines.Add(Format(‘Altura:%d’,
[dmPaperLength]));
if dmFields and DM_PAPERWIDTH <> 0 then
Memo1.Lines.Add(Format(‘Comprimento:%d’,
[dmPaperWidth]));
end;
end;

procedure TForm1.Button2Click(Sender:
TObject);
var
P: TPrinterSetupDialog;
begin
P := TPrinterSetupDialog.Create(self);
try
P.Execute;
finally
P.Free;
end;
AtualizaPrn;
end;

procedure TForm1.Button4Click(Sender:
TObject);
begin
MudaTamPapel(DMPAPER_LETTER, 0, 0);
MostraTamPapel;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
MudaTamPapel(DMPAPER_USER,
StrToInt(EdComp.Text),
StrToInt(EdAlt.Text));
end;

procedure TForm1.Button3Click(Sender:
TObject);
begin
Printer.Title := ‘Teste de filha’;
Printer.BeginDoc;
Printer.EndDoc;
end;

procedure TForm1.Button5Click(Sender:
TObject);
begin
MostraTamPapel;
end;

procedure TForm1.FormShow(Sender:
TObject);
begin
AtualizaPrn;
end;
Equipe GDI: Alexandre Andrade e Wagner Santos Todos os direitos
reservados 2000
Copyright © 2000 GDI - All rights reserved
561 - Testa se determinada tecla
está pressionada
function GetToggleState(Key: integer):
boolean;
begin
Result := Odd(GetKeyState(Key));
end;
end;
562 - Como evitar efeito de
maximização
Se você já desenvolveu uma aplicação MDI com um
formulário MDIChild que tem que ser exibido em estado
Maximizado (WindowState=wsMaximized),
provavelmente você já se deparou com aquele
deselegante problema em que o usuário acompanha a
maximização do seu formulário. Para evitar isto, faça o
seguinte:
Antes de criar o seu formulário para a exibição, utilize
LockWindowUpdate(Handle);
Após a criação do formulário, utilize
LockWindowUpdate(0);
Com isto, você dará um efeito mais profissional às suas
aplicações.
Exemplo:
procedure MainForm.ItemArqCadFor(Sender:
TObject);
begin
LockWindowUpdate(Handle);
with TFrmCadFor.Create(self) do Show;
LockWindowUpdate(0);
end;
563 - Como usar as teclas de
função F1, F2, etc?
- Para você colocar chamadas usando as teclas de
função basta colocar o seguinte código no evento
‘OnKeyDown’ do formulário:
procedure
Tform1.FormKeyDown(Sender:TObject; var
Key: Word; Shift: TShifState);
begin
if key = vk_F1 then begin
{ instrucoes a serem executadas }
end;
end;
- OBSERVAÇÃO:
Não se esqueça de colocar a propriedade ‘KeyPreview’
do formulário em ‘True’.
Você também pode usar as variáveis VK_F1 até
VK_F12 referentes as outras teclas de função.
564 - Rotina genérica para
tratamento de erros na aplicação -
BDE
Procedure TrataErro(vErro :
EDBEngineError);
Var
x : Integer;
Begin
For x := 0 To vErro.ErrorCount -1 Do
Begin
If vErro.Errors[x].NativeError=0 Then
Case vErro.Errors[x].ErrorCode Of
9475:Erro(‘Espaço Insuficiente em
Disco.’);
9479:Erro(‘Tabela Está Cheia’);
9429:Erro(‘Espaço Insuficiente em
Disco.’);
9432:Erro(‘Campo Obrigatório Sem
Valor.’);

10241:Erro(‘Registro em Uso Por Outro
Usuário.’);
Else
Erro(‘Comunique o Erro Abaixo ao
Departamento de Informática.’+#13+

IntToStr(vErro.Errors[x].ErroCode+’-‘+vErr
o.Errors[x].Message);
End;
End;
End;

–- MAIS –

ou
Procedure MostraErro;
Begin
ShowMessage(‘Ocorreu algum erro!’);
end;

TForm1.Create;
Begin
Application.OnException:=MostraErro;
end;
565 - Como usar o Install Shield
Supondo que você fez um sistema, que está no diretório
C:\Contas, deixe apenas o Arquivo executável .exe e as
suas tabela .db (para Arquivoc Paradox) e os arquivos
de índice que são de extensão *.PX e *.XG0. Se você
possui imagens coloque as também.
Supondo ainda que você queira instalar o seu programa
no diretório C:\ContasNew.
1) Na primeira tela, escolha a opção Create a new Setup
Project
2) Na segunta tela (New Project), na caixa Project Name
escreva o nome que quer dar em seu Projeto (Ex.
ContasNew)
3) Clique em Create
4)Na lista que irá aparecer clique no 1º botão
(Application Informatio)
5)Clique no botão Browse, e escolha o executável, no
meu caso será o Contas.exe que está dentro do diretório
C:\Contas
6)Na opção Defalt Destination Directory deixe apenas
C:\ContasNew, se quizer que seja instalado dentro do
diretório Arquivos de Programa deixe como ao lado
\ContasNew
7)Clique em OK
8)Clique na opção General Options, clique no DBE
(Borland DataBase Engine)
9)Irá aparecer uma segunda tela, clique em avançar.
10) Se no seu programa você utiliza um alias para se
referenciar as suas tabelas, clique em New você terá
que digitar o nome
do seu Alias e depois clique em OK
11) Clique em Avançar, escolha (marque a opção) Save
.CFG file for…….
12) Clique em Avançar. No campo Path digite o caminho
de suas tabelas (C:\ContasNew)
13) No campo Type, escolha o tipo de Tabela que você
usou (Paradox)
14) Clique em avançar, depois em Concluir e depois em
OK.
15) Clique no botão Groups and Files.
16) Clique sobre a pasta Program Files.
17) Clique em Launch Explorer, irá aparecer o Explorer
do windows. Entre no diretório que estão os seus
arquivos *.exe, *.db, *.PX e etc)
18) Selecione todos os Arquivos (Tecla Shift
pressionada)
19) Após selecionados os arquivos, arraste-os para a
barra de tarefas, em cima do Icone do InstallShield, ele
será maximizado e você colocará os arquivos no espaço
em branco do File Groups .
20) Clique em OK (neste monento, o DBE e todos os
seus arquivos já estão configurados).
21) Clique no botão Dialog Boxes. Iremos montar as
telas que irão fazer a interface com o usuário na hora da
instalação.
22) Selecione apenas a opção Welcome Message (2º),
Select Program Folder e a opção Setup Complete
(Última opção)
23) Clique em OK.
24) No final da página clique em Click Here for page 2
25) Clique no botão de Disk Builder
26) Escolha o tamanho dos disquetes Disk Syze (1.44),
depois clique em Build
27) Depois de pronto o disco, clique em Close. (Criamos
no mínimo 3 discos, pois o DBE ocupa 3 discos e mais o
nosso programa).
28) Se você quiser testar se a instalação está correta,
clique em Test Run.
29) Para copiar os discos de instalação, clique em Copy
to Floppy.
30) Selecione o disco que você quer copiar ou selecione
todos os discos em Copy All Disk ….. E selecione para
que drive será copiado os discos de instalação.
31) Pronto. Os seus discos de instalação já estão
copiados.
566 - Como limpar o conteudo de
um LookupComboBox
DBLookupComboBox1.KeyValue:=’ ‘;
567 - Como fazer para o sistema
nao pedir o Login (Password) Banco
de Dados
Coloque um componente TDatabase, a propriedade
LoginPrompt como
false e daí os parâmetros de nome de usuário e senha
na propriedades dos parâmetros…
568 - Dicas QuickReport
O objetivo deste exercício é fazer um relatório que
apresente uma relação um para muitos entre duas
tabelas. Por
exemplo:
A tabela 1 (MasterTable) possui a descrição de todos os
clientes da empresa e a tabela 2 (DetailTable) possui os
dados de todas as compras realizadas por cada cliente.
Temos neste caso uma relação 1:N. O objetivo deste
exemplo é produzir um relatório com o formato abaixo
descrito:

Nome: Paulo Ramos


Endereço: Rua N. S. Copacabana, 123
Telefone: 432-4455
Itens comprados:
4 pares de Sapatos
3 calças
Nome: Marcel Waintraub
Endereço: Rua das Acácias 22, apto 1105
Telefone:
Itens comprados:
1 gravata
2 meias
A tabela MasterTable será a tabela com o nome dos
clientes e a tabela DetailTable com as compras .
Devemos então escolher no menu do Delphi,
File/New/Forms e selecionar o formulário QuickReport
Master/Detail. O formulário inicial é apresentado abaixo:
Este formulário é composto de 5 bandas, 2
componentes Table e 1 DataSource (MasterDS). Na
banda Detail são colocados os componentes, por
exemplo, QRDBText e QRLabel referentes a tabela
MasterTable e na banda Subdetail os componentes
referentes a tabela Detailtable.
É importante verificar se a propriedade DataSet do
formulário foi inicializada corretamente para MasterTable
. A propriedade DataSet da Banda SubDetail tem que
ser alterada para DetailTable. Repare que o QuickReport
inicializa erroneamente o valor desta propriedade para
MasterTable.
Para cada tabela inicializa-se as propriedades
DataBaseName com seu alias, a propriedade
TableName com o nome das tabelas e a propriedade
Active para true.
Para a tabela DetailTable estabelecemos a relação um
para muitos. Para isto, devemos nos certificar que a
propriedade MasterSource está atribuida com o
Datasource MasterDS referente a tabela MasterTable.
Tendo feito isto é hora de se estabelecer de fato a
ligação um para muitos entre as duas tabelas. Para isto,
seleciona-se a tabela DetailTable e seleciona-se a
propriedade MasterField (dá-se um click com o mouse
no botão do lado direitro desta propriedade (…)).
Para se efetuar a ligação 1:N seleciona-se os campos
de ligação entre as duas tabelas.
Depois, coloca-se os componentes em suas respctivas
bandas. Por exemplo, colocamos dois componentes
QRLabel na banda Detail e alteramos as suas
propriedades Caption para Nome e Endereço do cliente.
A seguir, coloca-se dois componentes QRDBText logo
abaixo (ou do lado) dos componentes QRLabel. Para
cada um deles a propriedade DataSet é inicializada com
MasterTable e a propriedade DataField com os campos
da tabela Nome e Endereco.
Na banda SubDetail são colocados os itens
relacionados as compras dos clientes. Coloca-se
componentes QRDBText com a propriedade DataSet
sendo inicializada como DetailTable e a propriedade
DataField com os campos da tabela DetailTable, campo
Descrição.
Ao final temos aproximadamente :
Para vizualizar de imediato o resultado deste trabalho,
damos um click com a outra tecla do mouse em cima do
relatório. É apresentado um menu e escolhemos a
opção Preview. Que resulta em.
Quando houver necessidade de um relatório mais
sofisticado, por exemplo, com várias relações 1:N,
podemos partir de um relatório MasterDetail,
acrescentar bandas SubDetails com suas respectivas
tabelas.
Como foi visto no exemplo anterior, os cabeçalhos do
banda SubDetail foram postos na banda Detail. Mas
como ficaria se colocassemos mais uma banda
SubDetail?
O primeiro passo é colocar uma banda (terceiro
componente do QuikReport), depois estabeleça que a
propriedade HeaderBand da nova banda do SubDetail
seja igual ao nome desta nova banda (QRBand1). Para
finalizar coloque os componentes QRLabel na banda
QRBand1 para servirem como cabeçalhos do nova
relação um para muito.
Dicas
1.Caso se queira que o relatório apresente cada cliente
separadamente atribua a propriedade ForceNewPage
da banda Detail para true;
2.Para o caso de só imprimir um cliente quando ele
tiver efetuado uma compra, coloca-se o seguinte código
no evento BeforePrint da banda Detail
PrintBand:=DetailTable.RecordCount>0;
3.Para ativar impressão do formulário a um evento
OnClick, coloca-se a seguinte codificação:
QRMDForm.Print;
4.Para se inicializar campos antes da apresentaçãodo
formulário, coloca-se a codificação no evento
ONStartPage do Formulário, Por exemplo:
procedure
TDoseaciForm.DoseaciFormStartPage(Sender:
TQuickRep);
5. begin
QRLabel4.Caption:=nome_serv;

MasterTable.filter:=‘Id=’+InttoStr(id_serv
);
MasterTable.filtered:=true;
QRLabel18.Caption:=Form23.Edit2.text;
QRLabel18.Left:=doseaciForm.width div 2-
QRLabel18.width div 2;
try

QRMemo1.Lines.LoadFromFile(‘prelat.txt’);
QRImage1.Picture.loadfromfile(simbolo);
finally
end;
end;
6.Para ativar o formulário a um evento OnClick, coloca-
se a seguinte codificação:
QRMDForm.Preview;
570 - Função de potenciação -
Juros
Segue abaixo uma função para efetuar a potenciação. É
útil para compor formulas financeiras, como a de VP
(“PV” valor presente) VF (“FV” valor futuro)
Exemplo:
Calcular o valor de um produto para o prazo de 30 dias
com a taxa de juros de 5% mês.
var
i: Real; // taxa de juros
valor: Real; // valor base para calculo
do valor futuro.
pz: Integer // prazo em dias
begin
i := 5//100;
valor:= 1000.00
pz := 30
Result:= valor*( Pot( (1+i), (pz/30) )
//Resultado 1.050,00
end;
no excel a Pot é substituída pelo sinal ^ Ex. =E18*
((1+C19)^(C20/30))
Function Pot( base, expoente: real ):real;
// Potenciação
begin
{ utiliza a função de exponencial e de
logaritmo }
Result:= Exp((expoente * Ln( base )));
end;
Dicas:
Não amplie o nome da função, pois as funções
financeiras costumam ser bem extensas.
571 - Lista de erros BDE
System Related (Fatal Error)
8449 : $2101 : Cannot open a system
file.
8450 : $2102 : I/O error on a system
file.
8451 : $2103 : Data structure
corruption.
8452 : $2104 : Cannot find Engine
configuration file.
8453 : $2105 : Cannot write to Engine
configuration file.
8454 : $2106 : Cannot initialize with
different configuration file.
8455 : $2107 : System has been illegally
re-entered.
8456 : $2108 : Cannot locate IDAPI32
.DLL.
8457 : $2109 : Cannot load IDAPI32 .DLL.
8458 : $210A : Cannot load an IDAPI
service library.
8459 : $210B : Cannot create or open
temporary file.
8460 : $210C : Trying to load multiple
IDAPIxx.DLL
8461 : $210D : Shared Memory Conflict
Object of Interest not Found

8705 : $2201 : At beginning of table.


8706 : $2202 : At end of table.
8707 : $2203 : Record moved because key
value changed.
8708 : $2204 : Record/Key deleted.
8709 : $2205 : No current record.
8710 : $2206 : Could not find record.
8711 : $2207 : End of BLOB.
8712 : $2208 : Could not find object.
8713 : $2209 : Could not find family
member.
8714 : $220A : BLOB file is missing.
8715 : $220B : Could not find language
driver.
Physical Data Corruption

8961 : $2301 : Corrupt table/index


header.
8962 : $2302 : Corrupt file - other than
header.
8963 : $2303 : Corrupt Memo/BLOB file.
8965 : $2305 : Corrupt index.
8966 : $2306 : Corrupt lock file.
8967 : $2307 : Corrupt family file.
8968 : $2308 : Corrupt or missing .VAL
file.
8969 : $2309 : Foreign index file
format.
I/O related error

9217 : $2401 : Read failure.


9218 : $2402 : Write failure.
9219 : $2403 : Cannot access directory.
9220 : $2404 : File Delete operation
failed.
9221 : $2405 : Cannot access file.
9222 : $2406 : Access to table disabled
because of previous error.
Resource or Limit error

9473 : $2501 : Insufficient memory for


this operation.
9474 : $2502 : Not enough file handles.
9475 : $2503 : Insufficient disk space.
9476 : $2504 : Temporary table resource
limit.
9477 : $2505 : Record size is too big
for table.
9478 : $2506 : Too many open cursors.
9479 : $2507 : Table is full.
9480 : $2508 : Too many sessions from
this workstation.
9481 : $2509 : Serial number limit
(Paradox).
9482 : $250A : Some internal limit (see
context).
9483 : $250B : Too many open tables.
9484 : $250C : Too many cursors per
table.
9485 : $250D : Too many record locks on
table.
9486 : $250E : Too many clients.
9487 : $250F : Too many indexes on
table.
9488 : $2510 : Too many sessions.
9489 : $2511 : Too many open databases.
9490 : $2512 : Too many passwords.
9491 : $2513 : Too many active drivers.
9492 : $2514 : Too many fields in Table
Create.
9493 : $2515 : Too many table locks.
9494 : $2516 : Too many open BLOBs.
9495 : $2517 : Lock file has grown too
large.
9496 : $2518 : Too many open queries.
9497 : $2519 : Too many threads for
client.
9498 : $251A : Too many BLOBs.
9499 : $251B : File name is too long for
a Paradox version 5.0 table.
9500 : $251C : Row fetch limit exceeded.
9501 : $251D : Long name not allowed for
this tablelevel.
9502 : $251E : Insufficient shared
memory available.
Integrity Violation

9729 : $2601 : Key violation.


9730 : $2602 : Minimum validity check
failed.
9731 : $2603 : Maximum validity check
failed.
9732 : $2604 : Field value required.
9733 : $2605 : Master record missing.
9734 : $2606 : Master has detail
records. Cannot delete or modify.
9735 : $2607 : Master table level is
incorrect.
9736 : $2608 : Field value out of lookup
table range.
9737 : $2609 : Lookup Table Open
operation failed.
9738 : $260A : Detail Table Open
operation failed.
9739 : $260B : Master Table Open
operation failed.
9740 : $260C : Field is blank.
9741 : $260D : Link to master table
already defined.
9742 : $260E : Master table is open.
9743 : $260F : Detail table(s) exist.
9744 : $2610 : Master has detail
records. Cannot empty it.
9745 : $2611 : Self referencing
referential integrity must be entered one
at a time with no other changes to the
table.
9746 : $2612 : Detail table is open.
9747 : $2613 : Cannot make this master a
detail of another table if its details are
not empty.
9748 : $2614 : Referential integrity
fields must be indexed.
9749 : $2615 : A table linked by
referential integrity requires password to
open.
9750 : $2616 : Field(s) linked to more
than one master.
9751 : $2617 : Expression validity check
failed.
Invalid Request

9985 : $2701 : Number is out of range.


9986 : $2702 : Invalid parameter.
9987 : $2703 : Invalid file name.
9988 : $2704 : File does not exist.
9989 : $2705 : Invalid option.
9990 : $2706 : Invalid handle to the
function.
9991 : $2707 : Unknown table type.
9992 : $2708 : Cannot open file.
9993 : $2709 : Cannot redefine primary
key.
9994 : $270A : Cannot change this
RINTDesc.
9995 : $270B : Foreign and primary key
do not match.
9996 : $270C : Invalid modify request.
9997 : $270D : Index does not exist.
9998 : $270E : Invalid offset into the
BLOB.
9999 : $270F : Invalid descriptor
number.
10000 : $2710 : Invalid field type.
10001 : $2711 : Invalid field descriptor.
10002 : $2712 : Invalid field
transformation.
10003 : $2713 : Invalid record structure.
10004 : $2714 : Invalid descriptor.
10005 : $2715 : Invalid array of index
descriptors.
10006 : $2716 : Invalid array of validity
check descriptors.
10007 : $2717 : Invalid array of
referential integrity descriptors.
10008 : $2718 : Invalid ordering of
tables during restructure.
10009 : $2719 : Name not unique in this
context.
10010 : $271A : Index name required.
10011 : $271B : Invalid session handle.
10012 : $271C : invalid restructure
operation.
10013 : $271D : Driver not known to
system.
10014 : $271E : Unknown database.
10015 : $271F : Invalid password given.
10016 : $2720 : No callback function.
10017 : $2721 : Invalid callback buffer
length.
10018 : $2722 : Invalid directory.
10019 : $2723 : Translate Error. Value
out of bounds.
10020 : $2724 : Cannot set cursor of one
table to another.
10021 : $2725 : Bookmarks do not match
table.
10022 : $2726 : Invalid index/tag name.
10023 : $2727 : Invalid index descriptor.
10024 : $2728 : Table does not exist.
10025 : $2729 : Table has too many users.
10026 : $272A : Cannot evaluate Key or
Key does not pass filter condition.
10027 : $272B : Index already exists.
10028 : $272C : Index is open.
10029 : $272D : Invalid BLOB length.
10030 : $272E : Invalid BLOB handle in
record buffer.
10031 : $272F : Table is open.
10032 : $2730 : Need to do (hard)
restructure.
10033 : $2731 : Invalid mode.
10034 : $2732 : Cannot close index.
10035 : $2733 : Index is being used to
order table.
10036 : $2734 : Unknown user name or
password.
10037 : $2735 : Multi-level cascade is
not supported.
10038 : $2736 : Invalid field name.
10039 : $2737 : Invalid table name.
10040 : $2738 : Invalid linked cursor
expression.
10041 : $2739 : Name is reserved.
10042 : $273A : Invalid file extension.
10043 : $273B : Invalid language Driver.
10044 : $273C : Alias is not currently
opened.
10045 : $273D : Incompatible record
structures.
10046 : $273E : Name is reserved by DOS.
10047 : $273F : Destination must be
indexed.
10048 : $2740 : Invalid index type
10049 : $2741 : Language Drivers of Table
and Index do not match
10050 : $2742 : Filter handle is invalid
10051 : $2743 : Invalid Filter
10052 : $2744 : Invalid table create
request
10053 : $2745 : Invalid table delete
request
10054 : $2746 : Invalid index create
request
10055 : $2747 : Invalid index delete
request
10056 : $2748 : Invalid table specified
10058 : $274A : Invalid Time.
10059 : $274B : Invalid Date.
10060 : $274C : Invalid Datetime
10061 : $274D : Tables in different
directories
10062 : $274E : Mismatch in the number of
arguments
10063 : $274F : Function not found in
service library.
10064 : $2750 : Must use baseorder for
this operation.
10065 : $2751 : Invalid procedure name
10066 : $2752 : The field map is invalid.
Locking/Contention related

10241 : $2801 : Record locked by another


user.
10242 : $2802 : Unlock failed.
10243 : $2803 : Table is busy.
10244 : $2804 : Directory is busy.
10245 : $2805 : File is locked.
10246 : $2806 : Directory is locked.
10247 : $2807 : Record already locked by
this session.
10248 : $2808 : Object not locked.
10249 : $2809 : Lock time out.
10250 : $280A : Key group is locked.
10251 : $280B : Table lock was lost.
10252 : $280C : Exclusive access was
lost.
10253 : $280D : Table cannot be opened
for exclusive use.
10254 : $280E : Conflicting record lock
in this session.
10255 : $280F : A deadlock was detected.
10256 : $2810 : A user transaction is
already in progress.
10257 : $2811 : No user transaction is
currently in progress.
10258 : $2812 : Record lock failed.
10259 : $2813 : Couldn’t perform the edit
because another user changed the record.
10260 : $2814 : Couldn’t perform the edit
because another user deleted or moved the
record.
Access Violation - Security related

10497 : $2901 : Insufficient field rights


for operation.
10498 : $2902 : Insufficient table rights
for operation. Password required.
10499 : $2903 : Insufficient family
rights for operation.
10500 : $2904 : This directory is read
only.
10501 : $2905 : Database is read only.
10502 : $2906 : Trying to modify read-
only field.
10503 : $2907 : Encrypted dBASE tables
not supported.
10504 : $2908 : Insufficient SQL rights
for operation.
Invalid context

10753 : $2A01 : Field is not a BLOB.


10754 : $2A02 : BLOB already opened.
10755 : $2A03 : BLOB not opened.
10756 : $2A04 : Operation not applicable.
10757 : $2A05 : Table is not indexed.
10758 : $2A06 : Engine not initialized.
10759 : $2A07 : Attempt to re-initialize
Engine.
10760 : $2A08 : Attempt to mix objects
from different sessions.
10761 : $2A09 : Paradox driver not
active.
10762 : $2A0A : Driver not loaded.
10763 : $2A0B : Table is read only.
10764 : $2A0C : No associated index.
10765 : $2A0D : Table(s) open. Cannot
perform this operation.
10766 : $2A0E : Table does not support
this operation.
10767 : $2A0F : Index is read only.
10768 : $2A10 : Table does not support
this operation because it is not uniquely
indexed.
10769 : $2A11 : Operation must be
performed on the current session.
10770 : $2A12 : Invalid use of keyword.
10771 : $2A13 : Connection is in use by
another statement.
10772 : $2A14 : Passthrough SQL
connection must be shared
Os Error not handled by Idapi

11009 : $2B01 : Invalid function number.


11010 : $2B02 : File or directory does
not exist.
11011 : $2B03 : Path not found.
11012 : $2B04 : Too many open files. You
may need to increase MAXFILEHANDLE limit
in IDAPI configuration.
11013 : $2B05 : Permission denied.
11014 : $2B06 : Bad file number.
11015 : $2B07 : Memory blocks destroyed.
11016 : $2B08 : Not enough memory.
11017 : $2B09 : Invalid memory block
address.
11018 : $2B0A : Invalid environment.
11019 : $2B0B : Invalid format.
11020 : $2B0C : Invalid access code.
11021 : $2B0D : Invalid data.
11023 : $2B0F : Device does not exist.
11024 : $2B10 : Attempt to remove current
directory.
11025 : $2B11 : Not same device.
11026 : $2B12 : No more files.
11027 : $2B13 : Invalid argument.
11028 : $2B14 : Argument list is too
long.
11029 : $2B15 : Execution format error.
11030 : $2B16 : Cross-device link.
11041 : $2B21 : Math argument.
11042 : $2B22 : Result is too large.
11043 : $2B23 : File already exists.
11047 : $2B27 : Unknown internal
operating system error.
11058 : $2B32 : Share violation.
11059 : $2B33 : Lock violation.
11060 : $2B34 : Critical DOS Error.
11061 : $2B35 : Drive not ready.
11108 : $2B64 : Not exact read/write.
11109 : $2B65 : Operating system network
error.
11110 : $2B66 : Error from NOVELL file
server.
11111 : $2B67 : NOVELL server out of
memory.
11112 : $2B68 : Record already locked by
this workstation.
11113 : $2B69 : Record not locked.
Network related

11265 : $2C01 : Network initialization


failed.
11266 : $2C02 : Network user limit
exceeded.
11267 : $2C03 : Wrong .NET file version.
11268 : $2C04 : Cannot lock network file.
11269 : $2C05 : Directory is not private.
11270 : $2C06 : Directory is controlled
by other .NET file.
11271 : $2C07 : Unknown network error.
11272 : $2C08 : Not initialized for
accessing network files.
11273 : $2C09 : SHARE not loaded. It is
required to share local files.
11274 : $2C0A : Not on a network. Not
logged in or wrong network driver.
11275 : $2C0B : Lost communication with
SQL server.
11277 : $2C0D : Cannot locate or connect
to SQL server.
11278 : $2C0E : Cannot locate or connect
to network server.
Optional parameter related

11521 : $2D01 : Optional parameter is


required.
11522 : $2D02 : Invalid optional
parameter.
Query related

11777 : $2E01 : obsolete


11778 : $2E02 : obsolete
11779 : $2E03 : Ambiguous use of !
(inclusion operator).
11780 : $2E04 : obsolete
11781 : $2E05 : obsolete
11782 : $2E06 : A SET operation cannot be
included in its own grouping.
11783 : $2E07 : Only numeric and
date/time fields can be averaged.
11784 : $2E08 : Invalid expression.
11785 : $2E09 : Invalid OR expression.
11786 : $2E0A : obsolete
11787 : $2E0B : bitmap
11788 : $2E0C : CALC expression cannot be
used in INSERT, DELETE, CHANGETO and SET
rows.
11789 : $2E0D : Type error in CALC
expression.
11790 : $2E0E : CHANGETO can be used in
only one query form at a time.
11791 : $2E0F : Cannot modify CHANGED
table.
11792 : $2E10 : A field can contain only
one CHANGETO expression.
11793 : $2E11 : A field cannot contain
more than one expression to be inserted.
11794 : $2E12 : obsolete
11795 : $2E13 : CHANGETO must be followed
by the new value for the field.
11796 : $2E14 : Checkmark or CALC
expressions cannot be used in FIND
queries.
11797 : $2E15 : Cannot perform operation
on CHANGED table together with a CHANGETO
query.
11798 : $2E16 : chunk
11799 : $2E17 : More than 255 fields in
ANSWER table.
11800 : $2E18 : AS must be followed by
the name for the field in the ANSWER
table.
11801 : $2E19 : DELETE can be used in
only one query form at a time.
11802 : $2E1A : Cannot perform operation
on DELETED table together with a DELETE
query.
11803 : $2E1B : Cannot delete from the
DELETED table.
11804 : $2E1C : Example element is used
in two fields with incompatible types or
with a BLOB.
11805 : $2E1D : Cannot use example
elements in an OR expression.
11806 : $2E1E : Expression in this field
has the wrong type.
11807 : $2E1F : Extra comma found.
11808 : $2E20 : Extra OR found.
11809 : $2E21 : One or more query rows do
not contribute to the ANSWER.
11810 : $2E22 : FIND can be used in only
one query form at a time.
11811 : $2E23 : FIND cannot be used with
the ANSWER table.
11812 : $2E24 : A row with GROUPBY must
contain SET operations.
11813 : $2E25 : GROUPBY can be used only
in SET rows.
11814 : $2E26 : Use only INSERT, DELETE,
SET or FIND in leftmost column.
11815 : $2E27 : Use only one INSERT,
DELETE, SET or FIND per line.
11816 : $2E28 : Syntax error in
expression.
11817 : $2E29 : INSERT can be used in
only one query form at a time.
11818 : $2E2A : Cannot perform operation
on INSERTED table together with an INSERT
query.
11819 : $2E2B : INSERT, DELETE, CHANGETO
and SET rows may not be checked.
11820 : $2E2C : Field must contain an
expression to insert (or be blank).
11821 : $2E2D : Cannot insert into the
INSERTED table.
11822 : $2E2E : Variable is an array and
cannot be accessed.
11823 : $2E2F : Label
11824 : $2E30 : Rows of example elements
in CALC expression must be linked.
11825 : $2E31 : Variable name is too
long.
11826 : $2E32 : Query may take a long
time to process.
11827 : $2E33 : Reserved word or one that
can’t be used as a variable name.
11828 : $2E34 : Missing comma.
11829 : $2E35 : Missing ).
11830 : $2E36 : Missing right quote.
11831 : $2E37 : Cannot specify duplicate
column names.
11832 : $2E38 : Query has no checked
fields.
11833 : $2E39 : Example element has no
defining occurrence.
11834 : $2E3A : No grouping is defined
for SET operation.
11835 : $2E3B : Query makes no sense.
11836 : $2E3C : Cannot use patterns in
this context.
11837 : $2E3D : Date does not exist.
11838 : $2E3E : Variable has not been
assigned a value.
11839 : $2E3F : Invalid use of example
element in summary expression.
11840 : $2E40 : Incomplete query
statement. Query only contains a SET
definition.
11841 : $2E41 : Example element with !
makes no sense in expression.
11842 : $2E42 : Example element cannot be
used more than twice with a ! query.
11843 : $2E43 : Row cannot contain
expression.
11844 : $2E44 : obsolete
11845 : $2E45 : obsolete
11846 : $2E46 : No permission to insert
or delete records.
11847 : $2E47 : No permission to modify
field.
11848 : $2E48 : Field not found in table.
11849 : $2E49 : Expecting a column
separator in table header.
11850 : $2E4A : Expecting a column
separator in table.
11851 : $2E4B : Expecting column name in
table.
11852 : $2E4C : Expecting table name.
11853 : $2E4D : Expecting consistent
number of columns in all rows of table.
11854 : $2E4E : Cannot open table.
11855 : $2E4F : Field appears more than
once in table.
11856 : $2E50 : This DELETE, CHANGE or
INSERT query has no ANSWER.
11857 : $2E51 : Query is not prepared.
Properties unknown.
11858 : $2E52 : DELETE rows cannot
contain quantifier expression.
11859 : $2E53 : Invalid expression in
INSERT row.
11860 : $2E54 : Invalid expression in
INSERT row.
11861 : $2E55 : Invalid expression in SET
definition.
11862 : $2E56 : row use
11863 : $2E57 : SET keyword expected.
11864 : $2E58 : Ambiguous use of example
element.
11865 : $2E59 : obsolete
11866 : $2E5A : obsolete
11867 : $2E5B : Only numeric fields can
be summed.
11868 : $2E5C : Table is write protected.
11869 : $2E5D : Token not found.
11870 : $2E5E : Cannot use example
element with ! more than once in a single
row.
11871 : $2E5F : Type mismatch in
expression.
11872 : $2E60 : Query appears to ask two
unrelated questions.
11873 : $2E61 : Unused SET row.
11874 : $2E62 : INSERT, DELETE, FIND, and
SET can be used only in the leftmost
column.
11875 : $2E63 : CHANGETO cannot be used
with INSERT, DELETE, SET or FIND.
11876 : $2E64 : Expression must be
followed by an example element defined in
a SET.
11877 : $2E65 : Lock failure.
11878 : $2E66 : Expression is too long.
11879 : $2E67 : Refresh exception during
query.
11880 : $2E68 : Query canceled.
11881 : $2E69 : Unexpected Database
Engine error.
11882 : $2E6A : Not enough memory to
finish operation.
11883 : $2E6B : Unexpected exception.
11884 : $2E6C : Feature not implemented
yet in query.
11885 : $2E6D : Query format is not
supported.
11886 : $2E6E : Query string is empty.
11887 : $2E6F : Attempted to prepare an
empty query.
11888 : $2E70 : Buffer too small to
contain query string.
11889 : $2E71 : Query was not previously
parsed or prepared.
11890 : $2E72 : Function called with bad
query handle.
11891 : $2E73 : QBE syntax error.
11892 : $2E74 : Query extended syntax
field count error.
11893 : $2E75 : Field name in sort or
field clause not found.
11894 : $2E76 : Table name in sort or
field clause not found.
11895 : $2E77 : Operation is not
supported on BLOB fields.
11896 : $2E78 : General BLOB error.
11897 : $2E79 : Query must be restarted.
11898 : $2E7A : Unknown answer table
type.
11926 : $2E96 : Blob cannot be used as
grouping field.
11927 : $2E97 : Query properties have not
been fetched.
11928 : $2E98 : Answer table is of
unsuitable type.
11929 : $2E99 : Answer table is not yet
supported under server alias.
11930 : $2E9A : Non-null blob field
required. Can’t insert records
11931 : $2E9B : Unique index required to
perform changeto
11932 : $2E9C : Unique index required to
delete records
11933 : $2E9D : Update of table on the
server failed.
11934 : $2E9E : Can’t process this query
remotely.
11935 : $2E9F : Unexpected end of
command.
11936 : $2EA0 : Parameter not set in
query string.
11937 : $2EA1 : Query string is too long.
11946 : $2EAA : No such table or
correlation name.
11947 : $2EAB : Expression has ambiguous
data type.
11948 : $2EAC : Field in order by must be
in result set.
11949 : $2EAD : General parsing error.
11950 : $2EAE : Record or field
constraint failed.
11951 : $2EAF : When GROUP BY exists,
every simple field in projectors must be
in GROUP BY.
11952 : $2EB0 : User defined function is
not defined.
11953 : $2EB1 : Unknown error from User
defined function.
11954 : $2EB2 : Single row subquery
produced more than one row.
11955 : $2EB3 : Expressions in group by
are not supported.
11956 : $2EB4 : Queries on text or ascii
tables is not supported.
11957 : $2EB5 : ANSI join keywords USING
and NATURAL are not supported in this
release.
11958 : $2EB6 : SELECT DISTINCT may not
be used with UNION unless UNION ALL is
used.
11959 : $2EB7 : GROUP BY is required when
both aggregate and non-aggregate fields
are used in result set.
11960 : $2EB8 : INSERT and UPDATE
operations are not supported on
autoincrement field type.
11961 : $2EB9 : UPDATE on Primary Key of
a Master Table may modify more than one
record.
11962 : $2EBA : Queries on MS ACCESS
tables are not supported by local query
engines.
11963 : $2EBB : Preparation of field-
level constraint failed.
11964 : $2EBC : Preparation of field
default failed.
11965 : $2EBD : Preparation of record-
level constraint failed.
11972 : $2EC4 : Constraint Failed.
Expression:
Version Mismatch Category

12033 : $2F01 : Interface mismatch.


Engine version different.
12034 : $2F02 : Index is out of date.
12035 : $2F03 : Older version (see
context).
12036 : $2F04 : .VAL file is out of date.
12037 : $2F05 : BLOB file version is too
old.
12038 : $2F06 : Query and Engine DLLs are
mismatched.
12039 : $2F07 : Server is incompatible
version.
12040 : $2F08 : Higher table level
required
Capability not supported

12289 : $3001 : Capability not supported.


12290 : $3002 : Not implemented yet.
12291 : $3003 : SQL replicas not
supported.
12292 : $3004 : Non-blob column in table
required to perform operation.
12293 : $3005 : Multiple connections not
supported.
12294 : $3006 : Full dBASE expressions
not supported.
12295 : $3007 : Nested transactions not
supported.
System configuration error

12545 : $3101 : Invalid database alias


specification.
12546 : $3102 : Unknown database type.
12547 : $3103 : Corrupt system
configuration file.
12548 : $3104 : Network type unknown.
12549 : $3105 : Not on the network.
12550 : $3106 : Invalid configuration
parameter.
Warnings

12801 : $3201 : Object implicitly


dropped.
12802 : $3202 : Object may be truncated.
12803 : $3203 : Object implicitly
modified.
12804 : $3204 : Should field constraints
be checked?
12805 : $3205 : Validity check field
modified.
12806 : $3206 : Table level changed.
12807 : $3207 : Copy linked tables?
12809 : $3209 : Object implicitly
truncated.
12810 : $320A : Validity check will not
be enforced.
12811 : $320B : Multiple records found,
but only one was expected.
12812 : $320C : Field will be trimmed,
cannot put master records into PROBLEM
table.
Miscellaneous

13057 : $3301 : File already exists.


13058 : $3302 : BLOB has been modified.
13059 : $3303 : General SQL error.
13060 : $3304 : Table already exists.
13061 : $3305 : Paradox 1.0 tables are
not supported.
13062 : $3306 : Update aborted.
Compatibility related

13313 : $3401 : Different sort order.


13314 : $3402 : Directory in use by
earlier version of Paradox.
13315 : $3403 : Needs Paradox 3.5-
compatible language driver.
Data Repository related

13569 : $3501 : Data Dictionary is


corrupt
13570 : $3502 : Data Dictionary Info Blob
corrupted
13571 : $3503 : Data Dictionary Schema is
corrupt
13572 : $3504 : Attribute Type exists
13573 : $3505 : Invalid Object Type
13574 : $3506 : Invalid Relation Type
13575 : $3507 : View already exists
13576 : $3508 : No such View exists
13577 : $3509 : Invalid Record Constraint
13578 : $350A : Object is in a Logical DB
13579 : $350B : Dictionary already exists
13580 : $350C : Dictionary does not exist
13581 : $350D : Dictionary database does
not exist
13582 : $350E : Dictionary info is out of
date - needs Refresh
13584 : $3510 : Invalid Dictionary Name
13585 : $3511 : Dependent Objects exist
13586 : $3512 : Too many Relationships
for this Object Type
13587 : $3513 : Relationships to the
Object exist
13588 : $3514 : Dictionary Exchange File
is corrupt
13589 : $3515 : Dictionary Exchange File
Version mismatch
13590 : $3516 : Dictionary Object Type
Mismatch
13591 : $3517 : Object exists in Target
Dictionary
13592 : $3518 : Cannot access Data
Dictionary
13593 : $3519 : Cannot create Data
Dictionary
13594 : $351A : Cannot open Database
Driver related

15873 : $3E01 : Wrong driver name.


15874 : $3E02 : Wrong system version.
15875 : $3E03 : Wrong driver version.
15876 : $3E04 : Wrong driver type.
15877 : $3E05 : Cannot load driver.
15878 : $3E06 : Cannot load language
driver.
15879 : $3E07 : Vendor initialization
failed.
15880 : $3E08 : Your application is not
enabled for use with this driver.

P.S.: Caso alguem tenha essa lista de erros traduzida


por favor enviar para lloydsoft@uol.com.br
572 - Como utilizar strings de
recurso em suas aplicações
A utilização de strings de recurso em suas aplicações é
muito fácil e de grande portabilidade. Ao utilizá-las, você
terá as seguintes vantagens:
- Todos os programas que compõem a sua aplicação
poderão utilizá-las sem necessitarem ser reescritos,
assim, você ganha tempo, padronização no seu código,
além de ser uma prática estruturada.
- Você poderá internacionalizar sua aplicação a partir
das strings de recurso que você definiu.
- As mensagens podem ser formatadas para receberem
parâmetros, aumentando ainda mais a padronização e
estruturação do seu código.
Passos para a definição de strings de recurso
- Crie uma unit que conterá todas as suas strings de
recurso.(você também pode adicionar todas as
constantes da sua aplicação na seção Const).
- Na seção interface, utilize a palavra reservada
resourcestring.
- Defina as constantes na forma de pares
nome_identificador = valor da string;. É uma boa prática
utilizar o prefixo S para definir strings de recurso.
unit Constantes;

interface
const
// geral
appRegisterValue = 99.00;
// Fluxo de caixa
rgFluxoDataLimite = ‘Data limite’;
rgFluxoSaldoCaixa = ‘Saldo em caixa’;
// contas orçamentárias
tvSep = ‘ - ‘;
// diretório de figuras para os gráficos
(logomarca, etc…)
chtPicturePath = ‘Imagens dos gráficos’;

resourcestring
// strings de recurso
// geral
// string simples
SFechandoFilhas = ‘Fechando janelas
filhas abertas da aplicação…’;
// string com parâmetro
SInsercaoInvalida = ‘Não será possível
adicionar mais registros de %s.’;
// acesso
SInterfaceInserir = ‘Adicionar novos
registros de %s’;
SInterfaceEditar = ‘Alterar registros de
%s cadastrados’;
SInterfaceApagar = ‘Apagar registros de
%s cadastrados’;

implementation
end.
 Como utilizar as strings de recurso
Quando você desejar utilizar strings de recurso simples,
simplesmente adicione-as onde for necessário.
raise
EDatabaseError.Create(SFechandoFilhas);
ShowMessage(SFechandoFilhas);
Quando desejar utilizar strings de recurso com
parâmetros, utilize a função Format fornecendo como
parâmetros, os valores que você deseja exibir na forma
de array de argumentos.
raise
EDatabaseError.CreateFmt(SInsercaoInvalida
, [‘clientes’]);
>> saída >> ‘Não será possível adicionar mais registros
de clientes’
// observação: aqui não há a necessidade de utilizar a
função Format porque o método
// CreateFmt já requer dois parâmetros para a criação
de uma exceção.
ShowMessage(Format(SInsercaoInvalida,
[‘clientes’]));
>> saída >> ‘Não será possível adicionar mais registros
de clientes’
Para saber mais sobre a formatação de strings, procure
no help do Delphi por Format strings.
574 - Como inserir um registro com
o componente UpDateSQL
Na propriedade InsertSQL informe com a seguinte
sintaxe:
INSERT INTO “:Senior:E085CLI” (CodCli,
NomCli)
VALUES ( 1, ‘Jerônimo’ )
575 - Como saber qual o objeto que
esta com o foco no form
Através do evento onKeyPress do form, pode-se testar:
if (ActiveControl is TCustomEdit) and (Key
= #1) then
blablabla;
ou Como no exemplo abaixo:

procedure TForm1.mnuPasteClick(Sender:
TObject);
var
CanPaste: Boolean;
Ctrl: TWinControl;
begin
Ctrl := ActiveControl;
if (Assigned(Ctrl) and
Clipboard.HasFormat(CF_TEXT)) then
begin
if (Ctrl is TEdit) then
CanPaste := (not TEdit(Ctrl).ReadOnly)
else if (Ctrl is TMaskEdit) then
CanPaste := (not
TMaskEdit(Ctrl).ReadOnly)
else if (Ctrl is TMemo) then
CanPaste := (not TMemo(Ctrl).ReadOnly)
else if (Ctrl is TRichEdit) then
CanPaste := (not
TRichEdit(Ctrl).ReadOnly)
else
CanPaste := False;
if (CanPaste) then
TCustomEdit(Ctrl).PasteFromClipboard;
end;
end;
576 - Como utilizar o form Sobre
padrão do Windows
O Windows, como todos sabem, possui uma gama de
ferramentas embutidas em sua API (Application
Program Interface). Uma delas é o formulário “Sobre…”
(About…) que pode ser utilizado por quem desejar. Para
fazer uso deste formulário é muito simples:
1 - Adicione à cláusula uses da seção Interface do
formulário desejado, a unit ShellAPI.
2 - Agora, na procedure que exibe o formulário sobre,
escreva a seguinte linha:
ShellAbout(Handle, ‘Aplicativo’, ‘Autor’,
Application.Icon.Handle);
onde:
Handle -> é o manipulador do formulário que chama a
rotina da API. Utilize 0 (zero) se desejar.
Aplicativo -> é o nome do seu aplicativo. Utilize, para
facilitar, a variável Application.Title.
Autor -> é o nome do autor do aplicativo.
Application.Icon.Handle -> é o manipulador do ícone
pelo qual o seu aplicativo é representado.
Para maiores detalhes, leia sobre a função “ShellAbout”
no help on-line do Delphi.
577 - Como evitar as mensagens de
Warning do Compilador (Variavel não
inicializada)
{$WARNINGS OFF}
function TfrmEdit.ProjectTypeToUse(const
cPath: string): Integer; var
SR: TSearchRec;
begin
if not DirectoryExists(cPath) then begin
ErrMsg(‘Path não localizado!’);
Exit;
end;
try
if FindFirst(cPath +
‘\*.VBP’,faDirectory,SR) = 0 then
Result := VBP_FILTER
else
Result := DPR_FILTER;
except
ErrMsg(‘Falha de sistema -‘ + cPath);
Result := 1
end;
end;
{$WARNINGS ON}
578 - Como diminuir o tempo de
abertura do Table e Query
Operação feita quando é executado o método Open do
componente TTable ou TQuery, que produz a
compilação e execução do comando select. Quando
esse método é executado através do componente
TTable, o Delphi realiza uma série de outros comandos
SQLs para buscar informações do catálogo da tabela
necessárias para as operações de seleção e
atualização. Essa busca pode ser otimizada através da
opção ENABLE SCHEMA CACHE do BDE, fazendo
com que essas informações sejam lidas apenas uma
vez durante a execução da aplicação. Quando o
primeiro acesso é feito, o BDE armazena as
informações em um arquivo e qualquer nova
necessidade de abertura da mesma tabela não
necessita buscar novamente os elementos do catálogo.
Por outro lado, utilizando-se o componente TQuery,
pode-se desviar dessa busca desde que não se utilize a
propriedade Request Live que torna o “result set” da
“query” atualizável automaticamente pelo Delphi. Se o
valor da propriedade Request Live for TRUE e o
SELECT utilizado obedecer as restrições para que o
Delphi consiga atualizar o “result set”, as mesmas
buscas utilizadas para o componente TTable terão que
ser feitas.
Concluindo, para que a busca de elementos do catálogo
não seja feita é necessário utilizar o componente
TQuery e controlar as atualizações manualmente ou
através de componentes do tipo TUpdateSQL.
579 - Caixas de mensagens da
aplicação
procedure
TfrmProduto.DSMainUpdateData(Sender:
TObject);
var ret: integer;
begin
If OperState in [opNone,opNewForInsert]
then begin
ret:=Application.MessageBox(‘Deseja
salvar as alterações’,
‘Confirmação’, MB_YESNOCANCEL +
MB_ICONQUESTION );
case ret of
idYes: Save;
idNo: Discard;
idCancel: Abort;
end;
end;
end;
580 - Retorna que tipo de variavel
é
function GetVariantType(const v: variant):
string;
begin
case TVarData(v).vType of
varEmpty: result := ‘Empty’;
varNull: result := ‘Null’;
varSmallInt: result := ‘SmallInt’;
varInteger: result := ‘Integer’;
varSingle: result := ‘Single’;
varDouble: result := ‘Double’;
varCurrency: result := ‘Currency’;
varDate: result := ‘Date’;
varOleStr: result := ‘OleStr’;
varDispatch: result := ‘Dispatch’;
varError: result := ‘Error’;
varBoolean: result := ‘Boolean’;
varVariant: result := ‘Variant’;
varUnknown: result := ‘Unknown’;
varByte: result := ‘Byte’;
varString: result := ‘String’;
varTypeMask: result := ‘TypeMask’;
varArray: result := ‘Array’;
varByRef: result := ‘ByRef’;
end;
end;
581 - Retorna o último acesso de
um arquivo
function GetFileLastAccessTime(sFileName :
string ) : TDateTime;
var
ffd : TWin32FindData;
dft : DWord;
lft : TFileTime;
h : THandle;
begin
// get file information
h :=
Windows.FindFirstFile(PChar(sFileName),
ffd);
if(INVALID_HANDLE_VALUE <> h)then
begin
Windows.FindClose( h );

FileTimeToLocalFileTime(ffd.ftLastAccessTi
me, lft );

FileTimeToDosDateTime(lft,LongRec(dft).Hi,
LongRec(dft).Lo);
Result := FileDateToDateTime(dft);
end;
end;
582 - Retorna a versão do
aplicativo
function GetBuildInfo:string;
var
VerInfoSize: DWORD;
VerInfo: Pointer;
VerValueSize: DWORD;
VerValue: PVSFixedFileInfo;
Dummy: DWORD;
V1, V2, V3, V4: Word;
Prog : string;
begin
Prog := Application.Exename;
VerInfoSize :=
GetFileVersionInfoSize(PChar(prog),
Dummy);
GetMem(VerInfo, VerInfoSize);
GetFileVersionInfo(PChar(prog), 0,
VerInfoSize, VerInfo);
VerQueryValue(VerInfo, ‘',
Pointer(VerValue), VerValueSize);
with VerValue^ do
begin
V1 := dwFileVersionMS shr 16;
V2 := dwFileVersionMS and $FFFF;
V3 := dwFileVersionLS shr 16;
V4 := dwFileVersionLS and $FFFF;
end;
FreeMem(VerInfo, VerInfoSize);
result := Copy (IntToStr (100 + v1), 3, 2)
+ ‘.’ +
Copy (IntToStr (100 + v2), 3, 2) + ‘.’ +
Copy (IntToStr (100 + v3), 3, 2) + ‘.’ +
Copy (IntToStr (100 + v4), 3, 2);
end;
583 - Converte um arquivo JPEG em
BMP
function JpgToBmp(cImage: String):
Boolean;
// Requer a Jpeg declarada na clausua uses
da unit
var
MyJPEG : TJPEGImage;
MyBMP : TBitmap;
begin
Result := False;
if fileExists(cImage+’.Jpeg’) then
begin
MyJPEG := TJPEGImage.Create;
with MyJPEG do
begin
try
LoadFromFile(cImage+’.Jpeg’);
MyBMP := TBitmap.Create;
with MyBMP do
begin
Width := MyJPEG.Width;
Height := MyJPEG.Height;
Canvas.Draw(0,0,MyJPEG);
SaveToFile(cImage+’.Bmp’);
Free;
Result := True;
end;
finally
Free;
end;
end;
end;
end;
584 - Retorna a idade atual de uma
pessoa
function IdadeAtual(Nasc : TDate):
Integer;
Var AuxIdade, Meses : String;
MesesFloat : Real;
IdadeInc, IdadeReal : Integer;
begin
AuxIdade := Format(‘%0.2f’, [(Date -
Nasc) / 365.6]);
Meses :=
FloatToStr(Frac(StrToFloat(AuxIdade)));
if AuxIdade = ‘0’ then
begin
Result := 0;
Exit;
end;
if Meses[1] = ‘-‘ then
begin
Meses := FloatToStr(StrToFloat(Meses) *
-1);
end;
Delete(Meses, 1, 2);
if Length(Meses) = 1 then
begin
Meses := Meses + ‘0’;
end;
if (Meses <> ‘0’) And (Meses <> ”) then
begin
MesesFloat := Round(((365.6 *
StrToInt(Meses)) / 100) / 30.47)
end
else
begin
MesesFloat := 0;
end;
if MesesFloat <> 12 then
begin
IdadeReal :=
Trunc(StrToFloat(AuxIdade)); // +
MesesFloat;
end
else
begin
IdadeInc := Trunc(StrToFloat(AuxIdade));
Inc(IdadeInc);
IdadeReal := IdadeInc;
end;
Result := IdadeReal;
end;
585 - Transferência de som em um
CHAT
Utilizando Clientsocket e ServerSocket chame o
método
ClientSocket.socket.sendStream(SuaVozEmStream).
Ou utilizar os componentes TNMStrm e NMStrmServ
que são específicos para o envio de Streams.
Existe um exemplo em Delphi5\Demos\FastNet\Strm
que demonstra como transferir images usando esse
componente, mas é fácil trocar a imagem por voz.
586 - Como alterar o driver de
acesso do access no bde
automaticamente
Eu fiz um procedimentozinho que funciona:
procedure ChangeAccessDLL32(Dll : String);
// Altera a Propriedade do
BDE\Drivers\Native\MSACCESS\Dll32
var
Reg : TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if
Reg.OpenKey(‘\Software\Borland\DataBase
Engine\Settings\Drivers\MSACCESS\INIT’,
True)
then Reg.WriteString(‘DLL32’,Dll);
finally
Reg.CloseKey;
Reg.Free;
end;
end;

––-> Use de preferência no OnCreate do Form ou


DataModule da seguinte
forma:
ChangeACCESSDll32(‘IDDA3532.DLL’); //
Mudando a DLL de acesso ao ACCESS
587 - Emissao de NF e boleto
Nota Fiscal (UTILIZEI O BITBTN)Ocódigo comessa
abaixo.
––––––––––––––––––––––––––––––––––––––––––
procedure TFmPedidos.btNotaClick(Sender:
TObject);
var
Valorbase:DOUBLE;
valoricms:DOUBLE;
CONTADOR:Integer;
IMPRESSORA:TextFile;

begin
{POSICIONA O PONTEIRO DA TABELA DE
CLIENTES,
EM RELAÇÃO À TABELA DE PEDIDOS}

DmDados.tbClientes.FindKey([DMDADOS.Tbpedi
dosped_Cliente.Value]);
{Relaciona a variável impressora com a
lpt1: - Poderia ser LPT, COM1,//
Servidor/impressora}
AssignFile(IMPRESSORA,‘LPT1:’);
{abre a porta da impressão }
Rewrite(IMPRESSORA);
{envia caractere de controle para
comprimir a impressão}
Write(IMPRESSORA);
{ Imprime o caractere “x” (marcando Nota
de Saída) e salta para próxima linha}
Writeln(Impressora,Format(‘%80s’,
[‘x’]));
{ salta duas linhas}
Writeln(impressora);
Writeln(Impressora);
{ Imprime a string “Vendas”, alinhado à
esquerda”-” dentro de uma área de quarenta
caracteres}
Write(Impressora,Format(‘%-40s’,
[‘Vendas’]));
{ Imprime a string “5.12”, e salta para
próxima linha}
WriteLn(Impressora,Format(‘%10s’,
[‘5.12’]));
{ Salta duas linhas}
Writeln(impressora);
Writeln(Impressora);
{ –- Impressão dos Dados do Consumidor–
—}
{ Imprime a Razão Social, alinhado à
esquerda dentro de uma área de 90
caracteres}
Write (Impressora,Format(‘%-90s’, [
dmdados.tbClientesCli_Razao.Value]));
{ Imprime a CGC, alinhado à esquerda
dentro de umaárea de 30 caracteres}
Write(Impressora,Format(‘%-30s’,
[dmdados.tbClientesCli_CGC.Value]));
{ Imprime a Data de Emissão, baseada na
data atual e salta para próxima linha}
Writeln(Impressora,DatetoStr(Date));
{ Salta uma linha}
Writeln(Impressora);
{ Imprime Endereço,alinhado à
esquerda”-” dentro de uma área de 70
carcateres}
Write(Impressora,Format(‘%-70s’,
[dmdados.tbClientesCli_Endereco.Value]));
{Imprime Bairro, dentro de uma área de
35 carcateres}
Write(Impressora,Format(‘%-35s’,
[dmdados.tbClientesCli_Bairro.Value]));
{ Imprime CEP, dentro de uma área de 15
carcateres}
Write(Impressora,Format(‘%-15s’,
[dmdados.tbClientesCli_CEP.Value]));
{Imprime a Data de Saída, baseada na
Hora Atual e Salta para próxima Linha}
Writeln(Impressora,DatetoStr(Date));
{ Salta uma linha}
Writeln(Impressora);
{ Imprime Munícipio, dentro de uma área
de 60 caracteres}
Write(Impressora, Format(‘%-60s’,
[dmdados.tbClientesCli_Cidade.Value]));
{ Imprime DD+Telefone, dentro de uma
área de 30 caracteres}
Write(Impressora,Format(‘%-30s’,
[dmdados.tbClientesCli_DDD.Value+’ ‘+
dmdados.tbClientesCli_Fone1.Value]));
{ Imprime Estado (UF), dentro de uma
área de 5 caracteres}
Write(Impressora,Format(‘%-5s’,
[dmdados.tbClientesCli_Estado.Value]));
{ Imprime Inscrição Estadual, dentro de
uma área de 25 caracteres}
Write(Impressora,Format(‘%-25s’,
[dmdados.tbClientesCli_Inscricao.value]));
{ Imprime a Hora de Saída, baseada na
Hora Atual e Salta para próxima Linha}
Writeln(Impressora,TimetoStr(time));
{ Salta três linhas}
Writeln(Impressora);
Writeln(Impressora);
Writeln(Impressora);
{–— Fase de Emissão dos Itens da Nota –
—}
{ Zero variáveis}
Valorbase:=0;
valoricms:=0;
{ Move o ponteiro de registro da tabela
de Itens para o primeiro}
Dmdados.TbItens.First;
{ Início do Laço}
While not (Dmdados.tbItens.Eof) do
Begin
{ Imprime Código produto}
Write(Impressora,Format(‘%-15s’,
[InttoStr(Dmdados.tbItensIT_Produto.Value)
]));
{ Imprime Descrição do produto}
Write(Impressora,Format(‘%-68s’,
[dmdados.TbitensProdutos.value]));
{ Imprime Quantidade Comercializada}
Write(Impressora,Format(‘%12.2n’,
[Dmdados.tbItensIt_Quantidade.value]));
{ Imprime Preço Unitário produto}
Write(Impressora,Format(‘%15.2m’,
[dmdados.tbitensit_valor.value]));
{ Imprime o valor Total do Item e salta
uma linha}
Writeln(Impressora,Format(‘&15.2f’,
[dmdados.tbItensValorItem.Value]));
{ Soma o valor Base de Cálculo do ICMS}
Valorbase:=ValorBase +
dmdados.tbItensValorItem.Value;
{ Próximo Item}
Dmdados.Tbitens.next;
end;
{ laço de Itens}
{ Salta o núemro de linhas necessárias
para completar o espaço restante de itens}
For Contador:= 1 to (20-
dmdados.tbItens.recordCount)do
Writeln(Impressora);
{ Salta duas Linhas}
Writeln(Impressora);
Writeln(Impressora);
{ Imprime o valor total dos produtos e
salta uma linha}
Writeln(Impressora,Format(‘%120.2f’,
[ValorBase]));
{ Salta duas linhas}
Writeln(Impressora);
Writeln(Impressora);
{ Cálculo do Imposto - baseada na
Alíquota de 12%}
valoricms:=(Valorbase*0.12);
{ Imprime Valor base}

Write(Impressora,Format(‘%30.2f’,
[Valorbase]));
{ Imprime Valor ICMS e salta ‘p/ próxima
linha}
Write(Impressora, Format(‘%30.2f’,[
ValorICMS]));
{ Salta uma linha}
Writeln(Impressora);
{ Imprime o valor total da Nota e salta
uma linha}
Writeln(Impressora,Format(‘%120.2f’,
[Valorbase]));
{ Salta duas linhas}
Writeln(Impressora);
Writeln(Impressora);
{ Imprime informações transportador}
Writeln(Impressora,Format(‘%-30s’, [‘o
mesmo’]));
{ salta tr6es Linhas}
Writeln(Impressora);
Writeln(Impressora);
Writeln(Impressora);
{ Fecha a porta de impressão}
System.Close(Impressora);
end; { final da procedure}
BOLETA BANCARIA

procedure TFmGerRec.BtBoletaClick(Sender:
TObject);
Var
Impressora:TextFile;

begin
AssignFile(Impressora,‘LPT1:’);
Rewrite(Impressora);
Writeln(impressora);
//Imprime Local de pagamento
Write(impressora,Format(‘%-50s’,[‘
(PAGAVEL EM QUALQUER BANCO ATE O
VENCIMENTO)’]));
//Imprime Data Vencto e pula para próxima
linha
Writeln (impressora,Format(‘%-20s’,
[”+DatetoStr(DmDados.TbcontasRecRec_DataVe
ncto.Value)]));
//pula três linhas
Writeln(Impressora);
Writeln(impressora);
Writeln(impressora);

//Imprime Data de Emissão e Número


Documento e salta duas linhas

Writeln(impressora,Format(‘%-50s’,
[”+DatetoStr(DmDados.TbcontasRecRec_DataEm
issao.Value)]));
Writeln(impressora,Format(‘%-52s’,
[”+InttoStr(DmDados.TbcontasRecRec_Numero.
Value)]));

Writeln(impressora);
//Imprime valor do Documento e pula p/
Próxima linha

Write(impressora, Format(‘%-55s’,[ ‘
‘]));
Writeln(impressora, Format(‘%-8.2m’,
[DmDados.TbContasRecRec_Valor.Value]));

//Pula duas linhas


Writeln(impressora);
Writeln(impressora);

//Imprime informações de Responsabilidade


do Cedente

Writeln(impressora, Format(‘%-50s’,[‘
Neste Espaco Voce pode imprimir o
Texto’]));
Writeln(impressora, Format(‘%-50s’,[‘ De
Responsabilidade do Cedente, comum em
‘]));
Writeln(impressora, Format(‘%-50s’,[‘
Diversos Bancos,Ex: ‘]));
Writeln(impressora, Format(‘%-50s’,[‘ -
Cobrar Juros de 10%/Mes Apos
Vencimento’]));

// Pula duas Linhas

WriteLn(impressora);
Writeln(impressora);

//imprime informações do Sacado

Writeln(impressora, Format(‘%-50s’,
[”+DmDados.TbcontasRecRazao.Value+’-
CGC/CPF’+Dmdados.TbContasRecCgc.Value]));
Writeln(impressora, Format(‘%-50s’,
[”+DmDados.TbContasRecEndereco.Value]));
Writeln(impressora, Format(‘%-50s’,[‘
CEP’+DmDados.TbContasRecCEP.Value+”+Dmdado
s.TbContasRecCidade.Value+”+
Dmdados.TbContasRecEstado.Value]));

//Pula três linhas


Writeln(impressora);
Writeln(impressora);
Writeln(impressora);
CloseFile(impressora);
end;
588 - Gerando um arquivo HTML
AssignFile(Arq, ‘nomearq.html’);
Rewrite(Arq);
Writeln(Arq, ‘<html>’);
Writeln(Arq, ‘<head>’);
Writeln(Arq, ‘<title>SAAE S&atilde;o
Leopoldo - RS</title>’);
Writeln(Arq, ‘</head>’);
Writeln(Arq, ‘<body bgcolor=”#ffffff”
text=”#0000A0”>’);
Writeln(Arq, ‘<div align=“center”>’);
Writeln(Arq, ‘<table border=0
width=“100%”>’);
Writeln(Arq, ‘<tr><td colspan=“4”
align=“center” bgcolor=”#0080FF”>’);
Writeln(Arq, ‘<font size=3 face=“verdana”
color=”#ffffff”>’);
Writeln(Arq, ‘<b>Lancamento de
Conv&ecirc;nio</b><br></font></td></tr>’);
Writeln(Arq, ‘<tr><td colspan=“4”
align=“center”>’);
Writeln(Arq, ‘</font></td></tr></table>
</div></body></html>’);
CloseFile(Arq);
589 - Cuidado quando gravar
arquivos binarios
Quando gravar em arquivos binários deve evitar o uso
em seus records de longStrings pois, por default, uma
longstring é uma string “sem fim” . Se vc tentar gravar
em um arquivo binário ele irá truncá-la(ou seja, vai
cortar uma parte da string) e vc poderá perder dados. Ao
invés disso, use shorstrings para arquivos binários…
590 - Cuidados quando criar
procedimentos e funções com
parametros
Quando criamos procedimentos e funções podemos
introduzir parâmetros com valores defaultdevemos
porém respeitar algumas regras:
Esse parâmetros precisam ocorrer no final da lista;
precisam ser constantes
Não pode fazer por referência(var alguma coisa)
Respeitando essas regras o delphi permite criar sem
problemas funções ou procedimentos do tipo:
function Resizer(X: Real; Y: Real = 2.0):
Real;
procedimento Multiplicar(var
X:Real;X:Real=1;Resposta:Real=0);
etc…
Se vc chamar “resizer” sem os parâmetros o delphi
considera que vc quer usar os valores default da
função….
Tenha MUITA ATENÇÃO PORÉM com funções ou
procedimentos que forma declarados em overload ou
“sobrecarga” que permite que dois ou mais
procedimentos ou funções tenham nomes iguais desde
que tenham parâmetros diferentes.Isso criaria
problemas na lógica do compilador….Pense, O que
difere um procediemnto do tipo:
1)procedure teste(A:integer);overload
2)procedure teste(A:integer=0);overload;
Se vc chamar teste(x) o compilador não sabe se vc está
querendo chamar o procedimento 1 ou 2…
591 - Como atribuir um valor inicial
para uma variável global
No Delphi, pode-se atribuir um valor inicial para uma
variável global enquanto a declara. É possível escrever,
por exemplo:
var
Value: Integer = 10;
Correct: Boolean = True;
Esta técnica de inicialização funciona apenas para
variáveis globais, não para variáveis declaradas no
escopo de um procedimento ou método.
592 - Como criar um form completo
com botões dinamicamente
Você pode criar qualquer componente do delphi de
forma dinãmica, incluindo todos os componentes
visuais(buttons, textedits, maskedits, labels). Para que
serviria isso? Para muitas coisas, uma delas é que vocÊ
pode criar qualquer controle em tempo de execução e
depois de utiliza-lo descarrega-lo da memória…
Exemplo:Como Criar um botão quando o mouse for
pressionado e associar eventos nele….
É só colar dentro da unit da form….
=========inicio do copia e cola==========
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
contador:integer;
implementation

{$R *.DFM}
uses stdctrls;
procedure TForm1.FormMouseDown(Sender:
TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var b:tbutton;
begin
b:=Tbutton.create(self);
b.visible:=false;
b.parent:=self;
b.left:=x;
b.top:=y;
b.name:=‘Btn’+inttostr(contador);
b.Caption:=‘Clique-me’;
inc(contador);
b.visible:=true;

end;

procedure TForm1.FormCreate(Sender:
TObject);
begin
contador:=1;
end;

end.
============fim do copia e cola==========
Se quiser associar um evento ao botao é só copiar os
procedimento clicou e alterar
o procedmento mouse down para o que segue….
=======inicio do copia e cola
procedure TForm1.FormMouseDown(Sender:
TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var b:tbutton;
begin
b:=Tbutton.create(self);
b.visible:=false;
b.parent:=self;
b.left:=x;
b.top:=y;
b.name:=‘Btn’+inttostr(contador);
b.Caption:=‘Clique-me’;
inc(contador);
b.visible:=true;
b.onclick:=clicou;
end;

procedure TForm1.clicou(sender: TObject);


begin
ShowMessage(‘Clicou!!!’);
end;

=====fim do copia e cola======


Com isto concluimos que podemos criar qualquer coisa
em tempo de execução com economia de memória.
BAsta para isso dar o create da classe….
Para apagar o botao devemos ter cuidado para não
apagar dentro do evento visto que
gerara uma exceção. Existe duas formas de se
contornar isto, a primeira é fornecendo um atraso
e a segunda é atraves de uma API do windows mas isto
fica para os proximos e-mails…
Um abraço…
Israel Calheiros
593 - Problemas Delphi X
Impressora Xerox
Eu já ouvi falar que a própria Xerox já afirmou esta
imcompatibilidade entre seu driver e o quickreport.
No meu caso, temos uma impressora Xerox N32PCL e
para que não dê problema utilizo o driver da HP
LaserJet 5MP. Utilizando este driver a impressão sai
sem problemas na impressora Xerox.
Assim, tenho em meu computador instalado duas
impressoras (que na realidade são as mesmas). Uma
utilizando o driver da HP LaseJet 5MP (para ser utilizada
com o Delfi quando a aplicação contém relatórios com o
QuickReport) e outra utilizando o próprio drive da Xerox.
594 - Sublinhando no Canvas
printer.Canvas.Font.Style:=[FsUnderline]
595 - Como fazer para largura do
display do campo de um dbgrid fique
igual ao seu próprio tamanho na
tabela
procedure TForm1.btnTestClick(Sender:
TObject);
var i: integer;
begin
for i:= 0 to Table1.FieldCount-1 do
Table1.Fields[i].DisplayWidth:=
Length(Table1.Fields[i].DisplayLabel);
end;
596 - Exemplo de como pegar o
nome de um objeto ou janela
Faça um teste com isso. Coloque um Timer, umLabel,
dois Edit e um Button.
No OnTimer coloque:
var
p: TPoint;
i: THandle;
begin
GetCursorPos ( p );
i := WindowFromPoint ( p );
Label1.caption := intToStr ( i );
end;

No OnClick do botão coloque

var
i, x: integer;
s: array [ 0..2047 ] of char;
begin
i := strToInt ( Edit1.text );
GetWindowText ( i, s, x );
Edit2.text := s;
end;

Para isso, crie um formulário pequeno e deixe-o em uma


região discreta e passe o mouse sobre os
“componentes” da calculadora. Vc verá o caption do
label se modificar com o Handle do window sob o
mouse. Para obter o texto, use esse handle no primeiro
edit 1 clique no Botão para pegar o texto e trazê-lo para
o edit2.
597 - Instalando os componentes
RXLIB 2.40 no Delphi 3
- Execute o arquivo RxInst.exe
- Instale normalmente, deixe ele criar o diretorio padrão
dele.
- Depois de instalado, execute o delphi.
- Agora no Delphi, vá no menu FILE, e clique em OPEN.
- La em Tipos de Arquivos, peça para ele listar arquivos
do tipo *.DPK (Delphi Package Source).
- Agora indique o diretório que foi instalado os
componentes, provavelmente ele instalo dentro do
\delphi3\RX
No meu caso, eu tenho o delphi3 instalado no seguinte
diretório:
C:\APL\NORMAIS\DELPHI3-CS\DELPHI 3
Os componente foram instalados em
C:\APL\NORMAIS\DELPHI3-CS\DELPHI 3\RX
Então, você veja exatamente onde foi que ele instalo os
componentes, caso tenha dúvida, procure pelo arquivo
RXCTL.DPK e onde ele tiver, é onde esta instalado os
componentes.
Bom, então depois que você souber onde ele instalou os
componentes, indique o diretório que o RX esta
instalado, e pessa p/ ele abrir o arquivo RXCTL.DPK e
clique em OK.
Assim que você abrir o arquivo, ira aprecer uma janela,
e nessa janela tera um botão chamado OPTIONS, clique
nele.
Agora você vera várias ORELHAS (ABAS) la no topo,
clique na “ABA” GLOBAL.
Agora nessa aba, você vera uma parte onde está escrito
DPL OUTPUT DIRECTORY e ao lado dela, voce vera
um ComboBox, ponha o seguinte diretório dentro dele:
C:\WINDOWS\SYSTEM
Agora Clique em OK
Apos ter clicado em OK, você automaticamente voltará
para uma outra janela, e nessa janela tera um Botão
chamado Compile, clique nele.
Quando você clicar no COMPILE, ele ira ler o HD e você
ira perceber que nada ira acontecer, então, assim que
você perceber que ele ja compilou, feche essa janela.
Ele ira perguntar se deseja salvar, ponha SIM
Agora va novamente la no menu FILE, OPEN, e
novamente pessa para ele listar apenas arquivos *.DPK
e abra o arquivo RXDB.DPK e clique em OK
Assim que você abrir o arquivo , ira aprecer uma janela,
e nessa janela tera um botão chamado OPTIONS, clique
nele.
Agora voce vera varias ORELHAS (ABAS) la no topo,
clique na “ABA” GLOBAL.
Agora nessa aba, você verá uma parte onde está escrito
DPL OUTPUT DIRECTORY e ao lado dela, você vera
um ComboBox, ponha o seguinte diretório dentro dele:
C:\WINDOWS\SYSTEM
Agora Clique em OK
Apos ter clicado em OK, você automaticamente voltará
p/ uma outra janela, e nessa janela tera um Botão
chamado COMPILE , clique nele, e assim que terminar
de compilar, feche essa janela.
Ele ira perguntar se deseja salvar, ponha SIM
Va novamente no menu FILE, OPEN, pessa para listar
arquivos *.DPK, e pessa p/ abrir o arquivo
RXTOOLS.DPK, e clique em OK
Assim que você abrir o arquivo, ira aprecer uma janela,
e nessa janela tera um botão chamado OPTIONS, clique
nele.
Agora você vera varias ORELHAS (ABAS) la no topo,
clique na “ABA” GLOBAL.
Agora nessa aba, você vera uma parte onde está escrito
DPL OUTPUT DIRECTORY e ao lado dela, você vera
um ComboBox, ponha o seguinte diretório dentro dele:
C:\WINDOWS\SYSTEM
Agora Clique em OK
Apos ter clicado em OK, você automaticamente voltará
para uma outra janela, e nessa janela tera um Botão
chamado COMPILE, clique nele e assim, que terminar
de compilar, feche essa janela.
Ele ira perguntar se deseja salvar, ponha SIM

–ATENÇÃO ESSA PARTE AGORA PARECE SER


IGUAL A DE CIMA, MAS NÃO É–

15 - Agora va novamente no menu FILE, OPEN, e faça


o mesmo esquema, pessa para listar arquivos *.DPK e
pessa para abrir o arquivo DCLRXCTL.DPK e clique em
OK.
Assim que você abrir o arquivo , ira aprecer uma janela,
e nessa janela tera um botão chamado OPTIONS, clique
nele.
Agora você vera varias ORELHAS (ABAS) la no topo,
clique na “ABA” GLOBAL.
Agora nessa aba, você vera uma parte onde está escrito
DPL OUTPUT DIRECTORY e ao lado dela, você vera
um ComboBox, ponha o seguinte diretório dentro dele:
C:\WINDOWS\SYSTEM
Agora Clique em OK
Apos ter clicado em OK, você automaticamente voltará
para uma outra janela, e nessa janela tera um Botão
chamado INSTALL , só que NÃO clique em compile,
clique em INSTALL, ai ira aparecer um janela mostrando
os nomes de todos os componentes instalados, cl
Ele ira perguntar se deseja salvar, ponha SIM
Agora va denovo no menu FILE, OPEN, pessa para
listar arquivos *.DPK, e pessa para abrir o arquivo
DCLRXDB.DPK, e clique em OK.
Assim que você abrir o arquivo , ira aprecer uma janela,
e nessa janela tera um botão chamado OPTIONS, clique
nele.
Agora você vera várias ORELHAS (ABAS) la no topo,
clique na “ABA” GLOBAL.
Agora nessa aba, você vera uma parte onde está escrito
DPL OUTPUT DIRECTORY e ao lado dela, você vera
um ComboBox, ponha o seguinte diretório dentro dele:
C:\WINDOWS\SYSTEM
Agora Clique em OK
Apos ter clicado em OK, você automaticamente voltará
para uma outra janela, e nessa janela tera um Botão
chamado INSTALL, só que NÃO clique em compile,
clique em INSTALL, ai ira aparecer um janela mostrando
os nomes de todos os componentes instalados, cli
Ele ira perguntar se deseja salvar, ponha SIM
Va novamente no menu FILE, OPEN, e pessa para listar
arquivos *.DPK e pessa para abrir o arquivo
DCLRXTLS.DPK , e clique em OK.
Assim que você abrir o arquivo , ira aprecer uma janela,
e nessa janela tera um botão chamado OPTIONS, clique
nele.
Agora você vera várias ORELHAS (ABAS) la no topo,
clique na “ABA” GLOBAL.
Agora nessa aba, você vera uma parte onde está escrito
DPL OUTPUT DIRECTORY e ao lado dela, você vera
um ComboBox, ponha o seguinte diretório dentro dele:
C:\WINDOWS\SYSTEM
Agora Clique em OK
Apos ter clicado em OK, você automaticamente voltará
para uma outra janela, e nessa janela tera um Botão
chamado INSTALL, só que NÃO clique em compile,
clique em INSTALL, ai ira aparecer um janela mostrando
os nomes de todos os componentes instalados, cli
Ele ira perguntar se deseja salvar, ponha SIM
Autor da Dica
–––––––-
Eduardo
eduardo@mrsoftware.com.br
UIN 19495320
www.edudelphipage.cjb.net
EduDelphiPage
598 - Instalando os componentes
RXLIB 2.50/2.60/2.75 no Delphi 4
- Se já tiver o RXLIB instalado, desinstale tudo da
RXLIB, remova os Packages (atraves do menu
Component | Install Packages…), delete o diretório que
ele criou “RX”, deixe tudo limpo.
- Execute o arquivo RxInst.exe
- Instale normalmente
- Depois de instalado, execute o delphi.
- Atraves do Delphi, abra o arquivo RXCTL4.DPK (esta
no diretório que a RXLIB criou na hora da
instalação\units)
Agora ira abrir uma janelinha.
- Clique em COMPILE (clique 2 vezes, mas espere
compilar, depois clica + uma vez)
NÃO NÃO feche a janela.
- Agora abra o arquivo RXDB4.DPK
Agora ira aparecer mais uma janelinha, certifique-se de
que esta se refere ao arquivo aberto.
- Clique em COMPILE (clique 2 vezes, mas espere
compilar, depois clica + uma vez)
- Agora va no diretório que o RX criou na hora da
instalação(C:\Diretório do Delphi4\RX\Units) e copie os
arquivos RXCTL4.BPL , RXDB4.BPL para
C:\Windows\System, se ja existir,mande substituir.
Agora NÃO NÃO feche as janelas.
- Abra os arquivos DCLRX4.DPK e DCLRXDB4.DPK.
(Selecione os 2 juntos, mas o primeiro a ser
selecionado, deve ser o DCLRX4.DPK).
Feito isto, ira aparecer + 2 janelas.
- Veja qual janela se refere ao arquivo DCLRX4.DPK e
clique em INSTALL
- Agora veja qual janela se refere ao arquivo
DCLRXDB4.DPK e clique em INSTALL
- Feito isto, feche as 4 janelas e NÃO NÃO NÃO salve.
NA HORA QUE PEDIR PARA SALVAR, NÃO NÃO NÃO
SALVE
Agora feche o Delphi e inicie ele.
Veja se deu certo.

Autor da Dica
–––––––-
Eduardo
eduardo@mrsoftware.com.br
UIN 19495320
http://users.sti.com.br/sartel
EduDelphiPage
599 - Passando variáveis para o
ReportSmith
procedure TForm1.Button1Click(Sender:
TObject);
var
s: string;
begin
s:=‘CA’;
Report1.InitialValues.Add(‘@state=
<’+s+’>’);
Report1.run;
end;
600 - Adiciona a barra invertida a
um texto selecionado
function AddBarra(S: string): string;
var
Temp: string;
begin
Temp := S;
if S[Length(Temp)] <> ‘' then
Temp := Temp + ‘';
Result := Temp;
end;
601 - Como abrir um TComboBox
sem clicá-lo
ComboBox1.DroppedDown := True;
602 - Como Calcular Digito
Verificador de CNPJ e CPF
function CalculaCnpjCpf(Numero : String) :
String;
var
i,j,k, Soma, Digito : Integer;
CNPJ : Boolean;
begin
Result := Numero;
case Length(Numero) of
9:
CNPJ := False;
12:
CNPJ := True;
else
Exit;
end;
for j := 1 to 2 do
begin
k := 2;
Soma := 0;
for i := Length(Result) downto 1 do
begin
Soma := Soma + (Ord(Result[i])-
Ord(‘0’))*k;
Inc(k);
if (k > 9) and CNPJ then
k := 2;
end;
Digito := 11 - Soma mod 11;
if Digito >= 10 then
Digito := 0;
Result := Result + Chr(Digito +
Ord(‘0’));
end;
end;
Observação feita por um dos Usuários da DTDelphi
sobre a dica acima:

Na realidade, é uma correção da dica: Como calcular digito verificador de


Cnpj e CPF
Faltou um detalhe para calcular corretamente (que está destacado em
maícula).
Também alterei o seguinte:
Ao invés de retornar o digito, retorna true ou false;
Retira caracteres que não sejam números.

function CalculaCnpjCpf(Numero : String) : Boolean;


Var
i,d,b,
Digito : Byte;
Soma : Integer;
CNPJ : Boolean;
DgPass,
DgCalc : String;
begin
Result := False;
Numero := ApenasNumerosStr(Numero);
// Caso o número não seja 11 (CPF) ou 14 (CNPJ),
aborta
Case Length(Numero) of
11: CNPJ := False;
14: CNPJ := True;
else Exit;
end;
// Separa o número do digito
DgCalc := ”;
DgPass := Copy(Numero,Length(Numero)-1,2);
Numero := Copy(Numero,1,Length(Numero)-2);
// Calcula o digito 1 e 2
For d := 1 to 2 do begin
B := IIF(D=1,2,3); // BYTE
SOMA := IIF(D=1,0,STRTOINTDEF(DGCALC,0)*2);
for i := Length(Numero) downto 1 do begin
Soma := Soma + (Ord(Numero[I])-Ord(‘0’))*b;
Inc(b);
If (b > 9) And CNPJ Then
b := 2;
end;
Digito := 11 - Soma mod 11;
If Digito >= 10 then
Digito := 0;
DgCalc := DgCalc + Chr(Digito + Ord(‘0’));
end;
Result := DgCalc = DgPass;
end;

function ApenasNumerosStr(pStr:String): String;


Var
I: Integer;
begin
Result := ”;
For I := 1 To Length(pStr) do
If pStr[I] In
[‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘0’] Then
Result := Result + pStr[I];
end;

function IIf(pCond:Boolean;pTrue,pFalse:Variant):
Variant;
begin
If pCond Then Result := pTrue
else Result := pFalse;
end;

{Ass:Jefferson Bompadre}
604 - Desenhando texto 3D no
form com Canvas
Antes vc deve declarar esa procedure na seção private
procedure TForm1.imgPaintCanvas(TheCanvas
: TCanvas; TheString : String;
TheFontSize, UCorner, LCorner :
Integer);
Begin
TheCanvas.Brush.Style := bsClear;
TheCanvas.Font.Style := [fsBold];
TheCanvas.Font.Name := ‘MS Sans Serif’;
TheCanvas.Font.Size := TheFontSize;
TheCanvas.Font.Color := clBlack;
TheCanvas.TextOut(UCorner, LCorner,
TheString);
TheCanvas.Font.Color := clGray;
TheCanvas.TextOut(UCorner - 1, LCorner -
1, TheString);
TheCanvas.Font.Color := clSilver;
TheCanvas.TextOut(UCorner - 2, LCorner -
2, TheString);
TheCanvas.Font.Color := clBlack;
TheCanvas.TextOut(UCorner - 3, LCorner -
3, TheString);
End;

Exemplo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
imgPaintCanvas(Form1.Canvas,
‘WWW.LLOYDSOFT.HPG.COM.BR’, 10, 6, 4);
end;
605 - Como saber há quanto tempo
o WINDOWS foi inicializado?
Use a função GetTickCount da API do Windows. Ela
retorna o intervalo em milisegundos.
Obs.: Esta função é útil quando se quer determinar o
intervalo de tempo decorrido durante uma ação de um
aplicativo.
Ex.:
var
TempoInicial, TempoFinal, Intervalo:
Integer
begin
TempoInicial := GetTickCount;

// código a ser executado

TempoFinal := GetTickCount;
Intervalo := TempoFinal - TempoInicial;
end.
606 - Como alterar o tamanho do
papel na impressão?
Esta dica refere-se à utilização do objeto TQRPrinter.
Use a propriedade PaperSize.
Ex.
// não se esqueça de colocar QRPrntr na
cláusula uses de sua unit.
var
PrintTeste: TQRPrinter;
begin
PrintTeste := TQRPrinter.Create;
PrintTeste.PaperSize := A4; {os
parâmetros podem ser A5, B5, Letter e
outros}
end;
607 - Como filtrar registros de
uma tabela pelo mês de um campo
data
Você pode usar a função DecodeDate( ) no evento
onFilterRecord de um componente TTable.
Ex.:
// não se esqueça de mudar a propriedade
Filtered para True;
// isto fará com que o evento
onFilterRecord seja disparado.
procedure
TForm1.Table1FilterRecord(DataSet:
TDataSet; var Accept: Boolean);
var
Dia, Mes, Ano: word;
begin
Accept := false;

DecodeDate(Table1[‘Competencia’],Ano,Mes,D
ia);
if Mes=MesFiltrado then
Accept := True;
end;
Obs.: Você pode usar este mesmo código para filtrar por
Ano ou por Dia, basta utilizar a comparação adequada
no bloco if … then
608 - Otimizações SQL
As dicas abaixo foram testadas essencialmente com
Oracle
1) Todas as vezes que for utilizar um SQL que
possua condições de OR, é mais aconselhável e
mais rápido utilizar IN, como no exemplo:
AO INVÉS DE
Select * from projint where sit_projint = ‘AI’ or sit_projint
= ‘EL’
COLOQUE
Select * from projint where sit_projint IN (‘AI’,‘EL’);
2) Quando existem duas ou mais condições AND
juntas, especifique primeiro sempre a que possui o
maior limite de ocorrências
AO INVÉS DE
select count(*) from pessoa where sit_pessoa = 11
AND cod_munic > 1100155
COLOQUE
select count(*) from pessoa where cod_munic >
1100155 AND sit_pessoa = 11
3) Quando existem duas ou mais condições OR
juntas, especifique primeiro sempre a que possui o
maior limite de ocorrências
AO INVÉS DE
select count(*) from pessoa where cod_munic >
1100155 OR sit_pessoa = 11
COLOQUE
select count(*) from pessoa where sit_pessoa = 11 OR
cod_munic > 1100155
4) Tenha cuidado com o sinal de <>
AO INVÉS DE
select count(*) from pessoawhere cod_munic < >
1100155
COLOQUE
select count(*) from pessoawhere cod_munic <
1100155 OR cod_munic > 1100155
609 - Excluindo registros de uma
tabela
Desejo excluir registro de uma tabela que dependem da
existência de outros de outra(s) tabela(s), como fazer?
DELETE FROM <tabela1>
WHERE (<campo1>, <campo2>,<campo3>)
IN
(SELECT <campo1>, <campo2>,<campo3>
FROM <tabela1> a, <tabela2> b
WHERE a.<campo1> = b.<campo1>
AND b.<campo4> = ‘AP’ )
colaboração: Renato Costa Pereira - Brasília-DF
610 - Selecionando registros de
uma tabela que não existam em
outra tabela
(SELECT * FROM <tabela1>, <tabela2>
WHERE <tabela1>.<campo1> = <tabela2>.<campo1>
AND <tabela2>.<campo2> = ‘AP’
MINUS
(SELECT * FROM <tabela1>@remoto1,
<tabela2>@remoto1
WHERE <tabela1>@remoto1.<campo1> =
<tabela2>@remoto1.<campo1>
AND <tabela2>@remoto1.<campo2> = ‘AP’

obs: todos os campos retornados no SELECT


secundário deverá conter os mesmos campos do
SELECT primário

colaboração: Renato Costa Pereira - Brasília-DF


611 - Uso da cláusula HAVING
Quando usamos a clausula GROUP BY temos por
vezes a tendencia em usar o HAVING para
especificar uma condicao simples como
especificado abaixo:
SELECT
META_GB.COD_PROJINT,
META_GB.COD_METPADRAO,
METAPADRAO.DES_METPADRAO,
METAPADRAO.COD_UNIDMED,
UNIDMED.SIG_UNIDMED
FROM
META_GB,
METAPADRAO,
UNIDMED
WHERE
( META_GB.COD_METPADRAO =
METAPADRAO.COD_METPADRAO ) and
(METAPADRAO.COD_UNIDMED =
UNIDMED.COD_UNIDMED)
GROUP BY
META_GB.COD_PROJINT,
META_GB.COD_METPADRAO,
METAPADRAO.DES_METPADRAO,
METAPADRAO.COD_UNIDMED,
UNIDMED.SIG_UNIDMED
HAVING ( META_GB.COD_PROJINT = :Param1 )
ao inves de usar a clausula having para condicionar
coloque esta condicao na clausula WHERE como
especificado abaixo

SELECT
META_GB.COD_PROJINT,
META_GB.COD_METPADRAO,
METAPADRAO.DES_METPADRAO,
METAPADRAO.COD_UNIDMED,
UNIDMED.SIG_UNIDMED
FROM
META_GB,
METAPADRAO,
UNIDMED
WHERE
( META_GB.COD_METPADRAO =
METAPADRAO.COD_METPADRAO ) and
(METAPADRAO.COD_UNIDMED =
UNIDMED.COD_UNIDMED) and
( META_GB.COD_PROJINT = :Param1 )
GROUP BY
META_GB.COD_PROJINT,
META_GB.COD_METPADRAO,
METAPADRAO.DES_METPADRAO,
METAPADRAO.COD_UNIDMED,
UNIDMED.SIG_UNIDMED

obs: caso a condicionante seja de grupo esta tem


que ficar obrigatoriamente na clausula HAVING
612 - Bloco PL/SQL para inserção
de dados
Pergunta
Criar um bloco pl/sql que insira um novo dep na tabela
s_dept
- use a sequencia s_dept_id para o campo id da tabela
- solicite ao usuario o nome do dep
- insira valores nulos p/ o campo region_id
Resposta
-> no banco de dados…
create or replace
procedure insere_departamento (v_nome
char) is
v_id number;
begin
SELECT sequenciaID.NEXTVAL INTO v_id
FROM DUAL;
insert into tabela (id,dep,region_id)
values (v_id,v_nome,null);
end insere_departamento;

-> no delphi…

- coloque o objeto TStoredProc dentro do formulario que


ira disparar esta procedure;
- no evento que voce quiser que dispare coloque o
seguinte codigo:
var
v_nome : String[50];
begin
{caso vc queira informar o nome do
departamento atraves de uma caixa de
dialogo}
V_nome := inputbox(‘Informe o nome do
departamento.’,‘Depto:’,”);
<ObjetoTStoredProc>.Params[0].AsString
:= v_nome;
{caso vc queira buscar o nome atraves de
um TEdit já preenchido}
<ObjetoTStoredProc>.Params[0].AsString
:= <NomeDoTEdit>.Text;
<ObjetoTStoredProc>.ExecProc;
end;
613 - Como selecionar um item de
um listbox
ListBox1.Selected [ índice ] := true;
614 - Executa uma Url a partir do
Netscape mesmo que ele não seje o
Browser padrão
procedure NetscapeGotoURL( sURL : string
);
// ex:
NetscapeGotoURL(‘http://www.lloydsoft.hpg.
ig.com.br/’ );
// requer a unit DDEman na clausula Uses
var
dde : TDDEClientConv;
begin
dde := TDDEClientConv.Create( nil );
with dde do
begin
ServiceApplication :=‘C:… etscape.exe’;
SetLink( ‘Netscape’, ‘WWW_Activate’ );
RequestData(‘0xFFFFFFFF’);
SetLink( ‘Netscape’, ‘WWW_OpenURL’ );
RequestData(sURL+’,,0xFFFFFFFF,0x3,,,’ );
CloseLink;
end;
dde.Free;
end;
615 - Retorna a hora da criação de
um diretório
function DirectoryTime(aDir: String):
String;
var
srFile: TSearchRec;
begin
if
FindFirst(‘C:WINDOWS’,faDirectory,srFile)=
0 then
begin
result :=
TimeToStr(FileDateToDateTime(srFile.Time))
;
end;
end;
616 - Como fazer para que o
ComboBox abra na direcao desejada
SendMessage(ComboBox1.Handle,CB_SHOWDROPDO
WN,1,0);
617 - função captura a tela e
salva-a em um Bitmap
//Use-a assim:
//Image1.picture.Assign(CaptureScreenRect(
Rect(0,0,Width,Height)));
function CaptureScreenRect( ARect: TRect
): TBitmap;
var
ScreenDC: HDC;
begin
Result := TBitmap.Create;
with Result, ARect do
begin
Width := Right - Left;
Height := Bottom - Top;
ScreenDC := GetDC( 0 );
try
BitBlt( Canvas.Handle, 0, 0, Width,
Height, ScreenDC, Left, Top, SRCCOPY );
finally
ReleaseDC( 0, ScreenDC );
end;
// Palette := GetSystemPalette;
end;
end;
618 - Copia ou move arquivos
usando a API do Windows
function ProcessArquivo(const Origem,
Destino : string; Operacao, Modo:Integer)
: Boolean;
// Requer a unit ShellApi na clausula
uses da unit
Const
Aborted : Boolean = False;
var
shfo : TSHFileOpStruct;
begin
FillChar(shfo,SizeOf(shfo),$0);
with shfo do
begin
if Operacao > 2 then
begin
operacao := 2;
end;
if Modo > 5 then
begin
modo := 1;
end;
case operacao of
1: wFunc := FO_MOVE;
2: wFunc := FO_COPY;
end;
pFrom := Pchar(Origem);
pTo := Pchar(Destino);
case Modo of
1: fFlags := FOF_SILENT;
2: fFlags := FOF_ALLOWUNDO or
FOF_FILESONLY;
3: fFlags := FOF_RENAMEONCOLLISION;
4: fFlags := FOF_NOCONFIRMATION;
5: fFlags := FOF_SIMPLEPROGRESS;
end;
end;
Result := (SHFileOperation(shfo)= 0) and
(not Aborted);
end;
619 - converte o equivalente
decimal para horas
function DecimalHoras( cValor : real):
real;
// converte o equivalente decimal p/ horas
// antes de fazer qualquer operação
aritimética.
// aproveite apenas a parte Decimal
begin
result := (1000 + (cValor/1.666666));
end;
620 - Retorna um Stringlist com
todas as informações da tabela
Procedure GetTTableProp(hTmpCur: hDbiCur;
CurList: TStrings);
// Coloque um Componente TTable no form e
defina a propriedade
// Active para True
var
Prop : CURProps;
begin
Check(DbiGetCursorProps(hTmpCur, Prop));
with CurList do
begin
Add(‘Table Name: ‘ + Prop.szName);
Add(‘Table Type: ‘ + Prop.szTableType);
Add(‘Fields: ‘ + IntToStr(Prop.iFields));
Add(‘Record Buffer Size: ‘ +
IntToStr(Prop.iRecBufSize));
Add(‘Indexes: ‘ +
IntToStr(Prop.iIndexes));
Add(‘Validity Checks: ‘ +
IntToStr(Prop.iValChecks));
Add(‘Referential Integ Checks: ‘
+IntToStr(Prop.iRefIntChecks));
Add(‘Table Level: ‘ +
IntToStr(Prop.iTblLevel));
Add(‘Language Driver: ‘ +
Prop.szLangDriver);
end;
end;
621 - Bloqueia uma Tabela paradox
procedure LockPDOXTable(TableName,Password
: String);
// Requer a DBIProcs na clausula uses da
unit
var
TblDesc: CRTblDesc;
LocDB : TDatabase;
begin
Check(DBIInit(nil));
Randomize;
LocDB := TDatabase.Create(nil);
with LocDB do begin
Params.Add(‘path=’ +
ExtractFilePath(TableName));
DatabaseName := ‘PDOXEncryptDB’ +
IntToStr(Random(50));
DriverName := ‘STANDARD’;
Connected := True;
end;
FillChar(TblDesc, SizeOf(CRTblDesc), 0);
StrPCopy(TblDesc.szTblName,
ExtractFileName(TableName));
with TblDesc do begin
bProtected := True;
StrPCopy(TblDesc.szPassword, Password);
end;
try
Check(DbiDoRestructure(LocDB.Handle, 1,
@TblDesc,nil, nil, nil, False));
finally
LocDB.Free;
DBIExit;
end;
end;
622 - Testa se a tabela esta
bloqueada ou nao
Function LockTable(Tb: TTable; Vezes:
Integer): Boolean;
// Requer DBIprocs, DB, DBTables]
// declarados na clausula Uses da unit
var
FlagLock : Boolean;
Abandonou : Boolean;
Sempre : Boolean;
Ind : Integer;
Quant : Integer;
Temp : String;
NomeArq : String;
Mensagem : String;
begin
Sempre := (Vezes = 0);
FlagLock := True;
Abandonou := False;
Quant := 0;
NomeArq := ”;
Temp := Tb.TableName;
Ind := 1;
while Ind <= Length(Temp) do
begin
if Copy(Temp,Ind,1) = ‘.’ then
begin
Ind := Length(Temp);
end
else
begin
NomeArq := NomeArq + Copy(Temp,Ind,1);
end;
Ind := Ind + 1;
end;
NomeArq := UpperCase(NomeArq);
Mensagem := ‘O arquivo ”’+NomeArq+’” está
sendo usado por outro usuário da
rede.’+#13;
Mensagem := Mensagem + ‘Deseja continuar
tentando acessar este arquivo ?’;
while FlagLock do
begin
try
Tb.LockTable(ltWriteLock);
FlagLock := False;
except
if (Quant > Vezes) and not Sempre then
begin
if MessageBox(GetActiveWindow,
Pchar(Mensagem),‘Confirmação’,
MB_ICONQUESTION+MB_YESNO+MB_HELP) = idYes
then
begin
Quant := 0;
end
else
begin
FlagLock := False;
Abandonou := True;
end;
end;
end;
Quant := Quant + 1;
end;
Result := not Abandonou;
end;
623 - Retorna o IP de sua máquina
no momento em que você está
conectado
function GetIP:string;
//—> Declare a Winsock na clausula uses da
unit
var
WSAData: TWSAData;
HostEnt: PHostEnt;
Name:string;
begin
WSAStartup(2, WSAData);
SetLength(Name, 255);
Gethostname(PChar(Name), 255);
SetLength(Name, StrLen(PChar(Name)));
HostEnt := gethostbyname(PChar(Name));
with HostEnt^ do
begin
Result := Format(‘%d.%d.%d.%d’,
[Byte(h_addr^[0]),Byte(h_addr^[1]),
Byte(h_addr^[2]),Byte(h_addr^[3])]);
end;
WSACleanup;
end;
624 - Remove caracteres de uma
string deixando apenas numeros
function RemoveChar(Const
Texto:String):String;
//
// Remove caracteres de uma string
deixando apenas numeros
//
var
I: integer;
S: string;
begin
S := ”;
for I := 1 To Length(Texto) Do
begin
if (Texto[I] in [‘0’..‘9’]) then
begin
S := S + Copy(Texto, I, 1);
end;
end;
result := S;
end;
625 - Transformar literal em
extenso
Function Extenso(literal: Double): string;
var
i, centena, dezena, unidade : integer;
valor, monta, extenso : string;
begin
extenso:=”;
if literal=0.00 then
result:=‘zero’
else
begin

valor:=FormatFloat(‘000000000000.00’,liter
al);
i:=1;
while i<=13 do
begin
if (Pos(valor[i],‘0123456789’)=0) then
valor[i ] := ‘0’;
if (Pos(valor[i+1],‘0123456789’)=0) then
valor[i+1] := ‘0’;
if (Pos(valor[i+2],‘0123456789’)=0) then
valor[i+2] := ‘0’;
if (i=13) then
centena:=0
else
centena := StrToInt(valor[i]);
dezena := StrToInt(valor[i+1]);
if dezena>1 then
unidade := StrToInt(valor[i+2])
else
unidade := StrToInt(copy(valor,
(i+1),2));
if (((i=13) and
(StrToFloat(copy(valor,14,2))>0.01)) and
((StrToFloat(copy(valor,1,12)))<>0.00))
then
extenso:=Trim(extenso)+’ e’;
monta:=‘duzentos trezentos
quatrocentosquinhentos seiscentos
setecentos oitocentos novecentos’;
if ((dezena+unidade)=0) then
monta:=’ cem ‘+monta
else
monta:=’ cento ‘+monta;
extenso:=Trim(extenso)+’
‘+Trim(copy(monta,((centena*12)+1),12));
if ((centena<>0) and
((dezena+unidade)>0)) then
extenso:=Trim(extenso)+’ e’;
monta:=’ vinte trinta quarenta
cincoentasessenta setenta oitenta
noventa’;
extenso:=Trim(extenso)+’
‘+Trim(copy(monta,((dezena*9)+1),9));
if ((dezena>1) and (unidade>0)) then
extenso:=Trim(extenso)+’ e’;
monta:=’ um dois tres quatro cinco seis
sete oito nove dez onze doze treze
quatorze quinze dezeseis dezesete dezoito
dezenove’;
extenso:=Trim(extenso)+’
‘+Trim(copy(monta,((unidade*9)+1),9));
if ((centena+dezena+unidade)>0) then
begin
if i=1 then
if (((centena+dezena)=0) and
(unidade<=1)) then
extenso:=Trim(extenso)+’ bilhão’
else
extenso:=Trim(extenso)+’ bilhões’;
if (i=4) then
if ((centena+dezena=0) and
(unidade<=1))then
extenso:=Trim(extenso)+’ milhão’
else
extenso:=Trim(extenso)+’ milhões’;
if i=7 then
extenso:=Trim(extenso)+’ mil’;
if ((i<10) and (StrToFloat(copy(valor,
(i+3),(13-i)))>1.00))then
extenso:=extenso+’ e’;
end;
if ((i=1) and
(StrToFloat(copy(valor,4,9))=0.00) and
((centena+unidade+dezena)<>0)) then
extenso:=Trim(extenso)+’ de’;
if ((i=4) and
(StrToFloat(copy(valor,7,6))=0.00) and
((centena+unidade+dezena)<>0)) then
extenso:=Trim(extenso)+’ de’;
if ((i=10) and
(StrToFloat(copy(valor,1,12))<>0.00)) then
if (StrToFloat(copy(valor,1,12))=1.00)
then
extenso:=Trim(extenso)+’ real’
else
extenso:=Trim(extenso)+’ reais’;
if ((i=13) and ((dezena+unidade)<>0))
then
if ((dezena+unidade)=1) then
extenso:=Trim(extenso)+’ centavo’
else
extenso:=Trim(extenso)+’ centavos’;
i:=i+3;
end;
if literal<0.00 then
extenso:=Trim(extenso)+’ negativo’;
if (literal<1.0) then
if (StrToInt(copy(valor,14,2))=1) then
extenso:=Trim(extenso)+’ de real’ // “de
real/de reais” podem ser substituidos por
campos de arquivos de parametros
else // o que dá mais flexibilidade,
caso aconteçam mais planos econômicos.
extenso:=Trim(extenso)+’ de reais’;
result:=extenso;
end;
end;
626 - Rotina para apagamento da
senha do setup
procedure TForm1.Button1Click(Sender:
TObject);
begin
asm
mov ax,2eh
out 70h,ax
mov ax,2fh
out 71h,ax
end;
end;
627 - Imprime o conteúdo de um
TRichEdit
procedure PrintRichEdit(const Caption:
string;const RichEdt: TRichEdit);
// Requer a Printers e RichEdit declaradas
na clausula uses da unit
var
Range: TFormatRange;
LastChar, MaxLen, LogX, LogY, OldMap:
Integer;
begin
FillChar(Range, SizeOf(TFormatRange), 0);
with Printer, Range do
begin
BeginDoc;
hdc := Handle;
hdcTarget := hdc;
LogX := GetDeviceCaps(Handle, LOGPIXELSX);
LogY := GetDeviceCaps(Handle, LOGPIXELSY);
if IsRectEmpty(RichEdt.PageRect) then
begin
rc.right := PageWidth * 1440 div LogX;
rc.bottom := PageHeight * 1440 div LogY;
end
else
begin
rc.left := RichEdt.PageRect.Left * 1440
div LogX;
rc.top := RichEdt.PageRect.Top * 1440 div
LogY;
rc.right := RichEdt.PageRect.Right * 1440
div LogX;
rc.bottom := RichEdt.PageRect.Bottom *
1440 div LogY;
end;
rcPage := rc;
Title := Caption;
LastChar := 0;
MaxLen := RichEdt.GetTextLen;
chrg.cpMax := -1;
OldMap := SetMapMode(hdc, MM_TEXT);
SendMessage(RichEdt.Handle,
EM_FORMATRANGE, 0, 0);
try
repeat
chrg.cpMin := LastChar;
LastChar := SendMessage(RichEdt.Handle,
EM_FORMATRANGE, 1,Longint(@Range));
if (LastChar < MaxLen) and (LastChar < -1)
then
begin
NewPage;
end;
until (LastChar = MaxLen) or (LastChar =
-1);
EndDoc;
finally
SendMessage(RichEdt.Handle,
EM_FORMATRANGE, 0, 0);
SetMapMode(hdc, OldMap);
end;
end;
end;
628 - Como saber se estou
conectado à internet
interface
uses
Windows, SysUtils, Registry, WinSock,
WinInet;

type
TConnectionType = (ctNone, ctProxy,
ctDialup);

function ConnectedToInternet :
TConnectionType;
function RasConnectionCount : Integer;

implementation

const
cERROR_BUFFER_TOO_SMALL = 603;
cRAS_MaxEntryName = 256;
cRAS_MaxDeviceName = 128;
cRAS_MaxDeviceType = 16;
type
ERasError = class(Exception);

HRASConn = DWord;
PRASConn = ^TRASConn;
TRASConn = record
dwSize: DWORD;
rasConn: HRASConn;
szEntryName: Array[0..cRAS_MaxEntryName]
Of Char;
szDeviceType :
Array[0..cRAS_MaxDeviceType] Of Char;
szDeviceName : Array
[0..cRAS_MaxDeviceName] of char;
end;

TRasEnumConnections =
function (RASConn: PrasConn; { buffer para
receber dados da conexao}
var BufSize: DWord; { tamanho em bytes do
buffer }
var Connections: DWord { numero de
conexoes escritas no buffer }
): LongInt; stdcall;

function ConnectedToInternet:
TConnectionType;
var
Reg : TRegistry;
bUseProxy : Boolean;
UseProxy : LongWord;
begin
Result := ctNone;
Reg := TRegistry.Create;
with REG do
try
try
RootKey := HKEY_CURRENT_USER;
if
OpenKey(‘\Software\Microsoft\Windows\Curre
ntVersion\Internet settings’,False) then
begin
//I just try to read it, and trap an
exception
if GetDataType(‘ProxyEnable’) = rdBinary
then
ReadBinaryData(‘ProxyEnable’, UseProxy,
SizeOf(LongWord) )
else begin
bUseProxy := ReadBool(‘ProxyEnable’);
if bUseProxy then
UseProxy := 1
else
UseProxy := 0;
end;
if (UseProxy <> 0) and (
ReadString(‘ProxyServer’) <> ” ) then
Result := ctProxy;
end;
except
//Nao conectado com proxy
end;
finally
Free;
end;

if Result = ctNone then begin


if RasConnectionCount > 0 then Result :=
ctDialup;
end;
end;

function RasConnectionCount : Integer;


var
RasDLL : HInst;
Conns : Array[1..4] of TRasConn;
RasEnums : TRasEnumConnections;
BufSize : DWord;
NumConns : DWord;
RasResult : Longint;
begin
Result := 0;

//Load the RAS DLL


RasDLL := LoadLibrary(‘rasapi32.dll’);
if RasDLL = 0 then exit;
try
RasEnums :=
GetProcAddress(RasDLL,‘RasEnumConnectionsA
’);
if @RasEnums = nil then
raise
ERasError.Create(‘RasEnumConnectionsA not
found in rasapi32.dll’);

Conns[1].dwSize := Sizeof (Conns[1]);


BufSize := SizeOf(Conns);

RasResult := RasEnums(@Conns, BufSize,


NumConns);

If (RasResult = 0) or (Result =
cERROR_BUFFER_TOO_SMALL) then Result :=
NumConns;
finally
FreeLibrary(RasDLL);
end;
end;
629 - . Acessando o banco de
dados Oracle a partir do Delphi
Em vista de muitos hoje possuírem sistemas rodando
com banco de dados Oracle, resolvemos publicar em
detalhes todos passos necessários para se conectar a
um banco Oracle a partir do Delphi de modo nativo
(usando BDE) e através do ODBC. Temos observado
também que dúvidas sobre este assunto estão sempre
presentes nas listas de discussão sobre Delphi e sobre
Oracle.
Utilizamos com bons resultados as versões do Delphi
2.0 até a 4.0, BDE versões 4.5 e 5.0, e o Oracle7
Workgroup Server Release 7.3.2.1. Naturalmente tais
informações serão de grande ajuda para configuração
em outras versões.
Passos:
1 - Caso tenha instalado em sua máquina algum cliente
do Oracle 16 bits, poderá ter algum tipo de conflito com
drives de 32 bits. Portanto, desinstale todos os clientes
Oracle e instale somente o cliente Oracle 32 bits.
Normalmente isto é feito a partir do CD de instalação do
Oracle executando o programa d:\win95\install\setup.exe
2 - Ao executar o instalador do cliente Oracle para
Windows 95, você deverá de inicio informar o idioma (o
mesmo que foi informado durante a instalação do
próprio banco), tendo o English como padrão.
3 - Entre com o nome da empresa e o diretório onde
serão armazenados os arquivos do cliente Oracle.
4 - Será solicitado o tipo da instalação. Escolha a opção
“Selective Products Install”.
5 - Será apresentada uma lista dos produtos ou
componentes disponíveis. Apesar de poder instalar
todos, serão apenas necessários para a conexão com o
banco Oracle a partir do Delphi os seguintes
componentes:
Sql *Net Client (para criação do alias no cliente Oracle)
Oracle Installer (para instalar/remover componentes)
6 - Selecione os protocolos desejados para
comunicação com o banco, ou poderá deixar
selecionado a sugestão do instalador e prosseguir.
7 - Após completar 100% da instalação, você visualizará
os componentes instalados:
Oracle Installer
Oracle Named Pipes Adapter (protocolo de acordo com
sua rede)
Oracle SPX Adapter (protocolo de acordo com sua rede)
Oracle TCP/IP Adapter (protocolo de acordo com sua
rede)
Required Support Files
Sql *Net Client
8 - Saia do instalador. Não será necessário reiniciar a
máquina por enquanto.
9 - Clique no botão iniciar -> programas -> Oracle for
windows 95 -> Sql Net Easy Configuration
10 - Selecione “Add Database Alias”, e clique OK
11 - Informe na sequência:
Database Alias (nome na sua máquina que representará
o acesso ao banco)
Escolha o Protocolo (normalmente TCP/IP)
TCP/IP Host Name (informe o numero IP do servidor
Oracle)
Database Instance (nome da instância do banco,
consulte o DBA)
12 - Clique em “yes” e saia do Sql Net Easy
Configuration
13 - Chame o BDE Administrator, e clique na guia
Configuration -> Drivers ->Native e selecione ORACLE.
Como sugestão use as seguintes configurações:

VERSION 4.0

TYPE SERVER
DLL32 SQLORA32.DLL

VENDOR INIT ORA73.DLL

DRIVER FLAG (DEIXAR VAZIO)

TRACE MODE 0

BATCH COUNT 200

BLOB SIZE 32

BLOBS TO CACHE 64

ENABLE BCD FALSE

ENABLE INTEGERS FALSE

ENABLE SCHEMA FALSE


CACHE

LANGDRIVER (DEIXAR VAZIO)

LIST SYNONYMS NONE

MAX ROWS –1

NET PROTOCOL TNS

OBJECT MODE TRUE

OPEN MODE READ/WRITE

ROWSET SIZE 20

SCHEMA CACHE DIR (DEIXAR VAZIO)

SCHEMA CACHE 8
SIZE

SCHEMA CACHE –1
TIME
SERVER NAME (COLOQUE O NOME DA INSTANCIA
DO BANCO, DEFAULT: ORCL)

SQLPASSTHRU AUTOCOMMIT
MODE SHARED

SQLQRYMODE SERVER

USER NAME (NOME DE USUARIO, OPCIONAL)

14 - Clique no item de menu Object -> Apply


15 - Agora precisamos apenas criar um Alias que será
enxergado no Delphi. Para isso, clique na guia
Database, clique com o botão direito do mouse sobre o
item da lista ´Databases´ e selecione a opção ´New´.
Escolha a opção ORACLE. Entre com o nome do Alias,
que pode ser qualquer um que não exista. Agora altere
do lado esquerdo na guia Definition, no item SERVER
NAME, e coloque o nome do Database Alias que você
criou no Sql Net Easy Configuration.
16 - Clique no item de menu Object -> Apply
17 - Reinicialize seu computador.
18 - Ok, agora basta abrir o Delphi e utilizar este Alias
como qualquer outro!
630 - Como pegar a URL ativa no
Browser
uses ddeman;

function GetURL(Service: string): String;


var
ClDDE: TDDEClientConv;
temp:PChar;
begin
Result := ”;
//create a new DDE Client object
ClDDE:= TDDEClientConv.Create( nil );
with ClDDE do
begin
SetLink(Service,‘WWW_GetWindowInfo’);
temp := RequestData(‘0xFFFFFFFF’);
Result := StrPas(temp);
StrDispose(temp);
CloseLink;
end;
ClDDE.Free;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
ShowMessage(GetURL(‘IExplore’));
end;
631 - Compara dois arquivos textos
procedure TForm1.Button1Click(Sender:
TObject);
var
filename1 : string;
filename2 : string;
begin
filename1 := Edit1.Text;
filename2 := Edit2.Text;
compfile(filename1, filename2);
showmessage(‘Veja o resultado no arquivo
c:Tempdiff.txt’);
end;

procedure tform1.compfile(filename1,
filename2 : string);
var
f1 : system.textfile;
f2 : system.textfile;
diff : system.textfile;
buf1 : string;
buf2 : string;
l : integer;
begin
assignfile(f1, filename1);
assignfile(f2, filename2);
assignfile(diff, ‘c:Tempdiff.txt’);
reset(f1);
reset(f2);
rewrite(diff);
l := 1;
while not eof(f1) do
begin
readln(f1, buf1);
readln(f2, buf2);
if not (compstr(buf1, buf2) )then
begin
writeln(diff, ‘line: ‘+ inttostr(l) + ‘-‘
+ buf1);
writeln(diff, ‘line: ‘+ inttostr(l) + ‘-‘
+ buf2);
writeln(diff, ‘ ‘);
end;
inc(l);
end;
closefile(f1);
closefile(f2);
closefile(diff);
end;

function tform1.compstr(s1, s2 : string) :


boolean;
var
i : integer;
btemp : boolean;
begin
btemp := true;
if (length(s1) <> length(s2)) then begin
btemp := false;
end{if}
else begin
for i:= 1 to length(s1) do begin
if (s1[i] <> s2[i]) then begin
btemp := false;
exit;
end;{if}
end;{for}
end;{else}
result := btemp;
end;
632 - Procurando um arquivo em
todo o HD
interface

type
PRecInfo=^TRecInfo;
Trecinfo=record
prev:PRecInfo;
fpathname:string;
srchrec:Tsearchrec;
end;

implememtation

function
TForm1.RecurseDirectory(fname:string):tstr
inglist;
var
f1,f2:Tsearchrec;
p1,tmp:PRecInfo;
fwc:string;
fpath:string;
fbroke1,fbroke2:boolean;
begin
result:=tstringlist.create;
fpath:=extractfilepath(fname);
fwc:=extractfilename(fname);
new(p1);
p1.fpathname:=fpath;
p1.prev:=nil;
fbroke1:=false;
fbroke2:=false;
while(p1<>nil) do
begin
if (fbroke1=false) then
if (fbroke2=false) then
begin
if (findfirst(fpath+’*’,faAnyfile,f1)<>0)
then
break;
end
else if (findnext(f1)<>0) then
begin
repeat
findclose(f1);
if (p1=nil) then
break;
fpath:=p1.fpathname;
f1:=p1.srchrec;
tmp:=p1.prev;
dispose(p1);
p1:=tmp;
until (findnext(f1)=0);
if (p1=nil) then
break;
end;
if((f1.Name<>’.’) and (f1.name<>’..’) and
((f1.Attr and fadirectory)=fadirectory))
then
begin
fbroke1:=false;
new(tmp);
with tmp^ do
begin
fpathname:=fpath;
srchrec.Time:=f1.time;
srchrec.Size:=f1.size;
srchrec.Attr:=f1.attr;
srchrec.Name:=f1.name;
srchrec.ExcludeAttr:=f1.excludeattr;
srchrec.FindHandle:=f1.findhandle;
srchrec.FindData:=f1.FindData;
end;
tmp.prev:=p1;
p1:=tmp;
fpath:=p1.fpathname+f1.name+’';
if findfirst(fpath+fwc,faAnyfile,f2)=0
then
begin
result.add(fpath+f2.Name);
while(findnext(f2)=0) do
result.add(fpath+f2.Name);
findclose(f2);
end;
fbroke2:=false;
end
else
begin
if (findnext(f1)<>0) then
begin
findclose(f1);
fpath:=p1.fpathname;
f1:=p1.srchrec;
fbroke1:=false;
fbroke2:=true;
tmp:=p1.prev;
dispose(p1);
p1:=tmp;
end
else
begin
fbroke1:=true;
fbroke2:=false;
end;
end;
end;
fpath:=extractfilepath(fname);
if findfirst(fname,faAnyfile,f1)=0 then
begin
result.add(fpath+f2.Name);
while(findnext(f1)=0) do
result.add(fpath+f2.Name);
findclose(f1);
end;
end;

//Chame a funcao deste jeito:

procedure TForm1.Button1Click(Sender:
TObject);
var
l1:Tstringlist;
begin
l1:=tstringlist.create;
listbox1.items.clear;
listbox1.Items.BeginUpdate;
l1:=recursedirectory1(‘C:\*.exe’);
listbox1.items.assign(l1);
freeandnil(l1);
listbox1.Items.endUpdate;
end;
633 - Como desabilitar o menu pop-
up do windows(Na area de trabalho)
Set a seguinte chave no registro do windows:
HKey_Current_User\Software\Microsoft\Windows\Curren
tVersion\Policies\Explore
r\NoViewContextMenu para 0 habilita o click com o
botao direito e 1 desabilita.
634 - Como inserir um item em um
TreeView em Run Time

procedure TForm1.Button1Click(Sender:
TObject);
var
MyTreeNode1, MyTreeNode2: TTreeNode;
begin
with TreeView1.Items do
begin
Clear; { Remove qualquer node existente }
MyTreeNode1 := Add(nil, ‘RootTreeNode1’);
{ Adiciona o node raiz }
{ Adiciona um sub item no node adiciona
anteriormente }
AddChild(MyTreeNode1,‘ChildNode1’);
{Adiciona outro node raiz}
MyTreeNode2 := Add(MyTreeNode1,
‘RootTreeNode2’);
AddChild(MyTreeNode2,‘ChildNode2’);
MyTreeNode2 := TreeView1.Items[3];
AddChild(MyTreeNode2,‘ChildNode2a’);
Add(MyTreeNode2,‘ChildNode2b’);
Add(MyTreeNode1, ‘RootTreeNode3’);
end;
end;
635 - Como chamar a pasta
impressoras
Arquivo := ‘Control’;
Parametro := ‘Printers’;
ShellExecute(0, ‘open’, PChar(Arquivo),
PChar(Parametro), nil, SW_ShowNormal);
* colocar na uses shellapi;
636 - Mudar Impressora padrão
pelo nome
procedure SetDefaultPrinter(PrinterName:
String);
var
I: Integer;
Device : PChar;
Driver : Pchar;
Port : Pchar;
HdeviceMode: Thandle;
aPrinter : TPrinter;
begin
Printer.PrinterIndex := -1;
getmem(Device, 255);
getmem(Driver, 255);
getmem(Port, 255);
aPrinter := TPrinter.create;
for I := 0 to Printer.printers.Count-1
do
begin
if Printer.printers[i] = PrinterName
then
begin
aprinter.printerindex := i;
aPrinter.getprinter
(device, driver, port, HdeviceMode);
StrCat(Device, ‘,’);
StrCat(Device, Driver );
StrCat(Device, Port );
WriteProfileString(‘windows’, ‘device’,
Device);
StrCopy( Device, ‘windows’ );
SendMessage(HWND_BROADCAST,
WM_WININICHANGE,
0, Longint(@Device));
end;
end;
Freemem(Device, 255);
Freemem(Driver, 255);
Freemem(Port, 255);
aPrinter.Free;
end;
637 - Função para gerar Log de
Erros
function SaveLogError(Const AUnitError,
ASimbolError, ADescription, ATypeError,
ASQLError, AInsError: string): integer;
var
VMemory: TMemoryStatus;
VLogFile: TextFile;
VLogFileName: string;
vcount : Integer;
begin
VMemory.dwLength :=
SizeOf(TMemoryStatus);
GlobalMemoryStatus(VMemory);
VLogFileName := format(‘%spdferror.log’,
[GPathFile]);
try
AssignFile(VLogFile,VLogFileName);
if FileExists(VLogFileName) then
begin
Append(VLogFile);
Writeln(VLogFile,”);
Writeln(VLogFile,’––––––––––––––––––––—’);
Writeln(VLogFile,”);
end
else
begin
Rewrite(VLogFile);
Writeln(VLogFile,‘CABTEC - Soluções em
códigos de barras’);
Writeln(VLogFile,format(‘Fone %s - E-
Mail: cabtec@cabtec.com.br’,’(0xx31)3295-
0555’]));
Writeln(VLogFile,‘Rua Araguari, nº
358/16º andar - Barro Preto’);
Writeln(VLogFile,‘20190-110 - Belo
Horizonte - MG’);
Writeln(VLogFile,’========================
======================================’);
Writeln(VLogFile,”);
end;
Writeln(VLogFile,format(‘DATE/TIME…………:
%s’,[DateTimeToStr(Now)]));
Writeln(VLogFile,format(‘Unit
Error………..: %s’,[AUnitError]));
Writeln(VLogFile,format(‘Call
Symbol……….: %s’,[ASimbolError]));
Writeln(VLogFile,format(‘Error
type………..: %s’,[ATypeError]));

Writeln(VLogFile,format(‘Description……….:
%s’,[ADescription]));
Writeln(VLogFile,format(‘SQL Error…………:
%s’,[ASQLError]));
Writeln(VLogFile,format(‘Instruction
error….: %s’,[AInsError]));
Writeln(VLogFile,”);
Writeln(VLogFile,format(‘Memory
free……….: %.0f bytes’,
[(VMemory.dwAvailPhys / 1024)])); // bytes
livres de memória física
Writeln(VLogFile,format(‘Total
PageFile…….: %.0f
bytes’,[(VMemory.dwTotalPageFile /
1024)])); // bytes livres de paginação de
arquivo // bytes de paginação de arquivo
Writeln(VLogFile,format(‘Avail
PageFile…….: %.0f
bytes’,[(VMemory.dwAvailPageFile /
1024)])); // bytes em uso de espaço de
endereço
Writeln(VLogFile,format(‘Total Virtual
…….: %.0f
bytes’,[(VMemory.dwTotalVirtual /
1024)]));
Writeln(VLogFile,format(‘Avail virtual
free…: %.0f
bytes’,[(VMemory.dwAvailVirtual /
1024)])); // bytes livres
CloseFile(VLogFile);
result := IOResult;
except
result := IOResult;
result := -1;
end;
end;
para chamá-la faça assim:
try
Post;
result := True;
except
on E: Exception do
begin
SaveLogError(‘Unit_nota’,‘function
TForm_Nota.SetSaveItensData: boolean’,
E.Message, E.ClassName, ”, ‘Post’);
Application.MessageBox(‘Ocorreu um erro ao
gravar os dados na tabela de
ITENS!’,CCAPTIONAPPLICATIONTITLE,mb_Ok +
mb_IconStop + mb_DefButton1 +
mb_applmodal);
Cancel;
result := False;
break;
end;
end;
639 - MessageBox com o NÃO
como default
If Application.MessageBox(‘Deseja
Continuar??’,‘Confirmação’,MB_ICONQUESTION
+ MB_YESNO+MB_DEFBUTTON2)=idyes then
640 - Como verificar que sua
aplicação não está sendo utilizada
Voce pode testar, caso sua aplicacao tenha um unico
formulario, o evento OnDeactivate do formulario.
Mas, o melhor mesmo eh com a aplicacao.
Digite o seguinte codigo, no formulario principal:
TSeuFormulario = class (Tform)
public
procedure Desabilitou (Sender : TObject);
Isso voce deve ter notado que deve acrescentar um
metodo, manualmente, ao seu formulario.
A implementacao serah:
procedure TSeuFormulario.Desabilitou
(Sender : TObject);
Begin
{O que voce deseja fazer}
End;
No create de seu formulario principal, digite a linha
abaixo:
Application.OnDeactivate := Desabilitou;
Pronto.
641 - Como enviar mensagem para
todos que estão conectados na
REDE WinNT
function NetSend(dest, source, msg:
string): longint;
type
TNetMessageBufferSendFunction =
function(servername, msgname, fromname:
PWideChar; buf: PWideChar; buflen:
Cardinal): longint; stdcall;
var
NetMessageBufferSend:
TNetMessageBufferSendFunction;
SourceWideChar: PWideChar;
DestWideChar: PWideChar;
MessagetextWideChar: PWideChar;
Handle: THandle;
begin

Handle := LoadLibrary(‘NETAPI32.DLL’);
if Handle = 0 then
begin
Result := GetLastError;
exit;
end;

@NetMessageBufferSend :=
GetProcAddress(Handle,
‘NetMessageBufferSend’);
if @NetMessageBufferSend = nil then
begin
Result := GetLastError;
exit;
end;

MessagetextWideChar := nil;
SourceWideChar := nil;
DestWideChar := nil;

try
GetMem(MessagetextWideChar, Length(msg)
* SizeOf(WideChar) + 1);
GetMem(DestWideChar, 20 *
SizeOf(WideChar) + 1);
StringToWideChar(msg,
MessagetextWideChar, Length(msg) *
SizeOf(WideChar) + 1);
StringToWideChar(Dest, DestWideChar, 20
* SizeOf(WideChar) + 1);
if source = ” then
result := NetMessageBufferSend(nil,
DestWideChar, nil,
MessagetextWideChar, Length(msg) *
SizeOf(WideChar) + 1)
else
begin
GetMem(SourceWideChar, 20 *
SizeOf(WideChar) + 1);
StringToWideChar(source, SourceWideChar,
20 * SizeOf(WideChar) + 1);
result := NetMessageBufferSend(nil,
DestWideChar, SourceWideChar,
MessagetextWideChar, Length(msg) *
SizeOf(WideChar) + 1);
freemem(SourceWideChar);
end;
finally
FreeMem(MessagetextWideChar);
FreeLibrary(Handle);
end;
end;
642 - Criando um arquivo de texto
procedure AddLog;
var
log: textfile;
begin
try
AssignFile(log, ‘c:\log.log’);
if not FileExists(‘c:\log.log’) then
Rewrite(log,‘c:\log.log’);
Append(log);
WriteLn(log, ‘informações a serem
inclusas’);
finally
CloseFile(log);
end;
end;
643 - Problema com Null no Delphi
6
declare VARIANTS no USES e pronto
644 - Foto no InterBase
procedure
TFrmCredenc.CarregaFotoParaBanco(FileName:
String);
Var
stImagem: TFileStream;
begin
stImagem := TFileStream.Create(
FileName, fmOpenRead or
fmShareDenyWrite );
Try
// ibdsCredenciadosFOTO é um campo BLOB
SUB_TYPE 0

DMMain.ibdsCredenciadosFOTO.LoadFromStream
( stImagem );
Finally
stImagem.Free;
End;
end;

procedure
TFrmCredenc.ObtemImagemDoBanco(var
imgDestino: TImage);
Var
jpgImg: TJPEGImage;
stMem: TMemoryStream;
begin
If DMMain.ibdsCredenciadosFOTO.IsNull
Then Exit;
jpgImg := TJPEGImage.Create;
stMem := TMemoryStream.Create;
Try

DMMain.ibdsCredenciadosFOTO.SaveToStream(
stMem );
stMem.Position := 0;
jpgImg.LoadFromStream( stMem );
imgDestino.Picture.Assign( jpgImg );
Finally
stMem.Free;
jpgImg.Free;
End;
end;
645 - Comandos para Threads
minhathread.pause; {da pausa na thread }
minhathread.resume; { reinicia a thread }
minhathread.terminate; { termina a thread
}
minhatrhread.execute; { executa a thread }
646 - A melhor maneira de liberar
um form da memoria
Quando você usa Form.Free ou Form.Destroy, você
está imediatamento solicitando a destruição do
formulário. Com Form.Release, todas as mensagens
pendentes no pool do formulário são postadas -
exemplo: redesenho do formulário, movimento do
mouse, pressionamento de tecla,…
use assim:

FormXX := TFormXX.create ( application );


try
FormXX.ShowModal
finally
FormXX.Release;
FormXX := nil;
end;
647 - Para ocultar em tempo de
execução uma coluna de um
stringgrid
stringgrid1.colwidth[4]:=0; {neste caso a
5ª coluna seria oculta}
Já num dbgrid:
dbgrid1.Columns[7].Visible:=false; {aqui a
8ª coluna é escondida}

Dica Enviada por Douglas Cardoso


648 - Como colocar uma unica linha
de uma stringgrid editavel
use o evento OnSelectCell e verifique se é a linha que
vc quer…
caso seja a linha desejada, coloque a propriedade
GoEditing=true
senão coloque GoEditing=false….

if ARow=Linha
then Grid.Options := Grid.Options +
[goEditing]
else Grid.Options := Grid.Options -
[goEditing];
649 - Como gravar as alterações
feitas no DBGrid em tempo de
execução
Se você quer salvar apenas as configurações de um
DBGrid, faça assim:
DBGrid1.Columns.SaveToFile(‘c:\nome_arquiv
o’);
para abrir:
DBGrid1.Columns.LoadFromFile((‘c:\nome_arq
uivo’);

Essa dica foi capturada no grupo de discussão


delphi-br
ela foi enviada por Fernando Sarturi Prass
650 - Efeito legal no caption do
form
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
WGiro : Integer;
WMesage : String;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Timer1Timer(Sender:
TObject);
begin
Form1.Caption := WMesage;
Case WGiro of
1: begin
if Length(WMesage)<= 1 then
begin
WMesage := ‘ W’;
WGiro := (WGiro + 1);
end;
WMesage := Copy(WMesage, 2,250);
end;

2: begin
if Length(WMesage)<= 2 then
begin
WMesage := ‘ I’;
WGiro := (WGiro + 1);
end;
WMesage := Copy(WMesage, 3,250);
end;

3: begin
if Length(WMesage)<= 3 then
begin
WMesage := ‘ L ‘;
WGiro := (WGiro + 1);
end;
WMesage := ‘W’ + Copy(WMesage, 4,250);
end;

4: begin
if Length(WMesage)<= 4 then
begin
WGiro := (WGiro + 1);
end;
WMesage := ‘WI’ + Copy(WMesage, 5,250);
end;

5: begin
if Length(WMesage)<= 5 then
begin
WGiro := 1;
end;
WMesage := ‘WIL’ + Copy(WMesage, 6,250);
end;
end;
end;

procedure TForm1.FormShow(Sender:
TObject);
begin
Timer1.Enabled := True;
WMesage := ‘ ‘;
WGiro := 1;
end;

end.

Dica enviada por William - Marilia/SP Capital


Nacional do Alimento
651 - Enter funcionando como Tab
em toda a aplicação
Uses
Grids
procedure TfrmPri.MudarComEnter(var Msg:
TMsg; var Handled: Boolean);
begin
If not ((Screen.ActiveControl is
TCustomMemo) or
(Screen.ActiveControl is TCustomGrid) or
(Screen.ActiveForm.ClassName =
‘TMessageForm’)) then
begin
If Msg.message = WM_KEYDOWN then
begin
Case Msg.wParam of
VK_RETURN,VK_DOWN :
Screen.ActiveForm.Perform(WM_NextDlgCtl,0,
0);
VK_UP :
Screen.ActiveForm.Perform(WM_NextDlgCtl,1,
0);
end;
end;
end;
end;

no evento OnCreate o Form Principal digite a seguinte


linha

Application.OnMessage := MudarComEnter;
Dica Enviada por Márcio Souza
652 - Mudando a cor dos
componentes assim que receber o
foco
Uses
Typinfo

function AchaComponente(Nome: string; F:


TForm): TComponent;
var
i: integer;
C: TComponent;
begin
Result := nil;
// Converte nome para maiúscula
Nome := UpperCase(Nome);
// Varre o formulário à procura do
componente
for i := 0 to F.ComponentCount - 1 do
begin
C := F.Components[i];
// O nome está correto?
if UpperCase(C.Name) = Nome then
begin
// Retorna o componente
Result := C;
// Sai do loop
exit;
end;
end;
end;

// Atibui propriedade ao componente, dado


seu valor como string
procedure AtribuiProp(Comp: TComponent;
Const PropName: string; Val: string);
var
PInfo: PPropInfo;
begin
// Pega informações de tipo da
propriedade
PInfo := GetPropInfo(Comp.ClassInfo,
PropName);
// Achou?
if PInfo <> nil then
begin
// Trata conforme o tipo
case PInfo^.Proptype^.Kind of
tkInteger: SetOrdProp(Comp, PInfo,
StrToInt(Val));
tkChar, tkWChar: SetOrdProp(Comp, PInfo,
ord(Val[1]));
tkEnumeration: SetOrdProp(Comp, PInfo,
GetEnumValue(PInfo^.PropType^, Val));
tkFloat: SetFloatProp(Comp, PInfo,
StrToFloat(Val));
tkString, tkLString, tkWString:
SetStrProp(Comp, PInfo, Val);
tkVariant: SetVariantProp(Comp, PInfo,
Val);
tkInt64: SetInt64Prop(Comp, PInfo,
StrToInt64(Val));
else
ShowMessage(‘Este tipo não é suportado
por este programa’);
end;
end
else
ShowMessage(‘Propriedade não achada’);
end;

// Lê valor da propriedade do componente


function LeProp(Comp: TComponent; Const
PropName: string): string;
var
PInfo: PPropInfo;
begin
Result := ”;
// Pega informações de tipo da
propriedade
PInfo := GetPropInfo(Comp.ClassInfo,
PropName);
// Achou?
if PInfo <> nil then
begin
// Trata conforme o tipo
case PInfo^.Proptype^.Kind of
tkInteger: Result :=
IntToStr(GetOrdProp(Comp, PInfo));
tkChar, tkWChar: Result :=
char(GetOrdProp(Comp, PInfo));
tkEnumeration: Result :=
GetEnumName(PInfo^.PropType^,
GetOrdProp(Comp, PInfo));
tkFloat: Result :=
FloatToStr(GetFloatProp(Comp, PInfo));
tkString, tkLString, tkWString: Result
:= GetStrProp(Comp, PInfo);
tkVariant: GetVariantProp(Comp, PInfo);
tkInt64: Result :=
IntToStr(GetInt64Prop(Comp, PInfo));
else
ShowMessage(‘Este tipo não é suportado
por este programa’);
end;
end
else
ShowMessage(‘Propriedade não achada’);
end;

procedure TForm1.ColorControl(Sender:
TObject);
var
Cor: TColor;
I: integer;
begin
With Screen.ActiveForm do
begin
for I:= 0 to ComponentCount -1 do
begin
if Components[I] is TCustomEdit then
begin
if (Components[I] as
TCustomEdit).Focused then
Cor := clRed
else
Cor := clWindow;
AtribuiProp(Components[I], ‘Color’,
IntToStr(Cor));
end;
end;
end;
end;

procedure TForm1.FormCreate(Sender:
TObject);
begin
Screen.OnActiveControlChange :=
ColorControl;
end;

procedure TForm1.FormClose(Sender:
TObject; var Action: TCloseAction);
begin
Screen.OnActiveControlChange := nil;
end;

Dica Enviada por Márcio Souza


 
653 - Como Instalar no Delphi o
ActiveX do Flash
1. primeiro você deve instalar o Flash (as vezes não
se faz necessário)
2. ai você irá em COMPONENT –> IMPORT ACTIVEX
CONTROL
3. ai você irá instalar o ShockWave Flash (version 1.0)
4. pronto…
5. Vá na Aba ActiveX e vc encontrará o componente
ShockWaveFlash
6. é so especificar os parâmetros e usá-los,,,,

Dica retirada da Lista de Discussão Delphi-br


Para se inscrever na Delphi-br clique aqui
(Envie uma msg em branco)
654 - Como evitar que apareçam
numeros negativos na consulta
SELECT DECODE(SIGN(valor),-1,’????’,valor)
FROM arquivo
onde ???? é o que deve aparecer quando ‘valor’ for
menor que 0
655 - Como colocar imagens numa
StatusBar
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
ImgList, ComCtrls;

type
TForm1 = class(TForm)
StatusBar1: TStatusBar;
ImageList1: TImageList;
procedure StatusBar1DrawPanel(StatusBar:
TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
{Adicione um StatusBar e um ImageList,
iclua no imagelist as figuras que deseja
mostrar apos mude a propriedade Style dos
Panels do StatusBar para psOwnerDraw,
em seguida inclua o codigo abaixo no
evento OnDrawPanel do StatusBar}
procedure
TForm1.StatusBar1DrawPanel(StatusBar:
TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
begin
with StatusBar1.Canvas do
begin
FillRect(Rect);
//Definir Font e Style
Font.Name := ‘Arial’;
Font.Color := ClNavy;
Font.Style := [FsBold];
//Desenha as imagens de acordo com o
indice de cada panel

ImageList1.Draw(StatusBar1.Canvas,Rect.Lef
t+5,Rect.Top+1,Panel.Index);
//Escreve o texto em cada panel
if Panel.Index = 0 then
TextOut(Rect.Left + 25, Rect.Top +
1,‘LloydSoft - Panel1’);
if Panel.Index = 1 then
TextOut(Rect.Left + 25, Rect.Top +
1,‘LloydSoft - Panel 1’);
if Panel.Index = 2 then
TextOut(Rect.Left + 25, Rect.Top +
1,‘LloydSoft - Panel 2’);
end;
end;
end.

{Dica enviada por William - Marilia/SP Capital


Nacional do Alimento}
656 - Como pegar o diretorio de
uma ALIAS
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, Db, DBTables ;

type
TForm1 = class(TForm)
Label1: TLabel;
BitBtn1: TBitBtn;
Edit1: TEdit;
Table1: TTable;
Label2: TLabel;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
WAlias : TStringList; //Capitura o Alias
do Bde
WServidor : String; //Retorna o Caminho
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
procedure TForm1.BitBtn1Click(Sender:
TObject);
begin
{Para validar a Session e necessario ter
um compomente table anexado ao projeto}
WAlias := TStringList.Create;
// Session.GetAliasParams(‘CrAdm’,WAlias);
//Coloque o Alias diretamente ou Troque
pelo Edit
Session.GetAliasParams(Edit1.Text,WAlias)
;
WServidor := WAlias[0];
WServidor := Copy(WServidor,6,255);
WServidor := Copy(WServidor,1,
(Length(WServidor)));
Label1.Caption := WServidor;
end;

end.
{Dica enviada por William - Marilia/SP Capital
Nacional do Alimento}
657 - Como trocar a cor do
componente focado
Para mudar a cor do conponente que esta focado, e
depois voltar a cor quando não está mais focado.
No evento OnEnter.
Colocar as seguinter linhas de comando;

procedure TForm1.DBEdit1Enter(Sender:
TObject);
begin
// verificar o camponente
if (Sender is TDBEdit) then
// mudar a cor do componente
TDBEdit(Sender).Color:=ClBlue;
end;

No Evento OnExit:
Colocar as seguinter linhas de comando;

procedure TForm1.DBEdit1Exit(Sender:
TObject);
begin
// verificar o camponente
if (Sender is TDBEdit) then
// mudar a cor do componente
TDBEdit(Sender).Color:=clWindow;
end;

Desta Forma você pode utilizar esta procedure para


varios componentes
{Dica enviada por Fabio Tinti}
658 - Como instalar componentes 3
No delphi a três maneiras de instalar componentes.
Existe a possibilidade de instalar componentes através
de três tipos de extensões de arquivos: *.pas, *.dcu,
*.dpk.
Explicando um por um:
1 - Para arquivos que necessitam de um Package
(normalmente componentes que possuem somente o
*.PAS), execute o Delphi e feche o projeto, acesse o
menu ‘Component’ e clique na opção ‘install
component’. Na janela que se apresenta, acesse a aba ‘
Into New Packages’, clique no botão ‘Browse’ ao lado da
caixa de texto ‘Unit File Name’ abra o arquivo com
extensão *.pas, dê ok e logo após ‘Compile’ e ‘Install’ e
o arquivo criará uma aba na barra de componentes com
um nome para a sua localização.
2 - Para instalar pacotes de componentes (Packages,
arquivos com a extensão *.DPK), execute o Delphi e
feche o projeto, acesse o menu ‘File’ e clique na opção
‘Open’, abra o arquivo que contém os componentes. Dê
Ok e depois é só clicar en ‘install’. Pronto seu pacote de
componentes será instalado.
3 - Para arquivos com a extensão *.dcu, é um pouco
mais complicado. Acesse o menu ‘Component’ e clique
na opção ‘install package’. Verifique se na lista ‘Design
packages’ existe a opção ‘Borland user component’, se
sim, clique no botão ‘edit’, abrirá uma caixa de
mensagens, clique no botão ‘yes’. Na janela que
aparece clique no botão ‘add’, na janela que se abrirá
clique no botão ‘browse’ da caixa de texto ‘unit file
name’. Na caixa de combinação ‘files of type’ escolha
‘Delphi compiled unit(*.dcu)’, depois na caixa de texto
‘File name’ direcione o arquivo a ser instalado, clique no
botão ‘open’. Clique no botão ‘ok’ na janela que aparece
e clique no botão install. Pronto o seu componente será
instalado.
Observação:
Se na lista ‘Design packages’ não tiver a opção ‘Borland
user component’ você deverá primeiro instalar
componentes que estão em arquivos com extensão
*.pas.
{Dica enviada por Ederson Rutz Fischer}
659 - Não aparecer na barra e tb
como não aparecer no ctr+alt+del.
Coloca isso no evento oncreate do forms
procedure TForm1.FormCreate(Sender:
TObject);
type
TRegisterServiceProcess = function
(dwProcessID, dwType:DWord) : DWORD;
stdcall;
var
Handle: THandle;
RegisterServiceProcess:
TRegisterServiceProcess;
begin
//*** Nao aparece no Ctr+Alt+Del
******************************************
*****
Handle := LoadLibrary(‘KERNEL32.DLL’);
RegisterServiceProcess :=
GetProcAddress(Handle,
‘RegisterServiceProcess’);
RegisterServiceProcess(GetCurrentProcessID
, 1);
FreeLibrary(Handle);
//*** Nao aparece na barra
******************************************
*****
SetWindowLong(Application.Handle,
GWL_EXSTYLE,
GetWindowLong(Application.Handle,
GWL_EXSTYLE) or
WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
{Dica enviada por Ederson Rutz Fischer}
660 - Impressão apartir de Consult
Experimente usar o FILTRO na query do QReport.
var
frmqreport: TfrmQreport; {seu form de qr}
begin
try
try
qr.filtered:=false;
qr.filter:=‘cmpNome =’+sVarXXX;
qr.filtered:=true;
frmqreport:= Tfrmqreport.create(
application);
frmqreport.qreport.previewmodal;
except
{erro}
end;
finally
qr.filtered:=false;
qr.filter:=”;
frmqreport.free;
end;

Na string SQL da query:


select cmpNome, cmpXXXX, etc…
from “tabeladosdados.db”

Na string poderia usar também:


cmpNome LIKE “GUSTAVO” ao invés de FILTER.
Para colocar as ASPAS use QUOTESTR().
qr.SQL.ADD() veja help

sVarSQL:= ‘cmpNome LIKE ‘+ QUOTESTR(


sVarNome ) na última linha da string SQL

{Dica enviada por Ederson Rutz Fischer}


661 - Procedimentos com
parâmetros opcionais:
Quando você declara o procedimento:
procedure Esperar(Segundos: Byte);
Você está determinando que todas as vezes que o
procedimento. Esperar for chamado, deverá ser
passado um valor do tipo Byte. No entanto, esse tipo de
declaração exige que em todas as chamadas ao
procedimento Esperar seja especificado um parâmetro.
Se você fizer uma chamada do tipo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
Esperar()
end;
Será gerado um erro do tipo: Not enough actual
parameters. Mas você pode declarar e implementar o
procedimento da seguinte forma:
procedure Esperar(Segundos: Byte = 1);
begin
Sleep(Segundos * 1000);
end;
A declaração acima faz com que o procedimento
Esperar assuma o valor 1 caso nenhum parâmetro seja
passado. Assim você poderá fazer uma chamada ao
procedimento em qualquer das situações abaixo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
Esperar(); // nenhum parâmetro, será
assumido o valor 1
Esperar(1);
Esperar // nenhum parâmetro, será
assumido o valor 1
end;
{Dica enviada por Ederson Rutz Fischer}
662 - Exemplos de path via
registro
O exemplos abaixo lidam com arquivos INI. A idéia é a
mesma do registry, com a vantagem de que o INI
também roda no Kylix sem problemas. Eu não sou muito
fã do registry, embora sempre me veja mexendo nele.
Geralmente eu uso essas funções numa tela de login e
guardo o nome do último usuário e da última conexão.
procedure TfrmLogin.LoadConfig;
var
IniFile : TIniFile;
FIniFileName : ShortString;
begin
FIniFileName :=
LowerCase(ExtractFileName(Application.ExeN
ame));
FIniFileName := Copy(FIniFileName, 1,
Length(FIniFileName) - 3) + ‘ini’;
IniFile :=
TIniFile.Create(FIniFileName);
LogonUserName :=
IniFile.ReadString(SectionData, KeyUser, ”
);
ConnectionString :=
IniFile.ReadString(SectionData,
KeyConnection, ”);
IniFile.Free;
end;

procedure TfrmLogin.SaveConfig;
var
IniFile : TIniFile;
FIniFileName : ShortString;
begin
FIniFileName :=
LowerCase(ExtractFileName(Application.ExeN
ame));
FIniFileName := Copy(FIniFileName, 1,
Length(FIniFileName) - 3) + ‘ini’;
IniFile :=
TIniFile.Create(FIniFileName);
IniFile.WriteString(SectionData,
KeyUser, LogonUserName );
IniFile.WriteString(SectionData,
KeyConnection, ConnectionString);
IniFile.Free;
end;
A variável FIniFile permite que sejam criados arquivos
INI com o mesmo nome da aplicação. Isso é bom e é
ruim. É bom se cada aplicacao acessar um banco
diferente. Ruim se elas acessam o mesmo banco. Neste
ultimo caso, é só dar um nome fixo ao INI.

{Dica enviada por Ederson Rutz Fischer}


663 - Executar um programa do
Windows
uses Shellapi

procedure ExecutePrograma(Nome,
Parametros: String);
Var
Comando: Array[0..1024] of Char;
Parms: Array[0..1024] of Char;
begin
StrPCopy (Comando, Nome);
StrPCopy (Parms, Parametros);
ShellExecute (0, Nil, Comando, Parms,
Nil, SW_ShowMaximized);
end;

Para rodar ela:


ExecutePrograma(‘WinWord.Exe, ”);
ou se quiser rodar um documento ou arquivo:
ExecutePrograma
(‘C:\MSOffice\Excel\Excel.Exe’,
‘Contas.Xls’);
{Dica enviada por William}
664 - Como descobrir se você esta
conectado com a Internet?
1º) Você deve acrescentar um componente NMFTP (da
paleta FastNet).
2º) Insira o seguinte código no evento OnShow do
formulário.
If (NMFtp1.GetLocalAddress <> ‘0,0,0,0’)
Then ShowMessage(‘Você não está
conectado!’) Else ShowMessage(‘Você está
conectado!’);
3º) Execute o programa e veja o resultado.

By Carlos Naves -
http://www.carlosnaves.hpg.com.br/
665 - Como desabilitar as teclas
Alt + F4
public
{ Public declarations }
fecha: Boolean;
end;

implementation

{$R *.DFM}

Function GetStateK (Key: integer):


boolean;
begin
Result := Odd (GetKeyState (Key));
end;

procedure Tfrm_HIP.FormClose(Sender:
TObject; var Action: TCloseAction);
begin
If Not fecha Then
Action := caNone Else
Action := caFree;
end;

procedure Tfrm_HIP.FormKeyDown(Sender:
TObject; var Key: Word;
Shift: TShiftState);
begin
If GetStateK (VK_LMENU) And (Key = VK_F4)
Then
fecha := False;
end;

{Dica enviada por William}


666 - Para trocar as cores dos
botoes do radiogroup
No Object Inspector na propriedade Font coloque a cor
verde.
procedure TForm1.RADIOGROUP1Click(Sender:
TObject);
Var
i : Integer;
begin
// Para trocar as cores dos botoes do
RadioGroup
for i := 0 to RADIOGROUP1.Items.Count-1
do begin

TRadioButton(RADIOGROUP1.Controls[i]).Font
.Color := clGreen;

TRadioButton(RADIOGROUP1.Controls[i]).Font
.Style := [fsBold];
end;

TRadioButton(RADIOGROUP1.Controls[RADIOGRO
UP1.ItemIndex]).Font.Color := clRed;

TRadioButton(RADIOGROUP1.Controls[RADIOGRO
UP1.ItemIndex]).Font.Style := [fsBold];
end;
{Dica enviada por José do Amparo Soares}
667 - Como usar um frame em sua
aplicação
FORM Principal:
No “Form” principal do projeto, coloque um “Panel” para
o título do projeto ou apresentação com imagens, textos,
etc.
Panel - No Object Inspector:
Mude a propriedade “Align” para “alTop”. O tamanho -
Apenas “Height” (Altura) = 65, pois “Width” (largura) será
a do formulário pai.
FRAME:
Vamos criar os frames agora. Vá ao menu “File”, clicar
em “New Frame”. Abrirá um componente frame com o
nome de “Frame1”.
No Object Inspector, nas propriedades abaixo, fazer
alterações:
Name - Trocar o nome. (fraMenu - apenas
exemplo).
AutoScroll - True.
Height - 379.
Width - 140.
Coloque um Panel dentro do frame. Troque as
propriedades abaixo:
Name - Trocar o Nome.
Align - alClient.
Color - A cor desejada.
Caption - para vazio.
Dentro deste panel, coloque os componentes para
chamar os outros frames:
SpeedButton, BitBtn, Button, ou outros Panels, o que
desejar, desde que tenha o evento “OnClick”.
Para cada Button, Panel, etc. que chamar um formulário,
usar o comando abaixo.
Neste exemplo foi colocado um Panel, com o nome
pnlComponentes, para chamar um frame com o nome
de fraComponentes.
No OnClick deste componente, coloque o comando:
procedure
TfraMenu.pnlComponentesClick(Sender:
TObject);
begin
frmPrincipal.fraComponentes.Align:=alClien
t;

frmPrincipal.fraComponentes.Visible:=True;

frmPrincipal.fraComponentes.BringToFront;
End;
No form Principal, na palheta “Standard” do Delphi, dê
dois cliques no primeiro componente “Frames”,
aparecerá uma janela com os nomes dos frames já
criados. Escolha fraMenu: o sistema colocará este frame
dentro do form principal. O fraMenu que aparecer dentro
do form principal, trocar as propriedades abaixo:
Align - alLeft, isto colocará este frame a
esquerda no form principal.
Visible - True, isto fará com que este
frame ficará visível todo o tempo.
No fraMenu que aparece dentro do form principal, no
Evento “OnClick” deste Panel (pnlComponentes),
coloque o comando:
procedure
TfrmPrincipal.fraMenupnlComponentesClick(S
ender: TObject);
begin
fraMenu.pnlComponentesClick(Sender);
end;

No “OnCreate” do form principal, usar o comando


abaixo, incluindo todas as frames criadas, menos o
fraMenu:

procedure TfrmPrincipal.FormCreate(Sender:
TObject);
begin
fraMenu.pnlComponentes.Align:=alTop;
end;
Nos outros frames a serem criados, trocar as
propriedades abaixo:
Align - alNone.
Visible - False.
Com isto os frames dentro do form principal estarão
invisível, mas, quando clicar no componente dentro do
fraMenu, o frame chamado aparecerá.
{Dica enviada por José do Amparo Soares}
668 - Como trocar a cor do texto
de uma coluna do dbgrid
procedure
TForm1.DBGrid1DrawColumnCell(Sender:
TObject;
const Rect: TRect; DataCol: Integer;
Column: TColumn;
State: TGridDrawState);
begin
// Troca a cor de fundo do DBGrid
DBGrid1.Canvas.Brush.Color := clAqua;
if Column.Index = 1 then
begin
// Troca a cor do texto de uma coluna
DBGrid1.Canvas.Font.Color := clOlive;
end
else
DBGrid1.Canvas.Font.Color := clRed;
DBGrid1.Canvas.FillRect(Rect);

DBGrid1.Canvas.TextOut(Rect.Left+2,Rect.To
p,Column.Field.AsString);
end;

{Dica enviada por José do Amparo Soares}


669 - Deixando o EXE menor e
mais rápido
Para deixar o programa executável menor e mais rápido,
abra a tela de Options/Project.
Na página Compiler tire todos os “X” e deixe somente
nas caixas: Force far Calls, Smart Callbacks e Extended
Sintax.
Na página Linker marque um “X” em Optimize for size
and load time.
Lembre-se fazendo isso o programa ficará menor e mais
rápido, porém o Delphi levará mais tempo para compilá-
lo
{Dica enviada por Gladson J. Reis Vieira}
670 - Usando MessageBox
Para que as mensagens apareçam em portugues (na
lingua no sistema) não eh necessário a tradução das
units.
Invés de usar a função messagedlg eh melhor usar a
função MessageBox
Sintax:
MessageBox (Handle, Messagem, Caption,
Botoes)
onde
Handle : Endereço do form na memória ; Sempre usu
Application.Handle
Messagem : A messagem a ser mostrada
Caption : O titulo da messagem
Botoes : Os Botoes que irao ser mostrados. Na lingua
do sistema

MB_ABORTRETRYIGNORE A messagem mostra os


tres botoes: Abort, Retry, and Ignore.
MB_OK A messagem mostra um botoao: OK. This is the
default.
MB_OKCANCEL A messagem mostra os dois botoes:
OK and Cancel.
MB_RETRYCANCEL A messagem mostra os dois
botoes: Retry and Cancel.
MB_YESNO A messagem mostra os dois botoes: Yes
and No.
MB_YESNOCANCEL A messagem mostra os tres
botoes: Yes, No, and Cancel.
Sons
MB_ICONEXCLAMATION, MB_ICONWARNING: Mostra
o icone de exclamação e som conrrespondente. Analo
aos demais
MB_ICONINFORMATION, MB_ICONASTERISK
MB_ICONQUESTION
MB_ICONSTOP,
MB_ICONERROR,
MB_ICONHAND
Botoes padrao
MB_DEFBUTTON1: Padrao nao precisa ser colocado.
MB_DEFBUTTON2: Coloca o segundo botao como
padrao
MB_DEFBUTTON3: Coloca o terceiro botao como
padrao
MB_DEFBUTTON4: Coloca o quarto botao como padrao
Respostas
IDABORT
IDCANCEL
IDIGNORE
IDNO
IDOK
IDRETRY
IDYES
Exemplo
Case MessageBox (Application.Handle, Pchar
(‘Deseja excluir o arquivo’ + #13 +
Label1.caption), ‘Exclusao de arquivo’,
MB_YESNOCANCEL+MB_EXCLAMATION+MB_DEFBUTTON
2) of
idYes: Procedimento
idNo: Procedimento
idCancel: Procedimento
end;

{Dica enviada por José Pacelli Moreira de Oliveira}


671 - Efeito legal no Caption do
Form 2
declare as variaveis CAP e NCAR na declaração var do
Form
var
cap : String;
ncar : Integer;
Inicialize as variáveis no evento Show do Form
cap := ‘Digite aqui a Caption do
Formulário’;
ncar := 0;
- Coloque um objeto Timer no Form
- Modifique a Propriedade Interval do objeto Timer1 para
100
- No Evento OnTimer do objet Timer1 digite o seguinte
IF ncar <= length(cap) then
begin
Form1.caption := copy(cap,1,ncar);
ncar := ncar +1;
end
else
begin
ncar := 0;
end;
Pronto é só testar
{Dica enviada por Douglas Junior Ferreira}
672 - Criando tabela em tempo de
execução
if
FileExists(‘c:\contatos\contatos.db’)=fals
e then
begin
TableContatos.Close;
TableContatos.DatabaseName:=‘c:\contatos’;
TableContatos.TableName:=‘Contatos’;
TableContatos.TableType:=ttParadox;
TableContatos.FieldDefs.Clear;
TableContatos.FieldDefs.Add(‘Cod’,ftAutoIn
c,0,false);
TableContatos.FieldDefs.Add(‘Contato’,ftSt
ring,50,false);
TableContatos.FieldDefs.Add(‘Telefone’,ftS
tring,12,false);
TableContatos.FieldDefs.Add(‘Curso’,ftStri
ng,20,false);
TableContatos.FieldDefs.Add(‘Observacao’,f
tMemo,100,false);
TableContatos.IndexDefs.Clear;
TableContatos.IndexDefs.Add(‘iCod’,‘Cod’,
[ixPrimary,ixUnique]);
TableContatos.IndexDefs.Add(‘iContato’,‘Co
ntato’,[ixUnique]);
TableContatos.CreateTable;
TableContatos.Open;
ShowMessage(‘As tabelas foram criadas com
êxito!’);
end
else
begin
TableContatos.Close;
TableContatos.DataBaseName:=‘C:\contatos’;
TableContatos.TableName:=‘contatos.db’;
TableContatos.Open;
end;
673 - Criando tabelas em tempo de
execução 2
Criar um arquivo em tempo de execução é relativamente
simples, você tem que criar uma instância do objeto
TTable, esse objeto(de uma lida no Help TTable e suas
propriedades e metodos) tem um método de criação e
um de Criar tabela.
Depois disso é só definir as propriedades da nova
tabela:
DatabaseName := ‘c:\lista’;
TableName := ‘Produtos.dbf’;
TableType := ttDbase;
os campos da tabela:
Add(‘codigo’, ftString,7, false);
Add(‘Nome’, ftString, 45, false);
e os índices:
Add(‘prod1’, ‘codigo’, []);
Add(‘prod2’, ‘Fornecedor’, []);
com todos os dados devidamente setados:
CreateTable;
Procedure TMainForm.Inicializa;
var
Table1 : TTable;
begin
{ Criar componente TTable }
Table1 := TTable.create(Application);
{ Definições de Campos e criação do
arquivo }
with Table1 do
begin
DatabaseName := ‘c:\lista’;
TableName := ‘Produtos.dbf’;
TableType := ttDbase;
with FieldDefs do
begin
Clear;
Add(‘codigo’, ftString,7, false);
Add(‘Nome’, ftString, 45, false);
Add(‘Fornecedor’, ftString, 5,false );
Add(‘Custo’, ftCurrency, 0, false );
Add(‘Venda’, ftCurrency, 0, false );
end;
with IndexDefs do
begin
Clear;
Add(‘prod1’, ‘codigo’, []);
Add(‘prod2’, ‘Fornecedor’, []);
end;
CreateTable;
end;
end;
Utilizando o tipo ftCurrency, formato de valores do
sistema financeiro, o Delphi cria um campo Dbase com
N,20,4
674 - Usando o Registro do
Windows
Nesta matéria veremos como trabalhar com o registro
do windows utilizando suas “Api’s”. Esta matéria possui
algumas técnicas que tratam o registro do windows. Veja
as dicas desta matéria:
Como definir, que uma certa extensão de arquivo seja
aberta pelo seu programa.
Como escrever e ler algum valor no registro do windows.
E o que escrever lá, para que sua aplicação seja
inicializada junto com o windows.
Vejamos então a primeira dica:
Uses
Windows, Messages …. Registry; // Não
esqueça de adicionar a Unit Registry na
sessão uses…

procedure TForm1.Button1Click(Sender:
TObject);
Var
Reg : TRegistry;
Begin
Reg := TRegistry.Create;
try
with Reg do
begin
RootKey := HKEY_CLASSES_ROOT;
OpenKey(‘\MeuPrograma’, True);
WriteString(”, ‘Arquivo do meu
programa’); //Nome dado ao arquivo de sua
aplicação. “Ex: Imagem Gif”.
CloseKey;
OpenKey(‘MeuPrograma\DefaultIcon’,
True);
// O primeiro parâmetro da linha de
comando abaixo, é para escrever uma string
vazia.
// E o último parâmetro é para colocar o
ícone da sua aplicação nos arquivos que
serão abertos por ela.
WriteString(”, Application.ExeName +
‘,0’);
CloseKey;

OpenKey(‘MeuPrograma\shell\open\command’,
True);
WriteString(”, Application.ExeName + ‘
“%1”’);
CloseKey;
RootKey := HKEY_CLASSES_ROOT;
OpenKey(‘.ext’, True); // Substitua o
“ext” pela extensão que você deseja
utilizar.
WriteString(”, ‘MeuPrograma’);
CloseKey;
end;
finally
Reg.CloseKey;
Reg.Free;
end;
End;
Acredito que você tenha conseguido aplicar esta
técnica que lhe pode ser bastante útil. Vamos então ver
a segunda dica, com ela você aprenderá como ler ou
escrever um valor no registro do windows:
Uses
Windows, Messages …. Registry; // Não
esqueça de adicionar a Unit Registry na
sessão uses…

procedure button1.click(sender: Tobject);


var
Reg: Tregistry;
begin
Reg:=Tregistry.create;
with Reg do
begin
rootkey:=HKEY_LOCAL_MACHINE;
Openkey(‘Software\Microsoft\Outlook
Express\5.0\Default Settings\Recent
Stationery List’,false);
writestring(‘File0’, ‘Natureza.htm’);
writestring(‘File1’, ‘Dia Claro.htm’);
closekey;
end;
end;
No caso acima nós exemplificamos o que é escrever
no registro, Neste exemplo nós trocamos de ordem os
papeis de carta do Microsoft Outlook Explorer, embora
você possa alterar qualquer registro já existente no
“regedit”. Se o que você que é incluir um registro e não
editar, como nós fizemos, basta que no primeiro
parâmetro da linha de comando “writestring”, você
coloque um nome para o seu registro, que não exista
nesta pasta.
Agora no código abaixo veremos como ler um valor de
um registro qualquer:
Uses
Windows, Messages …. Registry; // Não
esqueça de adicionar a Unit Registry na
sessão uses…

procedure button1.click(sender: Tobject);


var
Reg: Tregistry;
S: String;
begin
Reg:=Tregistry.create;
with Reg do
begin
rootkey:=HKEY_LOCAL_MACHINE;

OpenkeyReadOnly(‘SOFTWARE\MICROSOFT\WINDOW
S\CURRENTVERSION',false);
s:=readstring(‘version’);
closekey;
end;
edit.text:=s;
end;
Neste caso nós pegamos o registro “version”, que
significa a versão do windows, colocamos o seu valor na
variável “s” e depois à “jogamos” num “edit” qualquer,
apenas para que possamos visualizá-la.
Agora que você já sabe como escrever no registro do
windows, veremos o que precisamos escrever, para
colocar a nossa aplicação para ser inicializada junto com
o windows.
Uses
Windows, Messages …. Registry; // Não
esqueça de adicionar a Unit Registry na
sessão uses…

procedure button1.click(sender: Tobject);


var
Reg: Tregistry;
begin
Reg:=Tregistry.create;
with Reg do
begin
rootkey:=HKEY_LOCAL_MACHINE;

Openkey(‘\MICROSOFT\WINDOWS\CURRENTVERSION
\RUN’,false);
writestring(‘MeuPrograma’,
pchar(application.exename));
closekey;
end;
end;
Com mais essa dica, finalizo a nossa matéria que
ensina a trabalhar com o registro do windows. Espero
que você tenha gostado e que lhe seja bastante útil.

Por Marco Antonio


marco@clubedelphi.com.br
675 - Usando o Registro do
Windows
Como usar o Registro do Windows
no seu programa Delphi
Os programas possuem cada vez mais opções. E você
precisa gravar essas opções em algum lugar. A primeira
coisa que lhe vem à cabeça é a criação de um arquivo
INI, como no Windows 3.x. O Delphi possui o objeto
TIniFile, que ajuda a ler e gravar dados nesse arquivo. A
não ser que esteja usando o Windows 3.x, essa técnica
deve ser repensada. No Windows 95 foi criado o
Registro do Windows (Windows Registry), cuja
finalidade é substituir os vários arquivos INI espalhados
pelo Winchester e encapsulá-los em um local
centralizado.
Para você ter uma idéia de como ele funciona, dê uma
olhada no Editor de Registro, que vem na instalação
padrão do Windows (vá em Iniciar|Executar e digite
RegEdit). O programa separa as opções de registro em
“pastas”, conhecidas aqui como “chaves“. Essas chaves
contém dados, chamados de “valores“. Esses valores
possuem um nome, um tipo e um valor específico.
O Delphi encapsula o Registro do Windows através o
objeto TRegistry. É através dessa classe que você irá
acessar dados do registro.
Para você entender melhor como funciona o objeto,
vamos explicar primeiro como funciona o Registro do
Windows:
As principais chaves “raízes” são:
HKEY_LOCAL_MACHINE e HKEY_CURRENT_USER.
Todas as informações sobre os programas ficam nessas
chaves (as outras normalmente possuem informações
sobre o Windows).
O InstallShield, por exemplo, instala as informações
sobre o nome de usuário e empresa do seu programa
em HKEY_LOCAL_MACHINE\SOFTWARE\Nome da
Sua Empresa\Nome Do Programa\Versão, com os
valores Company e Name (Empresa e Nome do
Usuário).
Os programas, por sua vez, usam a chave
HKEY_CURRENT_USER\Software para armazenar
informações de seus programas. E é nessa chave que
você deve inserir sua sub-chave e colocar lá as
informações necessárias.
Um pequeno exemplo de como utilizar o registro do
Windows. Suponhamos que o programa necessite
gravar a posição da janela, o seu tamanho e o diretório
inicial dos diálogos Abrir e Salvar.
Após a criação do objeto, devemos informar qual chave
devemos utilizar, utilizando o método OpenKey (Chave,
PodeCriar); onde Chave é o nome da sub-chave e
PodeCriar é um valor booleano que permite (ou não)
criar a chave caso a mesma não exista.
{ Este exemplo mostra como funciona como podemos
gravar dados do registro do Windows utilizando o Delphi
2 ou 3 }
procedure frmMain.GravarRegistro; const
Raiz : String = ‘Software\Programa’;
var
Registro : TRegistry;
begin
// Chama o construtor do objeto
Registro := TRegistry.Create;
{ Abre a chave (se o 2°. Parâmetro for True, ele cria a
chave caso ela ainda não exista. }
Registro.OpenKey (Raiz, True);
// Grava as informações do form
Registro.WriteInteger (‘Largura’, Width);
Registro.WriteInteger (‘Altura’, Height);
Registro.WriteInteger (‘Esquerda’, Left);
Registro.WriteInteger (‘Topo’, Top);
// Grava as informações das caixas Abrir e Salvar.
Registro.WriteString (‘Abrir Inicial’,
OpenDialog1.InitialDir);
Registro.WriteString(‘Salvar Inicial’,
SaveDialog1.InitialDir);
// Fecha a chave e o objeto
Registro.CloseKey;
Registro.Free;
end;
Após a criação do objeto, deve-se escolher uma chave
para armazenas os valores. No caso,
“Software\Programa“, cuja chave raiz é
HKEY_CURRENT_USER. Note que é para se separar
as chaves das sub-chaves utiliza-se o caracter “", tal
como nos diretórios do DOS.
Os métodos WriteInteger e WriteString são utilizados
para gravar valores inteiros e caracteres,
respectivamente. A sintaxe básica é:
Registro.WriteString (NomeDoValor, Conteúdo);
onde NomeDoValor é o nome que você vai dar ao valor
dentro da chave, e Conteúdo é o conteúdo desse valor.
Para se escrever dados de outros tipos, utilize as
funções:
WriteBool (NomeDoValor, Conteúdo); //
Boolean
WriteBinaryData (NomeDoValor, Conteúdo);
// Valor Binário
WriteCurrency (NomeDoValor, Conteúdo); //
Currency
WriteDate (NomeDoValor, Conteúdo); //
TDateTime
WriteDateTime (NomeDoValor, Conteúdo); //
TDateTime
WriteFloat (NomeDoValor, Conteúdo); //
Float (Real)
WriteInteger (NomeDoValor, Conteúdo); //
Integer
WriteString (NomeDoValor, Conteúdo); //
String
WriteTime (NomeDoValor, Conteúdo); //
TDateTime
{ Este exemplo mostra como funciona como podemos
ler dados do registro do Windows utilizando o Delphi 2
ou 3 }
procedure frmMain.LerRegistro;
const
Raiz : String = ‘Software\Programa’;
var
Registro : TRegistry;
begin
// Chama o construtor do objeto
Registro := TRegistry.Create;
with Registro do
begin
// Somente abre se a chave existir
if OpenKey (Raiz, False) then
// Envia as informações ao form, vendo se
os valores existem, primeiramente…
if ValueExists (‘Largura’) then
Width := ReadInteger (‘Largura’);
if ValueExists (‘Altura’) then
Height := ReadInteger (‘Altura’);
if ValueExists (‘Esquerda’) then
Left := ReadInteger (‘Esquerda’);
if ValueExists (‘Topo’) then
Top := ReadInteger (‘Topo’);
// Envia as informações para as caixas
Abrir e Salvar.
OpenDialog1.InitialDir := ReadString
(‘Abrir Inicial’);
SaveDialog1.InitialDir := ReadString
(‘Salvar Inicial’);
// Fecha a chave e o objeto
Registro.CloseKey;
Registro.Free;
end;
Sempre use CloseKey quando não for precisar do
Registro. Isso permite que as opções sejam gravadas
permanentemente, evitando que qualquer problema que
o computador tenha afete seu programa.
Os métodos ReadInteger e ReadString funcionam
praticamente da mesma maneira que seus
correspondentes de escrita. A diferença é que ao invés
de passar o valor Conteúdo, eles retornam o valor
armazenado. Os correspondentes dos outros tipos são:
ReadBool (NomeDoValor) : Boolean;
ReadBinaryData ( NomeDoValor ; var Buffer
; TamBuffer : Integer): Integer;
ReadCurrency (NomeDoValor) : Currency;
ReadDate (NomeDoValor) : TDateTime;
ReadDateTime (NomeDoValor) : TDateTime;
ReadFloat (NomeDoValor) : Double;
ReadInteger (NomeDoValor) : Integer;
ReadString (NomeDoValor) : String;
ReadTime (NomeDoValor) : TdateTime
676 - Tabelas DBase acentudas em
DOS, como corrigir?
Altere no BDE -> CONFIGURATION -> DRIVERS ->
NATIVE -> DBASE o parametro LANGDRIVER para
dBASE ENG cp437

O usuário Valmir Cardoso acrescentou que o cp437 não


funcinou com ele e sim o cp850
677 - Nomes dos arquivos que
estão sendo executados:
É comum e até relativamente fácil encontrarmos rotinas
para listar todas as janelas abertas. Mas muitas vezes
não é apenas o caption das janelas que queremos listar
e sim o nome do arquivo executável.
Veja então uma rotina que cria uma lista de strings com
esses nomes:
uses TLHelp32; // não esqueça de incluir
esta unit
procedure ListProcess(List: TStrings);
var
ProcEntry: TProcessEntry32;
Hnd: THandle;
Fnd: Boolean;
begin
List.Clear;
Hnd :=
CreateToolhelp32Snapshot(TH32CS_SNAPALL,
0);
if Hnd <> -1 then
begin
ProcEntry.dwSize :=
SizeOf(TProcessEntry32);
Fnd := Process32First(Hnd, ProcEntry);
while Fnd do
begin
List.Add(ProcEntry.szExeFile);
Fnd := Process32Next(Hnd, ProcEntry);
end;
CloseHandle(Hnd);
end;
end;
E para utilizar esta rotina é muito simples, veja:
procedure TForm1.Button1Click(Sender:
TObject);
begin
ListProcess(ListBox1.Items);
end;
678 - Como usar a cláusula UNION
em um Query:
O uso do componente TQuery gera muitas vantagens e
economiza muitas linhas de programação. Mas muitas
vezes nos deparamos com situações que parecem não
ser resolvidas com sentenças SQL. Vejamos um
exemplo:
Você possui 2 tabelas (VendasExternas e
VendasInternas) e deseja fazer um resumo de todas as
vendas de um vendedor chamado Marcos. Se você usar
a sentença
SELECT Nome, Valor FROM VendasExternas,
VendasInternas
WHERE Nome = ‘Marcos’
você vai obter como resultado uma query com 4 campos
(Nome, Valor, Nome_1 e Valor_1) e um resultado bem
confuso para ser manipulado.
Para resolver o problema, você poderá usar a sentença
SELECT Nome, Valor FROM VendasExternas
WHERE Nome = ‘Marcos’
UNION ALL
SELECT Nome, Valor FROM VendasInternas
WHERE Nome = ‘Marcos’
A sentença acima pede para que sejam identificados as
vendas de Marcos na tabela VendasExternas, as vendas
de Marcos na tabela VendasInternas e que o resultado
da primeira seja unido com o resultado da segunda
produzindo uma query com apenas 2 colunas.
679 - Alterando o NetDir via
programação:
Muitas vezes precisamos alterar o NetDir do BDE para
que nossas aplicações funcionem corretamente. E com
poucas linhas de código você poderá deixar para que
sua própria aplicação faça isso.
Abaixo está uma rotina para alterar o NetDir de acordo
com o drive informado como parâmetro:
uses BDE; // não esqueça de incluir esta
unit

// ChangeNetDir
procedure ChangeNetDir(Drive: Char);
var
hCur: hDBICur;
Config: CFGDesc;
Cont: Boolean;
begin
if DbiInit(nil) = DBIERR_NONE then
begin
hCur := nil;
if DbiOpenCfgInfoList(nil, dbiREADWRITE,
cfgPersistent,
‘\DRIVERS\PARADOX\INIT’, hCur) =
DBIERR_NONE then
begin
if DbiSetToBegin(hCur) = DBIERR_NONE
then
begin
Cont := True;
while Cont do
begin
if (DbiGetNextRecord(hCur, dbiWRITELOCK,
@Config, nil)
<> DBIERR_NONE) then
Cont := False
else if StrIComp(Config.szNodeName, ‘NET
DIR’) = 0 then
begin
StrPCopy(Config.szValue, Drive + ‘:');
DbiModifyRecord(hCur, @Config, True);
Cont := False
end;
end;
end;
end;
DbiExit();
end;
end;
O uso deste procedimento pode ser assim:
procedure TForm1.Button1Click(Sender:
TObject);
begin
ChangeNetDir(‘H’);
end;
682 - Zerar Campo
AutoIncremento:
Quanto trabalhamos com tabelas Paradox e apagamos
o seus registros, o contador do campo AutoIncremento
não é zerado, criando muitas vezes um grande
inconveniente. Para resolver esse problema, use a
seguinte função:
function ResetAutoInc(FileName: TFileName;
Base: Longint): Boolean;
begin
with TFileStream.Create(FileName,
fmOpenReadWrite) do
Result := (Seek($49, soFromBeginning) =
$49) and (Write(Base, 4) = 4);
end;
O parâmetro FileName é o nome da tabela, incluindo o
caminho. E o parâmetro Base é o valor inicial para o
contador do AutoIncremento.
683 - Manipulando o Internet
Explorer
Neste artigo ensinarei como manipular o Internet
Explorer, e através de sua aplicação poder ordenar
comandos ao Browser mais utilizado no mundo.
Inicie o Delphi e crie uma nova aplicação,Insira no
formulário 4 Tbuttons. Coloque na propriedade caption
do Button1 “Iniciar” e no evento OnClick, insira o
seguinte código:
procedure TForm1.Button1Click(Sender:
TObject);
begin
IEApp :=
CreateOLEObject(‘InternetExplorer.Applicat
ion’);
IEApp.visible := true;
IEApp.Top := 0;
IEApp.Left := 0;
IEApp.width := screen.width;
IEApp.height := screen.height;
IEApp.Navigate(‘http://www.ClubeDelphi.com
.br’);
end;
Explicando o código: Tenho certeza de que você já
notou a facilidade do código. Ele cria uma aplicação do
tipo Internet Explorer, e atribui algumas propriedades.
Essas propriedades servem para informar que o
navegador deve estar visível, informar a posição onde
será criado o browser, o tamanho da tela e o endereço
que ele vai abrir.
Coloque na propriedade caption do Button2 “Voltar” e no
evento OnClick, insira o seguinte código:
procedure TForm1.Button2Click(Sender:
TObject);
begin
IEApp.GoBack;
end;
Explicando o Código: O Botão irá funcionar como o
próprio botão Voltar do Browser.
Coloque na propriedade caption do Button3 “Avançar” e
no evento OnClick, insira o seguinte código:
procedure TForm1.Button3Click(Sender:
TObject);
begin
IEApp.GoForward;
end;
Explicando o Código: O Botão irá funcionar como o
próprio botão Avançar do Browser.
Coloque na propriedade caption do Button4 “Fechar” e
no evento OnClick, insira o seguinte código:
procedure TForm1.Button2Click(Sender:
TObject);
begin
IEApp.Quit;
end;
Explicando o Código: Este botão irá fechar o browser.
Agora, insira a Unit Comobj na parte de uses lá em cima
no código, depois adicione a variável IEApp do tipo
Variant na parte de declaração de variáveis onde está
declarado o formulário:
var
Form1: TForm1;
IEApp: Variant;

implementation
{$R *.DFM}
Agora salve e execute a sua aplicação e comece a
controlar o nosso Internet Explorer.
Existem ainda alguns outros comandos que podem ser
usados, tais como:
IEApp.Refresh; - Serve para atualizar o browser.
IEApp.Stop; - Serve para parar o browser.
IEApp.GoHome; - Serve para ir para a página inicial,
que está configurada em seu browser.
IEApp.FullScreen := true; - Serve para exibir o browser,
sem nenhuma barra de ferramenta.
IEApp.StatusText; := ‘Qualquer texto’;
Feito Por: Marco Antônio
marco@ClubeDelphi.com.br
684 - Como posso saber a coluna
que estou posicionado no DBGrid?
É fácil saber a coluna que você está no DBGrid. Para
isso vamos usar a propriedade SelectedIndex que
retorna o número da coluna. Veja um exemplo:
procedure
Tform1.DBGrid1ColEnter(Sender:TObject);
begin
Edit1.Text :=
IntToStr(DBGrid1.SelectedIndex);
end;
685 - Transformar inteiro em
romanos
function RomanNumber(Value: Longint):
string;
Label
A500, A400, A100, A90, A50, A40, A10,
A9, A5, A4, A1;
begin
Result := ”;
while Value >= 1000 do begin
Dec(Value, 1000); Result := Result +
‘M’;
end;
if Value < 900 then goto A500
else begin
Dec(Value, 900); Result := Result +
‘CM’;
end;
goto A90;
A400:
if Value < 400 then goto A100
else begin
Dec(Value, 400); Result := Result +
‘CD’;
end;
goto A90;
A500:
if Value < 500 then goto A400
else begin
Dec(Value, 500); Result := Result + ‘D’;
end;
A100:
while Value >= 100 do begin
Dec(Value, 100); Result := Result + ‘C’;
end;
A90:
if Value < 90 then goto A50
else begin
Dec(Value, 90); Result := Result + ‘XC’;
end;
goto A9;
A40:
if Value < 40 then goto A10
else begin
Dec(Value, 40); Result := Result + ‘XL’;
end;
goto A9;
A50:
if Value < 50 then goto A40
else begin
Dec(Value, 50); Result := Result + ‘L’;
end;
A10:
while Value >= 10 do begin
Dec(Value, 10); Result := Result + ‘X’;
end;
A9:
if Value < 9 then goto A5
else begin
Result := Result + ‘IX’;
end;
Exit;
A4:
if Value < 4 then goto A1
else begin
Result := Result + ‘IV’;
end;
Exit;
A5:
if Value < 5 then goto A4
else begin
Dec(Value, 5); Result := Result + ‘V’;
end;
goto A1;
A1:
while Value >= 1 do begin
Dec(Value); Result := Result + ‘I’;
end;
end;
686 - Como tabular um ListBox
procedure TForm1.FormActivate(Sender:
TObject);
var
MatTabs : Array[0..5] of Integer;
begin
MatTabs[0] := 40;
MatTabs[1] := 80;
MatTabs[2] := 200;
MatTabs[3] := 400;
MatTabs[4] := 500;
MatTabs[5] := 700;

ListBox1.Perform(LB_SETTABSTOPS,1,Integer(
@MatTabs[0]));
end;
687 - Pesquisa incremental em uma
listbox
procedure TForm1.Edit1Change(Sender:
TObject);
begin

Listbox1.Perform(LB_SELECTSTRING,0,LongInt
(PChar(Edit1.Text)));
end;
688 - Eliminando os hints de uma
treeview
procedure TForm1.Button1Click(Sender:
TObject);
begin
SetWindowLong(TreeView1.Handle, GWL_STYLE,
GetWindowLong(TreeView1.Handle,GWL_STYLE)
or $80);
end;
para mostrar os hints novamente
SetWindowLong(TreeView1.Handle, GWL_STYLE,
GetWindowLong(TreeView1.Handle,GWL_STYLE)
and not $80);
689 - Retorna o dia da semana em
formato string
Function DiadaSemana(Data : String) :
string;
const
semana : array[1..7] of string =
(‘Domingo’,‘Segunda-feira’,‘Terça-
feira’,‘Quarta-feira’,‘Quinta-
feira’,‘Sexta-feira’, ‘Sábado’);
begin
Result :=
semana[DayOfWeek(strtodate(Data))]
end;
690 - Pega o path de um arquivo
arrastado do explorer
uses
StdCtrls, ShellApi;
private
procedure WMDropFiles(var Msg :
TWMDropFiles); message WM_DROPFILES;

procedure TForm1.FormCreate(Sender:
TObject);
begin
DragAcceptFiles(Handle, True);
end;

procedure TForm1.WMDropFiles(var Msg:


TWMDropFiles);
var
i : Integer;
NumArqs : Integer;
NomeArq : String;
begin
SetLength(NomeArq,255);
NumArqs :=
DragQueryFile(Msg.Drop,$FFFFFFFF,PChar(Nom
eArq),255);
for i := 0 to NumArqs-1 do begin

DragQueryFile(Msg.Drop,i,PChar(NomeArq),25
5);
Listbox1.Items.Add(NomeArq);
end;
end;
691 - Como pegar a lista de
favoritos do Internet Explorer
function GetIEFavoritos(const favpath:
string):TStrings;
var
searchrec:TSearchrec;
str:TStrings;
path,dir,filename:String;
Buffer: array[0..2047] of Char;
found:Integer;
begin
str:=TStringList.Create;
//Pega todos os nomes de arquivo no path
dos favoritos
path:=FavPath+’\*.url’;
dir:=ExtractFilepath(path);

found:=FindFirst(path,faAnyFile,searchrec)
;
while found=0 do begin
SetString(filename, Buffer,
GetPrivateProfileString(‘InternetShortcut’
,
PChar(‘URL’), NIL, Buffer,
SizeOf(Buffer),
PChar(dir+searchrec.Name)));
str.Add(filename);
found:=FindNext(searchrec);
end;
found:=FindFirst(dir+’\*.*’,faAnyFile,sea
rchrec);
while found=0 do begin
if ((searchrec.Attr and faDirectory) >
0) and (searchrec.Name[1]<>’.’) then

str.AddStrings(GetIEFavourites(dir+’'+sear
chrec.name));
found:=FindNext(searchrec);
end;
FindClose(searchrec);
Result:=str;
end;

procedure TForm1.Button1Click(Sender:
TObject);
var pidl: PItemIDList;
FavPath: array[0..MAX_PATH] of char;
begin
SHGetSpecialFolderLocation(Handle,
CSIDL_FAVORITES, pidl);
SHGetPathFromIDList(pidl, favpath);
ListBox1.Items:= GetIEFavoritos
(StrPas(FavPath));
end;
692 - Como fechar um arquivo de
Help quando encerro minha
Aplicação
application.HelpCommand(help_quit, 0);
693 - Como mudar a cor de uma
regiao de Texto RichEdit
var
sStart: word;
begin
sStart := REdit.SelStart;
REdit.SelStart := 6;
REdit.SelLength := 10;
REdit.SelAttributes.color := clBlue; //
set color
REdit.SelAttributes.style :=
[fsUnderline]; // set attributes
Application.Processmessages;
REdit.SelStart := sStart;
REdit.SelLength := 0;
end;
694 - Como utilizar código de
barras no meu sistema
Para utilizar código de barras num sistema, existem
básicamente 03 tópicos:
1) Inclusão do código no seu banco
de dados:
O código de barras é um código como qualquer outro,
composto de números, e deve ser armazenado em seu
banco de dados num campo alfanumérico.
Existem vários tipos de código de barras, cada um com
seu algoritimo e tamanho. Os mais comuns - usados no
comercio - são o EAN8 e o EAN13, que como o próprio
nome já insinua têm 8 e 13 bytes cada um.
2)Leitura do código de barras:
Do ponto de vista do programa, existem 02 tipos de
leitura de código de barras: pela porta serial do micro e
pela interface do teclado.
A leitura feita pela interface do teclado (leitores
manuais) não requer nenhuma programação extra, pois
o código entra como se fosse digitado diretamente no
teclado.
A leitura feita pela porta serial já exige que você
implemente uma rotina de leitura da porta serial e deve
ser tratada internamente pelo programa, já que neste
caso nada vem pelo teclado.
3)Impressão do código de barras:
A maioria dos produtos hoje em dia já vêm com o
código de barras definidos e impressos pelo fabricante.
Para os casos em que o fabricante não,tenha um código
de barras definido, você pode e deve definir um código
interno e imprimi-lo.
Para a impressão do código, você pode desenvolver
sua própria rotina de impressão, usando o TPrinter, ou
usar algum componente pronto (nestes 02 casos, uma
impressora jato de tinta ou a laser resolvem), ou
comprar uma impressora específica para impressão de
código de barras.
Um bom livro sobre o assunto: Código de Barras - da
Teoria à Prática de Fábio Grossmann e Mauro Luiz
Zyngier.
695 - Como copiar tabelas Paradox
para Texto ou DBase e vice-versa
1) Inclua um TDATABASE no seu
Form e sete as seguintes
propriedades:
DatabaseName = ‘Temp’
DriverName = ‘STANDARD’
Params.Strings = ‘path=c:&#9;este’ (ou qq outro path)
Connected = True
2) Inclua outro TTable em seu Form
e sete as seguintes propriedades:
DatabaseName = ‘Temp’
Name = ‘DESTINO’
TableType = ttASCII ou ttDbase ou ttParadox
TableName = o nome da nova tabela, sem extensão.
Ex: ‘Clientes’
IMPORTANTE: Não mexa na propriedade ACTIVE.
3) Inclua um TTable em seu Form,
contendo a tabela que você quer
copiar e mude a propriedade Name
para ORIGEM.
IMPORTANTE: Não mexa na propriedade ACTIVE.
4) Inclua um TBATCHMOVE em seu
Form e sete as seguintes
propriedades:
Destination = ‘DESTINO’
Mode = batCopy
Source = ‘ORIGEM’
5) Inclua um TBUTTON em seu
form e dê um duplo click no evento
OnClick.
6) Escreva o seguinte código na
procedure OnClick:
var
fn: FMTNumber;
begin
// O código a seguir verifica se o
separador de
// decimais é virgula e muda-o, para
evitar
// problemas de compatibilidade
Check(DbiGetNumberFormat(fn));
if fn.cDecimalSeparator = ‘,’ then
begin
fn.cDecimalSeparator := ‘.’;
fn.cThousandSeparator := ‘,’;
DbiSetNumberFormat(fn);
end;
// Aqui executamos a CÓPIA
BatchMove1.Execute;
end;
696 - Deletar um diretório inteiro
de uma vez
Problemas para deletar um diretório com subdiretórios?
Utilize a função abaixo:
Uses
Shellapi, filectrl, //declare estas das
units!!!

function DeleteFolder(FolderName: String;


LeaveFolder: Boolean): Boolean;
var
r: TshFileOpStruct;
begin
Result := False;
if not DirectoryExists(FolderName) then
Exit;
if LeaveFolder then
FolderName := FolderName + ‘ *.* ‘
else
if FolderName[Length(FolderName)] = ‘ \
‘ then
Delete(FolderName,Length(FolderName),
1);
FillChar(r, SizeOf(r), 0);
r.wFunc := FO_DELETE;
r.pFrom := PChar(FolderName);
r.fFlags := FOF_ALLOWUNDO or
FOF_NOCONFIRMATION;
Result := ((ShFileOperation(r) = 0) and
(not r.fAnyOperationsAborted));
end;
Usa-se Assim:
procedure TForm1.Button1Click(Sender:
TObject);
begin
deleteFolder(‘c:\temp’,false);
end;
697 - Habilitar e desabiliar a senha
do protetor de tela
Inclua a unit REGISTRY na clausula uses do seu form.
// Habilita
procedure TForm1.Button1Click(Sender:
TObject);
var
Registry: TRegistry;
begin
Registry := TRegistry.Create;
Registry.RootKey := HKEY_CURRENT_USER;
Registry.OpenKey(‘\Control Panel\Desktop’,
TRUE);
Registry.WriteInteger(‘ScreenSaveUsePasswo
rd’,$0);
Registry.CloseKey;
Registry.Free;
end;

// Desabilita

procedure TForm1.Button2Click(Sender:
TObject);
var
Registry: TRegistry;
begin
Registry := TRegistry.Create;
Registry.RootKey := HKEY_CURRENT_USER;
Registry.OpenKey(‘\Control Panel\Desktop’,
TRUE);
Registry.WriteInteger(‘ScreenSaveUsePasswo
rd’,$1);
Registry.CloseKey;
Registry.Free;
end;
698 - Sobrescrevendo um evento
Para executar algo antes do evento Showmodal por
exemplo, utilize o seguinte:
public
function showmodal: integer;

function TMeuForm.Showmodal : integer;


begin
{ Aqui vai tudo que se precisa fazer antes
}
result := inherited showmodal;
end;
699 - “Clicando” um componente
sem clicar nele
1 - Insira um ListBox e preencha-o com alguns itens;
2 - Insira um botão qualquer;
3 - No evento OnDblClick do ListBox, digite:
Button1.Perform(WM_LBUTTONDOWN, 0, 0);
701 - Como fazer para ajustar o
tamanho da lista de um
DBLookupComboBox?
Resp: Altere o valor da propriedade DropDownWidth
para o tamanho desejado
{Dica retirada da Lista de Discussão Delphi-br}
{Resposta de Fernando Sarturi Prass}
corigida por Fabiano
 
702 - Como descobrir o código de
uma tecla pressionada?
Na maioria dos componentes existem eventos que
ocorrem quando o teclado é acionado
Ex:
Num Form existe os eventos:
1º OnKeyDown => Quando a tecla é apertada.
2º OnKeyUp => Quando a tecla é solta
3º OnKeyPress => Quando a tecla e apertada.
Os três devolvem uma variável chamada Key;
Os dois primeiros Key é uma word, no terceiro Key é um
char.
Para você saber o nº de um tecla é só colocar no evento
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word;
Shift:TShiftState);
Begin
ShowMessage(‘O nº da tecla:
‘+Char(ORD(Key))+’ é => ‘+IntToStr(key));
End;

Assim você sabe o valor de cada tecla e pode testar se


ela foi acionada.
O legal não é testar este valor e sim trabalhar com a
Virtual Key Code
Exemplo:
procedure TForm1.FormKeyDown(Sender:
TObject; var Key: Word; Shift:
TShiftState);
Begin
IF Key=VK_Return Then ShowMessage(‘Você
apertou o enter’);
End;

Esse VK_Return é da Virtual Key Code, você terá que


pesquisar no Help, Segue abaixo as outras teclas:
VK_LBUTTON Left mouse button
VK_RBUTTON Right mouse button
VK_CANCEL Control+Break
VK_MBUTTON Middle mouse button
VK_BACK Backspace key
VK_TAB Tab key
VK_CLEAR Clear key
VK_RETURN Enter key
VK_SHIFT Shift key
VK_CONTROL Ctrl key
VK_MENU Alt key
VK_PAUSE Pause key
VK_CAPITAL Caps Lock key
VK_KANA Used with IME
VK_HANGUL Used with IME
VK_JUNJA Used with IME
VK_FINAL Used with IME
VK_HANJA Used with IME
VK_KANJI Used with IME
VK_CONVERT Used with IME
VK_NONCONVERT Used with IME
VK_ACCEPT Used with IME
VK_MODECHANGE Used with IME
VK_ESCAPE Esc key
VK_SPACE Space bar
VK_PRIOR Page Up key
VK_NEXT Page Down key
VK_END End key
VK_HOME Home key
VK_LEFT Left Arrow key
VK_UP Up Arrow key
VK_RIGHT Right Arrow key
VK_DOWN Down Arrow key
VK_SELECT Select key
VK_PRINT Print key (keyboard-specific)
VK_EXECUTE Execute key
VK_SNAPSHOT Print Screen key
VK_INSERT Insert key
VK_DELETE Delete key
VK_HELP Help key
VK_LWIN Left Windows key (Microsoft
keyboard)
VK_RWIN Right Windows key (Microsoft
keyboard)
VK_APPS Applications key (Microsoft
keyboard)
VK_NUMPAD0 0 key (numeric keypad)
VK_NUMPAD1 1 key (numeric keypad)
VK_NUMPAD2 2 key (numeric keypad)
VK_NUMPAD3 3 key (numeric keypad)
VK_NUMPAD4 4 key (numeric keypad)
VK_NUMPAD5 5 key (numeric keypad)
VK_NUMPAD6 6 key (numeric keypad)
VK_NUMPAD7 7 key (numeric keypad)
VK_NUMPAD8 8 key (numeric keypad)
VK_NUMPAD9 9 key (numeric keypad)
VK_MULTIPLY Multiply key (numeric keypad)
VK_ADD Add key (numeric keypad)
VK_SEPARATOR Separator key (numeric
keypad)
VK_SUBTRACT Subtract key (numeric keypad)
VK_DECIMAL Decimal key (numeric keypad)
VK_DIVIDE Divide key (numeric keypad)
VK_F1 F1 key
VK_F2 F2 key
VK_F3 F3 key
VK_F4 F4 key
VK_F5 F5 key
VK_F6 F6 key
VK_F7 F7 key
VK_F8 F8 key
VK_F9 F9 key
VK_F10 F10 key
VK_F11 F11 key
VK_F12 F12 key
VK_F13 F13 key
VK_F14 F14 key
VK_F15 F15 key
VK_F16 F16 key
VK_F17 F17 key
VK_F18 F18 key
VK_F19 F19 key
VK_F20 F20 key
VK_F21 F21 key
VK_F22 F22 key
VK_F23 F23 key
VK_F24 F24 key
VK_NUMLOCK Num Lock key
VK_SCROLL Scroll Lock key
VK_LSHIFT Left Shift key (only used with
GetAsyncKeyState and GetKeyState)
VK_RSHIFT Right Shift key (only used with
GetAsyncKeyState and GetKeyState)
VK_LCONTROL Left Ctrl key (only used with
GetAsyncKeyState and GetKeyState)
VK_RCONTROL Right Ctrl key (only used with
GetAsyncKeyState and GetKeyState)
VK_LMENU Left Alt key (only used with
GetAsyncKeyState and GetKeyState)
VK_RMENU Right Alt key (only used with
GetAsyncKeyState and GetKeyState)
VK_PROCESSKEY Process key
VK_ATTN Attn key
VK_CRSEL CrSel key
VK_EXSEL ExSel key
VK_EREOF Erase EOF key
VK_PLAY Play key
VK_ZOOM Zoom key
VK_NONAME Reserved for future use
VK_PA1 PA1 key
VK_OEM_CLEAR Clear key
{Dica retirada da Lista de Discussão Delphi-br}
{Resposta de Claudio H. Binaghi}
703 - Como Reindexar um Banco
M$Access 2000?
Uses
comobj, db, dbtables;

procedure
TFormReindexar.Button1Click(Sender:
TObject);
var
dao: OLEVariant;
begin
try
Panel1.Caption:=‘Compactando Tabela’;
Panel1.Repaint;
dao := CreateOleObject(‘DAO.DBEngine.36’);
dao.CompactDatabase(extractfiledir(Applica
tion.ExeName)+’\banco.mdb’,
extractfiledir(Application.ExeName)+’\banc
o2.mdb’,”,0,’;pwd=1203583’);
Panel1.Caption:=‘Apagando Arquivo
Temporário’;
Panel1.Repaint;
if
FileExists(extractfiledir(Application.ExeN
ame)+’\banco2.mdb’) then
DeleteFile(extractfiledir(Application.ExeN
ame)+’\banco.mdb’);
Panel1.Caption:=‘Renomeando Arquivo’;
Panel1.Repaint;
if
FileExists(extractfiledir(Application.ExeN
ame)+’\banco2.mdb’) then
RenameFile(extractfiledir(Application.ExeN
ame)+’\banco2.mdb’,extractfiledir(Applicat
ion.ExeName)+’\banco.mdb’);
Panel1.Caption:=‘Arquivo Banco.mdb
Compactado’;
Panel1.Repaint;
except
panel1.caption:=‘Ocorreu um Erro durante a
compactação’;
end;
DataModule1.ADOConnection1.Connected:=true
;
end;

{Dica by Lloyd Dickinson}


704 - Como alterar a Página Inicial
do IE via Programação
Abaixo temos as duas funções que respectivamente
servem para: retornar a página inicial e alterar a pagina
inicial lembre-se que é necessário adcionar a Unit
Registry a cláusula uses do aplicativo para poder
compilar.

implementation
Uses Registry;
{$R *.DFM}

function GetIEStartPage : string;


Var
Reg : TRegistry;
begin
Reg:= TRegistry.Create;
try
Reg.RootKey:= HKEY_CURRENT_USER;
Reg.OpenKey(‘Software\Microsoft\Internet
Explorer\Main’,false);
try
result := Reg.ReadString(‘Start Page’);
except
result := ”;
end;
Reg.CloseKey;
finally
Reg.Free;
end;
end;

function SetIEStartPage(APage : string) :


boolean;
Var
Reg : TRegistry;
begin
Reg:= TRegistry.Create;
try
Reg.RootKey:= HKEY_CURRENT_USER;
Reg.OpenKey(‘Software\Microsoft\Internet
Explorer\Main’,false);
try
Reg.WriteString(‘Start Page’,APage);
result := true;
finally
Reg.CloseKey;
result := false;
end;
finally
Reg.Free;
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);{Aqui vc vê qual a página
inicial}
begin
ShowMessage(GetIEStartPage);
end;

procedure TForm1.Button2Click(Sender:
TObject);{Aqui vc altera a página inicial}
begin

SetIEStartPage(‘www.napoles.hpg.com.br’);
end;
end.

{Dica retirada do site Delphi Journal}


705 - Sistemas Numéricos
Introdução
Em nosso cotidiano utilizamos muitos números. E quase sempre
estamos usando o sistema decimal, ou seja, números formados
por dígitos de zero a nove. Porém existem outros sistemas
numéricos, os quais são usados para os mais variados
propósitos. Vejamos a seguir uma pequena lista dos principais
sistemas numéricos:

Decimal
Romano
Binário
Hexadecimal
BCD e outros.

Neste artigo estudaremos um pouco sobre os sistemas decimal,


binário e hexadecimal.
Sistemas Numéricos Posicionais
Para iniciar nossos estudos vamos entender o que é um sistema
numérico posicional. Para este propósito vamos considerar os
números 4664 (decimal) e XXXVII (37 em romano). Vamos
observar algumas propriedades importantes nestes dois
números:

O valor do primeiro algarismo 4 é diferente do valor do


último algarismo 4 no número decimal 4664. O primeiro
indica 4 mil e o último indica 4 unidades. O mesmo
acontece com o algarismo 6. O primeiro indica 6 centenas,
enquanto o segundo indica 6 dezenas.
No número romano, cada um dos X vale 10,
independentemente de sua posição. O mesmo acontece
com o V e com o I.

A partir destas observações podemos concluir que no sistema


decimal o valor de um determinado símbolo depende de sua
posição, ou seja, este é um sistema posicional. O mesmo não
acontece com o sistema romano e, portanto, o sistema romano
não é posicional.
Os sistemas binário e hexadecimal também são sistemas
numéricos posicionais.

Valor Posicional
Como já vimos, em um sistema posicional um mesmo símbolo
pode assumir valores diferentes dependendo de sua posição.
Sendo assim, para sabermos o valor de qualquer número que
esteja escrito em um sistema posicional, precisamos conhecer o
valor posicional de cada símbolo. Isto é o que veremos a seguir.

Fórmula para cálculo do valor posicional

Para calcular o valor de um determinado símbolo em um número


que esteja representado com sistema posicional, precisamos
aplicar a fórmula do valor posicional que é:
V=S*B^P
Vamos conhecer melhor esta fórmula:

V Valor posicional do símbolo. Exemplo: o valor posicional do símbolo 4


no número decimal 345 é 40.

S Valor absoluto do símbolo. Exemplo: o valor do símbolo 4 no sistema


decimal é 4.

B Base do sistema numérico. É a quantidade de símbolos que dispomos


para escrever os números. Exemplos:
No sistema decimal temos 10 símbolos (de zero a nove), portanto
a base deste sistema é 10.
No sistema binário temos 2 símbolos (zero e um), portanto a base
deste sistema é 2.

P É a posição em que o símbolo em questão se encontra no número.


Esta posição é definida da direita para esquerda e inicia em zero.
Exemplos:
A posição do símbolo 5 no número 345 é 0 (zero).
A posição do símbolo 4 no número 345 é 1.
A posição do símbolo 3 no número 345 é 2.

Obs.: Na fórmula V = S * B ^ P, usamos o asterisco para indicar multiplicação


e o acento circunflexo para indicar potência. Sendo assim leia-se esta
fórmula como:
V é igual a S que multiplica B elevado ao expoente P.

Conhecendo esta fórmula fica fácil sabermos o valor de


qualquer número, seja ele decimal, binário, hexadecimal, etc.
Basta calcular o valor posicional de cada símbolo do número
dado e então somar os valores encontrados. Vejamos um
exemplo:
Vamos considerar novamente o número decimal 345.

Posição 2 1 0

Símbolos 3 4 5

Valor V=3 * V=4 * V=5 *


posicional 10^2 10^1 10^0
V=3 * 100 V=4 * 10 V=5 * 1
V=300 V=40 V=5

Somando os valores encontrados temos:


300 + 40 + 5 = 345.
Acredito que nunca precisaremos fazer todos estes cálculos
para concluir que o número decimal 345 vale 345. Mas este é
apenas um exemplo didático para demonstrar a aplicação a
aplicação da fórmula do valor posicional.
Atenção!
Esta fórmula só se aplica a números que usem sistema
posicional. Não é válida, por exemplo, para calcular números no
sistema romano, visto que este não é um sistema posicional.
Sistema Decimal
O sistema decimal é provavelmente o sistema numérico
posicional mais antigo que conhecemos. Surgiu na Índia e, aos
poucos, foi substituindo os demais sistemas numéricos
existentes e hoje é quase universal. Para representar um
número decimal usamos 10 símbolos (0, 1, 2, …, 9), e portanto
sua base é 10.
Sistema Binário
Para nós, seres humanos, o sistema numérico decimal é
bastante satisfatório. No entanto para uma máquina, como o
computador, este sistema não é muito prático, visto que os
dados precisam ser interpretados usando-se o estado da
corrente elétrica (ligada/desligada, alta/baixa, ou algo parecido).
Para resolver este impasse foi elaborado o sistema de
numeração binária, que usa os dígitos ZERO e UM em sua
representação, os quais correspondem aos estados desligado e
ligado, respectivamente. O uso de dois símbolos determina que
este é um sistema de base 2. No sistema binário o valor de um
símbolo (zero ou um) depende de sua posição, o que significa
que este também é um sistema posicional.
Embora o sistema binário resolva o problema das máquinas
eletrônicas, para nós o sistema decimal continua sendo o
preferido. Então o que fazer para que possamos conviver
harmoniosamente com os dois sistemas numéricos? Precisamos
saber como converter números de decimal para binário e vice-
versa.

Convertendo de Decimal para Binário


Como representar o número 37 em binário? Para responder esta
pergunta podemos utilizar uma calculadora científica. Como não
teremos sempre uma calculadora científica ao nosso dispor é
melhor aprender todos os passos para fazer tal conversão.
Estes passos são, na verdade, divisões sucessivas do número
dado por 2 (base do sistema binário), até que tenhamos um
quociente zero. Veja abaixo como converter o número 37 para
binário:

Dividendo Divisor Quociente Resto

37 2 18 1

18 2 9 0

9 2 4 1
4 2 2 0

2 2 1 0

1 2 0 1

Para obtermos a representação binária, tomamos os restos das


divisões na ordem inversa. Para o caso anterior temos 100101,
que a representação binária do número 37.

Convertendo de Binário para Decimal


Já sabemos como converter de decimal para binário. Agora
vamos aprender a conversão inversa, ou seja, de binário para
decimal. Para fazer esta conversão precisamos calcular o valor
posicional de cada símbolo do número dado. Então usaremos a
fórmula valor posicional:
V=S*B^P
Sabendo que o sistema binário possui base igual a dois,
tomaremos o exemplo do número 100101:

Posição 5 4 3 2 1 0

Símbolo 1 0 0 1 0 1

Valor V=1*2^5 V=0*2^4 V=0*2^3 V=1 V=0*2^1 V=1*2^0


posicional V=1*32 V=0*16 V=0* 8 *2^2 V=0*2 V=1*1
V=1*4
V=32 V=0 V=0 V=0 V=1
V=4

Somando os valores dos dígitos (32 + 0 + 0 + 4 + 0 +1) teremos


o total 37, que é a representação decimal do número binário
100101.
Sistema Hexadecimal
Este é um outro sistema numérico posicional bastante usado em
informática, especialmente em programação assembly. Neste
sistema dispomos de 16 símbolos conforme mostra a tabela
abaixo:

Símbolo Valor
absoluto

0 0

1 1

2 2

3 3

4 4

5 5

6 6

7 7

8 8

9 9

A 10

B 11

C 12

D 13

E 14

F 15
Convertendo de Decimal para Hexadecimal
Sabendo-se que o sistema hexadecimal dispõe de 16 símbolos,
concluímos que sua base é 16. Aplicando a mesma técnica que
utilizamos na conversão de decimal para binário podemos
converter qualquer número decimal para hexadecimal
facilmente. Vejamos o exemplo da conversão do número
decimal 23870 para hexadecimal:

Dividendo Divisor Quociente Resto

23870 16 1491 14

1491 16 93 3

93 16 5 13

5 16 0 5

Tomando-se os restos na ordem inversa e seus respectivos


símbolos, temos:

Resto 5 13 3 14

Símbolo 5 D 3 E

Assim concluímos que o número decimal 23870 convertido para


hexadecimal é: 5D3E.

Convertendo de Hexadecimal para Decimal


Esta conversão também é bastante simples. Como o sistema
hexadecimal também é posicional, basta aplicar a fórmula do
valor posicional a cada símbolo e somar os resultados obtidos.
Veja no exemplo abaixo como converter o número hexadecimal
5C3FA para decimal:
Posição 4 3 2 1 0

Símbolo 5 C 3 F A

Valor absoluto 5 12 3 15 10

Valor V=5*16^4 V=12*16^3 V=3*16^2 V=15*16^1 V=10*16^0


posicional
V=5*65536 V=12*4096 V=3*256 V=15*16 V=10*1
V=327680 V=49152 V=768 V=240 V=10

Somando-se os valores posicionais encontrados, temos:


327680 + 49152 + 768 + 240 + 10 = 377850
Portanto o número hexadecimal 5C3FA convertido para decimal
é: 377850.

Autor: Daniel Pereira Guimarães


E-mail: tecnobyte@ulbrajp.com.br
Todos os direitos reservados.

IntereSite - www.ulbrajp.com.br/~tecnobyte
Dicas, artigos, apostilas, componentes, exemplos e código-fonte
para Delphi.
706 - Construindo Threads com
Delphi
Hoje em dia, os programas de computador devem ser
cada vez mais rápidos de serem executados e que
possam realizar várias tarefas ao mesmo tempo, para
que o usuário possa realizar outras operações, ao
mesmo tempo que as executa.
Mas para que isso aconteça, nós desenvolvedores de
software devemos escrever nossos programas
baseados nesta tecnologia de muitas linhas de
execução, ou simplesmente “Threads”.
Um thread pode realizar vários operações residindo num
memso espaço de endereço na memória, quem
realmente controla esses threads é o sistema
operacional, que se baseia em suas prioridades. Essas
proridades são setadas por nós quando desenvolvemos
um thread. A boa nova, é que o Delphi é compatível com
esta tecnologia e fico triste quando vejo muitas pessoas
que ainda se empolgam muito pelo fato do Delphi ser
visual e fácil de usar, e esquecem de seu enorme
potencial.
Eu resolvi mostrar como se faz um thread, pois, é de
suma responsabilidade de um programador que uma
aplicação fique estável, e não devemos, num projeto
grande, nos basear somente na arquitetura de
Orientação a Objeto e IDE aprimorado do Delphi para
Desenvolver software.
Para se criar um thread em Delphi, devemos criar uma
classe que derive da classe “TThread”, que está escrita
na biblioteca “Classes”. A classe TThread é uma classe
abstrata, portanto não podemos utilizá-la diretamente,
pois devemos implementar um de seus métodos. Esse
método se chama “Execute”, ele é responsável por todo
o funcionamento do seu Thread. Junto com esse
método, temos o outro método “Synchronize” que serve
para acessar partes da VCL sem que percamos o
controle da aplicação, ou seja, o Windows ainda possa
controlar nossos objetos enviando mensagens para
eles. Esse método tem um único argumento que é do
tipo procedimento, ou seja, temos que definir
procedimentos em nossa classe que controlem a VCL, e
quando quisermos chamá-los, devemos passá-los como
argumento do método Synchronize. O nosso thread fará
o seguinte: Ele irá contar quantas linhas um arquivo
texto possui, e a cada linha que ele ler, irá incrementar
uma label que estará num form. A classe ficará assim:

type
TContador = class(TThread)
private
FNomeArq: string;
FNLinhas: Longint;
protected
procedure Execute; override; // Método
anulado
procedure IncLabel; virtual;
public
constructor Create(const Arquivo:
string);
end;

implementation

procedure TContador.Execute;
var
Arq: TextFile;
S: string;
begin
try
AssignFile(Arq, FNomeArq);
Reset(Arq);
while (not SeekEof(Arq)) do
begin
ReadLn(Arq, S);
FNLinhas := FNLinhas + 1;
Synchronize(IncLabel); // Aqui é chamado
o contador…
end;
finally
CloseFile(Arq);
end;
end;

procedure TContador.IncLabel;
begin
Form1.Label1.Caption :=
IntToStr(FNLinhas);
{ o Contador será executado em modo
protegido por uma Seção Critica do
Windows}
end;

constructor TContador.Create(const
Arquivo: string);
begin
inherited Create(True); { Chama o
contrutor herdado. Ele irá temporariamente
colocar o thread em estado de espera para
depois executá-lo. }
FNomeArq := Arquivo;
FreeOnTerminate := True; // Libera o
objeto após terminar.
Priority := TpLower; { Configura sua
prioridade na lista de processos do
Sistema operacional. }
Resume; // Inicia o Thread.
end;

para construir este exemplo, inicie uma nova aplicação,


coloque um “Edit” e uma “Label” no Form. Inclua um
botão também que quando pressionado irá contar as
linhas do arquivo que estiver no Edit. Escreva a classe
acima numa unit separada e no código do botão faça
assim:
procedure TForm1.Button1Click(Sender:
TObject);
var
Cont: TContador;
begin
Cont := TContador.Create(Edit1.Text);
end;
Com esse código simples, podemos calcular quantas
linhas estiverem no arquivo do Edit. Para testar digite no
Edit o arquivo “C:\Frunlog.txt”.
Espero que vocês gostem da surpresa, e dada a
facilidade enorme de se criar um thread em Delphi,
aconselho a vocês a utilizarem threads mais
frequentemente nos seus aplicativos. Mas não em
excesso e sejam cautelosos configurando as prioridades
dos Threads.
Abraços
Ass.: Ricardo Ferreira
{Dica retirada do Site Delphi Journal}
707 - Validando formato de e-mail
Primeiramente vc deverá ter num form: Um Edit (ou
DBEdit), Um Button e Um Label.
Antes de implementation coloque:
const
msg1 = ‘Caractere(s) inválido(s) no
início do e-mail.’;
msg2 = ‘Símbolo @ não foi encontrado.’;
msg3 = ‘Excesso do símbolo @.’;
msg4 = ‘Caractere(s) inválido(s) antes
do símbolo @.’;
msg5 = ‘Caractere(s) inválido(s) depois
do símbolo @.’;
msg6 = ‘Agrupamento de caractere(s)
inválido(s) a esqueda do @.’;
msg7 = ‘Não existe ponto(s)
digitado(s).’;
msg8 = ‘Ponto encontrado no final do e-
mail.’;
msg9 = ‘Ausência de caractere(s) após o
último ponto.’;
msg10 = ‘Excesso de ponto(s) a direita
do @.’;
msg11 = ‘Ponto(s) disposto(s) de forma
errada após o @.’;
msg12 = ‘Caractere(s) inválido(s) antes
do ponto.’;
msg13 = ‘Caractere(s) inválido(s) depois
do ponto.’;

var
Form1: TForm1; { <– Nome do meu
formulário }
vet_valido: array [0..35] of string =
(‘0’,‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,
‘8’,‘9’,‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,
‘g’,‘h’,‘i’,‘j’,‘k’,‘l’,‘m’,‘n’,
‘o’,‘p’,‘q’,‘r’,‘s’,‘t’,‘u’,‘v’,
‘w’,‘x’,‘y’,‘z’);
Depois de implementation {$R *.DFM} coloque a
seguinte função:
function func_VerifEmail(email: string):
boolean;
var
i, j, tam_email, simb_arroba,
simb_arroba2, qtd_arroba, qtd_pontos,
qtd_pontos_esq, qtd_pontos_dir, posicao,
posicao2, ponto, ponto2: integer;
vet_email: array [0..49] of string; //50
posições, capacidade do Edit
msg: string;
begin
{Por Jaci Jr em 12-10-2001 (00:28 às
03:57)
Contatos por
jrcordeiro@eletroacre.com.br ou
jrcordeiro@bol.com.br
Nesta função (func_VerifEmail) é
utilizada a função Copy, exemplo:
Copy(s,i,t) significa trecho de s que
começa em i com tamanho t}

qtd_pontos:= 0; qtd_pontos_esq:= 0;
qtd_pontos_dir:= 0; qtd_arroba:= 0;
posicao:=0; posicao2:=0; simb_arroba:=0;
simb_arroba2:=0; ponto:= 0;
ponto2:= 0; msg:=”;
Result:= True;

//Verificando parte inicial do E-mail


tam_email:= Length(email);
for i:= 0 to tam_email-1 do
begin
vet_email[i]:= Copy(email,i+1,1);
if vet_email[i] = ‘@’ then
begin
Inc(qtd_arroba);
posicao:= i;
end;
end;

if ((vet_email[0] = ‘@’) or
(vet_email[0] = ‘.’) or (vet_email[0] =
‘-‘)) then
begin
Result:= False;
msg:= msg1;
end;

//Verificando se tem o símbolo @ e


quantos tem
if qtd_arroba < 1 then
begin
Result:= False;
msg:= msg2;
end
else if qtd_arroba > 1 then
begin
Result:= False;
msg:= msg3 + ‘ Encontrado(s):
‘+IntToStr(qtd_arroba)+’.’;
end
else
//Verificando o que vem antes e depois
do símbolo @
begin
for i:=0 to 35 do
begin
if vet_email[posicao-1] <> vet_valido[i]
then Inc(simb_arroba)
else Dec(simb_arroba);
if vet_email[posicao+1] <> vet_valido[i]
then Inc(simb_arroba2)
else Dec(simb_arroba2);
end;
if simb_arroba = 36 then
begin
//Antes do arroba há um símbolo
desconhecido do vetor válido
Result:= False;
msg:= msg4;
end
else if simb_arroba2 = 36 then
begin
//Depois do arroba há um símbolo
desconhecido do vetor válido
Result:= False;
msg:= msg5;
end
end;

//Verificando se há pontos e quantos, e


Verificando parte final do e-mail
for j:=0 to tam_email-1 do
if vet_email[j] = ‘-‘ then
if ((vet_email[j-1] = ‘.’) or
(vet_email[j-1] = ‘-‘)) then
begin
Result:= False;
msg:= msg6;
end;
for i:=0 to tam_email-1 do
if vet_email[i] = ‘.’ then
begin
Inc(qtd_pontos);
posicao2:= i+1;
if i > posicao then Inc(qtd_pontos_dir)
else Inc(qtd_pontos_esq);
if ((vet_email[i-1] = ‘.’) or
(vet_email[i-1] = ‘-‘)) then
begin
Result:= False;
msg:= msg6;
end;
end;
if qtd_pontos < 1 then
begin
Result:= False;
msg:= msg7;
end
else if vet_email[tam_email-1] = ‘.’
then
begin
Result:= False;
msg:= msg8;
end
else if vet_email[tam_email-2] = ‘.’
then
begin
Result:= False;
msg:= msg9;
end
else if qtd_pontos_dir > 2 then
begin
Result:= False;
msg:= msg10 + ‘ Encontrado(s): ‘+
IntToStr(qtd_pontos)+#10+‘Encontrado(s)
a direita do @: ‘+
IntToStr(qtd_pontos_dir)+’.’;
end
else if (not ((((tam_email - posicao2) =
3) and (qtd_pontos_dir = 1)) or
(((tam_email - posicao2) = 2) and
(qtd_pontos_dir = 2)) or
(((tam_email - posicao2) = 2) and
(qtd_pontos_dir = 1)))) then
begin
Result:= False;
msg:= msg11 +#10+ ‘Encontrado(s) a
esquerda do @: ‘+
IntToStr(qtd_pontos_esq) +#10+
‘Encontrado(s) a direita do @: ‘+
IntToStr(qtd_pontos_dir)+’.’;
end
else
//Verificando o que vem antes e depois
do ponto
begin
for i:=0 to 35 do
begin
if vet_email[posicao2-2] <>
vet_valido[i] then Inc(ponto)
else Dec(ponto);
if vet_email[posicao2] <> vet_valido[i]
then Inc(ponto2)
else Dec(ponto2);
end;
if ponto = 36 then
begin
//Antes do ponto há um símbolo
desconhecido do vetor válido
Result:= False;
msg:= msg12;
end
else if ponto2 = 36 then
begin
//Depois do ponto há um símbolo
desconhecido do vetor válido
Result:= False;
msg:= msg13;
end
end;

//Verificação final
if not Result then
begin
msg:= msg +#10+ ‘Formato de E-mail não
aceitável!!’;
MessageDlg(msg,mtWarning,[mbRetry],0);
end;
end;

{Os componentes devem ser configurados


assim: O Form possui keypreview=true e
evento onkeypress, o Edit possui evento
onchange e o Button possui evento onclick.
As procedures seguem abaixo}

procedure TForm1.Button1Click(Sender:
TObject);
begin
Label1.Caption:= ”;
if Trim(Edit1.Text)<>” then
if (func_VerifEmail(Trim(Edit1.Text)))
then
begin
Label1.Caption:= Trim(Edit1.Text)+’ está
OK.’+#10+‘Formato aceitável.’;
Button1.Enabled:= False;
end
else
begin Button1.SetFocus; Edit1.SetFocus;
Edit1.SelText; end
end;

procedure TForm1.FormKeyPress(Sender:
TObject; var Key: Char);
begin
if Key = #13 then Button1Click(Sender);
if (not ((Key in [‘0’..‘9’]) or (Key in
[‘A’..‘Z’]) or
(Key in [‘a’..‘z’]) or (Key = ‘@’) or
(Key = ‘.’) or (Key = ‘-‘))) then
Key:= #0;
end;

procedure TForm1.Edit1Change(Sender:
TObject);
begin
Label1.Caption:= ”;
Button1.Enabled:= True;
end;
//Ligue os eventos corretamente e verifique o resultado

{Dica Retirada do Site Delphi Journal}


708 - Como pegar a posição do
mouse na tela
Para obter os valores das coordenadas do mouse de
qualquer parte da tela, basta que se utiliza a função da
API do Windows GetCursorPos. Esta função é
interessante pois oferece ao programador os valores
(x,y) de qualquer ponto da tela e não somente da
aplicação.
Para implementação, esta função pode ser utilizada da
seguinte maneira:
procedure TForm1.Timer1Timer(Sender:
TObject);
var
pt: TPoint;
begin
GetCursorPos(pt); // Pega a posição
atual do mouse;
//Mostra os valores das coordenadas do
mouse
label1.caption := IntToStr(pt.x) + ‘,’ +
IntToStr(pt.y);
end;

Esta é mais uma das milhares de funções da API do


Windows.
Abraços,
Alessandro F. Leite

{Dica retirada do Site Delphi Journal}


709 - Como tranformar de inteiro
(Milisegundos) em formato Timer
Vc quer passar milisegundos para segundos no formato
Time. Faça assim:

function MSecToTime ( const intTime:


integer ): string;
const
intMSec = 1 / 24 / 60 / 60 / 1000; // o
equivalente a 1 milisegundo
begin
// define o retorno com o formato Time
result := TimeToStr ( intTime * intMSec
);
end;
{Dica retirada da lista de discussão Delphi-br}
{Resposta de Carlos A. Longen}
710 - Obter a célula de um
StringGrid que está sob o cursor do
mouse
Inclua na seção uses: Windows
procedure MouseCell(Grid: TStringGrid;
var Coluna, Linha: integer);
var
Pt: TPoint;
begin
GetCursorPos(Pt);
Pt := Grid.ScreenToClient(Pt);
if PtInRect(Grid.ClientRect, Pt) then
Grid.MouseToCell(Pt.X, Pt.Y, Coluna,
Linha)
else begin
Coluna := -1;
Linha := -1;
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
var
Coluna, Linha: integer;
begin
MouseCell(StringGrid1, Coluna, Linha);
if (Coluna >= 0) and (Linha >= 0) then
Caption := ‘Coluna: ‘ + IntToStr(Coluna)
+ ‘ - ‘ +
‘Linha: ‘ + IntToStr(Linha);
else
Caption := ‘O mouse não está no
StringGrid’;
end;
{Dica enviada por Marco Barki Algranti}
711 - Fechando todas as tabelas de
um aplicativo
var
i: integer;
begin
with Session do
for i:= 0 to DatabaseCount - 1 do
Databases[I].Close;
end;
{Dica enviada por Marco Barki Algranti}
712 - Retorna quantos dias tem um
referido mes do ano
function DiasNoMes(AYear, AMonth:
Integer): Integer;
const
DaysInMonth: array[1..12] of Integer =
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31);
begin
if AMonth = 2 then
begin
if Ayear mod 4 = 0 then
begin
Inc(DaysInMonth[AMonth]);
end;
end;
Result := DaysInMonth[AMonth];
end;
{Dica enviada por Marco Barki Algranti}
713 - Retorna a diferenca de dias
entre duas datas
function DifDias(DataVenc:TDateTime;
DataAtual:TDateTime): String;
Var Data: TDateTime;
dia, mes, ano: Word;
begin
if DataAtual < DataVenc then
begin
Result := ‘A data data atual não pode ser
menor que a data inicial’;
end
else
begin
Data := DataAtual - DataVenc;
DecodeDate( Data, ano, mes, dia);
Result := FloatToStr(Data)+’ Dias’;
end;
end;
{Dica enviada por Marco Barki Algranti}
714 - Converte um certo número de
segundos em horas já formatado
function FormatSecsToHMS(Secs: LongInt):
string;
var
Hrs, Min: Word;
begin
Hrs := Secs div 3600;
Secs := Secs mod 3600;
Min := Secs div 60;
Secs := Secs mod 60;
Result := Format(‘%d:%d:%d’, [Hrs, Min,
Secs]);
end;
{Dica enviada por Marco Barki Algranti}
715 - Como colocar um componente
ComboBox em um componente
StringGrid
//Inclua no seu Form um componente
ComboBox e um componente StringGrid.
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
ComboBox1: TComboBox;

procedure FormCreate(Sender: TObject);


procedure ComboBox1Change(Sender:
TObject);
procedure ComboBox1Exit(Sender: TObject);
procedure StringGrid1SelectCell
(Sender: TObject; Col, Row: Integer;
var CanSelect: Boolean);

private
{ Private declarations }

public
{ Public declarations }

end;

var
Form1: TForm1;

implementation

{$R *.DFM}

// Evento OnCreate do Form


procedure TForm1.FormCreate(Sender:
TObject);
begin
{ Ajusta a altura do ComboBox com a altura
da linha do StringGrid}
StringGrid1.DefaultRowHeight :=
ComboBox1.Height;
{Esconde o ComboBox}
ComboBox1.Visible := False;
end;

// Evento OnChange do componente ComboBox


procedure TForm1.ComboBox1Change(Sender:
TObject);
begin
StringGrid1.Cells[StringGrid1.Col,StringGr
id1.Row] :=
ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible := False;
StringGrid1.SetFocus;
end;

// Evento OnExit do componente ComboBox


procedure TForm1.ComboBox1Exit(Sender:
TObject);
begin
StringGrid1.Cells[StringGrid1.Col,StringGr
id1.Row] :=
ComboBox1.Items[ComboBox1.ItemIndex];
ComboBox1.Visible := False;
StringGrid1.SetFocus;
end;

// Evento OnSelectCell do componente


StringGrid
procedure
TForm1.StringGrid1SelectCell(Sender:
TObject; Col, Row: Integer;
var CanSelect: Boolean);
var
R: TRect;
begin
if ((Col = 3) AND
(Row <> 0)) then begin
R := StringGrid1.CellRect(Col, Row);
R.Left := R.Left + StringGrid1.Left;
R.Right := R.Right + StringGrid1.Left;
R.Top := R.Top + StringGrid1.Top;
R.Bottom := R.Bottom + StringGrid1.Top;
ComboBox1.Left := R.Left + 1;
ComboBox1.Top := R.Top + 1;
ComboBox1.Width := (R.Right + 1) - R.Left;
ComboBox1.Height := (R.Bottom + 1) -
R.Top;
ComboBox1.Visible := True;
ComboBox1.SetFocus;
end;
CanSelect := True;
end;

{Dica enviada por Marco Barki Algranti}


716 - Colocar senha geral em um
banco de dados Access
procedure TForm1.Button1Click(Sender:
TObject);
var
DBDAO: Variant;
begin
DBDAO :=
CreateOleObject(‘DAO.DBEngine.35’);
Screen.Cursor :=3D3D crHourGlass;
try
DBDAO.CompactDatabase(‘C:SeuBancodeDadosAt
ual.MDB’,
‘C:CopiaCompactadadoBancodeDados.MDB’,,,’;
PWD=3DsenhadoBD’);
finally
Screen.Cursor := crDefault;
DBDAO := Unassigned;
end;
ShowMessage(‘Operacao Concluida’);
end;
{Dica enviada por Marco Barki Algranti}
717 - Procedimento para pedir uma
senha antes de abrir o
FormPrincipal
procedimento para que seu sistema pessa uma senha
antes de abrir de um duplo clique no form principal e
digite o seguinte código:
procedure TForm1.FormCreate(Sender:
TObject);
var
senha: string[6];
begin
senha:=inputbox(‘Código’,‘Digite a Senha
de Acesso’,”);
if (senha<>‘MASTER’)and(senha<>‘master’)
then
begin {no lugar de Master digite sua
senha}
SHOWMESSAGE(‘SENHA INCORRETA’);
halt;
end;
end;
{Dica enviada por Pablo Gomes Mariano}
718 - Corrigir Erros de campo
AutoIncremento
Esta procedure corrige erro em campos auto incremento
(ftAutoInc), quando ocorre o key violation provocado
pela perda do sequencial do campo.

Procedure AcertaAutoInc(NomeAlias :
String);
Var ParamAlias, AliasTab: Tstrings;
contador, I : integer;
VlrAutoInc,VLRregAutInc : Longint;
AutoIncOK, EAutoInc : Boolean;
Tabela: TTable;
arqteste, CampoAutoInc, PathAlias:
String;
begin
EAutoInc := false;
ParamAlias := TStringList.create;
AliasTab := TStringList.create;

Session.GetTableNames(NomeAlias,’*.db’,tru
e, true, AliasTab);
contador := 0;

Session.GetAliasParams(NomeAlias,ParamAlia
s);
PathAlias := ParamAlias.Values[ ‘PATH’
];
if copy(PathAlias,length(PathAlias),1) =
‘' then
PathAlias :=
copy(PathAlias,1,length(PathAlias)-1);
while contador <> AliasTab.Count do
begin
with TFileStream.Create( PathAlias
+’'+AliasTab.Strings[contador],
fmOpenReadWrite) do
begin
AutoIncOK := (Seek($49, soFromBeginning)
= $49) and (Read(VlrAutoInc, 4) = 4);
free;
end;
if AutoIncOK then
begin
with TTable.Create(Application) do
try
DatabaseName := NomeAlias;
TableName := AliasTab.Strings[contador];
with FieldDefs do
begin
Update;
for I := 0 to Count -1 do
begin
if Items[i].DataType = ftAutoInc then
begin
CampoAutoInc := (Items[I].Name);
EAutoInc := true;
end;
end;
end;
finally
Free;
end;
end
else
begin
Application.MessageBox(‘Erro na
recuperação do campo Auto-
Incremento.’,‘Atenção’,MB_OK);
Exit;
end;
if EAutoInc then
begin
Tabela := TTable.create(Application);
Tabela.DatabaseName := NomeAlias;
Tabela.TableName :=
AliasTab.Strings[Contador];
Tabela.open;
if Tabela.RecordCount > 0 then
begin
Tabela.Last;
VLRregAutInc :=
Tabela.FieldByName(CampoAutoInc).Value;
end;
Tabela.close;
if VlrAutoInc < VLRregAutInc then
begin
with TFileStream.Create(PathAlias +’'+
AliasTab.Strings[contador],
fmOpenReadWrite) do
begin
AutoIncOK := (Seek($49, soFromBeginning)
= $49) and (Write(VLRregAutInc , 4) = 4);
free;
end;
end;
if AutoIncOK = false then
Application.MessageBox(‘Erro na
recuperação do campo Auto-
Incremento.’,‘Atenção’,MB_OK);
end;
EAutoInc := false;
contador := contador + 1;
end;
ParamAlias.Free;
AliasTab.Free;
end;
{Dica enviada por:Jasoni Corrêa}
719 - Label escrita letra a letra
Tenho uma dica aqui que até é legalzinha…
Ela digita letra por letra…
com certeza pode ser melhorado, mas é só uma dica..
Será utilizado: Um TLabel e um TTimer, sendo que o
Caption do Tlabel já esteja definido antes de dar o
Create do Form..

public
LetraNum:Integer;
Frase:String;

//No OnCreate do Form:


Frase := Label1.Caption;
LetraNum := 0;
Label1.Caption := ”;

//No OnTimer do TTimer:


Label1.Caption := Copy(Frase,1,LetraNum);
Inc(LetraNum);
if Label1.Caption = Frase then
Timer1.Enabled := False;
{Dica enviada por Marcus}
720 - Função Split
function splitstr(valor, caracter: string;
index: integer): string;
var
anterior,i,contador:integer;
begin
contador:=0;
for i:=0 to length(valor) do
begin
if valor[i]=caracter then
begin
if (contador = index-1) then
begin
result:=copy(valor,anterior+1,i-
anterior-1);
exit;
end;
anterior:=i;
inc(contador,1);
end;

if i=length(valor) then
begin
result:=copy(valor,anterior+1,i-
anterior);
exit;
end;

if index=1 then
begin

result:=copy(valor,0,pos(caracter,valor)-1
);
exit;
end;
end;
end;

exemplo:
splitstr(‘aaa\bbb\ccc\ddd’,’',3)=ccc
{Dica enviada por Tberg}
721 - Função que arredonda valores
Excelente função para arrendondamento de valores.
Alias, a única que funciona.
function Arredondar(Valor: Double; Dec:
Integer): Double;
var
Valor1,
Numero1,
Numero2,
Numero3: Double;
begin
Valor1:=Exp(Ln(10) * (Dec + 1));
Numero1:=Int(Valor * Valor1);
Numero2:=(Numero1 / 10);
Numero3:=Round(Numero2);
Result:=(Numero3 / (Exp(Ln(10) * Dec)));
end;

{Dica Enviada por Jair Marquetti}


722 - Como vazar um form usando
letras
Procedure TForm1.FormPaint(sender:
TObject);
var
r : hrgn;
begin
// para pintar em qualquer lugar use
GetWindowDC e passe o
// handle do local a ser pintado.
with canvas do begin
Handle := GetWindowDC(Form1.handle);
SetBkMode(handle,TRANSPARENT);
SetPolyFillMode(handle,WINDING);
// marca o inicio do “molde”
BeginPath(handle);
// escreve com a fonte, tamanho e estilo
do local a ser pintado
// caso queira mudar a fonte use (neste
caso estamos pintando no form)
// Form1.font.name := ‘Arial’; //nome da
fonte desejada
// Form1.font.size := 36;
// Form1.font.color := clBlue; // cor
desejada
TextOut(10,100,‘Delphi’);
// A área de pintura deve ser a área
original do componente ou
// form, se passar não vai aparecer.
EndPath(handle); // fim do “molde”
// A diferença vem agora, trasformamos o
path em região e
// trabalhamos como em uma imagem.
r := PathToRegion(Canvas.handle);
FillPath(handle);
// Agora podemos “recortar” o form
// a janela fica na forma do que foi
escrito.
SetWindowRGN(Form1.handle,r,true);
// lembre-se de colocar meios de se fechar
a janela, já que o botão // fechar também
será destruido. o alt+tab continua
ativando o // menu do sistema.
end; // fim do with

end;
{Dica enviada por Wendel Machado}
723 - Pesquisa de um string
mudando o texto
Coloque no OnChange do Edit1 o Código
Abaixo

var
i : integer;
aux: integer;
begin
aux:=1;
for i:=0 to Length(RichEdit1.Text) do
begin
if
(Copy(RichEdit1.Text,i+1,length(Edit1.Text
)) =
Edit1.Text) then
begin
RichEdit1.SelStart := aux;
RichEdit1.SelLength := i-aux+1;
RichEdit1.SelAttributes.Color := ClBlack;
RichEdit1.SelAttributes.Style := [];
RichEdit1.SelStart := i;
RichEdit1.SelLength := Length(Edit1.text);
RichEdit1.SelAttributes.Color := ClRed;
RichEdit1.SelAttributes.Style := [fsBold];
aux := i + length(Edit1.Text);
end;
end;
RichEdit1.SelStart := aux;
RichEdit1.SelLength := i-aux+1;
RichEdit1.SelAttributes.Color := ClBlack;
RichEdit1.SelAttributes.Style := [];
end;

A dica acima foi enviada por Wendel Bezerra Silva


Para usar vc deve colocar um Edit e um Richedit num
form e colocar algum texto no richedit!
Quando se digita alguma palavra no edit se ocorrer
alguma coincidencia no richedit esse texto ficará em
vermelho!
Bem legal essa dica!
Obs: Se o conteúdo do Richedit for excessivo o
processo fica um pouco demorado!
724 - Função para Abrir e Fechar
Query
Function AbreQuery(Qry: TQuery): Boolean;
begin
// Abre Querys
If not(Qry.Active) Then
Begin
If Not(Qry.Prepared) Then
Qry.Prepare;
Qry.Open;
Result := True;
End
Else
Result := False;
end;

Function FechaQuery(Qry: TQuery): Boolean;


begin
// Fecha Querys
If (Qry.Active) Then
Begin
Qry.Close;
Result := True;
End
Else
Result := False;
If (Qry.Prepared) Then
Qry.UnPrepare;
end;
{Dica enviada por Ricardo Figueira}
725 - Códigos de Erro do BDE
DECIMAL HEXADECIMAL DESCRICAO
0 0000 Término bem-sucedido.
33 0021 Erro do sistema.
34 0022 Objeto de interesse não-
localizado.
35 0023 Danos físicos aos dados.
36 0024 Erro relacionado a I/O.
37 0025 Erro de recurso ou limite.
38 0026 Violação de integridade de dados.
39 0027 Pedido inválido.
40 0028 Violação de bloqueio.
41 0029 Violação de acesso/segurança.
42 002A Contexto inválido.
43 002B Erro do sistema operacional.
44 002C Erro de rede.
45 002D Parâmetro opcional.
46 002E Processador de consulta.
47 002F Divergência de versão.
48 0030 Capacidade não aceita.
49 0031 Erro de configuração do sistema.
50 0032 Advertência.
51 0033 Diversos.
52 0034 Erro de compatibilidade.
62 003E Erro específico do driver.
63 003F Símbolo interno.
256 0100 KEYVIOL.
257 0101 PROBLEMS.
258 0102 CHANGED.
512 0200 Arquivo de índice de produção
inexistente, danificado ou não pode
interpretar chave de índice.
513 0201 Abrir apenas para leitura.
514 0202 Abrir a tabela no modo apenas de
leitura.
515 0203 Abrir e destacar.
516 0204 Abrir a tabela e destacar o
arquivo de índice de produção.
517 0205 Falha na abertura.
518 0206 Não abrir a tabela.
519 0207 Converter índice não-dBASE.
520 0208 Converter índice de produção para
formato do dBASE.
521 0209 Arquivo BLOB não localizado.
522 020A Abrir sem arquivo BLOB.
523 020B Abrir a tabela sem o arquivo
BLOB.
524 020C Esvaziar todos os campos BLOB.
525 020D Reinicializar arquivo BLOB e
perder todos os BLOBs.
526 020E Falha na abertura.
527 020F Não abra a tabela.
528 0210 Importar arquivo BLOB não-dBASE.
529 0211 Importar arquivo BLOB para o
formato do dBASE.
530 0212 Abrir como tabela não-dBASE.
531 0213 Abrir tabela e arquivo BLOB no
seu formato nativo.
532 0214 Divergência de driver de
linguagem do índice de produção.
533 0215 Índice de produção danificado.
534 0216 Recriar índice de produção.
535 0217 Recriar todos os índices de
produção.
1024 0400 Tabela de pesquisa não
localizada ou danificada.
1025 0401 Arquivo BLOB não localizado ou
danificado.
1026 0402 Abrir somente para leitura.
1027 0403 Abrir a tabela no modo somente
de leitura.
1028 0404 Falha na abertura.
1029 0405 Não abrir a tabela.
1030 0406 Remover pesquisa.
1031 0407 Remover vínculo com tabela de
pesquisa.
1280 0500 Existe objeto de dicionário.
1281 0501 Pular este objeto.
1282 0502 Pular a importação deste objeto
e seus relacionamentos associados.
1283 0503 Usar objeto existente.
1284 0504 Usar objeto do dicionário
existente para os relacionamentos.
1285 0505 Abortar
1286 0506 Abortar a operação.
1287 0507 Importação do objeto de
dicionário falhou.
4608 1200 SQL Unknown.
4609 1201 SQL Prepare.
4610 1202 SQL Execute.
4611 1203 SQL Error.
4612 1204 SQL STMT.
4613 1205 SQL Connect.
4614 1206 SQL Transact.
4615 1207 SQL BLOB I/O.
4616 1208 SQL Misc.
4617 1209 SQL Vendor.
4618 120A ORACLE – orlon.4619 120B ORACLE
– olon.4620 120C ORACLE – ologof.4621 120D
ORACLE – ocon.4622 120E ORACLE – ocof.4623
120F ORACLE – oopen.4624 1210 ORACLE –
osql3.4625 1211 ORACLE – odsc.4626 1212
ORACLE – odefin.4627 1213 ORACLE –
obndrv.4628 1214 ORACLE – obndrvn.4629
1215 ORACLE – oexec.4630 1216 ORACLE –
ofetch.4631 1217 ORACLE – ofen.4632 1218
ORACLE – ocan.4633 1219 ORACLE –
oclose.4634 121A ORACLE – oerhms.4635 121B
ORACLE – oparse.4636 121C ORACLE –
oflng.4637 121D ORACLE – odessp.4638 121E
ORACLE – odescr.4639 121F ORACLE –
oexn.4648 1228 INTRBASE –
isc_attach_database.4649 1229 INTRBASE –
isc_blob_default_desc.4650 122A INTRBASE –
isc_blob_gen_bpb.4651 122B INTRBASE –
isc_blob_info.4652 122C INTRBASE –
isc_blob_lookup_desc.4653 122D INTRBASE –
isc_close_blob.4654 122E INTRBASE –
isc_commit_retaining.4655 122F INTRBASE –
isc_commit_transaction.4656 1230 INTRBASE
– isc_create_blob.4657 1231 INTRBASE –
isc_create_blob2.4658 1232 INTRBASE –
isc_decode_date.4659 1233 INTRBASE –
isc_detach_database.4660 1234 INTRBASE –
isc_dsql_allocate_statement.4661 1235
INTRBASE – isc_dsql_execute.4662 1236
INTRBASE – isc_dsql_execute2.4663 1237
INTRBASE – isc_dsql_fetch.4664 1238
INTRBASE – isc_dsql_free_statement.4665
1239 INTRBASE – isc_dsql_prepare.4666 123A
INTRBASE – isc_dsql_set_cursor_name.4667
123B INTRBASE – isc_dsql_sql_info.4668
123C INTRBASE – isc_encode_date.4669 123D
INTRBASE – isc_get_segment.4670 123E
INTRBASE – isc_interprete.4671 123F
INTRBASE – isc_open_blob.4672 1240
INTRBASE – isc_open_blob2.4673 1241
INTRBASE – isc_put_segment.4674 1242
INTRBASE – isc_rollback_transaction.4675
1243 INTRBASE – isc_sqlcode.4676 1244
INTRBASE – isc_start_transaction.4677 1245
INTRBASE – isc_vax_integer.4688 1250 MSSQL
– dbbind.4689 1251 MSSQL – dbcmd.4690 1252
MSSQL – dbcancel.4691 1253 MSSQL –
dbclose.4692 1254 MSSQL – dbcollen.4693
1255 MSSQL – dbcolname.4694 1256 MSSQL –
dbcoltype.4695 1257 MSSQL – dbconvert.4696
1258 MSSQL – dbdataready.4697 1259 MSSQL –
dbdatlen.4698 125A MSSQL –
dberrhandle.4699 125B MSSQL –
dbfreebuf.4700 125C MSSQL –
dbfreelogin.4701 125D MSSQL –
dbhasretstat.4702 125E MSSQL – dbinit.4703
125F MSSQL – dblogin.4704 1260 MSSQL –
dbmoretext.4705 1261 MSSQL –
dbmsghandle.4706 1262 MSSQL –
dbnextrow.4707 1263 MSSQL – dbnumcols.4708
1264 MSSQL – dbnumrets.4709 1265 MSSQL –
dbopen.4710 1266 MSSQL – dbresults.4711
1267 MSSQL – dbretdata.4712 1268 MSSQL –
dbretlen.4713 1269 MSSQL –
dbretstatus.4714 126A MSSQL –
dbrpcinit.4715 126B MSSQL –
dbrpcparam.4716 126C MSSQL –
dbrpcsend.4717 126D MSSQL –
dbsetlogintime.4718 126E MSSQL –
dbsetmaxprocs.4719 126F MSSQL –
dbsetopt.4720 1270 MSSQL – dbsettime.4721
1271 MSSQL – dbsqlexec.4722 1272 MSSQL –
dbsqlok.4723 1273 MSSQL – dbsqlsend.4724
1274 MSSQL – dbtxptr.4725 1275 MSSQL –
dbtxtimestamp.4726 1276 MSSQL –
dbtxtsnewval.4727 1277 MSSQL – dbuse.4728
1278 MSSQL – dbwinexit.4729 1279 MSSQL –
dbwritetext.4738 1282 ODBC –
SQLAllocConnect.4739 1283 ODBC –
SQLAllocEnv.4740 1284 ODBC –
SQLAllocStmt.4741 1285 ODBC –
SQLBindCol.4742 1286 ODBC –
SQLBindParameter.4743 1287 ODBC –
SQLCancel.4744 1288 ODBC – SQLColumns.4745
1289 ODBC – SQLConnect.4746 128A ODBC –
SQLDataSources.4747 128B ODBC –
SQLDescribeCol.4748 128C ODBC –
SQLDisconnect.4750 128E ODBC –
SQLError.4751 128F ODBC –
SQLExecDirect.4752 1290 ODBC –
SQLExtendedFetch.4753 1291 ODBC –
SQLFetch.4754 1292 ODBC –
SQLFreeConnect.4755 1293 ODBC –
SQLFreeEnv.4756 1294 ODBC –
SQLFreeStmt.4757 1295 ODBC –
SQLGetConnectOption.4758 1296 ODBC –
SQLGetCursorName.4760 1298 ODBC –
SQLGetFunctions.4761 1299 ODBC –
SQLGetInfo.4762 129A ODBC –
SQLGetTypeInfo.4763 129B ODBC –
SQLNumResultCols.4764 129C ODBC –
SQLProcedures.4765 129D ODBC –
SQLProcedureColumns.4766 129E ODBC –
SQLRowCount.4767 129F ODBC –
SQLSetConnectOption.4768 12A0 ODBC –
SQLSetCursorName.4769 12A1 ODBC –
SQLSetParam.4770 12A2 ODBC –
SQLSetStmtOption.4771 12A3 ODBC –
SQLStatistics.4772 12A4 ODBC –
SQLTables.4773 12A5 ODBC –
SQLTransact.4788 12B4 SYBASE – dbbind.4789
12B5 SYBASE – dbcmd.4790 12B6 SYBASE –
dbcancel.4791 12B7 SYBASE – dbclose.4792
12B8 SYBASE – dbcollen.4793 12B9 SYBASE –
dbcolname.4794 12BA SYBASE –
dbcoltype.4795 12BB SYBASE –
dbconvert.4796 12BC SYBASE – dbpoll.4797
12BD SYBASE – dbdatlen.4798 12BE SYBASE –
dberrhandle.4799 12BF SYBASE –
dbfreebuf.4800 12C0 SYBASE –
dbloginfree.4801 12C1 SYBASE –
dbhasretstat.4802 12C2 SYBASE –
dbinit.4803 12C3 SYBASE – dblogin.4804
12C4 SYBASE – dbmoretext.4805 12C5 SYBASE
– dbmsghandle.4806 12C6 SYBASE –
dbnextrow.4807 12C7 SYBASE –
dbnumcols.4808 12C8 SYBASE –
dbnumrets.4809 12C9 SYBASE – dbopen.4810
12CA SYBASE – dbresults.4811 12CB SYBASE –
dbretdata.4812 12CC SYBASE – dbretlen.4813
12CD SYBASE – dbretstatus.4814 12CE SYBASE
– dbrpcinit.4815 12CF SYBASE –
dbrpcparam.4816 12D0 SYBASE –
dbrpcsend.4817 12D1 SYBASE –
dbsetlogintime.4818 12D2 SYBASE –
dbsetmaxprocs.4819 12D3 SYBASE –
dbsetopt.4820 12D4 SYBASE – dbsettime.4821
12D5 SYBASE – dbsqlexec.4822 12D6 SYBASE –
dbsqlok.4823 12D7 SYBASE – dbsqlsend.4824
12D8 SYBASE – dbtxptr.4825 12D9 SYBASE –
dbtxtimestamp.4826 12DA SYBASE –
dbtxtsnewval.4827 12DB SYBASE – dbuse.4828
12DC SYBASE – dbwinexit.4829 12DD SYBASE –
dbwritetext.4830 12DE SYBASE –
dbcount.4831 12DF SYBASE – dbdead.4942
134E Código de erro SQL não mapeado.
8449 2101 Impossível abrir arquivo do
sistema.
8450 2102 Erro de I/O em um arquivo do
sistema.
8451 2103 Danos na estrutura de dados.
8452 2104 Impossível localizar arquivo de
configuração do mecanismo.
8453 2105 Impossível gravar no arquivo de
configuração do mecanismo.
8454 2106 Impossível inicializar com
arquivo de configuração diferente.
8455 2107 Sistema foi reentrado
ilegalmente.
8456 2108 Impossível localizar
IDAPI32.DLL.
8457 2109 Impossível carregar IDAPI32.DLL.
8458 210A Impossível carregar uma
biblioteca de serviço IDAPI.
8459 210B Impossível criar ou abrir
arquivo temporário.
8705 2201 No início da tabela.
8706 2202 No final da tabela.
8707 2203 Registro movido porque o valor-
chave foi alterado.
8708 2204 Registro/chave alterados.
8709 2205 Nenhum registro atual.
8710 2206 Impossível localizar registro.
8711 2207 Fim do BLOB.
8712 2208 Impossível localizar objeto.
8713 2209 Impossível localizar membro da
família.
8714 220A Arquivo BLOB inexistente.
8715 220B Impossível localizar driver da
linguagem.
8961 2301 Cabeçalho de tabela/índice
danificado.
8962 2302 Arquivo danificado – não o
cabeçalho.8963 2303 Arquivo memo/BLOB
danificado.
8965 2305 Índice danificado.
8966 2306 Arquivo de bloqueio danificado.
8967 2307 Arquivo de família danificado.
8968 2308 Arquivo VAL danificado ou
inexistente.
8969 2309 Formato de arquivo de índice
externo.
9217 2401 Falha na leitura.
9218 2402 Falha na gravação.
9219 2403 Impossível acessar diretório.
9220 2404 Falha na operação de exclusão de
arquivo.
9221 2405 Impossível acessar arquivo.
9222 2406 Acesso à tabela desativado por
causa de erro anterior.
9473 2501 Memória insuficiente para esta
operação.
9474 2502 Alças de arquivo insuficientes.
9475 2503 Espaço em disco insuficiente.
9476 2504 Limite de recurso de tabela
temporária.
9477 2505 Tamanho do registro muito grande
para a tabela.
9478 2506 Muitos cursores abertos.
9479 2507 Tabela cheia.
9480 2508 Muitas sessões a partir desta
estação de trabalho.
9481 2509 Limite de número de série
(Paradox).
9482 250A Algum limite interno (ver
contexto).
9483 250B Muitas tabelas abertas.
9484 250C Muitos cursores por tabela.
9485 250D Muitos bloqueios de registro na
tabela.
9486 250E Muitos clientes.
9487 250F Muitos índices na tabela.
9488 2510 Muitas sessões.
9489 2511 Muitos bancos de dados abertos.
9490 2512 Muitas senhas.
9491 2513 Muitos drivers ativos.
9492 2514 Muitos campos na criação de
tabela.
9493 2515 Muitos bloqueios de tabela.
9494 2516 Muitos BLOBs abertos.
9495 2517 Arquivo de bloqueio cresceu
muito.
9496 2518 Muitas consultas abertas.
9498 251A Muitos BLOBs.
9499 251B Nome de arquivo muito longo para
uma tabela do Paradox 5.0.
9500 251C Limite de busca de linha
excedido.
9501 251D Nome longo não permitido para
este nível de tabela.
9729 2601 Violação de chave.
9730 2602 Falha na verificação de validade
mínima.
9731 2603 Falha na verificação de validade
máxima.
9732 2604 Valor de campo requerido.
9733 2605 Registro mestre inexistente.
9734 2606 Mestre possui registros de
detalhe. Impossível excluir ou modificar.
9735 2607 Nível da tabela mestra
incorreto.
9736 2608 Valor de campo fora do intervalo
da tabela de pesquisa.
9737 2609 Falha na operação de abertura de
tabela de pesquisa.
9738 260A Falha na operação de abertura de
tabela de detalhe.
9739 260B Falha na operação de abertura de
tabela mestre.
9740 260C Campo em branco.
9741 260D Vínculo com tabela mestre já
definido.
9742 260E Tabela mestre aberta.
9743 260F Tabelas de detalhe existem.
9744 2610 Mestre possui registros de
detalhe. Impossível esvaziá-la.
9745 2611 Integridade referencial de auto-
referência precisa ser incluída uma de
cada vez, sem outras mudanças na tabela.
9746 2612 Tabela de detalhe aberta.
9747 2613 Impossível tornar esta tabela
mestra em detalhe de outra tabela se seus
detalhes não estiverem vazios.
9748 2614 Campos de integridade
referencial precisam estar indexados.
9749 2615 Uma tabela vinculada pela
integridade referencial exige senha para
ser aberta.
9750 2616 Campo(s) vinculado(s) a mais de
um mestre.
9985 2701 Número fora do intervalo.
9986 2702 Parâmetro inválido.
9987 2703 Nome de arquivo inválido.
9988 2704 Arquivo não existe.
9989 2705 Opção inválida.
9990 2706 Alça inválida para a função.
9991 2707 Tipo de tabela desconhecido.
9992 2708 Impossível abrir arquivo.
9993 2709 Impossível redefinir chave
primária.
9994 270A Impossível alterar este
RINTDesc.
9995 270B Chave externa e primária
divergentes.
9996 270C Pedido de modificação inválido.
9997 270D Índice não existe.
9998 270E Offset inválido no BLOB.
9999 270F Número de descritor inválido.
10000 2710 Tipo de arquivo inválido.
10001 2711 Descritor de campo inválido.
10002 2712 Transformação de campo
inválida.
10003 2713 Estrutura de registro inválida.
10004 2714 Descritor inválido.
10005 2715 Array inválido de descritores
de índice.
10006 2716 Array inválido de descritores
de verificação de validade.
10007 2717 Array inválido de descritores
de integridade referencial.
10008 2718 Ordenação inválida de tabelas
durante a reestrutura.
10009 2719 Nome não exclusivo neste
contexto.
10010 271A Nome de índice exigido.
10011 271B Alça de sessão inválida.
10012 271C Operação de reestrutura
inválida.
10013 271D Driver não conhecido no
sistema.
10014 271E Banco de dados desconhecido.
10015 271F Senha inválida fornecida.
10016 2720 Nenhuma função de callback.
10017 2721 Tamanho inválido do buffer de
callback.
10018 2722 Diretório inválido
10019 2723 Erro de tradução. Valor fora
dos limites.
10020 2724 Impossível definir cursor de
uma tabela para outra.
10021 2725 Bookmarks não combinam com a
tabela.
10022 2726 Nome de índice/tag inválido.
10023 2727 Descritor de índice inválido.
10024 2728 Tabela não existe.
10025 2729 Tabela possui muitos usuários.
10026 272A Impossível avaliar chave ou
chave não passa condição de filtro.
10027 272B Índice já existe.
10028 272C Índice aberto.
10029 272D Tamanho de BLOB inválido.
10030 272E Alça de BLOB inválida no buffer
de registro.
10031 272F Tabela está aberta.
10032 2730 Precisa reestruturar (hard).
10033 2731 Modo inválido.
10034 2732 Impossível fechar índice.
10035 2733 Índice está sendo usado para
classificar tabela.
10036 2734 Nome de usuário e senha
desconhecidos.
10037 2735 Cascada multinível não é
aceita.
10038 2736 Nome de arquivo inválido.
10039 2737 Nome de tabela inválido.
10040 2738 Expressão de cursor vinculado
inválida.
10041 2739 Nome reservado.
10042 273A Extensão de arquivo inválida.
10043 273B Driver de linguagem inválido.
10044 273C Alias não aberto atualmente.
10045 273D Estruturas de registro
incompatíveis.
10046 273E Nome reservado pelo DOS.
10047 273F Destino precisa ser indexado.
10048 2740 Tipo de índice inválido.
10049 2741 Drivers de linguagem da tabela
e índice não combinam.
10050 2742 Alça do filtro inválida.
10051 2743 Filtro inválido.
10052 2744 Pedido Table Create inválido.
10053 2745 Pedido Table Delete inválido.
10054 2746 Pedido Index Create inválido.
10055 2747 Pedido Index Delete inválido.
10056 2748 Tabela inválida especificada.
10058 274A Hora inválida.
10059 274B Data inválida.
10060 274C Data/hora inválida.
10061 274D Tabelas em diretórios
diferentes.
10062 274E Divergência no número de
argumentos.
10063 274F Função não localizada na
biblioteca de serviço.
10064 2750 Precisa usar baseorder para
esta operação.
10065 2751 Nome de procedimento inválido.
10066 2752 O mapa de campo é inválido.
10241 2801 Registro bloqueado por outro
usuário.
10242 2802 Falha ao desbloquear.
10243 2803 Tabela está ocupada.
10244 2804 Diretório está ocupado.
10245 2805 Arquivo está bloqueado.
10246 2806 Diretório está bloqueado.
10247 2807 Registro já bloqueado por esta
sessão.
10248 2808 Objeto não bloqueado.
10249 2809 Tempo limite de bloqueio
esgotado.
10250 280A Grupo de chave está bloqueado.
10251 280B Bloqueio de tabela foi perdido.
10252 280C Acesso exclusivo foi perdido.
10253 280D Tabela não pode ser aberta para
uso exclusivo.
10254 280E Bloqueio de registro em
conflito nesta sessão.
10255 280F Um impasse (deadlock) foi
detectado.
10256 2810 Uma transação do usuário já
está em andamento.
10257 2811 Nenhuma transação do usuário em
andamento no momento.
10258 2812 Falha no bloqueio de registro.
10259 2813 Impossível realizar a edição
porque outro usuário alterou o registro.
10260 2814 Impossível realizar a edição
porque outro usuário excluiu ou moveu o
registro.
10497 2901 Direitos de campo insuficientes
para a operação.
10498 2902 Direitos de tabela
insuficientes para a operação. Senha
exigida.
10499 2903 Direitos de família
insuficientes para a operação.
10500 2904 Esse diretório é somente de
leitura.
10501 2905 Banco de dados é somente de
leitura.
10502 2906 Tentando modificar campo
somente de leitura.
10503 2907 Tabelas criptografadas do dBASE
não aceitas.
10504 2908 Direitos SQL insuficientes para
a operação.
10753 2A01 Campo não é um BLOB.
10754 2A02 BLOB já aberto.
10755 2A03 BLOB não aberto.
10756 2A04 Operação não se aplica.
10757 2A05 Tabela não é indexada.
10758 2A06 Mecanismo não inicializado.
10759 2A07 Tentativa de reinicializar
mecanismo.
10760 2A08 Tentativa de misturar objetos
de diferentes sessões.
10761 2A09 Driver do Paradox não ativo.
10762 2A0A Driver não carregado.
10763 2A0B Tabela apenas de leitura.
10764 2A0C Nenhum índice associado.
10765 2A0D Tabela(s) aberta(s). Impossível
realizar esta operação.
10766 2A0E Tabela não aceita esta
operação.
10767 2A0F Índice somente de leitura.
10768 2A10 Tabela não aceita esta operação
porque não está indexada exclusivamente.
10769 2A11 Operação precisa ser realizada
na sessão atual.
10770 2A12 Uso inválido da palavra-chave
10771 2A13 Conexão está em uso por outra
instrução.
10772 2A14 Conexão SQL de passagem precisa
ser compartilhada.
11009 2B01 Número de função inválido.
11010 2B02 Arquivo ou diretório não
existe.
11011 2B03 Caminho não localizado.
11012 2B04 Muitos arquivos abertos. Você
pode ter de aumentar o limite de
MAXFILEHANDLE na configuração IDAPI.
11013 2B05 Permissão negada.
11014 2B06 Número de arquivo incorreto.
11015 2B07 Blocos de memória destruídos.
11016 2B08 Memória insuficiente.
11017 2B09 Endereço inválido de bloco de
memória.
11018 2B0A Ambiente inválido.
11019 2B0B Formato inválido.
11020 2B0C Código de acesso inválido.
11021 2B0D Dados inválidos.
11023 2B0F Dispositivo não existe.
11024 2B10 Tentativa de remover diretório
atual.
11025 2B11 Não é o mesmo dispositivo.
11026 2B12 Não há mais arquivos.
11027 2B13 Argumento inválido.
11028 2B14 Lista de arquivos muito longa.
11029 2B15 Erro no formato de execução.
11030 2B16 Vínculo entre dispositivo.
11041 2B21 Argumento matemático.
11042 2B22 Resultado muito grande
11043 2B23 Arquivo já existe.
11047 2B27 Erro interno desconhecido do
sistema operacional.
11058 2B32 Violação de compartilhamento.
11059 2B33 Violação de bloqueio.
11060 2B34 Erro crítico do DOS.
11061 2B35 Unidade não está pronta.
11108 2B64 Leitura/gravação inexata.
11109 2B65 Erro de rede do sistema
operacional.
11110 2B66 Erro do servidor de arquivos
Novell.
11111 2B67 Servidor Novell sem memória.
11112 2B68 Registro já bloqueado por esta
estação de trabalho.
11113 2B69 Registro não bloqueado.
11265 2C01 Falha na inicialização da rede.
11266 2C02 Excedido o limite de usuários
da rede.
11267 2C03 Versão de arquivo NET
incorreta.
11268 2C04 Impossível bloquear arquivo da
rede.
11269 2C05 Diretório não é privado.
11270 2C06 Diretório é controlado por
outro arquivo NET.
11271 2C07 Erro de rede desconhecido.
11272 2C08 Não inicializado para acessar
arquivos da rede.
11273 2C09 Compartilhamento não carregado.
Exibido para compartilhar arquivos locais.
11274 2C0A Não está em uma rede. Não
conectado ou driver de rede errado.
11275 2C0B Comunicação perdida com o
servidor SQL.
11277 2C0D Impossível localizar ou
conectar-se ao servidor SQL.
11278 2C0E Impossível localizar ou
conectar-se ao servidor da rede.
11521 2D01 Parâmetro opcional exigido.
11522 2D02 Parâmetro opcional inválido.
11777 2E01 Obsoleto.
11778 2E02 Obsoleto.
11779 2E03 Uso ambíguo de ! (operador de
inclusão).
11780 2E04 Obsoleto.
11781 2E05 Obsoleto.
11782 2E06 Uma operação SET não pode ser
incluída em seu próprio agrupamento.
11783 2E07 Somente campos numéricos e
data/hora podem ter a média calculada.
11784 2E08 Expressão inválida.
11785 2E09 Expressão OR inválida.
11786 2E0A Obsoleto.
11787 2E0B Bitmap.
11788 2E0C Expressão CALC não pode ser
usada em linhas INSERT, DELETE, CHANGETO e
SET.
11789 2E0D Erro de tipo na expressão CALC.
11790 2E0E CHANGETO só pode ser usado em
um formulário de consulta de cada vez.
11791 2E0F Impossível modificar tabela
CHANGED.
11792 2E10 Um campo pode conter apenas uma
expressão CHANGETO.
11793 2E11 Um campo não pode conter mais
de uma expressão a ser inserida.
11794 2E12 Obsoleto.
11795 2E13 CHANGETO precisa ser seguido
pelo novo valor para o campo.
11796 2E14 Marca de seleção ou expressões
CALC não podem ser usadas em consultas
FIND.
11797 2E15 Impossível realizar operação em
tabela CHANGED junto com uma consulta
CHANGETO.
11798 2E16 Chunk.
11799 2E17 Mais de 255 campos na tabela
ANSWER.
11800 2E18 AS precisa ser seguido pelo
nome para o campo na tabela ANSWER.
11801 2E19 DELETE pode ser usado apenas em
um formulário de consulta de cada vez.
11802 2E1A Impossível realizar operação
sobre tabela DELETED junto com uma
consulta DELETE.
11803 2E1B Impossível deletar da tabela
DELETED.
11804 2E1C Elemento de exemplo é usado em
dois campos com tipos incompatíveis ou com
um BLOB.
11805 2E1D Impossível usar elementos de
exemplo em uma expressão OR.
11806 2E1E Expressão neste campo possui o
tipo errado.
11807 2E1F Encontrada vírgula extra.
11808 2E20 Encontrado OR extra.
11809 2E21 Uma ou mais linhas de consulta
não contribuem para a ANSWER.
11810 2E22 FIND pode ser usado apenas em
um formulário de consulta de cada vez.
11811 2E23 FIND não pode ser usado com a
tabela ANSWER.
11812 2E24 Uma linha com GROUPBY precisa
conter operações SET.
11813 2E25 GROUPBY só pode ser usado em
linhas SET.
11814 2E26 Use apenas INSERT, DELETE, SET
ou FIND na coluna mais à esquerda.
11815 2E27 Use apenas um INSERT, DELETE,
SET ou FIND por linha.
11816 2E28 Erro de sintaxe na expressão.
11817 2E29 INSERT s’pode ser usado em uma
consulta de cada vez.11818 2E2A Impossível
realizar operação sobre tabela INSERTED
junto com uma consultar INSERT.
11819 2E2B Linhas INSERT, DELETE, CHANGETO
e SET não podem ser marcadas.
11820 2E2C Campo precisa conter uma
expressão para inserir (ou estar em
branco).
11821 2E2D Impossível inserir na tabela
INSERTED.
11822 2E2E Variável é um array e não pode
ser acessado.
11823 2E2F Label.
11824 2E30 Linhas de elementos de exemplo
na expressão CALC precisam ser vinculadas.
11825 2E31 Nome da variável é muito longo.
11826 2E32 Consulta pode levar um longo
tempo para ser processada.
11827 2E33 Palavra reservada ou que não
pode ser usada como nome de variável.
11828 2E34 Falta vírgula.
11829 2E35 Falta parêntese da direita.
11830 2E36 Falta aspa da direita.
11831 2E37 Impossível especificar nomes de
coluna duplicados.
11832 2E38 Consulta não possui campos
marcados.
11833 2E39 Elemento de exemplo não possui
ocorrência de definição.
11834 2E3A Nenhum agrupamento definido
para operação SET.
11835 2E3B Consulta não faz sentido.
11836 2E3C Impossível usar padrões neste
contexto.
11837 2E3D Data não existe.
11838 2E3E Variável não recebeu um valor.
11839 2E3F Uso inválido do elemento de
exemplo na expressão de resumo.
11840 2E40 Instrução de consulta
incompleta. Consulta não possui uma
definição SET.
11841 2E41 Elemento de exemplo com ! não
faz sentido na expressão.
11842 2E42 Elemento de exemplo não pode
ser usado mais de duas vezes com uma
consulta !.
11843 2E43 Linha não pode conter
expressão.
11844 2E44 Obsoleto.
11845 2E45 Obsoleto.
11846 2E46 Não há permissão para inserir
ou excluir registros.
11847 2E47 Não há permissão para modificar
campo.
11848 2E48 Campo não localizado na tabela.
11849 2E49 Esperando um operador de coluna
no cabeçalho de tabela.
11850 2E4A Esperando um separador de
coluna na tabela.
11851 2E4B Esperando um nome de coluna na
tabela.
11852 2E4C Esperando nome da tabela.
11853 2E4D Esperando um número coerente de
colunas em todas as linhas da tabela.
11854 2E4E Impossível abrir tabela.
11855 2E4F Campo aparece mais de uma vez
na tabela.
11856 2E50 Essa consulta DELETE, CHANGE ou
INSERT não possui ANSWER.
11857 2E51 Consulta não está preparada.
Propriedades desconhecidas.
11858 2E52 Linhas DELETE não podem conter
expressão quantificadora.
11859 2E53 Expressão inválida na linha
INSERT.
11860 2E54 Expressão inválida na linha
INSERT.
11861 2E55 Expressão inválida na definição
SET.
11862 2E56 Uso de linha.
11863 2E57 Palavra-chave SET esperada.
11864 2E58 Uso ambíguo do elemento de
exemplo.
11865 2E59 Obsoleto.
11866 2E5A Obsoleto.
11867 2E5B Somente campos numéricos podem
ser somados.
11868 2E5C Tabela é protegida contra
gravação.
11869 2E5D Token não localizado.
11870 2E5E Impossível usar elemento de
exemplo com ! mais de uma vez em uma única
linha.
11871 2E5F Divergência de tipo na
expressão.
11872 2E60 Consulta parece fazer duas
perguntas não relacionadas.
11873 2E61 Linha SET não utilizada.
11874 2E62 INSERT, DELETE, FIND e SET só
podem ser usados na colunas mais à
esquerda.
11875 2E63 CHANGETO não pode ser usado com
INSERT, DELETE, FIND ou SET.
11876 2E64 Expressão precisa ser seguida
por um elemento de exemplo definido em um
SET.
11877 2E65 Falha de bloqueio.
11878 2E66 Expressão muito longa.
11879 2E67 Exceção de atualização durante
consulta.
11880 2E68 Consulta cancelada.
11881 2E69 Erro inesperado no mecanismo de
banco de dados.
11882 2E6A Não há memória suficiente para
concluir a operação.
11883 2E6B Exceção inesperada.
11884 2E6C Recurso ainda não implementado
na consulta.
11885 2E6D Formato de consulta não aceito.
11886 2E6E String de consulta está vazia.
11887 2E6F Tentou preparar uma consulta
vazia.
11888 2E70 Buffer muito pequeno para
conter string de consulta.
11889 2E71 Consulta não foi desmembrada ou
preparada anteriormente.
11890 2E72 Função chamou com alça de
consulta errada.
11891 2E73 Erro de sintaxe do QBE.
11892 2E74 Erro de contagem no campo de
sintaxe estendida da consulta.
11893 2E75 Nome de campo na cláusula de
classificação ou campo não localizado.
11894 2E76 Nome de tabela na cláusula de
classificação ou campo não localizado.
11895 2E77 Operação não aceita nos campos
BLOB.
11896 2E78 Erro geral do BLOB.
11897 2E79 Consulta precisa ser
reiniciada.
11898 2E7A Tipo de tabela de resposta
desconhecida.
11926 2E96 BLOB não pode ser usado como
campo de agrupamento.
11927 2E97 Propriedades de consulta não
foram apanhadas.
11928 2E98 Tabela de resposta é de tipo
inadequado.
11929 2E99 Tabela de resposta ainda não é
aceita sob o alias do servidor.
11930 2E9A Campo BLOB não nulo exigido.
Impossível inserir registros.
11931 2E9B Índice exclusivo obrigatório
para realizar CHANGETO.
11932 2E9C Índice exclusivo obrigatório
para deletar registros.
11933 2E9D Falha na atualização da tabela
no servidor.
11934 2E9E Impossível processar esta
consulta remotamente.
11935 2E9F Fim de comando inesperado.
11936 2EA0 Parâmetro não definido na
string de consulta.
11937 2EA1 String de consulta é muito
longa.
11946 2EAA Não existe tal nome de tabela
ou correlação.
11947 2EAB Expressão possui tipo de dado
ambíguo.
11948 2EAC Campo em ORDER BY precisa estar
no resultset.
11949 2EAD Erro de desmembramento geral.
11950 2EAE Falha na restrição de registro
ou campo.
11951 2EAF Campo de GROUP BY precisa estar
no resultset.
11952 2EB0 Função definida pelo usuário
não está definida.
11953 2EB1 Erro desconhecido da função
definida pelo usuário.
11954 2EB2 Subconsulta de única linha
produziu mais de uma linha.
11955 2EB3 Expressões em GROUP BY não são
aceitas.
11956 2EB4 Consultas sobre texto ou
tabelas ASCII não são aceitas.
11957 2EB5 Palavras-chave USING e NATURAL
da associação ANSI não são aceitas nesta
versão.
11958 2EB6 SELECT DISTINCT não pode ser
usado com UNION a menos que seja usado
UNION ALL.
11959 2EB7 GROUP BY é obrigatório quando
campos de agregação e não de agregação são
usados no resultset.
11960 2EB8 Operações INSERT e UPDATE não
são aceitas em tipo de campo de
autoincrement.
11961 2EB9 UPDATE em chave primária de uma
tabela mestre pode modificar mais de um
registro.
12033 2F01 Divergência de interface.
Versão diferente do mecanismo.
12034 2F02 Índice desatualizado.
12035 2F03 Versão mais antiga (ver
contexto).
12036 2F04 Arquivo VAL desatualizado.
12037 2F05 Versão do arquivo BLOB muito
antiga.
12038 2F06 DLLs de consulta e mecanismo
são divergentes.
12039 2F07 Servidor tem versão
incompatível.
12040 2F08 Exigido nível de tabela
superior.
12289 3001 Capacidade não aceita.
12290 3002 Ainda não implementado.
12291 3003 Réplicas do SQL não aceitas.
12292 3004 Coluna não BLOB na tabela
exigida para realizar operação.
12293 3005 Conexões múltiplas não aceitas.
12294 3006 Expressões completas do dBASE
não aceitas.
12545 3101 Especificação de alias de banco
de dados inválida.
12546 3102 Tipo de banco de dados
desconhecido.
12547 3103 Arquivo de configuração do
sistema danificado.
12548 3104 Tipo de rede desconhecido.
12549 3105 Fora da rede.
12550 3106 Parâmetro de configuração
inválido.
12801 3201 Objeto removido implicitamente.
12802 3202 Objeto pode estar truncado.
12803 3203 Objeto modificado
implicitamente.
12804 3204 As restrições de campo devem
ser verificadas?
12805 3205 Campo de verificação de
validade modificado.
12806 3206 Nível de tabela alterado.
12807 3207 Copiar tabelas vinculadas?
12809 3209 Objeto truncado implicitamente.
12810 320A Verificação de validade não
será imposta.
12811 320B Encontrados múltiplos
registros, mas somente um era esperado.
12812 320C Campo será aparado. Impossível
colocar registros mestre na tabela com
problema.
13057 3301 Arquivo já existe.
13058 3302 BLOB foi modificado.
13059 3303 Erro genérico da SQL.
13060 3304 Tabela já existe.
13061 3305 Tabelas do Paradox 1.0 não são
aceitas.
13062 3306 Atualização abortada.
13313 3401 Ordem de classificação
diferente.
13314 3402 Diretório em uso por versão
anterior do Paradox.
13315 3403 Precisa de driver de linguagem
compatível com Paradox 3.5.
13569 3501 Dicionário de dados está
danificado.
13570 3502 BLOB de informações do
dicionário de dados danificado.
13571 3503 Esquema do dicionário de dados
danificado.
13572 3504 Tipo de atributo já existe.
13573 3505 Tipo de objeto inválido.
13574 3506 Tipo de relação inválida.
13575 3507 Visão já existe.
13576 3508 Não existe tal visão.
13577 3509 Restrição de registro inválida.
13578 350A Objeto está em um DB lógico.
13579 350B Dicionário já existe.
13580 350C Dicionário não existe.
13581 350D Banco de dados de dicionário
não existe.
13582 350E Informações de dicionário
desatualizadas. Precisa atualizar.
13584 3510 Nome de dicionário inválido.
13585 3511 Existem objetos dependentes.
13586 3512 Muitos relacionamentos para
este tipo de objeto.
13587 3513 Existem relacionamentos com o
objeto.
13588 3514 Arquivo de troca de dicionário
danificado.
13589 3515 Divergência na versão do
arquivo de troca de dicionário.
13590 3516 Divergência no tipo de objeto
do dicionário.
13591 3517 Objeto já existe no diretório
de destino.
13592 3518 Impossível acessar dicionário
de dados.
13593 3519 Impossível criar dicionário de
dados.
13594 351A Impossível abrir banco de
dados.
15873 3E01 Nome de driver errado.
15874 3E02 Versão errada do sistema.
15875 3E03 Versão errada do driver.
15876 3E04 Tipo de driver errado.
15877 3E05 Impossível carregar driver.
15878 3E06 Impossível carregar driver de
linguagem.
15879 3E07 Falha na inicialização do
fornecedor.
15880 3E08 Sua aplicação não está ativada
para usar este driver.
726 - 20 motivos para você adotar
o InterBase em sua empresa!
1 DBA não requerido
O InterBase é feito idealmente para desenvolvedores de
aplicações que querem um banco de dados realmente encaixado.
A pequena footprint e pouca necessidade de manutenção (O DBA
não é requerido) do InterBase te dão a tranquilidade de que seus
clientes mal notarão que ele está lá.
2 Alta performance tanto em aplicações críticas como em
aplicações menores
O InterBase provê uma funcionalidade de alta performance que
suporta operações críticas de negócios em áreas como comércio
de mercadorias (ações, apólices), farmacêutica, aerospacial e
gerenciamento de rede, enquanto se mantém com preço acessível
(IB6 ser;a free) e fácil de usar para desenvolvedores de
aplicações menores.
3 Versioning
O servidor InterBase é construído em uma arquitetura multi-
geracional(MGA). O MGA provê um dispositivo versionig único que
assegura alta disponibilidade para usuários que suportam decisões
(support-decision). Servidores de banco de dados suportam
tradicionalmente o modelo de interação de banco de dados On-
Line Transaction Procesing (OLTP), caracterizado por um grande
volume de transações simples e curtas. Enquanto o dispositivo
versioning do InterBase suporta essas transações curtas, do tipo
OLTP, o InterBase supera a competição em aplicações reais
porque também gerencia ao mesmo tempo transações de longa
duração do tipo support-decision.
4 Arquitetura SuperServer
A arquitetura SuperServer aumenta a performance e otimiza o
uso de recursos de sistemas, especialmente por um grande
número de usuários. Isto te permite ter mais clientes no seu
servidor, e ainda aumentar a velocidade de suas repostas. Este é
um servidor multi-threaded compartilhado, que provê a melhor
performance já vista.
5 Instalação em minutos
O InterBase é instalado facilmente com um único comando. Ele
tem uma pequena footprint, então você não precisa se preocupar
em ter bastante espaço livre em disco e não precisará estabelecr
centenas de parâmetros de sintonia. O InterBase foi preparado
para requerer pouca manutenção, portanto ele otimiza suas
transações pra você.
6 Sinalizadores de Eventos
Sinalizadores de eventos tornam possível a existência de um
banco de dados ativo, avisando automaticamente as “partes
interessadas” quando certas mudanças acontecem. Tudo isso é
feito sem polling constante no banco de dados, portanto isto não
limita os recursos do sitema.
7 Funções Definidas pelo Usuário (UDFs)
UDFs provêem meios de aumentar as capacidades analíticas do
InterBase através da criação de funções habituais de negócios.
UDFs são um código reutilizável e asseguram a integridade e
confiabilidade dos dados. Da mesma maneira, UDFs podem ser
usadas para chmar aplicações externas ao banco de dados
8 BLOBs - Binary Large Objects
O InterBase estabeleceu o padrão industrial com o lançamento de
seu primeiro produto em 1986, quando armazenou som, imagem,
gráficos e informações binárias diretamente no banco de dados
usando os seus tipos de dados BLOB.
9 Arrays Multidimensionais
O InterBase também suporta os arrays multidimensionais usados
extensivamente em aplicações financeiras e científicas.
Armazenando arrays multidimensionais com até 16 dimensões em
um único campo no banco de dados o InterBase simplifica o
design da aplicação e aumenta a performance..
10 Banco de dados distribuídos para flexibilidade da
aplicação
Quando você precisar mover a sua solução desktop de banco de
dados para uma configuração client/server ou aumentar as suas
aplicações de grupo de trabalho para servir a um ou mais
departamentos, o InterBase é ideal, pois é feito para ambientes
de banco de dados distribuídos.
11 Junção de múltiplos bancos de dados
O InterBase é um verdadeiro servidor de bancos de dados
distribuídos SQL que permite que cada query do sistema de banco
de dados retorne a informação para qualquer outro servidor
InterBase
12 Commit em duas fases
O InterBase também gerencia transações com servidores
múltiplos de maneira rápida e fácil. Ele inclui o processamento de
transações com commit em duas fases, o que assegura que as
atualizações sejam feitas sem intervenção da aplicação. Toda vez
que uma transação abrange dois ou mais servidores de banco de
dados o InterBase primeiro investiga os servidores participantes
para assegurar de que eles estejam em atividade e rodando,
então envia o comando commit para completar a transação.
13 Recuperação distribuída de Commit em duas fases
O InterBase leva o processo de commit em duas fases um passo
além. Ele foi o primeiro produto de banco de dados a prover
recuperação distribuída para um commit em duas fases. Isto
assegura a recuperação completa sem o risco de um único ponto
de falha, pois a coordenação da submissão é distribuída entre
todos os servidores, reduzindo assim a necessidade de
administração dos dados. No evento em que a transação não
possa ser submetida em todos os servidores, a transação inteira é
automaticamente tolled back em todos os servidores.
14 ANSI SQL-92
Para soluções em aplicações de missão crítica, o InterBase oferece
total compatibilidade com SQL-92.
15 Sistema de travamento otimista
O Interbase utiliza tecnologia de travamento otimista para
proporcionar grande taxa de uso de operações de banco de dados
para clientes. O Interbase implementa travamentos a nível de
linha reais para restringir mudanças somente nos registros do
banco de dados que um cliente modifica. Diferente de
travamentos a nível de página, que restringe qualquer dado
arbitrário que estiver armazenado fisicamente próximo no banco
de dados. Travamentos a nível de linha permitem múltiplos
clientes atualizarem dados em uma mesma tabela sem conflito,
resultando em menor serialização das operações de bancos de
dados.
16 Usuários de peso
Vejam quem está utilizando o InterBase: NASA,Motorola, Nokia,
MCI, Northen Telecom, Philadelphia Stock Exchange, Bear
Stearns, First National Bank of Chicago, Money Store, US Army,
NASA, Boeing, IBM (Brasil).
17 Flexibilidade de plataformas Windows, Linux, Unix,
Solaris, NetWare…
Você escolhe qual usar,não ficando obrigado a certos sistemas
operacionais.
18 Internet Explorer?
Você sabia que para o SQL Server 7 funcionar você precisa do
Internet Explorer instalado em sua máquina?.
19 InterBase 6 tem distribuição livre
A versão 6 do InterBase é open-source e free, o que significa que
o custo de seu projeto cairá! Consequentemente seus clientes
ficarão bem satisfeitos.
20 O InterBase pode crescer com você Com produtos
InterBase,
você não tem somente uma melhor performance nas mais
populares plataformas UNIX e Windows, mas também uma melhor
performance adaptada às necessidades de sua empresa. O
InterBase é uma família de produtos que atravessa o espectro de
um único usuário e servidores de pequenos grupos até grandes
negócios. Com o recém-adicionado InterClient JDBC, você
também tem a flexibilidade que precisa. Então, enquanto você
cresce o InterBase pode crescer com você.
727 - 10 Passos para fazer o
Interbase “Voar”
Texto original : Bill Karwin
Adaptação e Tradução : Carlos H. Cantu
Inprise Conference, Agosto 1998
Design das Queries

Sub-queries co-relacionadas e joins


Subqueries são comandos SELECT que são incluídos como
cláusulas ou expressões dentro de outros comandos.
Geralmente são utilizados para gerar um valores ou um
resultados que serão utilizados nas condições em um Query
superior.
Uma Query correlacionada é uma em que as condições da
subquery são diferentes para cada linha(registro) da Query
pai, porque ela depende de valores que variam de linha
para linha. O Interbase executa a subquery diversas vezes,
uma para cada linha da Query pai. Avaliar cada linha tem
um alto custo em performance em relação a Queries que
não são correlacionadas. O InterBase optimiza Queries
não-correlacionadas fora do loop, executa 1 vez, e utiliza o
resultado como um dataset fixo.
Exemplo de uma query correlacionada:

SELECT *
FROM DEPARTMENT D
WHERE EXISTS
(SELECT *
FROM EMPLOYEE E
WHERE E.EMP_NO = D.MNGR_NO
AND E.JOB_COUNTRY = ‘England’)

O mesmo exemplo utilizando um JOIN:

SELECT D.*
FROM DEPARTMENT D JOIN EMPLOYEE E ON
D.MNGR_NO = E.EMP_NO
WHERE E.JOB_COUNTRY = ‘England’

PLANo de execução de uma Query


O PLANo descreve o meio que o optimizador do IB
escolheu para executar a Query. Para alguns tipos de
Query, o optimizador pode não ter escolhido o plano mais
adequado (eficiente). Uma pessoa pode analizar PLANos
alternativos e especificar manualmente o plano à ser
utilizado em uma Query, passando por cima da análise do
Optimizador. O resultado pode ser um ganho muito grande
de eficiência para alguns tipos de Query. Em casos
dramáticos, o tempo de execução de uma Query foi
reduzido de 15 minutos para 3 segundos !
Os elementos da definição de um plano são:

Atribuir os indíces
Combinar os indíces
Determinar a ordem do JOIN
Gerar os “rivers”
Estimativa de custo
Ordernar os “merges”

Foi adicionado ao comando SELECT uma sintaxe para


possibilitar que o usuário especifique o plano para uma
Query. A sintaxe deve funcionar para SELECTs dentro de
uma VIEW, STORED PROCEDURE ou TRIGGER.
Para maiores detalhes de como definir um plano, veja
http://www.interbase.com/tech/docs/manage.html

Preparando as Queries e os Parâmetros da


Query
O Interbase suporta Queries parametrizadas em DSQL,
para casos onde um comando deve ser executado diversas
vezes com diferentes valores. Por exemplo, preencher uma
tabela com dados requer uma serie de comandos INSERT
com os valores para cada registro inserido. Executar uma
Query parametrizada tem um impacto benéfico na
performance, pois o IB mantém a representação interna e a
optimização da Query após prepara-la uma única vez.
Use Queries parametrizadas em DSQL no Delphi seguindo
os seguintes passos :

1. Coloque um parâmetro no SQL utilizando a sintaxe


“:PARAMETRO” no lugar de uma constante na Query.
O Interbase não suporta parâmetros em nenhum outro
lugar sem ser constantes. Tabelas e nomes das
colunas não podem ser parametrizadas.
2. Prepare a Query. Use o método TQuery.Prepare. O
Delphi automaticamente prepara uma Query quando a
mesma é executa sem ter sido preparada
anteriormente, mas nesse caso, após a execução, o
Delphi automaticamente desprepara (Unprepare) a
Query. Quando uma Query for executada diversas
vezes, o programador deve manualmente preparar e
despreparar a Query para evitar que a mesma fique
sendo preparada/despreparada múltiplas vezes sem
necessidade.
3. Especifique os parametros. No caso de uma TQuery,
use PARAMS ou PARAMBYNAME para atribuir os
valores para os parâmetros da Query.
4. Execute a Query. Queries contendo o comando
SELECT devem ser executadas utilizando o método
OPEN. Queries contendo comandos INSERT,
UPDATE, e DELETE deve ser executadas pelo método
ExecSQL. Esses métodos preparam a Query para ser
executada caso isso ainda não tenha sido feito
anteriormente. Para aumentar a performance, um
aplicativo deve sempre PREPARAR uma Query antes
dela ser executada pela primeira vez.
5. Repita os passos 3 e 4 quantas vezes quiser.
6. Desrepare a Query.
Em casos reais, o uso de Queries parametrizadas
aumentou a performance em 100%.
Protocolo da Rede
O IB suporta os seguintes protocolos: NetBEUI quando
conectar um servidor NT, IPX/SPX quando conectar um
servidor NOVELL, e TCP/IP com qualquer servidor.

NetBEUI e IPX/SPX
Os protocolos NetBEUI e IPX/SPX são designados para
serem utilizados em pequenas redes. Esse protocolos são
normalmente utilizados para serviços de compartilhamento
de arquivos. Esse protocolos enviam pacotes para toda a
rede, aumentado o nível de “ruído” em uma LAN. O “ruído”,
do ponto de vista de qualquer terminal, pode ser definido
com um tráfego de dados que não é designado para esse
terminal. Em uma LAN com muitos terminais, usar os
protocolos NETBEUI ou IPX/SPX pode afogar a rede e
reduzir a banda livre para tráfego de dados. O uso desses
protocolos é desencorajado.

TCP/IP
TCP/IP é um protocolo baseado em conexão, significando
que os pacotes de dados são direcionados para um
determinado terminal, reduzindo o tráfego da rede e nos
terminais, disponibilizando muito mais banda livre, fazendo
com que a performance não se degrade.

DNS
Cada terminal em uma rede TCP/IP tem designado um
número IP que é utilizado para o direcionamento dos dados.
O TCP/IP requer um meio para que os clientes traduzam os
nomes dos terminais para seus respectivos números IP.
Isso é feito em cada cliente, através do arquivos
HOSTS/LMHOSTS, ou utilizando um servidor central
chamado DNS. O DNS recebe o nome do host e devolve o
número IP do mesmo para que o cliente se comunique
diretamente com o terminal desejado.
Dependendo do volume de dados e da carga do servidor
DNS, o processo de tradução de um nome para o IP pode
levar alguns segundos, significando uma demora nas
conexões da rede.
Então como posso aumentar a velocidade para a resolução
dos nomes ? Ao invés de utilizar um DNS, use o arquivo
HOSTS em cada terminal para determinar resolver os IPs.
Procurar por uma linha dentro de um arquivo local é muito
mais rápido do que esperar a resolução de um DNS remoto.
DHCP
Uma desvantagem do TCP/IP sobre os outros protocolos é
que ele é mais díficil de ser gerenciado do que o NetBEUI
ou o IPX/SPX. Todos os terminais de uma rede TCP/IP
devem ter designados um único número IP. Isso acaba
sendo uma árdua tarefa de configuração e administração.
O DHCP (Dynamic Host Configuration Protocol) pode
facilitar essa tarefa. A estação pergunta ao servidor DHCP e
o mesmo retorna um número de IP livre que pode ser
utilizado pela estação. A estação usa esse IP pela duração
da sua sessão na rede.
Configuração das páginas do BD

Tamanho da Página (Page size)


O tamanho da página padrão utilizada pelo Interbase é de
1K. Há um aumento de performance de 25-30% se esse
valor for alterado para 4K. Geralmente se fala que quanto
maior a página, melhor é a performance, devido à razões
que incluem :

Menos fragmentos de registros são dividos através das


páginas
É comum que os registros ocupem mais de 1K,
significando que em uma página de 1K, o registro
é divido e armazenado em múltiplas páginas.
Acessar esse registro faz com que o servidor tenha
de ler várias páginas do BD. Se o tamanho da
página for aumentado, o número de registros
fragmentados diminui e podem ser gravados de
modo mais contínuo.
Index B-trees são superficiais
Os índices são ponteiros em B-trees apontando
para páginas de dados contendo porções dos
valores indexados. Se a árvore B-tree for maior
que 1 página, páginas adicionais são alocadas
para a árvore de índice. Se as páginas de índices
são maiores, algumas páginas adicionais são
necesárias para armazenar os ponteiros. A árvore
B-tree é facilmente alocada na memória pelo
sistema de cache do BD, fazendo com que as
procuras indexadas fiquem extremamente rápidas.
I/O é mais contínua
Normalmente registros sucessivos em uma tabela
são lidos pela mesma Query. Isso é feito, por
exemplo, durante um scan por uma tabela, ou por
uma Query que retorna ou agrega todos os
registros de uma tabela. O Interbase armazena os
registros na primeira página livre do BD, não
garantindo que registros sucessivos sejam
armazenados perto um do outro. Um scan em uma
tabela pode exigir que o servidor “pule” por todo o
Banco de Dados acessando os registros, oque
pode influir negativamente na performance.
Uma página do BD só pode armazenar registros
de uma mesma tabela. Isso implica em que
páginas maiores conterão mais dados de uma
tabela e a leitura dessa página retornará dados
mais relevantes.
Buffers maiores = mais memória de cache
O cache do BD é alocado em número de páginas
ao invés de uma quantidade fixa de bytes. Então,
definindo uma página maior implicará no aumento
do cache/memória que conterá uma porção maior
do BD. Estatisticamente, as chances dos dados
serem encontrados em um cache grande é maior
do que em um cache pequeno.
A maior parte dos sistemas operacionais executam
leituras em baixo nível em blocos de 4096bytes.
Uma leitura de página é executado no nível do
Sistema Operacional, lendo incrementos de
4096bytes independente do tamanho do BD.
Definindo a página do BD em 4096 faz com que a
leitura de uma página coincida com a leitura de
baixo nível, garantindo uma melhor performance.

Voce pode mudar o tamanho padrão das páginas de um BD


quando estiver criando ou restaurando um BD. A
performance pode ser aumentada sem ter que mexer na
arquitetura do BD. O tamanho das páginas é transparente
para o cliente.
Embora 4K aparentemente seja o tamanho ideal para a
maioria dos BDs, isso vai depender da estrutura de cada
BD e do modo em que os aplicativos acessam esses dados,
portanto, é aconselhável que voce faça alguns testes com
outros valores para determinar o valor ideal para cada caso.

Compactando dados nas páginas para


bancos de dados read-only
As páginas de dados armazenam múltiplas versões dos
registros conforme os mesmos vão sendo atualizados.
Quando um BD é restaurado, o GBAK preenche as páginas
em até 80% do seu tamanho, deixando espaço para que
novas versões dos registros possam ser armazenadas, com
sorte, na mesma página que o registro original. No caso de
um BD que é mais usado para leitura e nem tanto para
inserção/atualização dos dados, esse espaço vago de 20%
na página não é interessante. Nesse casos o melhor é
restaurar os dados preenchendo 100% do espaço das
páginas. Fazendo isso se reduzirá o número de registros
fragmentados, bem como mais registros serão retornados
durante a leitura de uma página. Para retaurar um BD com
100% de capacidade em cada página utilize a sintaxe :
GBAK -C -USE_ALL_SPACE backup_file.gbk
database_file.gdb
Transações
O Interbase exige que qualquer Query ou outra operação
esteja associada com uma transação ativa. Isso é requerido
pela arquitetura multi-geracional do IB. Sem uma transação,
uma operação fica sem um contexto para manter um
“snapshoot” do banco de dados. O WISQL e a BDE tem
procedimentos automaticos que cuidam das transações
durante as operações, mas é mais eficiente iniciar e
terminar as transações manualmente.
No IB, um “snapshot” é gerado criando-se uma cópia do
estado de todas as outras transações no BD. Esse
“snapshot” é estático durante essa transação, o que
significa que nenhum dado inserido ou alterado após o
snapshot ter sido criado é visível a qualquer operação que
se utiliza desse snapshot. Esse é o modo de isolamento
conhecido como repeatable read. Assim se garante que 2
queries identicas executadas em diferentes horários sempre
retornem o mesmo resultado, independente dos dados
estarem sendo atualizados por outros clientes.
Iniciar uma transação e fazer um “snapshot” da estrutura de
dados para a nova transação implica em algum tempo
gasto. Esse tempo gasto é maior quando se utiliza um
método de gerenciamento automático de transações, pois
nele uma transação é iniciada e terminada para cada
operação executada no BD.
Outro modo de isolamento (o padrão para a BDE) é
chamado de read commited. Nesse modo, o “snapshot” é
atualizado sempre que o estado de qualquer transação é
alterado. Isso permite que as operações executadas dentro
da transação atual “enxerguem” as alterações postadas
após o snapshot ter sido criado. O processo de atualização
do snapshot também consome algum tempo, por isso é
aconselhável sempre utilizar o modo repeatable read no IB.
Para isso, configure os flags no drive do Interbase na BDE
para 512 ou 4608.
Índices
Os índices podem aumentar dramaticamente a performance
de um SELECT. Quanto mais registros houver em uma
tabela, maior o benefício de um índice. Analizando
corretamente seu banco de dados e definindo índices
adequados sempre implicará em ganho de performance.
Um índice dentro do IB é uma estrutura de dados dentro do
arquivo do BD que disponibiliza um meio rápido de acesso
à valores específicos dentro de uma tabela. As queries
automaticamente fazem uso apropriado dos índices graças
ao optimizador do IB que analiza as tabelas e campos
utilizados na query e determina quais os índices que
agilizarão a procura, ordenação e as operações de join.
Os índices implicam em um pequeno “custo” para manter a
estrutura da árqvore B-tree durante as operações de
inserção e atualização dos dados. Por esse motivo voce
não deve criar índices deliberadamente. Não crie índices
redundantes e não crie um índice para cada coluna em uma
tabela ao invés de analizar o BD para saber quais índices
são realmente necessários.
Os índices são atualmente prejudiciais para a performance
quando criados em colunas que contenham poucos valores
únicos. Um exemplo clássico é a coluna SEXO dentro de
uma tabela; os únicos valores para essa coluna seria
feminino, masculino e talvez indefinido. Manter um índice
como esse tem um custo alto de performance, e uma
pesquisa nessa coluna consumiria mais tempo assim do
que sem o índice.

O que utiliza um índice:


Chaves primárias e secundárias
Chaves de ordenação, incluindo DISTINCT e GROUP
BY
Critério de busca (WHERE)
O que não utiliza um índice:
Critério de busca utilizando CONTAINING, LIKE, <>
Colunas usadas em funções de agregamento, como
por ex. COUNT()
Outras expressões, como UPPER()

Índices Direcionais
Os índices podem ser definidos como ascendentes e
descendentes (ASCENDING ou DESCENDING). Para
ordenar em ambas as direções, voce precisa de um índice
de cada tipo. Isso é muito importante de voce costuma
utilizar DBGrids no Delphi.

Ajustando os índices
A seletividade de um índice é o indicador da sua
exclusividade. O optimizador usa a seletividade no seu
algoritmo para decidir se deve ou não utilizar um índice
dentro de um PLANo em uma query. Se a seletividade está
atrasada e não representa adequadamente o estado de um
índice, o optimizador podera usar ou não o índice de
maneira inadequada. Isso geralmente não provoca uma
perda de performance, a não ser que a seletividade esteja
muito desatualizada. Para recalcular a seletividade de um
índice use :
SET STATISTICS name;
Periodicamente, a estrutura da árqvore B-tree pode se
tornar desbalanceada, ou pode conter valores na árvore
que não existem mais no BD (isso não deve acontecer no
IB 5.0 ou superior devido ao recurso de Index Garbage
Collection). Voce deve periodicamente re-construir um
índice :
ALTER INDEX name INACTIVE;
ALTER INDEX name ACTIVE;
Cache do Banco de Dados
O processo IBSERVE.EXE rodando no servidor mantém um
cache na memória com os dados e as páginas de índices
utilizados recentemente. Como qualquer cache, o ganho de
performance depende da repetição dos acessos aos
mesmos dados. Nas versões SuperServer do IB (IB 4.2 e
superiores), o cache é compartilhado com todos os clientes
conectados ao BD.
Por default, o IB aloca memória suficiente para armazenar
256 páginas do BD. Se o tamanho da página está definido
em 1K, então 256K de memória será usada pelo cache. Se
o tamanho da página é de 4K, então 1MB de memória será
usada. A API do Interbase possibilita uma maneira de
qualquer cliente pedir ao servidor que o tamanho do cache
seja aumentado. A partir do IB 5.0, voce pode setar uma
propriedade em cada BD que especifique o tamanho do
cache que deve ser usado quando houver uma conexão ao
BD.
GFIX.EXE -BUFFERS 5000 DATABASE.GDB
O valor padrão de 256 foi utilizado para máquinas com
pouquissíma memória, impedindo que o IB consumisse
muita memória no sistema. Aumentar o tamanho do cache é
benéfico para a performance. Nos servidores de hoje, onde
há grande quantidade de memória disponível, é altamente
recomendável que se aumente o tamanho do cache.
Não aumente o tamanho do cache em um valor muito alto,
que faça com que o IBSERVER.EXE tenha que utilizar a
memória virtual (SWAP) do servidor. Isso estaria anulando
totalmente a vantagem de se usar um cache visto que o
acesso ao disco (SWAP) é muito mais lento do que o
acesso à memória.
Não aumente o tamanho do cache para um valor mais alto
do que o número de páginas do BD (voce pode ver o
número das páginas através do Server Manager na opção
Database Statistics ou através do utilitário GSTAT.EXE).
Qualquer página do disco ocupa apenas 1 página no cache
e nunca é duplicada.
Um bloco de memória é alocado para cada cache por cada
BD. Se um cliente se conecta à 2 BD diferentes no mesmo
servidor, o processo IBSERVER.EXE manterá 2 áreas de
memória separadas para cada cache.
Voce deve experimentar os valores do cache e analizar o
ganho de performance para cada caso. Voce pode ganhar
até 30% de performance com isso.
Bufferização de I/O
O IB em plataformas Windows-Intel implementa um cache
de gravação do tipo write-through como padrão. Cada
operação de escrita no cache é imediatamente passada
para o Sistema Operacional (que pode utilizar um cache de
gravação ou não).
Em contraste, o modo de cache write-back armazena e
atrasa a gravação dos dados para depois. Múltiplas
operações de escrita para uma página do cache são
executadas na memória para depois serem gravadas no
disco, resultando em um melhor tempo de resposta para a
maioria das operações de escrita. O modo write write back
é muito mais eficiente do que o modo write-through.
O Interbase utiliza o modo write-back como default nas
versões em UNIX, mas não na versão Wintel. O modo write-
back pode ser configurado manualmente através do
comando GFIX.EXE -WRITE ASYNC ou desativando a
opção “Enable Forced Writes” na página “Database
Properties” no Server Manager.
O benefício de se usar escrita assíncrona (write-back) é de
mais ou menos 4 vezes mais performance, apesar de
alguns usuarios reportarem um ganho de até 20x em
aplicações que executam muitas operações de escrita
(INSERT, UPDATE, DELETE).
O problema do write-back é que dados podem ser perdidos
no caso do servidor sofrer uma queda de energia, ou se o
IBSERVER.EXE travar ou for finalizado de maneira
anormal. Isso não ocorre se o modo escolhido é o write-
through. Se voce testou e verificou que o servidor não está
suscetível à esses problemas, então é recomendável que
voce utilize o modo write-back.
Servidor Ativo
O Interbase oferece metadata ativa para permitir que o
servidor de banco de dados seja centralizado :

Regras de negócios (Business rules )


Segurança
Integridade de dados
Menos tráfego na rede

Características do InterBase para a metadata ativa

Triggers
Stored Procedures
SELECT Procedures
Integridade Referencial em cascata (PRIMARY KEY e
FOREIGN KEY)
Privilégios de SQL
Funções definidas pelo usuário
Exceções definidas pelo usuário
Eventos

Veja http://www.interbase.com/tech/docs/trig_sp.html
http://www.interbase.com/tech/docs/udfs.html para mais
informações.
Configuração da BDE
Mude os padrões da BDE através do BDE Administrator.

Driver flags
O valor recomendável para a opção DRIVER FLAGS é de
4608.
Setando 512 ao valor do DRIVER FLAGS na BDE, voce
estará especificando que o modo de isolamento
transacional utilizado será o “repeatable read”, reduzindo
assim o overhead que o modo de transações automáticas
ocasiona. (veja #7: Transações).
Utilizando o valor 4096 na opção DRIVER FLAGS, voce
estará setando a BDE para utilizar o modo “soft commit”.
Soft commits é um recurso do IB que permite o driver reter
o cursor enquanto está executando as alterações. Soft
commits aumenta a performance nas atualizações de
grandes volumes de dados. Quando se usa hard commits, a
BDE deve reler todos os registros de um dataset, mesmo
após a mudança de um único registro. Isso não é tão
problemático quando se está usando um banco de dados
desktop, pois os dados são transferidos no centro de
memória. Para um banco de dados C/S (como o InterBase),
atualizar um dataset consome muita banda da rede e
degrada a performance radicalmente. No modo soft commit,
o cursor é mantido e não ocorre a re-leitura dos dados
(refetch).

DRIVER FLAGS Tipo de Isolamento Tipo de Execução

0 Read committed hard commit

512 Repeatable read hard commit


4096 Read committed soft commit

4608 Repeatable read soft commit

Aviso: soft commits nunca são usados em transações


explícitas iniciadas pelas aplicações BDE. Isso significa que
se voce inicia e termina suas transações explicitamente, o
driver flag para soft commit não é usado.

Modo SQL Passthru


O valor recomendado para essa propriedade é SHARED
NOAUTOCOMMIT
SQLPASSTHRU MODE especifica como a BDE e
comandos explícitos em SQL compartilham a mesma
conexão. Na maioria dos casos, o modo SQLPASSTHRU
MODE é configurado para SHARED AUTOCOMMIT. Se no
entanto, voce deseja enviar ao servidor comandos de
controle de transação, voce deve utilizar o SQL Explorer e
setar o modo SQLPASSTHRU para NOT SHARED. Há
casos reportados de ganhos de performance de até 10x
utilizando essa setagem, no entando isso dependo do
volume de dados.
Utilize controle de transação explícita e evite instruções de
autocommitted. Utilize sim os comandos:

TDatabase.StartTransaction
TDatabase.Commit

SQL Query Mode


Configure para SERVER permitindo que o servidor SQL
interprete e execute os comandos SQL, e não a BDE.
Propriedades dos componentes VCL

TQuery
CachedUpdates = False
Permite ao servidor gerenciar as atualizações,
deletações e conflitos
RequestLive = False
Há relatos de usuários do Delphi que setando essa
opção para false previne que o VCL mantenha
uma cópia dos dados no cliente, diminuindo o
tráfego na rede.

Em uma configuração C/S, uma re-leitura (“fetch-all”) é a


“desgraça” da performance, pois ela provoca a re-leitura de
toda uma dataset, sobrecarregando a rede. Aqui estão
alguns casos onde uma TQuery provoca um fetch-all :

O método Locate; use somente em base de dados


locais
A propriedade RecordCount; é interessante saber
quantos registros há em um dataset, mas isso gera um
fetch-all.
A propriedade Constraints; Deixe que o servidor se
encarregue disso.
A propriedade Filter; use a cláusula WHERE para que
o servidor selecione os dados.
Commit, quando os flags não são 4096, ou quando
estiver usando controle de transações explícitas.

TTable
A TTable é designada para o uso em tabelas de médio
tamanho em base de dados locais. A TTable lê informações
da metadata de uma tabela, e tenta manter um cache dos
dados do dataset na memória. Essa cópia dos dados é
atualizada quando voce executa um POST ou um
ROLLBACK. Isso implica em uma grande sobrecarga na
rede para a maioria dos banco de dados C/S, que tem
tabelas muito maiores e que geralmente são acessados por
toda a rede. Voce pode observar a atividade de uma
TTABLE através do SQL monitor, que lhe mostrará todas as
chamadas da TTABLE feitas para a BDE e para a API do
Interbase.
Não use TTable para C/S, use
TQuery
Apesar da TTable ser muito conveniente por suas
características RAD e seu modelo abstrato, ela deve ser
evitada com o Interbase. A TTable não foi designada para
ser utilizada em aplicações client/server.

Alternatives para a BDE


IB Objects
IBX

Free IB Components
Informações adicionais
Screen savers
Não utilize Screen Savers (Protetores de tela) no servidor !
Pode parecer que não mas eles consomem processamento
e podem fazer grande diferença na performance do seu
servidor, principalmente os baseados em Open GL ! Se
voce for utilizar um screen saver, opte por aqueles que
simplesmente deixam a tela preta ou colocam o monitor em
stand-by.

Console logins
Não deixe o servidor logado em uma máquina Windows NT.
Mesmo quando o desktop está em idle, ele pode estar
utilizando até 30% do processamento só para manter a
interface. Basicamente todas as tarefas relativas a
manutenção do BD podem ser realizadas em qualquer
estação de trabalho.

Fast I/O
Utilize um HD rápido. Algumas considerações:

Use SCSI; O uso da tecnologia SCSI diferente do que


muitos pensam não tem um ganho de transferência
muito superior a da EIDE
(PC Magazine,
http://www.zdnet.com/pcmag/pclabs/report/r960702a.ht
m); mas as interfaces SCSI bus-mastering toma menos
recursos da CPU
Use um controlador de disco com memória cache
embutida
Disk striping (incluído em RAID níveis 0, 3, ou 5) ganha
em acesso paralelo à multiplos discos; relatos de até
10x.
Pesquise a performance antes de comprar um HD

Servidor Dedicado
Utilize sempre um servidor dedicado. Use máquinas
separadas para servidor de impressão e arquivos.

Optimização do Windows NT
Jung Vu (jungv@knowledgeweb.com) escreveu:

“Configurando o Windows NT para “Optimized for


Network Applications” (Painel de Controle -> Rede ->
Servidor) aumenta e muito a performance do IB. O pico
de consumo que pode ocorrer por alguns segundos
deixará de acontecer.”

Multiprocessadores
Muitos usuários tem reportado apenas um modesto ganho
de performance com o uso do IB em sistemas com multiplos
processadores. Apesar do IB ser certificado para funcionar
com SMP, sua versão atual não implementa características
de execução paralela (que está planejada para uma futura
versão).
O gerenciador de locks do IB não está condificado em multi-
tarefa, portanto os acessos aos dados tendem à ser
serializados. Isso geralmente não é um fator limitante de
performance, pois o gerenciamento de locks é uma
operação de alto rendimento se comparado à I/O física.
Sistemas SMP podem trazer benefícios ao IB pensando que
as CPUs adicionais podem se ocupar com outros serviços
do servidor, como serviços de rede, desktop e outros
processos. O tamanho do ganho de performance nesses
casos depende da demanda de outros processos
relacionados ao processo servidor IB. Baseado nos
relatórios de alguns clientes, esse ganho é de 5% a 20%.
Por outro lado, nosso suporte técnico prefere dizer que o
SMP atualmente contribui para degradar a performance do
IB quando utilizado no Windows NT.

Tamanho dos campos Blob


Um Blob é um tipo de dado sem limite definido de tamanho.
Ele pode ter muitos MBs, um tamanho muito maior que
qualquer banco de dados pode gerenciar em uma simples
operação de I/O. Portanto, BLOBs são definidos como uma
série de segmentos do mesmo tamanho, e a interface de
I/O transfere 1 segmento de cada vez. O padrão do
tamanho do segmento no IB é de 80bytes.
É aconselhável que se defina o segmento de um BLOB
para o mesmo tamanho da página. Se ambos o segmento
do BLOB e a página estão definidos em 4096, queries com
vários blobs podem atingir a velocidade de transferência de
20MB/s. O Interbase deixa de ter qualquer fator de limitação
de performance.

Prefira o UNIX/LINUX ao Windows NT


O UNIX e o Linux são sistemas operacionais mais indicados
para servidores do que o Windows NT. Em escalabilidade,
segurança, estabilidade e especialmente performance, o
Unix/Linux contém tecnologia mais madurada e testada. Em
todas essas áreas, o Linux/Unix mostrá a sua superioridade
sobre os sistemas operacionais da Microsoft. Algumas das
áreas onde a deficiência do NT resulta em performance
inferior incluem :

o NT faz um uso pobre da memória (incluindo a virtual)


o NT tem um modelo de prioridade de
multiprocessamento pobre
o NT tem bugs nos seus processos de scheduling nos
hardwares SMP
o NT requer muito mais CPU e memória para atingir a
mesma performance do Linux/Unix

Interbase-BR - Copyright (c) 2000 by Carlos H. Cantu


728 - Como interromper o
desligamento do Windows
Esta dica ensina como interromper o processo de
desligamento do Windows. Com esta dica você poderá
evitar que desliguem o Windows enquanto a sua
aplicação estiver aberta e correr o risco de perder ou
corromper dados. O código abaixo mostra como fazer
isto.
private
{ Private declarations }
procedure WMQueryEndSession (var Msg :
TWMQueryEndSession); message WM_QueryEndSession;

public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WMQueryEndSession (var Msg :


TWMQueryEndSession);
begin
if MessageDlg(‘O Windows deseja desligar agora, Permitir ?’,
mtConfirmation, [mbYes,mbNo], 0) = mrNo then
Msg.Result := 0
else
Msg.Result := 1;
end;

A Msg “WM_QUERYENDSESSION” é enviada


para todas as aplicações que estão “abertas”
quando o usuário clica em uma das opções
“desligar” do windows ou quando uma aplicação
chama a função “ExitWindows“. Se qualquer
aplicação retornar zero, o Windows não se fechará
e sistema irá parar de enviar as Msg
“WM_QUERYENDSESSION“.
Após ter processado esta Msg, o sistema envia a
mensagem “WM_ENDSESSION” junto do
parâmetro “wParam” com os resultados da
mensagem de “WM_QUERYENDSESSION“.
Finalizando ou não o Windows.

Por Marco Antonio


marco@clubedelphi.com.br
ClubeDelphi ©- Todos os direitos reservados
admin@clubedelphi.com.br
729 - Opções de Projeto
(Desenvolvimento e Distribuição)
Resumo:
Algumas opções são recomendadas durante a fase de
desenvolvimento, mas na criação do produto final elas
podem comprometer o desempenho do sistema.
Project Options -> Compiler

Recomendação para
DESENVOLVIMENTO:
Code Generation
Optimization - OFF
Aligned record fields - ON
Stack frames - ON
Pentium-safe DIV - OFF

Sintaxe Options
Strict var-strings - ON
Complete boolean eval - OFF
Extended syntax - ON
Typed @ operator - ON
Open parameters - ON
Huge strings - ON
Assignable typed constants - OFF

Runtime errors
Range checking - ON
I/O checking - ON
Overflow checking (Q) - ON

Debug
Debug information - ON
Local symbols - ON
Reference info (Y) - ON
Definitions only - ON
Assertions (C) - ON
Use Debug DCUs - ON

Messages
Show hints - ON
Show warnings - ON
Recomendação para
DISTRIBUIÇÃO:
Code Generation
Optimization - ON
Aligned record fields - ON
Stack frames - OFF
Pentium-safe DIV - OFF

Sintaxe Options
Strict var-strings - ON
Complete boolean eval - OFF
Extended syntax - ON
Typed @ operator - ON
Open parameters - ON
Huge strings - ON
Assignable typed constants - OFF

Runtime errors
Range checking - OFF
I/O checking - ON
Overflow checking (Q) - OFF

Debug
Debug information - OFF
Local symbols - OFF
Reference info (Y) - OFF
Definitions only - OFF
Assertions (C) - OFF
Use Debug DCUs - OFF

Messages
Show hints - ON
Show warnings - ON
730 - Melhorando a aparência do
seu Hint
Resumo:
Se vc tiver a Biblioteca de Componentes RxLib , vc pode
usar a Unit RxHints p/ Melhorar a aparência do seu Hint
mudando a Formação p/ Balão, Retangulo … e p/
melhorar mias formatando a cor de fundo , sustentando
por mais tempo e com mais de uma linha.
Texto:
Abaixo um exemplo de implementação:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,
Dialogs, StdCtrls, RxHints ;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender:
TObject);
begin
// —> Formação do Hints
RxHints.SetHintStyle(hsEllipse, 5, true,
taLeftJustify ); // Forma de Balão
Application.HintColor := $005BFFAD ; //
muda a cor de fundo
Application.HintHidePause := 100000 ; //
Sustenta o Hint em quase 2min

// —> mostra o Hint com mais de uma


linha
Form1.Hint := ‘ Consulta Geral do
CLiente ‘ + #13 + ‘ Cadastra Novo CLiente
‘ + #13 +
’ Altera Cadastro do
CLiente ‘ +#13 + ‘ Exclui Cadastro do
CLiente ‘ ;
Form1.ShowHint := True ;

end;

end.
731 - Criando e Distribuindo
Aplicações Shareware
Shareware oferece a possibilidade de compartilhar seus projetos
pessoais com o resto do mundo e o potencial por fazer um pouco
dinheiro vivo no processo. Neste artigo, Clay Shannon mostra como
você pode maximizar as vendas de suas aplicações shareware incluindo
um processo de registro fácil para implementar e fazendo sua aplicação
prontamente acessível para clientes potenciais.
Descrição:
Criando e Distribuindo Aplicações Shareware
Clay Shannon
www.guiadodelphi.com.br
Traduzido por: Marcos Ribeiro
16/12/2001
Shareware oferece a possibilidade de compartilhar seus projetos
pessoais com o resto do mundo e o potencial por fazer um pouco
dinheiro vivo no processo. Neste artigo, Clay Shannon mostra como
você pode maximizar as vendas de suas aplicações shareware incluindo
um processo de registro fácil para implementar e fazendo sua aplicação
prontamente acessível para clientes potenciais.
Se você é desenvolver de uma corporação, consultor, estudante, ou
hobista, produzir aplicações shareware pode ser de benefício para você.
Além dos benefícios monetários óbvios, escrevendo shareware podem o
ajudar também para:
• Expandir suas habilidades de codificação, se o shareware que você
escreve para pedras de amolar, aumenta a sua habilidade atual ou o
leva em regiões do universo da programação que você não explorou
previamente.
• Mantém seu interesse vivo na programação (acontece de você estar
trabalhando em um menor que rebitado projeto de trabalho).
• Provê um meio para ganhar experiência do mundo real em novas
metodologias e disciplinas de programação.
Como você pode ver, há muitas razões boas para estar trabalhado em ”
projetos “, aparte do que você faz no trabalho ou escola. De fato, se a
atração monetária não faz sentido ou até mesmo é repugnante para
você, freeware pode ser o modo para você faze-lo.
A ferramenta certa para o
trabalho
Quando Delphi inicio sobre a cena da programação, era muito elogiado
como oferecendo ” a facilidade do VB e o poder do C “. Isso não era
marketing. Embora não apresentando um ambiente de programação
completo podia ser descrito como “fácil” quando comparado ao C e C++
que VB e Delphi. Até onde poder está preocupado, você pode criar
qualquer tipo de software que você pode imaginar com o Delphi.
Até onde estão preocupados com ferramentas de programação, Delphi
é sem dúvida a melhor escolha para criar aplicações shareware. Para a
maioria dos projetos, você não precisará do Delphi Enterprise. Porém,
se você está usando a edição Personal do Delphi, você não poderá criar
aplicações comerciais. Em outras palavras, você não pode cobrar
dinheiro por aplicações que você cria com a edição Personal.
A melhor ratoeira
Se as pessoas vão carregar, tentam, e continuam usando seu programa,
deve ser útil, diversão para usar, ou (preferentemente) uma combinação
dos dois.
Se você cria um editor de texto, por exemplo, precisa ser melhor que os
usuários já adquirem com Windows (Notepad). Caso contrário, por que
eles trocariam? Mais para o ponto, por que eles o pagariam uma
utilidade que eles já possuem? Se sua aplicação é um editor de texto,
planilha eletrônica, ferramenta de administração de banco de dados, ou
qualquer outra coisa, deve ser melhor que o que já está prontamente
disponível ao usuário. Isto não é dizer que tem que emparelhar
característica-para-característica de produtos de rival. Como um homem
sábio uma vez disse, ” Menos é mais “. por exemplo, muitas pessoas
poderiam preferir um processador de texto com menos características
que o ” tudo mais a pia da cozinha ” que os processadores de texto
principais ostentam, se a versão “lite ” estivesse mais amigável ao
usuário, menos bug, e menos caro.
Outro, talvez até mesmo uma opção mais desafiadora é criar um tipo
único de aplicação. O truque aqui é este: Se o tipo de aplicação que
você tem em mente ainda não foi criado, realmente há um mercado para
ele? Talvez assim, mas é possível que um programa semelhante exista
e simplesmente não foi aceito na feira. Antes invista dúzias, centenas,
ou milhares de horas em seu software magnum opus, faça alguma
pesquisa para ver se uma aplicação semelhante já existe. Você pode
construir uma significativamente melhor? Nesse caso, então vá em
frente! Se não (vou ser honesto com você), trabalhe em outra idéia.
Não doe a loja
O que é aquela expressão velha sobre leite livre e uma vaca? Usuários
de sua aplicação shareware podem não ser deliberadamente
desonestos ou baratos quando eles não registram (e pagam) a cópia
deles da sua aplicação. Muito pode ser esquecimento ou procrastinação
prolongado por parte de usuários que estão agüentando do modo de
sua remuneração receptora de seu trabalho duro. Em um nível pessoal,
tenho que admitir que eu usei o PKZip durante anos antes de eu
finalmente paga por ele. Isto não era mesquinhez minha, mas bastante
procrastinação extraordinária.
Você não tem que se sentar passivamente atrás e esperar que os
usuários farão a coisa certa, entretanto, eventualmente. Você pode fazer
algo que encorajará que os usuários registrem a cópia deles do seu
software: Só “Interdite” uma característica importante aos usuários
registrados. Tenha cuidado para você não impedir aos clientes
potenciais de ver as características principais de sua aplicação. Senão,
isso os frustrará e provocará uma viagem rápida para Iniciar |
Configurações | Painel Controle | Adicionar ou Remove Programas.
Uma boa escolha para lacrar uma característica seria algo que não é
absolutamente essencial, mas sem o qual software é menos precioso.
Exemplos disso é imprimir funcionalidades em algumas aplicações ou,
no caso de aplicações de banco de dados, habilita para adicionar um
novo registro ou modificar registros existentes.
Um fácil esquema para bloquea
algumas características
Alguns registros shareware são implantados suas próprias chaves de
registro em um Web sites. Aqui, entretanto, eu lhe mostrarei um modo
fácil para programar a desaprovação aos usuários não registrados de ter
acesso as características específicas de sua aplicação, junto com um
modo fácil para estas características ser “destravado ” quando eles
pagam seu software.
Em um nutshell, você escreve o código para conferir a existência de um
arquivo que você enviará aos usuários registrados. Preferentemente,
este arquivo será enviado por e-mail, mas quando necessário (o usuário
não possui um endereço de e-mail), você também pode enviar este por
disquete. Quando o arquivo é encontrado, uma string codificada é lida
dele, claro que, decifrado. Se ele combinar com o que você tem em seu
código fonte, pode ser assumido que é um arquivo genuíno, e é feita a
funcionalidade que só está disponível aos usuários registrados. Este
esquema não trancará para determinados hackers, claro que, mas
deveria ser mais que suficiente desencorajar o usuário comum de tentar
usar as características avançadas de seu programa sem pagar por ele.
Como um exemplo, se você está usando um componente DBGrid junto
com PrintDat! de GreBarSys (como eu tenho em meu programa
shareware EZ DB, disponível no CodeCentral em
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16306),
você pode usar o código semelhante ao seguinte:

{–––––––––––––––––-}
procedure
TWhatever.btnPrintClick(Sender:
TObject);
begin
if RegisteredCopy then
DBGridPrintJob1.Print
else

MessageDlg(SAdvantagesOfRegistering,mtIn
formation, [mbOK], 0)
end;
{–––––––––––––––––-}
{ The user must have a “genuine” copy of
the file
EZDB.RegVal in the same dir as the .exe
(genuine
= it contains the encrypted password).
sRegVal and
MAGIC_NUMBER are in EZDBGlobals. }
function RegisteredCopy: Boolean;

function RegFileContainsCorrectValue:
Boolean;
var
sl: TStrings;
sDecryptedRegVal: String;
i: Integer;
begin
sl := TStringList.Create;
try
sl.LoadFromFile(SEZDBReg);
{ Just to be on the “safe side”,remove
empty items }
for i := Pred(sl.Count) downto 0 do
if Trim(sl[i]) = ” then
sl.Delete(i);
sDecryptedRegVal :=
Decrypt(Trim(sl[0]),MAGIC_NUMBER);
Result :=
AnsiSameText(sDecryptedRegVal, sRegVal);
finally
sl.Free;
end;
end;

begin
Result := FileExists(SEZDBReg) and
RegFileContainsCorrectValue
end;

{–––––––––––––––––-}
{ Adapted from strDecrypt from the
freeware unit
XProcs by Stefan Boethe }
function Decrypt(const S: String; Key:
Int64): String;
var
I: Integer;
begin
{$IFDEF Win32}
SetLength(Result,Length(S));
{$ELSE}
Result[0]:=Chr(Length(S));
{$ENDIF}
for I := 1 to Length(S) do
begin
Result[I] := char(Ord(S[I]) xor (Key
shr 8));
Key := (Ord(S[I]) + Key) * C1 + C2;
end; //for I := 1 to Length(S) do
end;
Claro que para gerar o valor correto para o arquivo
que você enviará aos usuários registrados, você
primeiro tem que codificar a string encriptada que
você conferirá. Isto é feito usando Decrypt função irmã
de Encrypt:
{–––––––––––––––––-}
{ Adapted from strEncrypt from the
freeware unit
XProcs by Stefan Boethe }
function Encrypt(const S: String; Key:
Int64): String;
var
I: Integer;
begin
{$IFDEF Win32}
SetLength(Result,Length(S));
{$ELSE}
Result[0]:=Chr(Length(S));
{$ENDIF}
for I := 1 to Length(S) do
begin
Result[I] := Char(Ord(S[I]) xor (Key
shr 8));
Key := (Ord(Result[I]) + Key) * C1 +
C2;
end; // for I := 1 to Length(S) do
end;
Para elucidar o código do procedimento, aqui está
alguns valores pertinentes do projeto da unidade
Globals que ajuda implementar a funcionalidade de
lock/unlock:
{ Encryption values (C1 and C2) adapted
from the
freeware unit XProcs by Stefan Boethe. }
SEZDBReg = ‘EZDB.RegVal’;
sRegVal =
‘SportsDefinition_RunJumpSweatAndSmashIn
toThings’;
MAGIC_NUMBER = 1958;
C1 = 52845;
C2 = 22719;
Você é seu host
Não é bastante para terminar a codificação de sua aplicação
simplesmente. Uma vez completo, você tem que fazer isto disponível
para seu publico, quer dizer, clientes potenciais.
Uploading de software é uma atividade que a Web alterou
drasticamente. Anos atrás, você podia fazer upload de suas aplicações
para serviços on-line múltiplos e boletim que hospedariam as aplicações
fisicamente para você. Com o advento de “nada mais que a Net”,
entretanto, a maioria dos sites shareware agora esperam que você
possa hospedar seus programas por conta própria em seus sites e lhes
dar um link para seu arquivo. Uma exceção para isto é Winsite
(www.winsite.com). Eles ainda lhe permitem armazenar seu arquivo
fisicamente em seus servidores.
Como um programador Delphi, você tem duas opções básicas:
• Você pode criar um Site da Web que hospedará sua aplicação
Shareware.
• Você pode fazer upload de sua aplicação para o Winsite ou para o
CodeCentral da Borland.
Se você opta para o CodeCentral, você terá que unir-se a comunidade
Borland para ter acesso aos arquivos de upload. Como desenvolvedor
Delphi, entretanto, se você já não fez isto, você provavelmente deva
fazer de qualquer maneira. Muitas submissões valiosas são enviadas
para lá regularmente, como componentes freeware, rotinas, e
atualizações para IB Express e IB Console.
Nota: Se você for um membro do AOL, você também pode fazer upload
de seu arquivo para lá diretamente (nenhum URL preexistente é
necessário).
Antes de você fazer upload de sua aplicação, entretanto, existe algum
trabalho preparatório que precisa ser realizado.
Crie uma instalação profissional
Um boa primeira impressão é muito importante quando lidando com
clientes potenciais. Se sua aplicação se parece algo que foi lançado
junto sem muito pensamento ou sem preocupação, não será muito
provável que eles levem isto a serio, ou seu criador (você), seriamente.
Uma ajuda para apresentar um produto profissional com seu software é
usar um instalador. O InstallShield Express é incluído com a maioria das
edições do Delphi. Usando este, você pode facilmente criar uma
instalação para sua aplicação Shareware. Usando InstallShield para
criar sua instalação está além do âmbito deste artigo, mas é fácil usar e
contem seu próprio arquivo de Ajuda para lhe mostra como iniciar.
Falando de arquivos de Ajudar, além de seu EXE, o onipresente
readme.txt, e quaisquer outros arquivos subordinados de suas
necessidades de programa, você também seriamente deve considerar
criar um arquivo de Ajuda independente para sua aplicação.
Nota: além de uma descrição básica de sua aplicação, informações de
direitos autorais, e qualquer outro que você precisa deixar os usuários
conhecerem, seu arquivo readme.txt deve conter suas informações de
contato de forma que clientes saibam para onde enviar o pagamento
(isto está assumindo que você não está aceitando cartões de crédito on-
line).
Uma vez que você tenha criado seus arquivos de instalação usando
InstallShield (ou outra ferramenta de instalação de sua escolha), você
tem então, claro, queira comprimir estes arquivos em um arquivo ZIP
único. Neste ponto, você está pronto para submeter seu arquivo para
vários locais de Shareware.
Além de ter seu arquivo ZIP pronto, também escreva uma descrição
pequena com antecedência como também uma descrição longa de sua
aplicação, porque a maioria dos sites de upload pedi este.
Adicionalmente, uma lista de palavras chaves, às vezes ou pelo menos
é requerida. O mais preciso que você faça sua descrição e lista de
palavras chaves, o mais relevante que seu programa obterá de clientes
potenciais. Sua aplicação pode ajustar as necessidades deles para um
T, mas eles acharão só isto se você faz isto acessível e seus benefícios
óbvio.
Propague a
Finalmente, você está pronto para anunciar a existência de sua nova
aplicação. Com URL na mão (ou, ser mais preciso, colado em Notepad
ou sua substituição de Notepad, junto com suas descrições de programa
e palavras-chaves), você pode então visitar os seguintes locais, onde
você pode fazer o mundo ciente de sua melhor “ratoeira”:
• www.simtel.net
• www.upload.com
• www.tucows.com
• www.winsite.com/help/howtocontrib.html
Agora você faça isto!
Como você pode ver, criando, comercializando, e desdobrando
Shareware não é trivial. Por outro lado, não é ciência de foguete,
qualquer um. Com uma boa idéia, trabalho duro, e planejamentos
sólidos, podem acrescentar suas habilidades de programação, proveja
um pedaço valioso de software para a comunidade mundial, e faça
algum dinheiro para inicializar!
Clay Shannon
BClayShannon@aol.com
Além de escrever sobre o Delphi, Clay Shannon é o autor de dois
romances: “Twisted Roads”, que apresenta um desenvolvedor Delphi
como um dos principais personagens, e “The Resurrection of Samuel
Clemens”. Para mais informações acesse:
http://www.greatunpublished.com/bookstore/author.php3?
accountID=GRTU00694 ou
http://hometown.aol.com/bclayshannon/myhomepage/index.html
O Projeto em Delphi, Clay está mais orgulhoso de seu programa “Bible
XRef”. Que você pode baixa-lo de:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16435
CodeCentral Borland ou http://www.winsite.com/bin/Info?
4000000036430
www.guiadodelphi.com.br
Traduzido por: Marcos Ribeiro
16/12/2001
732 - Os limites do InterBase

Questões / Problemas / Resumo:


Na hora de se construir uma Base de Dados, temos que
ter bastante atenção quanto as limitações do Sistema
Gerenciador de Banco de Dados, se não levarmos em
conta, poderemos ter varias surpresas desagraveis
durante o desenvolvimento da mesma….
Descrição:
Os limites do InterBase
Traduzido por: Marcos Ribeiro
Por: Iván Pons
Na hora de se construir uma Base de Dados, temos que
ter bastante atenção quanto as limitações do Sistema
Gerenciador de Banco de Dados, se não levarmos em
conta, poderemos ter varias surpresas desagraveis
durante o desenvolvimento da mesma.
Muitas vezes podemos “ignorar” o problema, e
buscarmos uma solução que nos permite sair do passo
como está, porém em outros casos, nós nos
encontramos com uma triste realidade de um Sistema,
que não tem toda a potencia de que precisamos.
Por tudo isso, e a pesar de divulgar muitas vezes o
InterBase como um sistema “maravilhoso”, devemos
conhecer de antemão, até onde ele pode chegar:
1 - Número máximo de clientes conectados em um
servidor
Não tem um número máximo de clientes que um
Servidor do IB pode servir. Dependerá de uma
combinação de fatores, incluindo capacidade do
Sistema Operacional, Limitações de Hardware e o que
cada cliente pode no servidor. Em uma aplicação
“normal”, que executa interações humanas e um
servidor médio, o IB pode responder tranqüilamente a
mais de 150 clientes.
2 - Tamanho Máximo da Base de Dados
O tamanho máximo direcionado de um arquivo, em um
único arquivo é de 2Gb no Windows95/98, 4Gb em NT4
e na maioria dos sistemas UNIX. As limitações
dependem do Sistema Operacional. Em uma
configuração de múltiplos arquivos, podem chegar a ter
o tamanho de Terrabytes.
3 – Máximo número de arquivos por Base de Dados
Pode ser, 2 elevado a 16 (65.536), porque os arquivos
estão numerados com um número de 16 bits. Os
arquivos Shadow apontam para este limite. É o limite do
InterBase, porém a maioria dos sistemas operacionais
tem um limite menor de arquivos que podem ser usados
simultaneamente por um único processo.
4 - Número Máximo de Tabelas em uma Base de
Dados
Podem ser, 2 elevado a 16 (65.536), porque as tabelas
estão enumeradas usando um número de 16 bits.
5 – Tamanho Máximo de Filas
64Kb. Os Blobs e Arrays contribuem cada um com
8Bytes. As tabelas de sistemas tem uma limitação de
tamanho de coluna de 128 Kb.
6 – Número Máximo de Filas e Colunas por tabela
Pode ser, 2 elevado a 32 filas, e as filas estão
numeradas com um inteiro de 32 bits, por tabela. O
número de colunas em uma fila dependerá do tipo de
dados usado. Assim, uma fila pode ter um tamanho de
64K, e poderíamos definir 16.384 colunas do tipo
INTEGER (quatro bytes) em uma tabela.
7 – Número Máximo de Índices por tabela
Pode ser 2 elevado a 16 (65.356), porque estão
enumerados com um inteiro de 16 bits.
8 – Número Máximo de Índices por Base de Dados
Pode ser 2 elevado a 32, porque se podem criar 216
tabelas por Base de Dados, e cada tabela pode chegar
a ter 216 índices.
9 – Tamanho Máximo da Chaves de um Índice
Inicia com 256 bytes para uma chave simples de coluna,
aumentando-se 200 para chaves de múltiplas colunas,
restando 4 bytes por cada coluna adicional.
10 – Máximo número de eventos por Procedimento
Armazenado
Não tem restrições para desenvolvimento, porém tem
um limite prático, dado por um limite em tamanho do
código de um Procedimento Armazenado em uma
Trigger.
11 – Tamanho máximo do código de um
Procedimento Armazenado em uma Trigger
48Kb de BLR (Linguagem compilada de um
Procedimento Armazenado ou de uma Trigger.)
12 – Tamanho Máximo de um Blob
O tamanho máximo de um Blob dependerá do tamanho
de página de uma Base de Dados. Assim:
1Kb de tamanho de página à 64Mb
2Kb de tamanho de página a 512Mb
4Kb de tamanho de página a 4Gb
8Kb de tamanho de página a 32 Gb
O tamanho máximo de um segmento de um Blob é de
64Kb.
13 – Número máximo de tabelas em um Join
Não tem restrições, porém o tempo de resposta em uma
tarefa de cruzar tabelas e exponencial em relação com o
número de tabelas que participam em um JOINEI
número máximo de tabelas em um JOIN, para que seja
eficiente é sobre 16 tabelas, porém a realidade e
experiência com nossas aplicações, com uma carga real
de dados em nossas tabelas poderá ter um rendimento
aceitável.
14 – Número máximo de consultas dentro de outras
consultas
Não tem restrições, porém o limite prático dependerá do
tipo de consulta de teremos.
15 – Número máximo de colunas para um índice
composto
16
16 – Número de Procedimentos Armazenados na
Trigger dentro de um PA em uma Trigger.
Em Windows 95/98/NT 750. Em plataformas Unix 1000.
17 – Tamanho máximo de chave em uma sentença
SORT
32Kb
18 – Entre Datas
Entre o 01/01/100 aC até 29/02/32768 Dc
Informacões extraidas da Borland Inc.
Os Limite do InterBase
www.brasilsoft.cjb.net
733 - Alinha o título da barra de
títulos do form à Esquerda (Normal)
ou a direita.

//Deve ser usada assim:


//Procedure TForm1.Titulo(Titulo:
Pchar;pos,wParam: Integer);
//e declarada na clausua private.

procedure Titulo(Titulo: Pchar;pos,wParam:


Integer);
var
DC: THandle;
R1, R2: TRect;
begin
DC := GetWindowDC(Handle);
try
SetWindowText(Handle, nil);
GetWindowRect(Handle, R2);
R1.Left := GetSystemMetrics(SM_CXSIZE) +
GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXFRAME);
R1.Top := GetSystemMetrics(SM_CYFRAME);
R1.Right := R2.Right - R2.Left - R1.Left -
2 *
GetSystemMetrics(SM_CXSIZE);
R1.Bottom := R1.Top +
GetSystemMetrics(SM_CYSIZE);
if wParam = 1 then
begin
SetBkColor(DC,
GetSysColor(COLOR_ACTIVECAPTION));
end
else
begin
SetBkColor(DC,
GetSysColor(COLOR_INACTIVECAPTION));
end;
SetTextColor(DC,
GetSysColor(COLOR_CAPTIONTEXT));
if pos = 1 then
begin
DrawText(DC, Titulo, -1, R1, DT_LEFT or
DT_VCENTER);
end
else
begin
DrawText(DC, Titulo, -1, R1, DT_RIGHT or
DT_VCENTER);
end;
finally
ReleaseDC(Handle, DC);
end;
end;
734 - Carrega os dados, salvos em
um arquivo, em um StringGrid
Procedure LoadGrid(FilePath: String; grid:
TStringGrid);
var
f: textfile;
temp,x,y:integer;
tempstr: string;
begin
assignfile (f,FilePath + ‘'+ Grid.Name +
‘.inf’);
reset (f);
readln (f,temp);
grid.colcount := temp;
readln (f,temp);
grid.rowcount := temp;
For X := 0 to grid.colcount-1 do
begin
For y := 0 to grid.rowcount-1 do
begin
readln (F, tempstr);
grid.cells[x,y]:=tempstr;
end; //For y := 0 to grid.rowcount-1 do
end; // For X := 0 to grid.colcount-1 do
closefile (f);
end;
735 - Executando o comando ARJ
em um aplicativo Delphi
WinExec(‘command.com /c Arj a -vva -jm -p1
-r a:copia.arj + Arj C:\Meus
Documentos\*.* A:/copia.arj’,
WS_MAXIMIZE);
(obs: para descompactar use Arj x -vva -jm -p1 -r)
736 - Trabalhando com Strings
Delete
Insert
InttoStr
Length
Lowercase
Pos
delete - Deleta uma substring dentro de uma string.
Delete (Mystring, 2,1) // delete da
variável mysring, na segunda posição, 1
caractere
insert - Insereuma substring em uma string .
Insert (“z”, mystring, 1 ) //insere a
letra z no começo da string
Inttostr - Converte um valor inteiro para string.
MyString := Inttostr(Shape1.top) //A
variaável mystring recebe o valor top do
componente Shape1
length - Retorna o número de caracteres de uma string
canvas.textout ( 10, 10, ‘ Número de
caracteres =’ + InttoStr (length MmyString
))); //exibe o número de caracteres
contido em uma string.
Lowercase - Converte para menúsculos os caracteres
alfabétiocs de uma string;
a variável Nome_tal recebe a palavara ‘ sorte ‘ em
maiúsculas…
Var
Nome_tal : string;
Begin
Nome_tal := Lowercase( ‘ sorte ‘ );
End;
Pos - Esta função retorna um valor integer
correspondente a posição de uma string dentro de uma
outra string.
Var
VPalavra : string;
VNumero : Integer;
Begin
VPalavra := ‘ Pernambuco ‘ ;
VNumero := Pos ( ‘ a ‘ , VPalavra ) ; //
Numero retorna o valor 5
end;
exemplo II:
if Pos(Edit2.text,Edit1.text) 0 then
begin
ShowMessage(‘Esta letra exite’);
end
else
begin
ShowMessage(‘Esta letra não existe’)
end;
STR -Esta procedure converte um valor inteiro ou real
para uma string.
// a variável Vs recebe o valor da
variável Vn
Var
Vn : real;
Vs : string;
Begin
Vn := 100 ;
Str (Vn, Vs) ;
end;
StrtoInt - Esta função converte um valor string para um
valor inteiro.
// A variável Vlocal recebe o valor (
inteiro ) top do componente Shape1.
Var
vLocal : String;
Begin
Vlocal : InttoStr ( Shape1. Top) ;
End
UPPERCASE - Esta rotina substitui todas as letras
minúsculas de uma string por letras maiúsculas.
//No exemplo abaixo o Caption de um Label
recebe em maiúsculas o texto de um Edit.
Label1.Caption := Uppercase ( Edit1. Text
);
Obs:
Atente para a linha a seguir. Ela deve ser escrita no
evento OnKeyPress de um Edit e converte
automaticamente as letras digitadas para maiúscula.
VAL - Esta rotina extrai o valor numérico ( tipo real ou
integer ) de uma String;
Sua sintaxe é :
Val ( S ; var v ; var Code : integer );
Observe o exemplo abaixo :
Var
N, C : integer ;
Begin
Val ( Edit1.Text, N, C ) ;
Button1.Top := N ;
End ;
// Se a variável C tiver valor diferente
de 0 significa que ouve erra na
conversção.
{ ex : O texto do Edit não é um número
intéiro válido }
Declarando uma strings:
var
terra: string; //declaração simples
marte: string [5]; //delimitado 5
caracteres para a string
venus: shortstring; //string de menos de
256 caracteres
737 - Atalhos de Teclado da IDE
do Delphi
Há algum tempo, montei uma pequena relação de
alguns truques, macetes e atalhos que considero ótimos
para aumentar a produtividade no trabalho com o
Delphi. Esta relação, passo a vocês (abaixo) e torço
para que as dicas lhes sejam proveitosas.
Ctrl+Shift+I: Indentar multiplas linhas de código de uma
única vez em “n” espaços (conforme o que estiver
especificado em Tools/Editor Options/General/Block
Indent).
Ctrl+Shift+U: Recuar indentação em “n” espaços (ídem
acima).
Ctrl+Shift+0 a 9: Inserir um Bookmark no editor de
código. Ex: Você está na linha 845 e tecla Ctrl+Shift+0
(irá aparecer um pequeno quadrado com o número 0 à
esquerda do editor). Você vai para o início da unit e,
para voltar para a linha 845, é só teclar Ctrl+0. Tecle
novamente Ctrl+Shift+0 para desmarcar.
Alt+G: Ir para uma determinada linha.
Ctrl+Shift+Seta para cima ou para baixo: Intercala entre
o cabeçalho da procedure/função e a implementação da
mesma.
Ctrl+Shift+C: Class Completion. Este recurso é muito
interessante para “auto-completar” uma
função/procedure que você irá criar. Ex: Você digita o
seguinte cabeçalho de procedure na seção de interface
da unit:
procedure Imprimir(Sender: TObject;
Relatorio: String);
Ao teclar Ctrl+Shift+C, automaticamente o Delphi insere
na área de Implementation (no final da unit) o “corpo” da
procedure, como segue:
procedure Imprimir(Sender: TObject;
Relatorio: String);
begin
end;
Este recurso também funciona da forma inversa, ou
seja, se você implementar o “corpo” da
procedure/function, e teclar Ctrl+Shift+C, o Delphi irá
adicionar o cabeçalho na área de interface da unit.
Ctrl+Mouse: Clique com o botão esquerdo do mouse
mantendo pressionada a tecla Ctrl sobre a chamada a
uma procedure/function/variável para localizá-la na unit
atual ou em outra unit.
Ctrl+J (Code Templates): Este recurso também tem
uma boa utilidade.
Digamos que você, a todo momento, precise usar um
“if..then..else”. Ao invés de digitar todo comando, você
pode teclar Ctrl+J e, localizar o Template (modelo)
apropriado na janela que se abre. Tecle enter para
aplicar o Template escolhido. Para alterar ou incluir
novos templates, vá em Tools/Editor Options/Code
Insight.
Ctrl+O+U: Alterna a caixa (maiúscula/minúscula) do
código selecionado.
Ctrl+K+E: Converter o código selecionado para
minúsculas.
Ctrl+K+F: Converter o código selecionado para
maiúsculas.
Ctrl+E: Ativa a busca incremental. Você pode
pressionar Ctrl+E e digitar diretamente a palavra que
deseja procurar, sem a necessidade de passar por uma
caixa de diálogo especial (Ctrl+F).
Ctrl+Shift+Setas: Mover o(s) componente(s)
selecionado(s) rapidamente no form. O “salto” da
movimentação é determinado pelo valor informado em
Tools/Environment Options/Grid size X e Y.
Ctrl+Setas: Move o componente pixel a pixel.
Shift+Setas: Redimensiona o componente pixel a pixel.
OUTRAS DICAS:
Quando estamos trabalhando com o Delphi, muitas
vezes aparece a dita
cuja Ampulheta e temos que ficar aguardando a boa
vontade da mesma em voltar ao normal. Isso se deve ao
fato de o Delphi manter uma análise de segundo plano
constante, tanto do código-fonte que você está
escrevendo, quando do código-fonte das units a que a
sua unit atual se refere. Este recurso tem por finalidade
auxiliar na codificação e na depuração do programa. O
ideal é desabilitar este recurso e só habilitá-lo quando
necessário. Para isso, entre em Tools/Editor
Options/Code Insight e, no grupo Automatic Features,
desmarque as opções 1, 2 e 4. Além disso, diminua o
Delay para 0,5 sec.
Quando for necessário usar estes recursos proceda da
seguinte forma:
- Se quiser usar o Code Completion, no momento em
que digitar o comando e o ponto (Ex. Edit1. ), presione
Ctrl+Barra de Espaço para forçar a exibição dos
comandos relativos àquele componente.
- Se quiser usar o Code Parameters, para visualizar os
tipos de parâmetros usados por uma função, após
digitar o nome da função e o parêntesis, pressione
Ctrl+Shift+Barra de Espaço (Ex: ZeraCod( ). Isto fará
com que um hint apareça, exibindo qual parâmetro deve
ser informado naquele momento.
- Quando você move o ponteiro do mouse sobre um
componente, uma dica de tela aparece mostrando o
nome e o tipo do mesmo (Ex: CdEmp: TEdit).
- Quando você redimensiona um componente, a dica
mostra o tamanho (width x height) atuais.
- Quando você move um componente, a dica indica a
posição atual (left e top).
- Para selecionar vários componentes, mantenha a tecla
Ctrl pressionada enquando arrasta o ponteiro do mouse
sobre os mesmos. Esta técnica é muito útil quando se
quer selecionar componentes que estão inseridos em
um componente do tipo container (Panel, GroupBox,
ScrollBox, etc).
- Se você precisa adicionar vários componentes do
mesmo tipo num form, mantenha a tecla Shift
pressionada e clique sobre o componente desejado na
paleta de componentes do Delphi. Agora é só ir clicando
no form, onde quer que os novos componentes sejam
inseridos. Para desfazer a “trava” do componente, clique
no botão que tem um ponteiro de mouse, localizado no
lado esquerdo da paleta de componentes.
{Dica Enviada por Adriano Machado}
738 - Lock de Registro
Busquei maiores informações sobre lock de registros, e
encontrei uma solução mais adequada para o seguinte
problema:
1) Tabela: pedido
Tabela: itemspedido
Tabela: estoque
 Problemas:
1) Atualizar o estoque e impedir a atualização de outros
usuários;
2) Atualizar o campo de status do pedido para
atualizado após atualização de
todos os items do pedido;
 Solução:
try
database.starttransaction
query1.sql.text := ‘update pedido set
status = “C” where nropedido = ‘ +
ednro.text;
query1.execsql // Neste momento o
registro do pedido sera lockado
while not itemspedido.eof
begin
query1.sql.text := ‘update estoque set
qtde = qtde + ‘ + edqtde.text + ‘ where
codpro = ‘ + edprod.text;
query1.execsql // Neste momento o
registro do produto sera atualizado e
lockado
end;
database.commit // apos o while
significa que tudo foi OK, conclui todas
as atualizaçoes e libera os locks
except
// caso aconteca algum problema nao
atualizará os registros e liberara todos
os locks
database.rollback
end;
Neste exemplo, coloquei a atualizacao do pedido no
inicio do bloco, numa abordagem inicial poderia pensar
em erro na logica, porem como esta sendo tratado tudo
dentro de uma transacao ou necessito lockar o registro
do pedido no inicio e para isso eu executei o UPDATE e
caso dê algum problema na execucao do bloco este
registro nao sera atualizado.
É muito interessante também abordar que os controles
de timeout e niveis de isolamento, para o banco de
dados utilizado.
Outro aspecto para discussão seria : Por que nao utilizar
as opcoes do dataset de edit, update, post … em vez de
utilizar o execsql de uma query.
Entao pensemos no seguinte bloco
try
database.starttransaction
estoque.edit
estoque.qtde := estoque.qtde +
edqtde.text
estoque.update
database.commit
except
database.rollback
end
Parece lógico e certo, mas para um ambiente
monousuario, pois num ambiente multiusuário o valor da
qtde sofre mudancas constantes e no momento que este
bloco estiver sendo executado o valor de qtde ja foi
atualizado por outro usuario e a informacao que voce
esta trabalho é velha . Isto certamente nao acontecera
num bloco de transacao via comando update pois ele
sempre trabalhara com a qtde atual e travara o registro,
entao observemos o comando update.
update estoque
set qtde = qtde + ediqtde.text
where codpro = edtpro.text
Observe que qtde corresponde ao valor atual do banco
e nao uma variavel armazenada pelo sistema a qual fica
desatualizada.
Nesta solucao o meu estoque e pedido estarao
INTEGROS e nao me darao sustos em valores de
saldos incorretos
{Enviada por Mario Ferreira}
739 - Como mudar o foco após
digitar toda a data
Pode ser no OnChange do mesmo:
if Lenght(Edit1.Text)>10 then {10 digitos}
edit2.setfocus
{Dica enviada por Andersom}
740 - 13 Pequenas modificações no
Delphi
As alterações abaixo devem ser feitas no registro com
muito cuidado! Faça um backup do seu registro antes de
iniciar a alteração!
1) Fazer com que a orelha da paleta de componentes
seja automaticamente selecionada quando o mouse
estiver sob ela:
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Extras]
“AutoPaletteSelect”=“1”
2) Fazer o Scroll para a direita e para a esquerda
quando o mouse estiver sobe as setas da paleta de
componentes:
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Extras]
“AutoPaletteScroll”=“1”
3) Desabilitar a seleção de menus com seqüências
de Ctrl+Alt em teclados internacionais
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Editor\Options]
“NoCtrlAltKeys”=“0”
4) Forçar o texto da direita para a esquerda no form
designer (? ainda nãovi funcionando)
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Form Design]
“AlwaysEnableMiddleEast”=“0”
5) Mostrar as fontes no object inspector. Fica lento
se houver muitas fontes instaladas
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Extras]“FontNamePropertyDisplayFontNames”=“1”
6) Mostra erros de compilação no message view
window
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Compiling]
“ShowCodeInsiteError”=“1”
7) Mudar a cor da metade da direita ad paleta de
propriedades do object inspector
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Globals]
“PropValueColor”=“clNavy”
8) Desabilitar pacotes
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Disabled Packages]
“$(DELPHI)\Bin\dcldss50.bpl”=”
9) Valor default de TwoDigitYearCenturyWindow (see
the help file)
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Globals]
“TwoDigitYearCenturyWindow”=“50”
10) Diretório alternativo de componentes
templates(shared/network)
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Component Templates]
“CCLibDir”=“C:\D5\Lib\Comps”
11) Fonte Default para novos formulários
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
FormDesign]
“DefaultFont”=“MSSansSerif,10,Normal”
12) Não perguntar ao mudar o atual JIT debugger (?
ainda não vi funcionando)
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Debugging]
“DontPromptForJITDebugger”=“0”
13) Dll usada para a versão de controle de interface
na IDE
[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\
Version Control]
“VCSManager”=“C:\D5\VersCtrl\VersCtrl.dll”
Dica enviada por André Fisher
741 - Macro no rxQuery
Para usar macros no rxQuery (componente query da
biblioteca) RxLib, faça o seguinte:
1) no componente coloque a seguinte instrução: Select *
From TABELA Order By %mColunaOrdem
2) no programa use a seguinte linha de codigo:
rxQuery1.MacroByName( ‘mColunaOrdem’ ).AsString :=
‘NOME_CLIENTE’ ;
3) depois é tudo igual.
Qual a vantagem de usar macros: em algunas situações
como a seleção de colunas para ordenação não é
possivel usar parametros e as macros funcionam
perfeitamente.
Espero ter sido claro.
Dica enviada por Joubert Rinaldi
742 - Como anda a lista de
processos do windows NT
Precisando saber como anda a lista de processos do
windows e só sabe o nome do executável…

HLF - 29/04/2002 - Gerernciar Processos


do NT

OBS:
É necessário ter a biblioteca psapi.dll
instalada.

Lista de funcoes e Procedures para


gerenciamento:
procedure ListaProcessosNT;
- Cria lstProcesses se não existir e
adiciona a ela todos os processos
atualmente abertos do NT
seguindo o registro TItem

procedure FinalizaListaProcessosNT;
- Libera a memória ocupada pelos itens
da lista lstProcesses

function
IsFileActive(fileName:string):Boolean;
- verifica se um arquivo 8.3 DOS está
carregado

function
GetProcessoIDfromFileName(fileName:string)
: DWORD;
- pega o numero do processo (Thread
principal do arquivo

function
GetProcessofromFileName(fileName:string):
Integer;
- pega o numero do processo pelo nome do
arquivo

function
TerminateProcessbyFileName(FileName:String
):Boolean;
- terminador do processo utilizando o
nome doa rquivo como referencia

procedure
RemoveProcessoListaNome(fileName:string);
- executado internamente apos o
terminateProcessbyfilename

Function
GETWindowbyThread(idThread:DWORD): HWND;
- pega o HWND de uma janela cujo
idthread foi informado

function
GetWindowfromFileName(fileName:string):
DWORD;
- pega HWND da janela de um arquivo

function
GetThreadIDfromFileName(fileName:string):
DWORD;
- pega o Numero da Thread Principal do
Arquivo

procedure ExecApp(AFileName: String;


bWait: Boolean);
- executa uma apalicacao
}
unit UProcessNT;

interface

uses
Windows, SysUtils, Classes, Psapi,
ShellApi;

procedure ListaProcessosNT;
procedure FinalizaListaProcessosNT;

function
IsFileActive(fileName:string):Boolean;
function
TerminateProcessbyFileName(FileName:String
):Boolean;

procedure
RemoveProcessoListaNome(fileName:string);
procedure ExecApp(AFileName: String;
bWait: Boolean);

Function
GETWindowbyThread(idThread:DWORD): HWND;
function
GetWindowfromFileName(fileName:string):
DWORD;
function
GetThreadIDfromFileName(fileName:string):
DWORD;
function
GetProcessoIDfromFileName(fileName:string)
: DWORD;
function
GetProcessofromFileName(fileName:string):
Integer;
type
PItem=^TItem;
TItem=record
Nome : String[200];
ProcessID : DWORD;
ThreadID : DWORD;
Window : HWND;
Processo : Integer;
end;
var
i: Integer;
Ignore: Boolean;
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
lstProcesses : Tlist;
ModuleCount: Cardinal;
Modules: array[0..512] of DWord;
Proceso: THandle;
ProcesoName: array[0..512] of Char;
ProcesoNameStr: string;
Procesoes: array[0..512] of DWord;
Used: Cardinal;
Item :Titem;
lstWin : TStrings;

implementation

procedure ListaProcessosNT;
var
_PItem : PItem;
locHandle : THandle;
j: integer;
begin
if Not Assigned(lstProcesses)
then lstProcesses := Tlist.Create
else begin
FinalizaListaProcessosNT;
lstProcesses := Tlist.Create;
end;
locHandle :=0;
Win32Check(EnumProcesses(@Procesoes[0],
sizeof(Procesoes), Used));
for j := 0 to (Used div sizeof(DWord)) -
1 do begin
Ignore := False;
Proceso :=
OpenProcess(PROCESS_QUERY_INFORMATION or
PROCESS_VM_READ,False, Procesoes[j]);
if Proceso = 0 then
begin
ProcesoNameStr := ‘unknown’;
end
else
begin
try
Win32Check(EnumProcessModules(Proceso,
@Modules[0], sizeof(Modules[0]),
ModuleCount));
GetModuleBaseName(Proceso, Modules[0],
ProcesoName, sizeof(ProcesoName));
ProcesoNameStr := string(ProcesoName);
locHandle := Proceso;
CloseHandle(Proceso);
except
CloseHandle(Proceso);
Ignore := True;
end;
end;
if not Ignore then
begin
GetMem(_PItem,Sizeof(item));
_PItem^.Nome := ProcesoNameStr;
_PItem^.Processo := Proceso;
_PItem^.ProcessID := Procesoes[j];
_PItem^.ThreadID := Procesoes[j];
_PItem^.Window :=
GETWindowbyThread(_PItem^.ThreadID);
lstProcesses.add(_PItem);
end;
end;
end;

procedure FinalizaListaProcessosNT;
var
j:integer;
begin
for j:=0 to lstProcesses.Count-1 do
Freemem(PItem(lstProcesses.Items[j]),Sizeo
f(item));
lstProcesses.Free;
end;

function
IsFileActive(fileName:string):Boolean;
var
lnome :string;
j:integer;
begin
// Atualiza lista de processos na memoria
ListaProcessosNT;
// — necessário para localizar todos os
itens carregados na memória no momento
Result := false;
for j:=0 to lstProcesses.Count-1 do
begin
lnome :=
PItem(lstProcesses.items[j])^.Nome;
if (uppercase(lnome) =
Uppercase(filename))
then begin
Result := True;
break;
end;
end;
end;

function
GetProcessoIDfromFileName(fileName:string)
: DWORD;
var
j :integer;
begin
Result := 0;
for j:=0 to lstProcesses.Count-1 do
if
uppercase(PItem(lstProcesses.items[j])^.No
me) = Uppercase(filename)
then begin
Result :=
PItem(lstProcesses.items[j])^.ProcessID;
break;
end;
end;

function
GetThreadIDfromFileName(fileName:string):
DWORD;
var
j :integer;
begin
Result := 0;
for j:=0 to lstProcesses.Count-1 do
if
uppercase(PItem(lstProcesses.items[j])^.No
me) = Uppercase(filename)
then begin
Result :=
PItem(lstProcesses.items[j])^.ThreadID;
break;
end;
end;

function
GetWindowfromFileName(fileName:string):
DWORD;
var
j :integer;
begin
Result := 0;
for j:=0 to lstProcesses.Count-1 do
if
uppercase(PItem(lstProcesses.items[j])^.No
me) = Uppercase(filename)
then begin
Result :=
PItem(lstProcesses.items[j])^.Window;
break;
end;
end;

function
GetProcessofromFileName(fileName:string):
Integer;
var
j :integer;
begin
Result := 0;
for j:=0 to lstProcesses.Count-1 do
if
uppercase(PItem(lstProcesses.items[j])^.No
me) = Uppercase(filename)
then begin
Result :=
PItem(lstProcesses.items[j])^.Processo;
break;
end;
end;
function
TerminateProcessbyFileName(FileName:String
):Boolean;
var
Process: THandle;
ProcessId, exitcode: DWord;
begin
Result := False;
ProcessId :=
GetProcessoIDfromFileName(FileName);
Process :=
OpenProcess(PROCESS_TERMINATE, False,
ProcessId);
if Process = 0 then exit;
TerminateProcess(Process,1);
CloseHandle(Process);
Result := True;
// retirar da lista de processos
RemoveProcessoListaNome(FileName);
end;

procedure
RemoveProcessoListaNome(fileName:string);
var
j :integer;
begin
for j:=0 to lstProcesses.Count-1 do
if
uppercase(PItem(lstProcesses.items[j])^.No
me) = Uppercase(filename) then
begin

FreeMem(PItem(lstProcesses.items[j]),sizeo
f(item));
lstprocesses.Delete(j);
break;
end;
end;

{
//Caso seja informado true no parâmetro
bWait, a rotina deve esperar o término do
processo através da função de sinconização
WaitForSingleObject.

Exemplo:
procedure TForm1.Button1Click(Sender:
TObject);
begin
ExecApp(‘c:\windows\calc.exe’,true); //
Epera terminar
end;
}
procedure ExecApp(AFileName: String;
bWait: Boolean);
var
RetCode: Boolean;
begin

{ fill with known state }


FillChar(StartInfo,
SizeOf(TStartupInfo), #0);
FillChar(ProcInfo,
SizeOf(TProcessInformation), #0);

StartInfo.cb := SizeOf(TStartupInfo);

RetCode :=
CreateProcess(PChar(AFileName), nil, nil,
nil, False,
CREATE_NEW_PROCESS_GROUP or
NORMAL_PRIORITY_CLASS,
nil, nil, StartInfo, ProcInfo);
// Verifica se criou processo e se
espera terminar
if (RetCode and bWait) then
WaitForSingleObject(ProcInfo.hProcess,
INFINITE);

end;

Function
GETWindowbyThread(idThread:DWORD): HWND;
var
retorno :HWND;
Function Windowlistbythread(hWnd: HWND;
lParam: LPARAM): BOOL;stdcall;
Var
sgTitle : Array[0..255] of char;
sgBase : String;
sgH : String;
inLen : Integer;
sgText : String;
dwProcess : DWord;
Begin

GetWindowThreadProcessId(hWnd,@dwProcess);
if dwProcess = idThread then
begin
retorno:=hWnd;
end;
Result := true;
End;
Begin
Try
retorno := 0;
EnumWindows(@Windowlistbythread,0);
Result := retorno;
Except
Result :=0;
exit;
End;
end;
end.
Dica Enviada por Heverton Luiz Fornazari
743 - Como adicionar uma linha
formatada (cor, negrito, etc) num
RichEdit
Richedit1.SelAttributes.Color:=clBLue; //
Cor Azul
Richedit1.SelAttributes.Style:=
[fsBold,fsUnderline]; // Negrito e
sublinhado
Richedit1.Lines.Add(‘Linha’); // Adiciona
linha
Richedit1.SelAttributes.Style:=[]; //
Volta ao estilo normal
Richedit1.SelAttributes.Color:=clBlack; //
Volta à cor normal
Dica enviada por Marcus
744 - Criando fontes no Delphi
PARA CRIAR UMA FONTE COMO A TIMES NEW
ROMAN:
CreateFont(18,9,7,7,FW_LIGHT,0,0,0,DEFAULT
_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_P
RECIS,1,2,‘MyFont’);
PARA CRIAR A FIXEDSYS:
CreateFont(15,8,9,9,FW_LIGHT,0,0,0,DEFAULT
_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_P
RECIS,1,FF_MODERN,‘MyFont’);
PARA CRIAR A FIXEDSYS TACHADA E
SUBLINHADA:
CreateFont(15,8,9,9,FW_LIGHT,0,1,1,DEFAULT
_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_P
RECIS,1,FF_MODERN,‘MyFont’);
PARA CRIAR UM MODELO BONITO PARECIDO COM
A MS SANS SERIF E A ARIAL:
CreateFont(16,6,0,0,FW_LIGHT,0,0,0,DEFAULT
_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_P
RECIS,0,FF_SWISS,‘MyFont’)
PARA CRIAR UM MODELO BONITO QUE SE
ASSEMELHA COM A ARIAL ITÁLICO:
CreateFont(17,5,0,0,FW_LIGHT,1,0,0,DEFAULT_CHAR
SET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS
,2,FF_SWISS,‘MyFont’);
OUTRO MODELO PARECIDO COM A ARIAL:
CreateFont(16,5,0,0,FW_LIGHT,1,0,0,DEFAULT
_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_P
RECIS,0,FF_SWISS,‘MyFont’);
MODELO PARECIDO COM TAHOMA (OU VERDANA):
CreateFont(16,6,0,0,FW_LIGHT,0,0,0,DEFAULT
_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_P
RECIS,2,FF_SWISS,‘MyFont’);
Essas funções retornam um valor inteiro. Para usá-los
em um componente que tenha a propriedade ‘Handle’
de um objeto ‘TFont’. Exemplo:
Edit1.Font.Handle := CreateFont(…);
Memo1.Font.Handle := CreateFont(…);

Dica enviada por MuriloSH


745 - Como colocar BitButton no
messagedlg
Arquivo: Dialogs.pas
// with TButton.Create(Result) do // linha
original
with TBitBtn.Create(Result) do // linha
modificada
begin
Name := ButtonNames[B];
Parent := Result;
Caption :=
LoadResString(ButtonCaptions[B]);
ModalResult := ModalResults[B];
if Name = ‘Yes’ then
Kind := bkYes;
if Name = ‘No’ then
Kind := bkNo;
if Name = ‘OK’ then
Kind := bkOK;
if Name = ‘Cancel’ then
Kind := bkCancel;
if Name = ‘Abort’ then
Kind := bkAbort;
if Name = ‘Retry’ then
Kind := bkRetry;
if Name = ‘Ignore’ then
Kind := bkIgnore;
if Name = ‘All’ then
Kind := bkAll;
if Name = ‘NoToAll’ then
Kind := bkNo;
if Name = ‘YesToAll’ then
Kind := bkAll;
if Name = ‘Help’ then
Kind := bkHelp;
Dica Enviada por Silvio Guedes dos Santos
746 - Teclas de funções no Dbgrid
Procedure
TFmCadPedidos.FormKeyDown(Sender: TObject;
var Key: Word;
Shift: TShiftState);
begin
Case Key Of
Vk_Return,
Vk_Down:if not (ActiveControl is
TDBGrid) then
Perform(Wm_NextDlgCtl,0,0);
Vk_Up :if not (ActiveControl is TDBGrid)
then
Perform(Wm_NextDlgCtl,1,0);
Vk_Insert : if (ActiveControl is
TDBGrid) then
BBtnNovoItem.Click;
Vk_F10 : if (ActiveControl is TDBGrid)
then
BBtnGravarItem.Click;
Vk_Delete : if (ActiveControl is
TDBGrid) then
BBtnExcluirItem.Click;
Vk_F6 : if (ActiveControl is TDBGrid)
then
BBtnCancelaItems.Click;
Vk_F2 : if (ActiveControl is TDBGrid)
then
BBtnAtualizaItems.Click;
Vk_F4 : if (ActiveControl is TDBGrid)
then
SBCancelPedido.Click
else
messagedlg(‘Voce precisa primeiro
cancelar os items!’+#13+‘para em seguida
cancelar os pedidos’, mtWarning,[mbok],0);
Vk_F12 : if (ActiveControl is TDBGrid)
then
SBFechaPedido.Click;
end;
end;
Dica Enviada por Silvio Guedes dos Santos
747 - Detectando o tipo de
Conexão com a internet
uses Wininet

function ConnectionKind: Boolean;


var
flags: DWORD;
begin
Result :=
InternetGetConnectedState(@flags, 0);
if Result then
begin
if (flags and INTERNET_CONNECTION_MODEM)
= INTERNET_CONNECTION_MODEM
then
ShowMessage(‘Modem’);
if (flags and INTERNET_CONNECTION_LAN) =
INTERNET_CONNECTION_LAN then
ShowMessage(‘LAN’);
if (flags and INTERNET_CONNECTION_PROXY)
= INTERNET_CONNECTION_PROXY
then
ShowMessage(‘Proxy’);
if (flags and
INTERNET_CONNECTION_MODEM_BUSY) =
INTERNET_CONNECTION_MODEM_BUSY then
ShowMessage(‘Modem Busy’);
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
ConnectionKind;
end;
748 - Comandos para Dial-up com
Delphi
Alem de poder usar o ShellExecute, WinExec…
podemos utilizar tambem varias APIs…vejam :
RasDial // para discar
RasCreatePhoneBookEntry // criar uma nova entrada
RAS
RasHangUp // desconectar
RasEnumConnection // para enumerar as coneccoes
ativas
entre varias outras.
No help do DELPHI contem a descricao delas (veja em
WIN32.HLP).
749 - Como usar os arquivos QRP
criados com QuickReport
para exibir o arquivo:
QuickRep1.Prepare;
QuickRep1.QRPrinter.Load(‘c:\teste.qrp’);
QuickRep1.QRPrinter.Preview;
Application.ProcessMessages;
depois que exibir precisa liberar, caso contrário trava
tudo :
QuickRep1.QRPrinter.Free;
QuickRep1.QRPrinter := nil;
750 - Como incrementar a Barra de
Status
No formulário principal coloque uma statusbar com 3
panels,1 time e aplicationeventos e digite as funções
abaixo ->

function mostrahora:string;
begin
mostrahora:=timetostr(time);
end;
function mostradata:string;
var
dthoje:tdatetime;
diasemana:integer;
strdiasemana:string;
begin
dthoje:=date;
diasemana:=dayofweek(dthoje);
case diasemana of
1:strdiasemana:=‘Domingo’;
2:strdiasemana:=‘Segunda-feira’;
3:strdiasemana:=‘Terça-feira’;
4:strdiasemana:=‘Quarta-feira’;
5:strdiasemana:=‘Quinta-feira’;
6:strdiasemana:=‘Sexta-feira’;
7:strdiasemana:=‘Sábado’;
end;
mostradata:=strdiasemana+’
‘+datetostr(dthoje);
end;
// Selecione o aplicationeventos e na guia
eventos do objeto inspector depois clique
no evento OnHint e digite o código ->
procedure
TFnomedoform.ApplicationEvents1Hint(Sender
: TObject);
Begin

StatusBar1.Panels[2].Text:=Application.Hin
t;
// todos os hints do seu projeto
apareceram no statusbar
end;

// agora faça com que suas funções


apareçam o resultado

procedure TFnomedoform.Timer1Timer(Sender:
TObject);
var
presente:tdatetime;
ano,mes,dia:word;
begin
presente:=now;
decodedate(presente,ano,mes,dia);
case mes of
1:STATUSBAR1.PANELS[1].TEXT:=’ JANEIRO
‘+inttostr(ano);

2:STATUSBAR1.PANELS[1].TEXT:=‘FEVEREIRO’+i
nttostr(ano);
3:STATUSBAR1.PANELS[1].TEXT:=‘MARÇO
‘+inttostr(ano);
4:STATUSBAR1.PANELS[1].TEXT:=‘ABRIL
‘+inttostr(ano);
5:STATUSBAR1.PANELS[1].TEXT:=‘MAIO
‘+inttostr(ano);
6:STATUSBAR1.PANELS[1].TEXT:=‘JUNHO
‘+inttostr(ano);
7:STATUSBAR1.PANELS[1].TEXT:=‘JULHO
‘+inttostr(ano);
8:STATUSBAR1.PANELS[1].TEXT:=‘AGOSTO
‘+inttostr(ano);
9:STATUSBAR1.PANELS[1].TEXT:=‘SETEMBRO
‘+inttostr(ano);
10:STATUSBAR1.PANELS[1].TEXT:=‘OUTUBRO
‘+inttostr(ano);
11:STATUSBAR1.PANELS[1].TEXT:=‘NOVEMBRO
‘+inttostr(ano);
12:STATUSBAR1.PANELS[1].TEXT:=‘DEZEMBRO
‘+inttostr(ano);
end;
STATUSBAR1.PANELS[0].TEXT:=mostrahora();
STATUSBAR1.PANELS[1].TEXT:=mostradata();
end;

// ***** Viu como é fácil enfeitar seu


projeto ******

Dica enviada por: Samuel Santos


email:samuelsantos@mgconecta.com.br
751 - Função para Desligar o
Windows 2000

Use-a assim: WinExit(EWX_SHUTDOWN or


EWX_FORCE);

function WinExit(flags: integer): boolean;


function SetPrivilege(privilegeName:
string; enable: boolean): boolean;
var
tpPrev, tp : TTokenPrivileges;
token : THandle;
dwRetLen : DWord;
begin
result := False;
OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
token);
tp.PrivilegeCount := 1;
if LookupPrivilegeValue(nil,
pchar(privilegeName),
tp.Privileges[0].LUID) then
begin
if enable then
tp.Privileges[0].Attributes :=
SE_PRIVILEGE_ENABLED
else
tp.Privileges[0].Attributes := 0;
dwRetLen := 0;
result :=
AdjustTokenPrivileges(token, False, tp,
SizeOf(tpPrev), tpPrev, dwRetLen);
end;
CloseHandle(token);
end;
begin
if SetPrivilege(‘SeShutdownPrivilege’,
true) then
begin
ExitWindowsEx(flags, 0);
SetPrivilege(‘SeShutdownPrivilege’,
False)
end;
end;
752 - Como fazer para um
executavel se Auto-Deletar
Até onde sei é impossivel fazer com que um executavel
de Auto-Delete, porém podemos criar um arquivo de lote
(*.bat) para que o mesmo faça o serviço.
E é o que a dica abaixo faz!

unit Unit_AutoDelecao;

interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TDriveType = (dtUnknown, dtNoDrive,
dtFloppy, dtFixed, dtNetwork, dtCDROM,
dtRAM);
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function GetTmpDir: string; // Get the


windows temporary directory
var
pc: PChar;
begin
pc := StrAlloc(MAX_PATH + 1);
GetTempPath(MAX_PATH, pc);
Result := string(pc);
StrDispose(pc);
end;

procedure DelExe; // procedure to delete


the current program
function GetTmpFileName(ext: string):
string;
var
pc: PChar;
begin
pc := StrAlloc(MAX_PATH + 1);
GetTempFileName(PChar(GetTmpDir),
‘EZC’, 0, pc);
Result := string(pc);
Result := ChangeFileExt(Result, ext);
StrDispose(pc);
end;
var
batchfile: TStringList;
batchname: string;
begin
if
(TDRiveType(GetDriveType(PChar(‘C:'))) =
dtFloppy) or
(TDRiveType(GetDriveType(PChar(‘C:'))) =
dtFixed) then
begin
batchname := GetTmpFileName(‘.bat’);
FileSetAttr(ParamStr(0), 0);
batchfile := TStringList.Create;
with batchfile do
begin
try
Add(‘:Label1’);
Add(‘del ”’ + ParamStr(0) + ‘”’);
Add(‘if Exist ”’ + ParamStr(0) +
’” goto Label1’);
Add(‘rmdir ”’ +
ExtractFilePath(ParamStr(0)) + ‘”’);
Add(‘del ”’ + GetTmpDir +
ExtractFileName(ParamStr(0)) + ‘”’);
Add(‘del ‘ + batchname);
SaveToFile(batchname);
ChDir(GetTmpDir);
WinExec(PChar(batchname),
SW_HIDE);
finally
batchfile.Free;
end;
Halt;
end;
end //else with Owner as TForm do Close;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
DelExe;
end;

end.
753 - Funções de CRC
{*****************************************
********************}
{ CRC Calculator Unit for Delphi
16/32 }
{ Version:
2.0
}
{ Author: Aleksey
Kuznetsov
}
{ E-Mail:
aleksey@utilmind.com
}
{ Home Page:
http://www.utilmind.com
}
{ Created: March, 30, 1999 for Karol
Suchanek }
{ Modified: April, 6,
1999 }
{ Legal: Copyright (c) 1999, UtilMind
Solutions }
{ Idea: Edwin T.
Floyd
}
{*****************************************
********************}
{ This unit provides three speed-optimized
functions to }
{ compute (or continue computation of) a
Cyclic Redundency }
{ Check (CRC). Applicable to XModem
protocol (16-bit CRC), }
{ SEA’s “ARC” utility, PKZip (32-bit CRC)
and many others }
{ compatible
software.
}
{ Please see TESTCRC.DPR for
example. }
{*****************************************
********************}
{ Each function takes three
parameters: }
{
}
{ InitCRC - The initial CRC value. This
may be the }
{ recommended initialization value if this
is the first or }
{ only block to be checked, or this may be
a previously }
{ computed CRC value if this is a
continuation. }
{ XModem and ARC usually starts with zero
(0), 32 bit crc }
{ starts with all bits on
($FFFFFFFF). }
{
}
{ Buffer - An untyped parameter (Pointer^)
specifying the }
{ beginning of the memory area to be
checked. }
{
}
{ Length - A word indicating the length of
the memory area to }
{ be checked. If Length is zero, the
function returns the }
{ value of
InitCRC.
}
{
}
{ The function result is the updated
CRC. }
{*****************************************
********************}

unit CRC;
interface

function UpdateCRC16(InitCRC: Word; var


Buffer;
Length: {$IFDEF Win32} LongInt {$ELSE}
Word {$ENDIF}): Word;
{ I believe this is the CRC used by the
XModem protocol.
The transmitting end should initialize
with zero, UpdateCRC16 for
the block, Continue the UpdateCRC16 for
two nulls, and append the
result (hi order byte first) to the
transmitted block. The receiver
should initialize with zero and
UpdateCRC16 for the received block
including the two byte CRC. The result
will be zero (why?) if there
were no transmission errors. (I have not
tested this function with
an actual XModem implementation, though I
did verify the behavior
just described. See TESTCRC.DPR.) }

function UpdateCRCArc(InitCRC: Word; var


Buffer;
Length: {$IFDEF Win32} LongInt {$ELSE}
Word {$ENDIF}): Word;
{ This function computes the CRC used by
SEA’s ARC utility.
Initialize with zero.}

function UpdateCRC32(InitCRC: LongInt; var


Buffer;
{$IFDEF Win32} Length: LongInt {$ELSE}
Length: Word {$ENDIF}): LongInt;
{ This function computes the CRC used by
PKZIP and Forsberg’s ZModem.
Initialize with high-values ($FFFFFFFF),
and finish by inverting
allbits (Not). }

function FileCRC16(FileName: String; var


CRC16: Word): Boolean; { Return True if ok
}
function FileCRCArc(FileName: String; var
CRCArc: Word): Boolean; { Return True if
ok }
function FileCRC32(FileName: String; var
CRC32: LongInt): Boolean; { Return True if
ok }

implementation

const
CrcArcTab: Array[0..$FF] of Word =
($00000, $0C0C1, $0C181, $00140, $0C301,
$003C0, $00280, $0C241,
$0C601, $006C0, $00780, $0C741, $00500,
$0C5C1, $0C481, $00440,
$0CC01, $00CC0, $00D80, $0CD41, $00F00,
$0CFC1, $0CE81, $00E40,
$00A00, $0CAC1, $0CB81, $00B40, $0C901,
$009C0, $00880, $0C841,
$0D801, $018C0, $01980, $0D941, $01B00,
$0DBC1, $0DA81, $01A40,
$01E00, $0DEC1, $0DF81, $01F40, $0DD01,
$01DC0, $01C80, $0DC41,
$01400, $0D4C1, $0D581, $01540, $0D701,
$017C0, $01680, $0D641,
$0D201, $012C0, $01380, $0D341, $01100,
$0D1C1, $0D081, $01040,
$0F001, $030C0, $03180, $0F141, $03300,
$0F3C1, $0F281, $03240,
$03600, $0F6C1, $0F781, $03740, $0F501,
$035C0, $03480, $0F441,
$03C00, $0FCC1, $0FD81, $03D40, $0FF01,
$03FC0, $03E80, $0FE41,
$0FA01, $03AC0, $03B80, $0FB41, $03900,
$0F9C1, $0F881, $03840,
$02800, $0E8C1, $0E981, $02940, $0EB01,
$02BC0, $02A80, $0EA41,
$0EE01, $02EC0, $02F80, $0EF41, $02D00,
$0EDC1, $0EC81, $02C40,
$0E401, $024C0, $02580, $0E541, $02700,
$0E7C1, $0E681, $02640,
$02200, $0E2C1, $0E381, $02340, $0E101,
$021C0, $02080, $0E041,
$0A001, $060C0, $06180, $0A141, $06300,
$0A3C1, $0A281, $06240,
$06600, $0A6C1, $0A781, $06740, $0A501,
$065C0, $06480, $0A441,
$06C00, $0ACC1, $0AD81, $06D40, $0AF01,
$06FC0, $06E80, $0AE41,
$0AA01, $06AC0, $06B80, $0AB41, $06900,
$0A9C1, $0A881, $06840,
$07800, $0B8C1, $0B981, $07940, $0BB01,
$07BC0, $07A80, $0BA41,
$0BE01, $07EC0, $07F80, $0BF41, $07D00,
$0BDC1, $0BC81, $07C40,
$0B401, $074C0, $07580, $0B541, $07700,
$0B7C1, $0B681, $07640,
$07200, $0B2C1, $0B381, $07340, $0B101,
$071C0, $07080, $0B041,
$05000, $090C1, $09181, $05140, $09301,
$053C0, $05280, $09241,
$09601, $056C0, $05780, $09741, $05500,
$095C1, $09481, $05440,
$09C01, $05CC0, $05D80, $09D41, $05F00,
$09FC1, $09E81, $05E40,
$05A00, $09AC1, $09B81, $05B40, $09901,
$059C0, $05880, $09841,
$08801, $048C0, $04980, $08941, $04B00,
$08BC1, $08A81, $04A40,
$04E00, $08EC1, $08F81, $04F40, $08D01,
$04DC0, $04C80, $08C41,
$04400, $084C1, $08581, $04540, $08701,
$047C0, $04680, $08641,
$08201, $042C0, $04380, $08341, $04100,
$081C1, $08081, $04040);

Crc16Tab: Array[0..$FF] of Word =


($00000, $01021, $02042, $03063, $04084,
$050a5, $060c6, $070e7,
$08108, $09129, $0a14a, $0b16b, $0c18c,
$0d1ad, $0e1ce, $0f1ef,
$01231, $00210, $03273, $02252, $052b5,
$04294, $072f7, $062d6,
$09339, $08318, $0b37b, $0a35a, $0d3bd,
$0c39c, $0f3ff, $0e3de,
$02462, $03443, $00420, $01401, $064e6,
$074c7, $044a4, $05485,
$0a56a, $0b54b, $08528, $09509, $0e5ee,
$0f5cf, $0c5ac, $0d58d,
$03653, $02672, $01611, $00630, $076d7,
$066f6, $05695, $046b4,
$0b75b, $0a77a, $09719, $08738, $0f7df,
$0e7fe, $0d79d, $0c7bc,
$048c4, $058e5, $06886, $078a7, $00840,
$01861, $02802, $03823,
$0c9cc, $0d9ed, $0e98e, $0f9af, $08948,
$09969, $0a90a, $0b92b,
$05af5, $04ad4, $07ab7, $06a96, $01a71,
$00a50, $03a33, $02a12,
$0dbfd, $0cbdc, $0fbbf, $0eb9e, $09b79,
$08b58, $0bb3b, $0ab1a,
$06ca6, $07c87, $04ce4, $05cc5, $02c22,
$03c03, $00c60, $01c41,
$0edae, $0fd8f, $0cdec, $0ddcd, $0ad2a,
$0bd0b, $08d68, $09d49,
$07e97, $06eb6, $05ed5, $04ef4, $03e13,
$02e32, $01e51, $00e70,
$0ff9f, $0efbe, $0dfdd, $0cffc, $0bf1b,
$0af3a, $09f59, $08f78,
$09188, $081a9, $0b1ca, $0a1eb, $0d10c,
$0c12d, $0f14e, $0e16f,
$01080, $000a1, $030c2, $020e3, $05004,
$04025, $07046, $06067,
$083b9, $09398, $0a3fb, $0b3da, $0c33d,
$0d31c, $0e37f, $0f35e,
$002b1, $01290, $022f3, $032d2, $04235,
$05214, $06277, $07256,
$0b5ea, $0a5cb, $095a8, $08589, $0f56e,
$0e54f, $0d52c, $0c50d,
$034e2, $024c3, $014a0, $00481, $07466,
$06447, $05424, $04405,
$0a7db, $0b7fa, $08799, $097b8, $0e75f,
$0f77e, $0c71d, $0d73c,
$026d3, $036f2, $00691, $016b0, $06657,
$07676, $04615, $05634,
$0d94c, $0c96d, $0f90e, $0e92f, $099c8,
$089e9, $0b98a, $0a9ab,
$05844, $04865, $07806, $06827, $018c0,
$008e1, $03882, $028a3,
$0cb7d, $0db5c, $0eb3f, $0fb1e, $08bf9,
$09bd8, $0abbb, $0bb9a,
$04a75, $05a54, $06a37, $07a16, $00af1,
$01ad0, $02ab3, $03a92,
$0fd2e, $0ed0f, $0dd6c, $0cd4d, $0bdaa,
$0ad8b, $09de8, $08dc9,
$07c26, $06c07, $05c64, $04c45, $03ca2,
$02c83, $01ce0, $00cc1,
$0ef1f, $0ff3e, $0cf5d, $0df7c, $0af9b,
$0bfba, $08fd9, $09ff8,
$06e17, $07e36, $04e55, $05e74, $02e93,
$03eb2, $00ed1, $01ef0);

Crc32Tab: Array[0..$FF] of LongInt =


($00000000, $77073096, $ee0e612c,
$990951ba, $076dc419, $706af48f,
$e963a535, $9e6495a3, $0edb8832,
$79dcb8a4, $e0d5e91e, $97d2d988,
$09b64c2b, $7eb17cbd, $e7b82d07,
$90bf1d91, $1db71064, $6ab020f2,
$f3b97148, $84be41de, $1adad47d,
$6ddde4eb, $f4d4b551, $83d385c7,
$136c9856, $646ba8c0, $fd62f97a,
$8a65c9ec, $14015c4f, $63066cd9,
$fa0f3d63, $8d080df5, $3b6e20c8,
$4c69105e, $d56041e4, $a2677172,
$3c03e4d1, $4b04d447, $d20d85fd,
$a50ab56b, $35b5a8fa, $42b2986c,
$dbbbc9d6, $acbcf940, $32d86ce3,
$45df5c75, $dcd60dcf, $abd13d59,
$26d930ac, $51de003a, $c8d75180,
$bfd06116, $21b4f4b5, $56b3c423,
$cfba9599, $b8bda50f, $2802b89e,
$5f058808, $c60cd9b2, $b10be924,
$2f6f7c87, $58684c11, $c1611dab,
$b6662d3d, $76dc4190, $01db7106,
$98d220bc, $efd5102a, $71b18589,
$06b6b51f, $9fbfe4a5, $e8b8d433,
$7807c9a2, $0f00f934, $9609a88e,
$e10e9818, $7f6a0dbb, $086d3d2d,
$91646c97, $e6635c01, $6b6b51f4,
$1c6c6162, $856530d8, $f262004e,
$6c0695ed, $1b01a57b, $8208f4c1,
$f50fc457, $65b0d9c6, $12b7e950,
$8bbeb8ea, $fcb9887c, $62dd1ddf,
$15da2d49, $8cd37cf3, $fbd44c65,
$4db26158, $3ab551ce, $a3bc0074,
$d4bb30e2, $4adfa541, $3dd895d7,
$a4d1c46d, $d3d6f4fb, $4369e96a,
$346ed9fc, $ad678846, $da60b8d0,
$44042d73, $33031de5, $aa0a4c5f,
$dd0d7cc9, $5005713c, $270241aa,
$be0b1010, $c90c2086, $5768b525,
$206f85b3, $b966d409, $ce61e49f,
$5edef90e, $29d9c998, $b0d09822,
$c7d7a8b4, $59b33d17, $2eb40d81,
$b7bd5c3b, $c0ba6cad, $edb88320,
$9abfb3b6, $03b6e20c, $74b1d29a,
$ead54739, $9dd277af, $04db2615,
$73dc1683, $e3630b12, $94643b84,
$0d6d6a3e, $7a6a5aa8, $e40ecf0b,
$9309ff9d, $0a00ae27, $7d079eb1,
$f00f9344, $8708a3d2, $1e01f268,
$6906c2fe, $f762575d, $806567cb,
$196c3671, $6e6b06e7, $fed41b76,
$89d32be0, $10da7a5a, $67dd4acc,
$f9b9df6f, $8ebeeff9, $17b7be43,
$60b08ed5, $d6d6a3e8, $a1d1937e,
$38d8c2c4, $4fdff252, $d1bb67f1,
$a6bc5767, $3fb506dd, $48b2364b,
$d80d2bda, $af0a1b4c, $36034af6,
$41047a60, $df60efc3, $a867df55,
$316e8eef, $4669be79, $cb61b38c,
$bc66831a, $256fd2a0, $5268e236,
$cc0c7795, $bb0b4703, $220216b9,
$5505262f, $c5ba3bbe, $b2bd0b28,
$2bb45a92, $5cb36a04, $c2d7ffa7,
$b5d0cf31, $2cd99e8b, $5bdeae1d,
$9b64c2b0, $ec63f226, $756aa39c,
$026d930a, $9c0906a9, $eb0e363f,
$72076785, $05005713, $95bf4a82,
$e2b87a14, $7bb12bae, $0cb61b38,
$92d28e9b, $e5d5be0d, $7cdcefb7,
$0bdbdf21, $86d3d2d4, $f1d4e242,
$68ddb3f8, $1fda836e, $81be16cd,
$f6b9265b, $6fb077e1, $18b74777,
$88085ae6, $ff0f6a70, $66063bca,
$11010b5c, $8f659eff, $f862ae69,
$616bffd3, $166ccf45, $a00ae278,
$d70dd2ee, $4e048354, $3903b3c2,
$a7672661, $d06016f7, $4969474d,
$3e6e77db, $aed16a4a, $d9d65adc,
$40df0b66, $37d83bf0, $a9bcae53,
$debb9ec5, $47b2cf7f, $30b5ffe9,
$bdbdf21c, $cabac28a, $53b39330,
$24b4a3a6, $bad03605, $cdd70693,
$54de5729, $23d967bf, $b3667a2e,
$c4614ab8, $5d681b02, $2a6f2b94,
$b40bbe37, $c30c8ea1, $5a05df1b,
$2d02ef8d);

function UpdateCRC16(InitCRC: Word; var


Buffer;
Length: {$IFDEF Win32} LongInt {$ELSE}
Word {$ENDIF}): Word;
begin
asm
{$IFDEF Win32}
push esi
push edi
push eax
push ebx
push ecx
push edx
lea edi, Crc16Tab
mov esi, Buffer
mov ax, InitCrc
mov ecx, Length
or ecx, ecx
jz @@done
@@loop:
xor ebx, ebx
mov bl, ah
mov ah, al
lodsb
shl bx, 1
add ebx, edi
xor ax, [ebx]
loop @@loop
@@done:
mov Result, ax
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
{$ELSE}
lea di, Crc16Tab
push ds
pop es
push ds
lds si, Buffer
mov ax, InitCrc
mov cx, Length
or cx, cx
jz @@done
@@loop:
xor bx, bx
mov bl, ah
mov ah, al
lodsb
shl bx, 1
xor ax, es:[di + bx]
loop @@loop
pop ds
@@done:
mov Result, ax
{$ENDIF}
end;
end;

function UpdateCRCArc(InitCRC: Word; var


Buffer;
Length: {$IFDEF Win32} LongInt {$ELSE}
Word {$ENDIF}): Word;
begin
asm
{$IFDEF Win32}
push esi
push edi
push eax
push ebx
push ecx
push edx
lea edi, CrcArcTab
mov esi, Buffer
mov ax, InitCrc
mov ecx, Length
or ecx, ecx
jz @@done
@@loop:
xor ebx, ebx
mov bl, al
lodsb
xor bl, al
shl bx, 1
add ebx, edi
mov bx, [ebx]
xor bl, ah
mov ax, bx
loop @@loop
@@done:
mov Result, ax
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
{$ELSE}
lea di, CrcArcTab
push ds
pop es
push ds
lds si, Buffer
mov ax, InitCrc
mov cx, Length
or cx, cx
jz @@done
@@loop:
xor bx, bx
mov bl, al
lodsb
xor bl, al
shl bx, 1
mov bx, es:[di + bx]
xor bl, ah
mov ax, bx
loop @@loop
pop ds
@@done:
mov Result, ax
{$ENDIF}
end;
end;

function UpdateCRC32(InitCRC: LongInt; var


Buffer;
{$IFDEF Win32} Length: LongInt {$ELSE}
Length: Word {$ENDIF}): LongInt;
begin
asm
{$IFDEF Win32}
push esi
push edi
push eax
push ebx
push ecx
push edx
lea edi, Crc32Tab
mov esi, Buffer
mov ax, word ptr InitCRC
mov dx, word ptr InitCRC + 2
mov ecx, Length
or ecx, ecx
jz @@done
@@loop:
xor ebx, ebx
mov bl, al
lodsb
xor bl, al
mov al, ah
mov ah, dl
mov dl, dh
xor dh, dh
shl bx, 1
shl bx, 1
add ebx, edi
xor ax, [ebx]
xor dx, [ebx + 2]
loop @@loop
@@done:
mov word ptr Result, ax
mov word ptr Result + 2, dx
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
{$ELSE}
push ds
pop es
push ds
lea di, CRC32Tab
lds si, Buffer
mov ax, word ptr InitCRC
mov dx, word ptr InitCRC + 2
mov cx, Length
or cx, cx
jz @@done
@@loop:
xor bh, bh
mov bl, al
lodsb
xor bl, al
mov al, ah
mov ah, dl
mov dl, dh
xor dh, dh
shl bx, 1
shl bx, 1
xor ax, es:[di + bx]
xor dx, es:[di + bx + 2]
loop @@loop
@@done:
pop ds
mov word ptr Result, ax
mov word ptr Result + 2, dx
{$ENDIF}
end;
end;
function FileCRC16(FileName: String; var
CRC16: Word): Boolean; { Return True if ok
}
var
f: File;
p: Pointer;
FSize: LongInt;
{$IFNDEF Win32}
tmp: Word;
{$ENDIF}
begin
{$I+}
try
AssignFile(f, FileName);
Reset(f, 1);
FSize := FileSize(f);
if FSize <> 0 then
begin
{$IFDEF Win32}
GetMem(p, FSize);
BlockRead(f, p^, FSize);
CRC16 := UpdateCrc16(0, p^, FSize); {!}
FreeMem(p, FSize);
{$ELSE}
CRC16 := 0; { Usualy from zero }
while FSize <> 0 do
begin
if FSize > $FFFF then tmp := $FFFF else
tmp := FSize;
dec(FSize, tmp);
GetMem(p, tmp);
BlockRead(f, p^, tmp);
CRC16 := UpdateCrc16(Crc16, p^, tmp); {!}
FreeMem(p, tmp);
end;
{$ENDIF}

GetMem(p, 2); { Finish XModem crc with two


nulls }
FillChar(p^, 2, 0);
Crc16 := UpdateCrc16(Crc16, p^, 2);
FreeMem(p, 2);

end;
Result := True;
except
Result := False;
end;
try
CloseFile(f);
except
end;
{$I-}
end;

function FileCRCArc(FileName: String; var


CRCArc: Word): Boolean; { Return True if
ok }
var
f: File;
p: Pointer;
FSize: LongInt;
{$IFNDEF Win32}
tmp: Word;
{$ENDIF}
begin
{$I+}
try
AssignFile(f, FileName);
Reset(f, 1);
FSize := FileSize(f);
if FSize <> 0 then
begin
{$IFDEF Win32}
GetMem(p, FSize);
BlockRead(f, p^, FSize);
CRCArc := UpdateCrcArc(0, p^, FSize); {!}
FreeMem(p, FSize);
{$ELSE}
CRCArc := 0; { Usualy from zero }
while FSize <> 0 do
begin
if FSize > $FFFF then tmp := $FFFF else
tmp := FSize;
dec(FSize, tmp);
GetMem(p, tmp);
BlockRead(f, p^, tmp);
CRCArc := UpdateCrcArc(CrcArc, p^, tmp);
{!}
FreeMem(p, tmp);
end;
{$ENDIF}
end;
Result := True;
except
Result := False;
end;
try
CloseFile(f);
except
end;
{$I-}
end;

function FileCRC32(FileName: String; var


CRC32: LongInt): Boolean; { Return True if
ok }
var
f: File;
p: Pointer;
FSize: LongInt;
{$IFNDEF Win32}
tmp: Word;
{$ENDIF}
begin
{$I+}
try
AssignFile(f, FileName);
Reset(f, 1);
FSize := FileSize(f);
if FSize <> 0 then
begin
{$IFDEF Win32}
GetMem(p, FSize);
BlockRead(f, p^, FSize);
CRC32 := UpdateCrc32($FFFFFFFF, p^,
FSize); {!}
FreeMem(p, FSize);
{$ELSE}
CRC32 := $FFFFFFFF; { Usualy }
while FSize <> 0 do
begin
if FSize > $FFFF then tmp := $FFFF else
tmp := FSize;
dec(FSize, tmp);
GetMem(p, tmp);
BlockRead(f, p^, tmp);
CRC32 := UpdateCrc32(Crc32, p^, tmp); {!}
FreeMem(p, tmp);
end;
{$ENDIF}
CRC32 := not CRC32; { Finish 32 bit crc by
inverting all bits }
end;
Result := True;
except
Result := False;
end;
try
CloseFile(f);
except
end;
{$I-}
end;

end.
//Use-a assim:
procedure TForm1.BitBtn1Click(Sender:
TObject);
var
f: File;
CRC16: Word;
CRC32: LongInt;
CRCArc: Word;
procedure Error;
begin
Application.MessageBox(‘Open error.’, ‘I/O
Error’, mb_Ok or mb_IconStop)
end;
begin
if OpenDialog.Execute then
begin
if not FileCRC16(OpenDialog.FileName,
CRC16) then
begin
Error;
Exit;
end;
Label1.Caption := ‘CRC16 = ‘ +
IntToStr(CRC16);

if not FileCRC32(OpenDialog.FileName,
CRC32) then
begin
Error;
Exit;
end;
Label2.Caption := ‘CRC32 = ‘ +
IntToStr(CRC32);

if not FileCRCArc(OpenDialog.FileName,
CRCArc) then
begin
Error;
Exit;
end;
Label4.Caption := ‘CRCArc = ‘ +
IntToStr(CRCArc);
end;
end;
754 - Funções para detectar o
SoftIce
Pra quem não conhece o SoftIce é um software
comunmente usado para Crackear programas.
Então uma boa saida é usar essa dica juntamente com a
dica 752 para proteger bem seu programa!
Se quer mesmo proteger seu programa de crackers
(coisa que hoje em dia é muito dificil) é só usar também
a dica 753 de CRC.

Function IsSoftIce95Loaded: boolean; Var


hFile: Thandle;
Begin
result := false;
hFile := CreateFileA(‘\.\SICE’,
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then
begin
CloseHandle(hFile);
result := TRUE;
end;
End;

Function IsSoftIceNTLoaded: boolean;


Var
hFile: Thandle;
Begin
result := false;
hFile := CreateFileA(‘\.\NTICE’,
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if( hFile <> INVALID_HANDLE_VALUE ) then
begin
CloseHandle(hFile);
result := TRUE;
end;
End;
755 - Como apagar uma imagem de
um TImage
Image1.Canvas.Brush.Color := clWhite;
Image1.Canvas.Rectangle( 0, 0,
Image1.Width, Image1.Height );
Image1.Picture.Bitmap.Assign(nil);
756 - Baixando arquivos da internet
Esta dica serve para quem deseja criar um sistema que
atualize seus softwares via internet, e também para
quem faz jogos online, ou seja, jogos que exigem a
conexão com a internet para serem jogados, pode
precisar de um meio rápido, fácil e desburocratizado
para baixar arquivos de um site ou de um lugar qualquer
da rede. Veja só como é simples e sem contra
indicações fazer isso:
function DownloadFile(Source, Dest:
string): Boolean;
begin
try
Result:= UrlDownloadToFile(nil,
PChar(source),PChar(Dest), 0, nil) = 0;
except
Result:= False;
end;
end;
Para usar esta function é preciso declarar Urlmon na
seção uses da unit. Depois basta fazer uma chamada
padrão:
if DownloadFile
(‘http://www.onde.com/arq.htm’,‘c:\arq.htm
’) then
ShowMessage(‘Download Concluído.’);
Alexandre de Andrade Gonçalves
Analista/Programador
Minas Export Ltda
(37) 3371-1963
www.minasexport.com.br
757 - Criptografando Imagens
procedure cripto(const BMP: TBitmap; Key:
Integer);
var
BytesPorScan: Integer;
w, h: integer;
p: pByteArray;
begin
try
BytesPorScan :=
Abs(Integer(BMP.ScanLine[1]) -
Integer(BMP.ScanLine[0]));
except
raise Exception.Create(‘Erro !’);
end;
RandSeed := Key;
for h := 0 to BMP.Height - 1 do
begin
P := BMP.ScanLine[h];
for w := 0 to BytesPorScan - 1 do
P^[w] := P^[w] xor Random(256);
end;
end;

Agora vamos ao evento onclick do Button chamar a


nossa procedure cripto, basta digitar o seguinte código:

procedure TForm1.Button1Click(Sender:
TObject);
begin
cripto(Image1.Picture.Bitmap, 1);
Image1.Refresh;
end;
Ao chamar a rotina passamos como parâmetro o
caminho da imagem que no exemplo foi utilizado o
componente image e 1 como um valor inteiro para
retornamos a imagem normal, logo após a execução da
nossa procedure atualizamos o image para que ele
possa exibir nossa imagem criptografada.

Dica Enviada por eltonsilva@sinos.net e tb por


andrepbol@bol.com.br
758 - Compilar *.pas fora do Delphi
Vi nas suas dicas sobre compilação da Unit, o qual obti
apenas uma forma que não a certa de compilá-la,
fazendo um projeto, utilizar uma unit compilar e despois
desprezar o projeto, e passar assim utilizar a unit.dcu
compilada.
Ocorre que no diretório bin do delphi temos um arquivo
chamado dcc32.exe, que nada mais é do que um
compilador pascal,
executando no dos o seguinte parametro:
dcc32 unit.pas, será criando a sua unit.dcu
espero que ajude mais e mais os usuários delpheiros,
um abraço, e continue com o sucesso que é o Dicas e
Truques !!
Enviada por
Ricardo C. Figueiredo
759 - Validando Titulo de Eleitor
function ValidaTituloEleitor(NumTitulo:
string): Boolean;
var
i, Soma : integer;
sTitulo: string;
Resto, Dig1, Dig2 : double;
begin
sTitulo := ”;
for i := 1 to Length(NumTitulo) do
if (Copy(NumTitulo,i,1) >= ‘0’) and
(Copy(NumTitulo,i,1) <= ‘9’) then
sTitulo := sTitulo +
Copy(NumTitulo,i,1);
sTitulo := FormatFloat(‘0000000000000’,
StrToFloat(sTitulo));
Soma := StrToInt(sTitulo[1]) * 2 +
StrToInt(sTitulo[2]) * 9 +
StrToInt(sTitulo[3]) * 8 +
StrToInt(sTitulo[4]) * 7 +
StrToInt(sTitulo[5]) * 6 +
StrToInt(sTitulo[6]) * 5 +
StrToInt(sTitulo[7]) * 4 +
StrToInt(sTitulo[8]) * 3 +
StrToInt(sTitulo[9]) * 2 ;
Resto := Soma mod 11;

if (Resto = 0) or (Resto = 1) then


begin
if (Copy(sTitulo,10,2) = ‘01’) or
(Copy(sTitulo,10,2) = ‘02’) then
begin
if Resto = 0 then
Dig1 := 1
else
Dig1 := 0;
end
else
Dig1 := 0
end
else
Dig1 := 11 - Resto;

Soma :=
StrToInt(FloatToStr((StrToInt(sTitulo[10])
* 4) +
(StrToInt(sTitulo[11]) * 3) + (Dig1 *
2)));
Resto := Soma mod 11;

if (Resto = 0) or (Resto = 1) then


begin
if (Copy(sTitulo,10,2) = ‘01’) or
(Copy(sTitulo,10,2) = ‘02’) then
begin
if Resto = 0 then
Dig2 := 1
else
Dig2 := 0;
end
else
Dig2 := 0;
end
else
Dig2 := 11 - Resto;
if (StrToInt(sTitulo[12]) > Dig1) or
(StrToInt(sTitulo[13]) > Dig2) then
Result := False
else
Result := True;
end;
Enviada por: Guilherme
Agradecimento também ao Rodrigo Ferreira Duarte que
enviou uma dica bem parecida!
valeu!!
760 - Função que retorna texto
entre caracteres
Esta função retorna o texto que está entre caracteres.

Function RetornaTexto(Texto:String;
Caracter:Char):String;
var
I,Posicao1,Posicao2:Integer;
TextoInvertido:String;
begin
Result:=”;
for I := Length(Texto) downto 1 do
begin

TextoInvertido:=TextoInvertido+Texto[I]
end;
Posicao1:=Pos(Caracter,Texto)+1;

Posicao2:=Pos(Caracter,TextoInvertido)-1;

Result:=Copy(Texto,Posicao1,Length(Texto)-
(Posicao1+Posicao2));
end;

Uso:
RetornaTexto(‘Exemplo de um “texto” entre
aspas’,’”’);
retornará uma string contendo a palavra texto.

Enviada por:
Marcus Vitoratti
761 - Mover Timage sem que ele
“pisque”
Quando você vai mover um TShape ou um TImage ou
um TLabel, etc. Ele fica “piscando”. Para que não ocorra
isto coloque no OnCreate do Form:

DoubleBuffered:=True; // Caso o objeto


esteje no Form.
Panel1.DoubleBuffered:=True // Caso esteje
no Panel1.

Enviada por:
Marcus Vitoratti
762 - Como colocar Captions no
DBNavigator
type
TDBNewNavigator = class(TDBNavigator);

procedure TForm1.FormCreate(Sender:
TObject);
var
B: TNavigateBtn;
begin
for B := Low(TNavigateBtn) to
High(TNavigateBtn) do
with
TDBNewNavigator(DBNavigator1).Buttons[B]
do
begin
Case Index of
nbFirst : Caption := ‘Inicio’;
nbPrior : Caption := ‘Anterior’;
nbNext : Caption := ‘Próximo’;
nbLast : Caption := ‘Último’;
nbInsert : Caption := ‘Novo’;
nbDelete : Caption := ‘Apagar’;
nbEdit : Caption := ‘Alterar’;
nbPost : Caption := ‘Gravar’;
nbCancel : Caption := ‘Cancelar’;
nbRefresh: Caption := ‘Atualizar’;
End;
Layout := blGlyphTop; { uses
Buttons}
Hint := Caption;
ShowHint := True;
end;
end;
end;
Enviada por:
Carlos Hegeto Junior
763 - Como separar termos de uma
string
Como separar termos de uma string usando comandos
básicos como Delete, Copy e Pos e guardar os valores
em um array.
Supondo que tenho um arquivo que o formato de cada
linha seja “website|titulo|descricao|categoria”, gostaria
de enviar cada termo para um array e disponibilizar em
um Listbox o website e a categoria. Difícil? Não.
var
MeuArray: array of array of string;
// Em MeuArray tenho que:
// MeuArray[0][0] = Website da 1ª linha
// MeuArray[0][1] = Título da 1ª linha
// MeuArray[0][2] = Descrição da 1ª
linha
// MeuArray[0][3] = Categoria da 1ª
linha
Arquivo: TStringList;
// Arquivo é uma variável TStringList,
que facilitará o uso das strings;
LoopI,PosBarra: Integer;
// Em LoopI será executado um “for”.
// PosBarra é a posição de “|”.
Linha: String;
// Linha é a linha que está sendo
executada no momento.
begin
Arquivo:=TStringList.Create;
Arquivo.LoadFromFile(‘C:\Sites.txt’); //
Abrir o arquivo C:\Sites.txt.
SetLength(MeuArray,Arquivo.Count+1,4);
// Definir o tamanho do array.
for LoopI := 0 to Arquivo.Count -1 do //
Fazer o “for”.
begin
Linha:=Arquivo.Strings[LoopI]; //
Linha atual.
PosBarra:=Pos(‘|’,Linha);
MeuArray[LoopI][0] :=
Copy(Linha,1,PosBarra-1);
Delete(Linha,1,PosBarra); // Deleta,
porque já peguei valor do 1º
PosBarra:=Pos(‘|’,Linha); // Pega
novamente a posição de “|”
MeuArray[LoopI][1] :=
Copy(Linha,1,PosBarra-1);
Delete(Linha,1,PosBarra);
PosBarra:=Pos(‘|’,Linha);
MeuArray[LoopI][2] :=
Copy(Linha,1,PosBarra-1);
Delete(Linha,1,PosBarra);
PosBarra:=Pos(‘|’,Linha);
MeuArray[LoopI][3] := Linha; // É o
que restou da variável Linha.
ListBox1.Items.Add(MeuArray[LoopI]
[0]+’: ‘+MeuArray[LoopI][2]);
end;
Arquivo.Free;
end;

PS: Este código ainda é muito simples, precisa ser


aperfeiçoado, mas funciona!

Enviada por:
Marcus Vitoratti
764 - Como arredondar um valor do
tipo Float / Double
Exemplo :

QryBasico.FieldByName(‘Valor’).AsFloat
:= SimpoRound(Passe Seu Valor Aqui);

O Valor passado para a função simporound será


arrendodado em um valor exato. Diferente da função
round onde ela arredonda o valor mais as vezes
arredonda errado.

Enviada por:
Jason Lopes G Silva
765 - Como transformar de uma
Classe para outra
Você tem a variavel Sender como sendo TObject, mas
você gostaria de usar esta TObject como um TForm ?
Se você tentou assim:

Sender.show;

vai dar erro.


Agora tente assim:

(Sender as TForm).show;

Enviada por:
Bruno Martins Stuani
766 - Selecionando vários objetos
dentro de um outro como se fosse
selecionar um objeto imposto no
formulário:
Segure o Control, clique e arraste o cursor do mouse
dentro de um objeto que contenha outro dentro dele
Enviada por:
Bruno Martins Stuani
767 - Como colocar imagens em um
TStatusBar
1) Insira um TStatusBar em seu projeto.
2) Faça os “Panels”.
3) Vamos supor que queira que o “Panel 2” (Lembre-se
que começa com 0 a contagem) receba a imagem,
mude a propriedade Style do “Panel 2” para
psOwnerDraw. Em seguida, no evento OnDrawPanel
coloque:

var
Imagem:TBitmap;
begin
if Panel = 2 then // Caso seja o “Panel
2”…
begin
Imagem:=TBitmap.Create;
Imagem.LoadFromFile(‘C:\Imagem.Bmp’);
// Estou carregando de um arquivo, mas há
possibilidades de carregar de um resource
também.
try

StatusBar1.Canvas.Draw(Rect.Left,Rect.Top,
Imagem) // Tenta carregar.
finally
Imagem.Free;
end; // Depois de carregar, libera a
imagem.
end;
end;

4) Rode o projeto e veja que a imagem em


C:\Imagem.bmp carregou no Panel 2!

Enviada por:
Marcus Vitoratti
768 - Validando CEP
Function ValidarCEP(const CEP: string):
string;
var
I: integer;
begin
Result := ”;
for I := 1 to Length(CEP) do
if CEP[I] in [‘0’..‘9’] then
Result := Result + CEP[I];
if Length(Result) <> 8 then
raise Exception.Create(‘CEP
inválido.’)
else
Result := Copy(Result, 1, 2) + ‘.’ +
Copy(Result, 3, 3) + ‘-‘ + Copy(Result, 6,
3);
end;

Enviada por:
Fábio André Campos da Cruz
769 - Como obter uma string entre
outras duas
function
Copy(Frase,Inicio,Fim:String):String;
{ função criada por Marcus Vitoratti }
var
iAux,kAux:Integer;
begin
Result:=”;
if (Pos(Fim,Frase) <> 0) and
(Pos(Inicio,Frase)<>0) then
begin

iAux:=Pos(Inicio,Frase)+length(Inicio);
kAux:=Pos(Fim,Frase);
Result:=Copy(Frase,iAux,kAux-iAux);
end;
end;

Exemplo:
label1.caption:= Copy(‘<TITLE>Título da
página</TITLE>’,’<TITLE>’,’</TITLE>’);
//retornará a string ‘Título da página’.

Enviada por: Marcus Vitoratti


770 - Como passar parâmetros
entre 2 forms
Suponha que você esteja no Form1 e precise chamar o
Form2 passando dois parametros (“Aden” e
“Rodrigues”).
1. Crie as variáveis de instancia do Form2 que
receberão os dois parâmetros.
2. Reescreva o Construtor desse form, de forma receber
os parametros e atribui-los às suas variáveis de
instância:
type
TForm2 = class(TForm)
private
Parametro1 : String;
Parametro2 : String;
public
constructor Create(AOwner : TComponent;
pParm1, pParm2 : String);
end;

var
Form2: TForm2;

implementation

Constructor TForm2.Create(AOwner :
TComponent; pParm1, pParm2 : String);
begin
inherited Create(AOwner);
Parametro1 := pParm1;
Parametro2 := pParm2;
end;

Agora no seu form1, abra o form2 com a seguinte


sintaxe:
With TForm2.Create(self, ‘Aden’,
‘Rodrigues’) do
Begin
ShowModal;
Free;
End;

Obs: Não deixe o delphi criar automaticamente o


formulário. Crie-o (e destrua-o) manualmente.

Enviada por:
Gelson Luiz
771 - Transforma a imagem em
negativo de fotografia
procedure ColorToNegative(ABmp: TBitmap);
//
// Transforma a imagem em negativo de
fotografia
//
// Use-o assim:
//
// var x: TBitmap;
// begin
//
// x := TBitmap.create;
// x.LoadFromFile(‘c:\MVC-267S.bmp’);
// ColorToNegative(x);
// image1.Picture.Assign(x);
// end;
//
//
const
_high = 255;
var
c: TCursor;
x, y: Integer;
ColorRGB: LongInt;
begin
c := Screen.Cursor;
Screen.Cursor := crHourGlass;
for y := 0 to (ABmp.Height - 1) do
for x := 0 to (ABmp.Width - 1) do
begin
ColorRGB :=
ColorToRGB(ABmp.Canvas.Pixels[x, y]);
ABmp.Canvas.Pixels[x, y] :=
PaletteRGB(_high -
GetRValue(ColorRGB),_high -
GetGValue(ColorRGB), _high -
GetBValue(ColorRGB));
end;
Screen.Cursor := c;
end;

Enviada por: Thiago Ribeiro da Silva


772 - Função para obter os termos
de uma string
function ObterTermo(APosicao: Integer;
ASeparador,ALinha: String): String;
var
sAux: TStringList;
begin
Result:=”;
sAux:=TStringList.Create;

sAux.Text:=StringReplace(ALinha,ASeparador
,#13#10,[rfReplaceAll, rfIgnoreCase]);
if APosicao <= sAux.Count then
Result:=sAux.Strings[APosicao-1];
sAux.Free;
end;

Utilização:
ObterTermo(2, ‘:’, ‘Abc:Def:Ghi’);
retornará ‘Def’

Obs: Não compatível com Delphi 3 - (Função somente


testada em Delphi 6)

Enviada por: Marcus Vitoratti


773 - Função que deleta vários
items de um listbox
procedure TForm1.DeletarVarios(var
ListBox1: TListBox);
var
lista1,lista2:TStringList;
i:integer;
begin
for i:=0 to ListBox1.Items.Count-1 do
if ListBox1.Selected[i] then
begin
ListBox1.Items.Strings[i]:=”;

ListBox1.Items.SaveToFile(extractfilepath(
application.ExeName)+‘items.txt’);
end;
lista2:=TStringList.Create;
lista1:=TStringList.Create;

lista1.LoadFromFile(extractfilepath(applic
ation.ExeName)+‘items.txt’);
for i:=0 to lista1.Count-1 do
begin
if lista1.Strings[i]<>” then
begin
lista2.Add(lista1.Strings[i]);

lista2.SaveToFile(extractfilepath(applicat
ion.ExeName)+‘items.txt’);
end
else

lista2.SaveToFile(extractfilepath(applicat
ion.ExeName)+‘items.txt’);
end;
ListBox1.Items.LoadFromFile(extractfilepat
h(application.ExeName)+‘items.txt’);

DeleteFile(extractfilepath(application.Exe
Name)+‘items.txt’);
end;

Enviada por David


774 - Como ir para o final de um
texto com o Richedit
RichEdit.SelLength := 0;
RichEdit.SelStart:= RichEdit.GetTextLen;
// position caret at end
RichEdit.Perform( EM_SCROLLCARET, 0, 0 );
// ensure viewport is right
Enviado por Felipe
775 - Como retornar quantidade de
dias meses e anos entre duas datas
Ola

Hoje de manhã procurei uma função no Delphi que


fizesse o que eu queria e não achei nada , ai fui
obrigado a fazer . Bom, pode ser util pra mais gente .
Esta procedure retorna a diferença entre 2 datas em
dias, meses e anos .

Procedure EntreDatas(DataFinal,DataInicial
: TDate ; var Anos,Meses,Dias : Integer) ;
//
// Retorna a diferença em Dias,Meses e
Anos entre 2 datas
//
Function Calcula(Periodo : Integer) :
Integer ;
var
intCont : Integer ;
begin
intCont := 0 ;
Repeat
Inc(intCont) ;
DataFinal :=
IncMonth(DataFinal,Periodo * -1) ;
Until DataFinal < DataInicial ;
DataFinal :=
IncMonth(DataFinal,Periodo) ;
Inc(intCont,-1) ;
Result := intCont ;
End ;
begin
if DataFinal <= DataInicial then
begin
Anos := 0 ;
Meses := 0 ;
Dias := 0 ;
exit ;
end;
Anos := Calcula(12) ;
Meses := Calcula(1) ;
Dias := Round(DataFinal - DataInicial) ;
end;

Um abraço

Fábio Macedo Garcia


Analista Programador - Delphi
fabio@copaninfo.com.br
fabiomaced@hotmail.com
776 - Para chamar um HTMLHelp
(.chm) a partir da aplicação Delphi
No formulario principal , logo apois o primeiro Uses da
seção Interface , defina :
Function HtmlHelp(hwndCaller: THandle;
pszFile: PChar; uCommand: cardinal;
dwData: longint): THandle; stdcall;
external ‘hhctrl.ocx’ name ‘HtmlHelpA’ ;

No onCreate do formulário principal faça o seguinte :

Application.OnMessage := ChamaHelp ;

Agora é só usar essa procedure

procedure TfrmPrincipal.ChamaHelp(var Msg:


TMsg; var Handled: Boolean);
begin
if (Screen.ActiveForm.ClassName =
‘TMessageForm’) = false then
if Msg.message = WM_KEYDOWN then
if Msg.wParam = VK_F1 then
HtmlHelp(Screen.ActiveForm.Handle,
PChar(Arquivo_de_Help.CHM), $F,
Screen.ActiveForm.HelpContext ) ;
end;

Pronto . Ao apertar a tecla F1 em qualquer parte do


projeto o help será chamado , desde que o no formulário
ativo , onde for pressionada o F1 a propriedade
HelpContext esteja preenchida .
Importante : Não coloque o nome do arquivo de help no
Project/Options/HelpFile , nem no Application.HelpFile ,
pois ao pressionar F1 a aplicação tentará carregar o
Htmlhelp (.CHM) que estiver lá , gerando uma exception
pois o formato CHM não é suportado pelo Delphi .
Atenciosamente,

Fábio Macedo Garcia


Gerente de Desenvolvimento
fabio@copaninfo.com.br
fabiomaced@hotmail.com
777 - Como adicionar items de
menu dinâmicamente
Normalmente nós criamos nossos menus, diretamente
no Delphi em time project.
Mas e se por algum motivo quisermos incluir itens em
um menu em runtime ?
Bom, o TMainMenu possui métodos capazes de
incluir(Insert) e excluir(Delete) itens
de um menu, como fazer isso? Fácil. No exemplo vamos
incluir todas as fontes do windows
em um sub-menu.

1: Inicie um novo projeto e inclua um componente


TMainMenu no form.
2: Faça com que o menu tenha a seguinte estrutura.
Arquivo Editar
Abrir Copiar
Fechar Colar
Fontes
3: Coloque um TButton no form e inclua o seguinte
código no evento onClick do mesmo.

procedure TfMtCpPrMs.Button1Click(Sender:
TObject);
var
I : Integer;
NovoItem : TMenuItem;
begin
For I := 0 to Screen.Fonts.Count - 1 do
begin
NovoItem :=
TMenuItem.Create(MainMenu1);
NovoItem.Caption := Screen.Fonts[I];

MainMenu1.Items[1].Items[2].Insert(I,NovoI
tem);
end;
NovoItem.Free;
end;

Bom, beleza o menu será criado.


Na linha
MainMenu1.Items[1].Items[2].Insert(I,NovoItem);
Existe uma lógica, veja:
MainMenu1.Items[1] = Menu Editar
MainMenu1.Items[1].Items[2] = Item 3 de
menu Editar, no caso Fontes
(Lembre-se que o indece começa em 0)
4: Ótimo, mas o que fazer com um item de menu que
não tem funcinalidade?
Para que nosso exemplo faça sentido, precisamos que o
item clicado execute alguma ação. Para isso no
momento da criação é necessário associar ao evento
onClick do mesmo uma ação, no nosso caso vamos
criar uma procedure para ele.
Crie uma procedure na área publica ou privada do seu
form, algo como.

procedure CapturaClick(Sender : TObject);

5: Escreva o seguinte código na sua nova procedure;

procedure TfMtCpPrMs.CapturaClick(Sender:
TObject);
begin
ShowMessage(‘Você escolheu a fonte: ‘ +
TMenuItem(Sender).Caption);
end;

6: Agora associe a procedure CapturaClick ao evento de


cada item adicionado;
Adicione a seguinte linha ao laço For;
MainMenu1.Items[1].Items[2].Items[I].OnCli
ck := CapturaClick;
//Atenção, não passe parâmetros para a
procedure
//Modo incorreto.
MainMenu1.Items[1].Items[2].Items[I].OnCli
ck := CapturaClick(Sender);

7: O código de inclusão do item de menu completo fica


assim:

procedure TfMtCpPrMs.Button1Click(Sender:
TObject);
var
I: Integer;
NovoItem : TMenuItem;
begin
For I := 0 to Screen.Fonts.Count - 1 do
begin
NovoItem :=
TMenuItem.Create(MainMenu1);
NovoItem.Caption := Screen.Fonts[I];

MainMenu1.Items[1].Items[2].Insert(I,NovoI
tem);

MainMenu1.Items[1].Items[2].Items[I].OnCli
ck := CapturaClick;
end;
NovoItem.Free;
end;

Pronto, teste o programa.


Enviado por Adriano
778 - Mostrar todas as unidades
mapeadas na máquina.
1: Coloque um TListBox, TButton no form;
2: Crie a seguinte procedure;

procedure TForm1.MapeamentosDisponiveis;
var
I : Integer;
Caminho, Drive : String;
Tamanho : Cardinal;
begin
SetLength(Caminho,255);
Tamanho:=255;
For I:=0 to 25 do
begin
Drive := Chr(Ord(‘A’)+I)+’:’;
if
WNetGetConnection(PChar(Drive),PChar(Camin
ho),Tamanho) = NO_ERROR then
ListBox1.Items.Add(LowerCase(Drive +
‘ - ‘+Caminho));
end;
end;

2: Digite o código seguindo no evento OnClick do


TButton;
MapeamentosDisponiveis;
Enviado por Adriano
779 - Clonando um Form
1: Adicione alguns componentes no form;
2: Adicione um botão no form e no evento onClick do
mesmo digite o código abaixo;
3:
var
Ms : TMemoryStream;
NewForm : TForm1;
begin
Ms := TMemoryStream.Create;
Try
Ms.WriteComponent(Form1);
NewForm :=
TForm1.CreateNew(Application);
Ms.Position := 0;
Ms.ReadComponent(NewForm);
NewForm.Show;
ShowMessage(‘Mova o Form de lugar’)
Finally
Ms.Free;
end;

Execute o programa e clique no botão, com este


exemplo o clone do form é criado em cima do form
orginal, para perceber a mudança arraste o form criado.
Enviado por Adriano
780 - Como formatar um TMemo ou
TRichEdit em formato HTML
1: Crie a seguinte procedure;
procedure HTMLSyntax(RichEdit: TRichEdit;
TextCol, TagCol, DopCol: TColor);
var
i, iDop: Integer;
s: string;
Col: TColor;
isTag, isDop: Boolean;
begin
iDop := 0;
isDop := False;
isTag := False;
Col := TextCol;
RichEdit.SetFocus;
for i := 0 to Length(RichEdit.Text) do
begin
RichEdit.SelStart := i;
RichEdit.SelLength := 1;
s := RichEdit.SelText;
if (s = ‘<’) or (s = ‘{‘) then
isTag := True;
if isTag then
if (s = ‘”’) then
if not isDop then
begin
iDop := 1;
isDop := True;
end
else
isDop := False;
if isTag then
if isDop then
begin
if iDop <> 1 then Col := DopCol;
end
else
Col := TagCol
else
Col := TextCol;
RichEdit.SelAttributes.Color := Col;
iDop := 0;
if (s = ‘>’) or (s = ‘}’) then
isTag := False;
end;
RichEdit.SelLength := 0;
end;

2: Para usar a unit digite o seguinte código ao evento


onChange do TMemo ou TRichEdit;
RichEdit1.Lines.BeginUpdate;
HTMLSyntax(RichEdit1, clBlue, clRed,
clGreen);
RichEdit1.Lines.EndUpdate;

Enviado por Adriano


781 - Animando a abertura de um
form 
Temos uma API que pode tornar a abertura dos forms
mais atrativa!

ex:
Digamos que temos dois forms. Form1 e Form2. O
Form1 deve chamar o Form2 (que está setado para
auto-criação)!
o código abaixo chama o form2 (a partir de um button)
com um efeito bem legal

procedure TForm1.Button1Click(Sender:
TObject); begin
form2.BringToFront;
form1.Hide;

AnimateWindow(form2.Handle,2000,AW_CENTER)
;
form2.show;
end;

no evento OnHide do form2 coloque:

procedure TForm2.FormHide(Sender:
TObject);
begin
form1.Show;
end;

Lista de Animações:
AW_BLEND //Somente no Windows 2000
AW_CENTER
AW_HOR_POSITIVE
AW_HOR_NEGATIVE
AW_VER_POSITIVE
AW_VER_NEGATIVE

Dica retirada de http://www.planet-source-code.com/


Essa dica foi testada com o Delphi 6. Talvez não
funcione com versões anteriores!
782 - Alterando a cor dos
TabSheet de um PageControll
- Coloque um PageControll num form
- Adicione 6 TabSheet (New Page)
- Agora basta implementar o codigo abaixo

procedure
TForm1.PageControl1DrawTab(Control:
TCustomTabControl;
TabIndex: Integer; const Rect: TRect;
Active: Boolean);
begin
case TabIndex of
0: Control.Canvas.Font.Color:=clgreen;
1: Control.Canvas.Font.Color:=clred;
2: Control.Canvas.Font.Color:=clblue;
3:
Control.Canvas.Font.Color:=clYellow;
4:
Control.Canvas.Font.Color:=clMaroon;
5: Control.Canvas.Font.Color:=clWhite;
end;

Control.Canvas.TextOut(Rect.left+5,Rect.to
p+3,PageControl1.Pages[tabindex].Caption);

PageControl1.Pages[TabIndex].Font.Color:=C
ontrol.Canvas.Font.Color;
end;

procedure TForm1.FormCreate(Sender:
TObject);
begin
PageControl1.OwnerDraw:=true;
end;
783 - Como reduzir expressões if
then else
Vamos a um exemplo prático:

if x >= 5 then
Aprovado := True
else
Aprovado := False;

Podemos simplesmente escrever assim:

Aprovado := x >= 5;

Pois o resultado de x >= 5 é um valor True ou False


dependendo do valor de x.
784 - Como saber quantas paginas
vão ser impressas com Quickrep
Essa é uma dica muito útil!
Antes do .PREVIEW ou .PRINT do relatório, colocar a
seguinte rotina:

QuickReport.Prepare;
QuickReport.QRLabel.Caption :=
IntToStr(QuickReport.QRPrinter.PageCount);

depois é só enviar um

QuickReport.Print;
ou
QuickReport.Preview;
785 - Rotina para criptografia mais
absoluta
function Crypt(Action, Src: String):
String;
Label Fim;
var KeyLen : Integer;
KeyPos : Integer;
OffSet : Integer;
Dest, Key : String;
SrcPos : Integer;
SrcAsc : Integer;
TmpSrcAsc : Integer;
Range : Integer;
begin
if (Src = ”) Then
begin
Result:= ”;
Goto Fim;
end;
Key :=
‘YUQL23KL23DF90WI5E1JAS467NMCXXL6JAOAUWWMC
L0AOMM4A4VZYW9KHJUI2347EJHJKDF3424SKL
K3LAKDJSL9RTIKJ’;
Dest := ”;
KeyLen := Length(Key);
KeyPos := 0;
SrcPos := 0;
SrcAsc := 0;
Range := 256;
if (Action = UpperCase(‘C’)) then
begin
Randomize;
OffSet := Random(Range);
Dest := Format(‘%1.2x’,[OffSet]);
for SrcPos := 1 to Length(Src) do
begin
Application.ProcessMessages;
SrcAsc := (Ord(Src[SrcPos]) +
OffSet) Mod 255;
if KeyPos < KeyLen then KeyPos :=
KeyPos + 1 else KeyPos := 1;
SrcAsc := SrcAsc Xor
Ord(Key[KeyPos]);
Dest := Dest + Format(‘%1.2x’,
[SrcAsc]);
OffSet := SrcAsc;
end;
end
Else if (Action = UpperCase(‘D’)) then
begin
OffSet := StrToInt(‘$’+
copy(Src,1,2));
SrcPos := 3;
repeat
SrcAsc := StrToInt(‘$’+
copy(Src,SrcPos,2));
if (KeyPos < KeyLen) Then KeyPos :=
KeyPos + 1 else KeyPos := 1;
TmpSrcAsc := SrcAsc Xor
Ord(Key[KeyPos]);
if TmpSrcAsc <= OffSet then TmpSrcAsc
:= 255 + TmpSrcAsc - OffSet
else TmpSrcAsc := TmpSrcAsc - OffSet;
Dest := Dest + Chr(TmpSrcAsc);
OffSet := SrcAsc;
SrcPos := SrcPos + 2;
until (SrcPos >= Length(Src));
end;
Result:= Dest;
Fim:
end;

Usa-se C para Criptografar e D para Descriptografar


Ex de Criptografia:
Edit2.text:= Crypt(‘C’,Edit1.text);

Ex: de Descriptografia
Edit3.text:= Crypt(‘D’,Edit2.text);
786 - Exportando uma Tabela ou
uma Query para uma página HTML
Esta dica ensina a exportar os dados de uma
table/query para uma página html. A forma ensinada
abaixo é uma maneira bem rústica de fazer isto, mas
bastante usada ainda. Ele simplesmente lê o conteúdo
do dataset e exportamos para um arquivo texto com
alguns códigos para gerar o arquivo html. Depois de
gerar o arquivo basta abri-lo em seu browser. Vamos ver
e entender o código abaixo.
Primeiramente abra o delphi e inicie uma nova
aplicação, coloque uma table e um botão no seu
formulário. Agora sete a propriedade DatabaseName da
Table1 para “DBDEMOS” e a propriedade TableName
para “Animals.dbf”. Após configurada a table, coloque no
evento onclick do botão o seguinte código:

procedure TForm1.Button1Click(Sender:
TObject);
var
i, j, w: integer;
linha: string;
htmlfile: TextFile;
const
wrap=#13+#10; {estamos declarando esta
constante com o valor da tecla enter …}
begin
AssignFile(HtmlFile,
‘c:\htmlfile.html’);
Rewrite(HtmlFile);
writeln(htmlfile, ‘<html><head>’ + wrap
+ {estamos gerando o inicio do arquivo
html}
‘<title>’+ Table1.name + ‘</title>’ +
wrap +
‘</head>’ + wrap + ‘<body
bgcolor=”#FFFBCB”>’ +
wrap + ‘<table border =1>’ + wrap);
{Nesse ponto iremos gerar a tabela html}
with table1 do
begin
for w:=0 to fieldCount - 1 do
writeln(htmlfile, ‘<td>’ +
(Fields[w].FieldName) + ‘</td>’);
{Na linha de cima iremos gerar uma coluna
em html para cada campo da table 1 com os
seus nomes}
table1.first;
for i:=0 to recordcount-1 do
begin
linha:=’<tr>’+wrap;
for j:=0 to fieldcount-1 do
begin
linha:= linha + ‘<td>’ +
Fields[j].AsString + ‘</td>’;
{Este código pega o valor dos
campos de cada linha da table e joga na
tabela de html}
end;
writeln(htmlfile, linha);
writeln(htmlfile, ‘</tr>’);
next;
end;
end;
writeln(htmlfile, ‘</body></html>’);
{Finaliza o arquivo html}
CloseFile(htmlfile);
end;

Salve a sua aplicação, execute-a (F9) e aperte o botão.


Então, ao final de tudo procure o arquivo HtmlFile.html
na pasta “c:" e execute-o. Assim verá a página html
gerada com o valor passado pela table. Para aplicar
essa técnica com a query, é só trocar para query onde
usamos a table.

Enviada por Jackson Pires


787 - Criando drivers ODBC
através do Delphi
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);

private
{ Private declarations }

public
{ Public declarations }

end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure CreateODBCDriver(Const
cDSNName,cExclusive,cDescription,cDataBase
,cDefaultPath,cConfigSql,cDriver: string);
type
TSQLConfigDataSource = function(
hwndParent: HWND; fRequest: WORD;
lpszDriver: LPCSTR;
lpszAttributes: LPCSTR ): BOOL; stdcall;
const
ODBC_ADD_DSN = 1; // Adiciona uma fonte
de dados (data source)
ODBC_CONFIG_DSN = 2; // Configura a
fonte de dados (data source)
ODBC_REMOVE_DSN = 3; // Remove a fonte
de dados (data source)
ODBC_ADD_SYS_DSN = 4; // Adiciona um DSN
no sistema
ODBC_CONFIG_SYS_DSN = 5; // Configura o
DSN do sistema
ODBC_REMOVE_SYS_DSN = 6; // Remove o DSN
do sistema
var
pFn: TSQLConfigDataSource;
hLib: LongWord;
strDriver: string;
strHome: string;
strAttr: string;
strFile: string;
fResult: BOOL;
ModName: array[0..MAX_PATH] of Char;
srInfo : TSearchRec;
begin
Windows.GetModuleFileName( HInstance,
ModName, SizeOf(ModName) );
strHome := ModName;
while ( strHome[length(strHome)] <> ‘' )
do
Delete( strHome, length(strHome), 1 );
strFile := strHome + cDatabase; // Teste
com access (Axes = Access)
hLib := LoadLibrary( pChar(cDefaultPath)
); // carregando para o diretório padrão
if( hLib <> NULL ) then
begin
@pFn := GetProcAddress( hLib,
pChar(cConfigSql) );
if( @pFn <> nil ) then
begin
strDriver := cDriver;
strAttr := Format( ‘DSN=%s’+#0+
‘DBQ=%s’+#0+
‘Exclusive=%s’+#0+
‘Description=%s’+#0+#0,

[cDSNName,strFile,cExclusive,cDescription]
);
fResult := pFn( 0, ODBC_ADD_SYS_DSN,
@strDriver[1], @strAttr[1] );
if( fResult = false ) then
ShowMessage( ‘Falha ao tentar
criar o DSN (Data source).’ );
if( FindFirst( strFile, 0, srInfo )
<> 0 ) then
begin
strDriver := cDriver;
strAttr := Format( ‘DSN=%s’+#0+
‘DBQ=%s’+#0+
‘Exclusive=%s’+#0+
‘Description= %s’+#0+#0+
‘CREATE_DB=”%s”’#0+#0,

[cDSNName,strFile,cExclusive,cDescription,
strFile]);
fResult := pFn( 0,
ODBC_ADD_SYS_DSN, @strDriver[1],
@strAttr[1] );
if( fResult = false ) then
ShowMessage( ‘Falha ao tentar
criar o banco de dados’ );
end;
FindClose( srInfo );
end;
FreeLibrary( hLib );
if fResult then
ShowMessage( ‘Banco de dados
criado.’ );
end
else
begin
ShowMessage( ‘o sistema não pode
carregar a biblioteca ODBCCP32.DLL’ );
end;
end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
CreateOdbcDriver(‘Cludelphi DSN’, ‘1’,
‘clubedelphi’, ‘clubedelphi.MDB’,
‘ODBCCP32’, ‘SQLConfigDataSource’,
‘Microsoft Access Driver (*.mdb)’);
end;

end.

Concluções: Com esta dica você poderá criar drivers


ODBC em tempo de execução, softwares de instalação,
economizando tempo e deixando suas aplicações mais
dinâmicas.

Enviada por Jackson Pires


788 - Tabela de Máscaras
Caracter Definições
! Faz com que a digitação da máscara fique
parada no primeiro caracter, fazendo com
que os caracteres digitados que se movam.
Ex: !;0;_
> Todos os caracteres digitados serão
convertidos para maiúsculas. Ex: >aaa;0;_
< Todos os caracteres digitados serão
convertidos para minúsculas. Ex:
<> Anula o uso dos caractes > e <, ou
seja, utilizado para cancelar a opção de
máscara para os caracteres a direita. Ex:
>aaa<>aaa;0;_
\ Utilizado para marcar determinado
caracter não especial como fixo. Ex: !\
(999\)000-0000;0;_
L Exige caracteres alfabéticos
obrigatórios para a posição, do tipo A-Z,
a-z. Ex: LLL;1;_
l Somente caracteres alfabéticos para a
posição, mas não-obrigatórios, do tipo A-
Z, a-z. Ex: lll;1;_
A Exige caracteres alfanuméricos
obrigatórios para a posição, do tipo A-Z,
a-z, 0-9. Ex: AAA;1;_
a Somente caracteres alfanuméricos para a
posição, mas não-obrigatórios, do tipo A-
Z, a-z, 0-9. Ex: aaa;1;_
C Requer um caracter obrigatório para a
posição. Ex: CCC;1;_
c Permite o uso de qualquer caracter para
a posição, limitando apenas o número de
caracteres. Ex: ccc;1;_
0 Exige caracteres numéricos obrigatórios
para a posição, do tipo 0-9. Ex: 000;1;_
9 Somente caracteres numéricos para a
posição, não-obrigatórios, do tipo 0-9.
Ex: 999;1;_
# Somente caracteres numéricos para a
posição e o uso dos sinais de - ou +, não-
obrigatórios. Ex: ###;1;_
: Utilizado como separador de horas,
minutos e segundos.
/ Utilizado como separador de dia, mês e
ano.

Enviada por Jackson Pires


789 - Como evitar as mensagens de
Warning do Compilador (Variavel não
inicializada)

Basta digitar a Diretiva de Compilação {$WARNINGS


OFF} e {$WARNINGS ON}. O Complilador irá iguinorar
as mensagens Warning vindas desse trecho de código

{$WARNINGS OFF}
function TfrmEdit.ProjectTypeToUse(const
cPath: string): Integer;
var
SR: TSearchRec;
begin
if not DirectoryExists(cPath) then
begin
ErrMsg(‘Path não localizado!’);
Exit;
end;
try
if FindFirst(cPath +
‘\*.VBP’,faDirectory,SR) = 0 then
Result := VBP_FILTER
else
Result := DPR_FILTER;
except
ErrMsg(‘Falha de sistema -‘ + cPath);
Result := 1
end;
end;
{$WARNINGS ON}

Enviada por Jackson Pires


790 - Selecionar todo o conteúdo
de um Memo ou RichEdit com as
teclas Ctrl+A
procedure
TfrmShowPas.RichEdit1KeyDown(Sender:
TObject; var Key: Word;
Shift: TShiftState);
begin
if (Shift = [ssCtrl]) then
case Key of
65: (Sender as TRichEdit).SelectAll;
end;
end;

Enviada por Jackson Pires


791 - Criar Código de Barras 2x5i
Procedure CriaCodigo(Cod : String; Imagem
: TCanvas);

Const
digitos : array[‘0’..‘9’] of string[5]=
(‘00110’,
‘10001’,
‘01001’,
‘11000’,
‘00101’,
‘10100’,
‘01100’,
‘00011’,
‘10010’,
‘01010’);
Var
Numero : String;
Cod1 : Array[1..1000] Of Char;
Cod2 : Array[1..1000] Of Char;
Codigo : Array[1..1000] Of Char;
Digito : String;
c1,c2 : Integer;
x,y,z,h : LongInt;
a,b,c,d : TPoint;
I : Boolean;
Begin
Numero := Cod;
For x := 1 to 1000 Do
Begin
Cod1 [x] := #0;
Cod2 [x] := #0;
Codigo[x] := #0;
End;
c1 := 1;
c2 := 1;
x := 1;
For y := 1 to Length(Numero) div 2 do
Begin
Digito := Digitos[Numero[x ]];
For z := 1 to 5 do
Begin
Cod1[c1] := Digito[z];
Inc(c1);
End;
Digito := Digitos[Numero[x+1]];
For z := 1 to 5 do
Begin
Cod2[c2] := Digito[z];
Inc(c2);
End;
Inc(x,2);
End;
y := 5;
Codigo[1] := ‘0’;
Codigo[2] := ‘0’;
Codigo[3] := ‘0’;
Codigo[4] := ‘0’; { Inicio do Codigo }
For x := 1 to c1-1 do
begin
Codigo[y] := Cod1[x]; Inc(y);
Codigo[y] := Cod2[x]; Inc(y);
end;
Codigo[y] := ‘1’; Inc(y); { Final do
Codigo }
Codigo[y] := ‘0’; Inc(y);
Codigo[y] := ‘0’;
Imagem.Pen .Width := 1;
Imagem.Brush.Color := ClWhite;
Imagem.Pen .Color := ClWhite;
a.x := 1; a.y := 0;
b.x := 1; b.y := 79;
c.x := 2000; c.y := 79;
d.x := 2000; d.y := 0;
Imagem.Polygon([a,b,c,d]);
Imagem.Brush.Color := ClBlack;
Imagem.Pen .Color := ClBlack;
x := 0;
i := True;
for y:=1 to 1000 do
begin
If Codigo[y] <> #0 Then
Begin
If Codigo[y] = ‘0’ then
h := 1
Else
h := 3;
a.x := x; a.y := 0;
b.x := x; b.y := 79;
c.x := x+h-1; c.y := 79;
d.x := x+h-1; d.y := 0;
If i Then
Imagem.Polygon([a,b,c,d]);
i := Not(i);
x := x + h;
End;
end;
end;

Como Usar:

procedure TForm1.Button1Click(Sender:
TObject);
begin
CriaCodigo(‘03213213241’,Image1.Canvas);
end;

Enviada por Jackson Pires


792 - Exibindo imagens em caixas
de mensagens de Aplicações CLX

Este código mostra como exibir imagens .bmp em


caixas de diálogos. Desta maneira você não precisará
se prender as imagens padrões do Delphi.
Inicie uma nova aplicação CLX (File | New | CLX
Application) depois coloque o código a seguir no evento
OnClose do formulário.

procedure TForm1.FormClose(Sender:
TObject; var Action: TCloseAction);
var B : TBitmap;
begin
B:=TBitmap.Create;
try
try
//lembre-se que para este exemplo
funcionar é preciso que o arquivo
// “msg_image.bmp” esteja em “C:"
B.LoadFromFile(‘c:\msg_image.bmp’);
if MessageDlg(‘Confirme’,‘Deseja
realmente sair do programa?’,mtCustom,
[mbYes,mbNo],0,mbNo,B) = mrYes then
Application.Terminate
else
Action:=caNone;
except
ShowMessage(‘Não foi possível abrir
o arquivo “c:\icone.bmp”’);
end;
finally
B.Free;
end;
end;
Conclusões: Ao clicar no ícone para fechar o formulário
você receberá a imagem .bmp da maneira como ela foi
configurada.
Enviada por Jackson Pires
793 - Como gerar numeros
randomicos para loterias
Crie um form com os seguintes objetos:
- Listbox1 com a fonte “Courier New”
- Edit1 com Edit1.Text := 6 Numero de
Dezenas
- Edit2 with Edit2.Text := 49 Valor
Maximo
- Edit3 with Edit3.Text := 10 Numero de
Jogos
- Button1 com onClick com o evento
Button1Click abaixo

Isto criará 10 serie de jogos


com os numeros entre 1 e 49
Numeros não serão repetidos
vc poderá mudar os tres valores

procedure TForm1.Button1Click(Sender:
TObject); var
MyList: TStringList;
Times, I, Number: Integer;
cInt, cLen: string;
begin
// make the button disabled to prevent
multiple clicks
Self.enabled := False;
// convert the highest number
Number := StrToInt(Edit2.Text);
// this creates the correct format-
argument for every
// max-numbers (e.g. 49 , 120, 9999 ….)
cLen :=
IntToStr(length(trim(Edit2.text)) + 1);
MyList := TStringList.Create;
try
// first clear the Listbox
Listbox1.clear;
// here we start a new serie
for Times := 1 to StrToInt(Edit3.Text)
do
begin
// we go thru this while-loop until
the max-numbers
// are created. Not every loop
creates an entry
// to the list because double
numbers are ignored.
while MyList.Count <
StrToInt(Edit1.Text) do
begin
// get a new random number
I := Random(Number);
if (I 0) then
begin
// cLen has the number of chars
from max-number plus one
// e.g.
// if max-number is 49 cLen is
3
// if max-number is 111 cLen is
4
// if max-number is 9999 cLen is
5
// this formatting is needed for
the correct
// sorting of all List-Entries
cInt := Format(‘%’ + cLen +
‘.1d’, [I]);
// here we look at double
entries and ignore it
if (MyList.IndexOf(cInt) < -1)
then
continue;
// now we add a new
randomnumber
MyList.Add(cInt);
end;
end;
cInt := ”;
// max-numbers are created now we
sort it
MyList.Sort;
// and put it all into Listbox
for I := 0 to MyList.Count - 1 do
cInt := cInt + MyList.Strings[I];
ListBox1.Items.Add(cInt);
// clear MyList for the next serie
MyList.clear;
end;
finally
MyList.Free;
end;
// make the button enable for the next
click
Self.enabled := True;
end;

Outra opção sem utilizar componentes visuais é:

type
{array of series of picks, used in Pick
function}
TPick = array of array of integer;

function Pick (APicks, AMax, ASeries:


integer): TPick;
var
I, J, Index: integer;
PickArray: array of integer;
begin
if (APicks = AMax) then
begin
raise Exception.Create (‘Pick: Max
available number should be larger than
number of picks’);
end; {if}
if (APicks < 1) then
begin
raise Exception.Create (‘Pick: You
should request at least one pick’);
end; {if}
if (ASeries < 1) then
begin
raise Exception.Create (‘Pick: You
should request at least one series’);
end; {if}

SetLength (Result, ASeries);


for I := Low (Result) to High (Result)
do
begin
{populate AArray }
SetLength (PickArray, AMax);
for J := Low (PickArray) to High
(PickArray) do
begin
PickArray [J] := J + 1;
end; {for}

SetLength (Result [I], APicks);


for J := Low (Result [I]) to High
(Result [I]) do
begin
Result [I, J] := 0;
while (Result [I, J] = 0) do
begin
Index := Random (AMax);
Result [I, J] := PickArray
[Index];
PickArray [Index] := 0;
end; {while}
end; {for J}
end; {for I}
end; {—Pick—}

Exemplo de Uso

var
APick: TPick;
begin
APick := Pick (6, 49, 10); {we need 10
series of 6/49 numbers}

Enviada por Jackson Pires


794 - Função para Criar Subescrito
e Sobrecrito
procedure SuperSubLabelOut(Canvas:TCanvas;
const aRect:TRect; X, Y:integer;
text:String); var
i,xx:integer;
// s:string[16];
subScript, superScript:boolean;
DefFont:TFont;
begin
Canvas.FillRect(aRect);
DefFont:=TFont.Create;
DefFont.Assign(Canvas.Font);
with Canvas do
begin
xx:=X;
for i:=1 to length(text) do
begin
if text[i-1] = ‘_’ then
subScript:=true
else
subScript:=false;
if text[i-1] = ‘^’ then
superScript:=true
else
superScript:=false;

if (text[i] < ‘_’ ) and (text[i] <


‘^’ ) then
begin
if ( subScript ) then
begin

Canvas.Font.Height:=Canvas.Font.Height*8
div 10;
TextRect(Rect(xx,aRect.Top,xx+TextWidth(te
xt[i]),aRect.Bottom),xx,Y+abs(8*Canvas.Fon
t.Height-10*DefFont.Height) div 10,
text[i]);
inc(xx,TextWidth(text[i]));
end;

if ( not subScript) and ( not


superScript ) then
begin
Canvas.Font:=DefFont;

TextRect(Rect(xx,aRect.Top,xx+TextWidth(te
xt[i]),aRect.Bottom),xx, Y, text[i]);
inc(xx,TextWidth(text[i]));
end;

if ( superScript ) then
begin

Canvas.Font.Height:=Canvas.Font.Height*9
div 10;

TextRect(Rect(xx,aRect.Top,xx+TextWidth(te
xt[i]),aRect.Bottom),xx, Y-
abs(8*Canvas.Font.Height-
10*DefFont.Height) div 20, text[i]);
inc(xx,TextWidth(text[i]));
end;
Canvas.Font:=DefFont;
end;
end; //for loop
end; // with
DefFont.Free;
end;

Exemplo de uso:
Coloque um Label com propriedade Caption com:
“Formula da Agua H_2O” ou “medida 3000 cm^3”

procedure TForm1.Button1Click(Sender:
TObject);
begin
SuperSubLabelOut(Canvas,ClientRect
,100,100,Label1.Caption);
end;

Enviada por Jackson Pires


795 - Como trocar o Glyph de um
BitButton em tempo de execução
Insira uma ImageList com as imagens que deseja usar,
depois basta inserir o seguinte código no evento que irá
trocar a figura do botão, trocando o número zero pelo
índice da imagem:
BitBtn1.Glyph := nil;
ImageList1.GetBitmap(0,BitBtn1.Glyph);

Enviada por Fábio K. Salviano


796 - Validar Inscrições Estaduais
para validar inscrições estaduais de qualquer estado,
visite o site www.sintegra.gov.br e confira as fórmulas de
todos os estados, ou, melhor ainda, baixe a DLL
disponível pelo governo.
Abraços…
Lucas Augusto Deters
ITAPIRANGA - SANTA CATARINA
797 - InputBox para entrada de
Senhas (com caracter *)
Função PasswordInputBox: é utilizada assim como a
função InputBox, o 1o. parametro é o caption do
formulário, o 2o. é o caption do label. Não tem o 3o.
parametro porque não tem cabimento colocar uma
resposta padrão para um pedido de senha.
obs: necessita da unit “dialogs” na clausula uses

function PasswordInputBox(const ACaption,


APrompt:string): string;
var
Form: TForm;
Prompt: TLabel;
Edit: TEdit;
DialogUnits: TPoint;
ButtonTop, ButtonWidth, ButtonHeight:
Integer;
Value: string;
I: Integer;
Buffer: array[0..51] of Char;
begin
Result := ”;
Form := TForm.Create(Application);
with Form do
try
Canvas.Font := Font;
for I := 0 to 25 do Buffer[I] := Chr(I
+ Ord(‘A’));
for I := 0 to 25 do Buffer[I + 26] :=
Chr(I + Ord(‘a’));
GetTextExtentPoint(Canvas.Handle,
Buffer, 52, TSize(DialogUnits));
DialogUnits.X := DialogUnits.X div 52;
BorderStyle := bsDialog;
Caption := ACaption;
ClientWidth := MulDiv(180,
DialogUnits.X, 4);
ClientHeight := MulDiv(63,
DialogUnits.Y, 8);
Position := poScreenCenter;
Prompt := TLabel.Create(Form);
with Prompt do
begin
Parent := Form;
AutoSize := True;
Left := MulDiv(8, DialogUnits.X, 4);
Top := MulDiv(8, DialogUnits.Y, 8);
Caption := APrompt;
end;
Edit := TEdit.Create(Form);
with Edit do
begin
Parent := Form;
Left := Prompt.Left;
Top := MulDiv(19, DialogUnits.Y, 8);
Width := MulDiv(164, DialogUnits.X,
4);
MaxLength := 255;
PasswordChar := ‘*’;
SelectAll;
end;
ButtonTop := MulDiv(41, DialogUnits.Y,
8);
ButtonWidth := MulDiv(50,
DialogUnits.X, 4);
ButtonHeight := MulDiv(14,
DialogUnits.Y, 8);
with TButton.Create(Form) do
begin
Parent := Form;
Caption := ‘OK’;
ModalResult := mrOk;
Default := True;
SetBounds(MulDiv(38, DialogUnits.X,
4),ButtonTop, ButtonWidth,ButtonHeight);
end;
with TButton.Create(Form) do
begin
Parent := Form;
Caption := ‘Cancel’;
ModalResult := mrCancel;
Cancel := True;
SetBounds(MulDiv(92, DialogUnits.X,
4),ButtonTop, ButtonWidth,ButtonHeight);
end;
if ShowModal = mrOk then
begin
Value := Edit.Text;
Result := Value;
end;
finally
Form.Free;
Form:=nil;
end;
end;

Exemplo de como usar:

if PasswordInputBox(‘Senha’,‘Digite sua
senha:’) = ‘123456’ then
ShowMessage(‘Senha Correta’)
else
ShowMessage(‘Senha Errada’);

Dica Enviada por: Luis Felipe Cipriani


(www.superscout.hpg.com.br)
798 - Coloração Gradiente no Form
procedure TForm1.FormPaint(Sender:
TObject);
var
altura, coluna: Word;
begin
altura := (ClientHeight + 255) div 256;
for coluna := 0 to 255 do
with Canvas do
begin
Brush.Color := RGB(coluna, 0, 0); {
Modifique para obter cores diferentes }
FillRect(Rect(0, coluna * altura,
ClientWidth, (coluna + 1) * altura)) ;
end;
end;

procedure TForm1.FormResize(Sender:
TObject);
begin
Invalidate;
end;

Enviada por Elionai


799 - Como alterar a coluna
Description do IBConsole
Se vc gosta de usar o IBConsole, pode perceber que
sempre existe uma coluna Description nas Tabelas,
Domains, Views,Store Procedure e etc…
Então ta aqui um macete de como adicionar ou alterar
as Descrições via instrução SQL:
- DOMAINS:
update RDB$FIELDS set RDB$DESCRIPTION = ‘digite
aqui a descrição’ where RDB$FIELD_NAME=‘nome-do-
domain’
- TABLES:
update RDB$RELATIONS set RDB$DESCRIPTION =
‘digite aqui a descrição’ where
RDB$RELATION_NAME=‘nome-da-tabela’
- INDEXES
update RDB$INDICES set RDB$DESCRIPTION = ‘digite
aqui a descrição’ where RDB$INDEX_NAME=‘nome-do-
indice’
- VIEWS
update RDB$RELATIONS set RDB$DESCRIPTION =
‘digite aqui a descrição’ where
RDB$RELATION_NAME=‘nome_do_view’
- STORE PROCEDURES:
update RDB$PROCEDURES set RDB$DESCRIPTION
= ‘digite aqui a descrição’ where
RDB$PROCEDURE_NAME=‘nome-da-procedure’
- EXTERNAL FUNCTIONS:
update RDB$FUNCTIONS set RDB$DESCRIPTION =
‘digite aqui a descrição’ where
RDB$FUNCTION_NAME=‘nome-da-funcao’
- EXCEPTIONS
update RDB$EXCEPTIONS set RDB$DESCRIPTION =
‘digite aqui a descrição’ where
RDB$EXCEPTION_NAME=‘nome-da-exceção’
- BLOB FILTERS
update RDB$FILTER set RDB$DESCRIPTION = ‘digite
aqui a descrição’ where
RDB$FUNCTION_NAME=‘nome-do-filtro’
Aprendeu? então organize-se! :-)
OBS: Não existirá no banco uma TABELA com o mesmo
nome do VIEW, pois a tabela de sistema é a mesma.
Por isso se usa o mesmo código de alteração da
descrição da TABELA como do VIEW.
Depois de qualquer alteração de um COMMIT;
Gostou? R$ 10,00 (REAL) ehehehhehehehehhehehe
Penei pra descobrir!

.––––{ cHaPlinux® }––––.


/ Paulo Henrique de F. Martins /
/ UIN: 22189584 /
/ Mailto: chaplinux@ieg.com.br /
/ chaplinux@ig.com.br /
`–––––––––––––´
800 - Converter DBGrig em Html
///////Inicio do Código

function ColorToHtml(mColor: TColor): string; begin


mColor := ColorToRGB(mColor);
Result := Format(‘#%.2x%.2x%.2x’,
[GetRValue(mColor), GetGValue(mColor), GetBValue(mColor)]);
end; { ColorToHtml }

function StrToHtml(mStr: string; mFont: TFont = nil): string;


var
vLeft, vRight: string;
begin
Result := mStr;
Result := StringReplace(Result, ‘&’, ‘&AMP;’, [rfReplaceAll]);
Result := StringReplace(Result, ‘<’, ‘&LT;’, [rfReplaceAll]);
Result := StringReplace(Result, ‘>’, ‘&GT;’, [rfReplaceAll]);
if not Assigned(mFont) then Exit;
vLeft := Format(‘<FONT FACE=”%s” COLOR=”%s”>’,
[mFont.Name, ColorToHtml(mFont.Color)]);
vRight := ‘</FONT>’;
if fsBold in mFont.Style then begin
vLeft := vLeft + ‘<B>’;
vRight := ‘</B>’ + vRight;
end;
if fsItalic in mFont.Style then begin
vLeft := vLeft + ‘<I>’;
vRight := ‘</I>’ + vRight;
end;
if fsUnderline in mFont.Style then begin
vLeft := vLeft + ‘<U>’;
vRight := ‘</U>’ + vRight;
end;
if fsStrikeOut in mFont.Style then begin
vLeft := vLeft + ‘<S>’;
vRight := ‘</S>’ + vRight;
end;
Result := vLeft + Result + vRight;
end; { StrToHtml }

function DBGridToHtmlTable(mDBGrid: TDBGrid; mStrings: TStrings;


mCaption: TCaption = ”): Boolean;
const
cAlignText: array[TAlignment] of string = (‘LEFT’, ‘RIGHT’, ‘CENTER’);
var
vColFormat: string;
vColText: string;
vAllWidth: Integer;
vWidths: array of Integer;
vBookmark: string;
I, J: Integer;
begin
Result := False;
if not Assigned(mStrings) then Exit;
if not Assigned(mDBGrid) then Exit;
if not Assigned(mDBGrid.DataSource) then Exit;
if not Assigned(mDBGrid.DataSource.DataSet) then Exit;
if not mDBGrid.DataSource.DataSet.Active then Exit;
vBookmark := mDBGrid.DataSource.DataSet.Bookmark;
mDBGrid.DataSource.DataSet.DisableControls;
try
J := 0;
vAllWidth := 0;
for I := 0 to mDBGrid.Columns.Count - 1 do
if mDBGrid.Columns[I].Visible then begin
Inc(J);
SetLength(vWidths, J);
vWidths[J - 1] := mDBGrid.Columns[I].Width;
Inc(vAllWidth, mDBGrid.Columns[I].Width);
end;
if J <= 0 then Exit;
mStrings.Clear;
mStrings.Add(Format(‘<TABLE BGCOLOR=”%s” BORDER=1 WIDTH=“100%%”>’,
[ColorToHtml(mDBGrid.Color)]));
if mCaption <> ” then
mStrings.Add(Format(‘<CAPTION>%s</CAPTION>’, [StrToHtml(mCaption)]));
vColFormat := ”;
vColText := ”;
vColFormat := vColFormat + ‘<TR>’#13#10;
vColText := vColText + ‘<TR>’#13#10;
J := 0;
for I := 0 to mDBGrid.Columns.Count - 1 do
if mDBGrid.Columns[I].Visible then begin
vColFormat := vColFormat + Format(
‘ <TD BGCOLOR=”%s” ALIGN=%s WIDTH=”%d%%”>DisplayText%d</TD>’#13#10,
[ColorToHtml(mDBGrid.Columns[I].Color),
cAlignText[mDBGrid.Columns[I].Alignment],
Round(vWidths[J] / vAllWidth * 100), J]);
vColText := vColText + Format(
‘ <TD BGCOLOR=”%s” ALIGN=%s WIDTH=”%d%%”>%s</TD>’#13#10,
[ColorToHtml(mDBGrid.Columns[I].Title.Color),
cAlignText[mDBGrid.Columns[I].Alignment],
Round(vWidths[J] / vAllWidth * 100),
StrToHtml(mDBGrid.Columns[I].Title.Caption,
mDBGrid.Columns[I].Title.Font)]);
Inc(J);
end;
vColFormat := vColFormat + ‘</TR>’#13#10;
vColText := vColText + ‘</TR>’#13#10;
mStrings.Text := mStrings.Text + vColText;
mDBGrid.DataSource.DataSet.First;
while not mDBGrid.DataSource.DataSet.Eof do begin
J := 0;
vColText := vColFormat;
for I := 0 to mDBGrid.Columns.Count - 1 do
if mDBGrid.Columns[I].Visible then begin
vColText := StringReplace(vColText, Format(‘>DisplayText%d<’, [J]),
Format(‘>%s<’, [StrToHtml(mDBGrid.Columns[I].Field.DisplayText,
mDBGrid.Columns[I].Font)]),
[rfReplaceAll]);
Inc(J);
end;
mStrings.Text := mStrings.Text + vColText;
mDBGrid.DataSource.DataSet.Next;
end;
mStrings.Add(‘</TABLE>’);
finally
mDBGrid.DataSource.DataSet.Bookmark := vBookmark;
mDBGrid.DataSource.DataSet.EnableControls;
vWidths := nil;
end;
Result := True;
end; { DBGridToHtmlTable }

///////Fim do Código

{ uses ShellApi; }

///////Inicio do Exemplo

procedure TForm1.Button1Click(Sender: TObject);


begin
DBGridToHtmlTable(DBGrid1, Memo1.Lines, Caption);
Memo1.Lines.SaveToFile(‘c:\temp.htm’);
ShellExecute(Handle, nil, ‘c:\temp.htm’, nil, nil, SW_SHOW);
end;

///////Fim do Exemplo

Alexandre de Andrade Gonçalves

Analista/Programador

www.minasexport.com.br

www.cafemokaonline.com.br
801 - Criar Um Programa Para
Transferencia Via Ftp

Criando arqiuvo .dat

var
arq : TextFile;
i : Integer;
begin
AssignFile(Arq, ‘nome_arquivo.dat’);
Rewrite(Arq);
Writeln(Arq, ‘open servidor.com.br’);
Writeln(Arq, ‘usuario’);
Writeln(Arq, ‘senha’);
Writeln(Arq, ‘prompt off’);
Writeln(Arq, ‘bin’);
Writeln(Arq, ‘cd caminho arquivo’);
Writeln(Arq, ‘mput arquivo’);
Writeln(Arq, ‘quit’);
CloseFile(Arq);
end;

Criando Arquivo .bat

var
arqbat : TextFile;
begin
AssignFile(Arqbat, ‘Nome_Arquivo.bat’);
Rewrite(Arqbat);
Writeln(Arqbat, ‘ftp -s:Nome_Arquivo.dat’);
CloseFile(Arqbat);
end;
Executando

WinExec(‘command.com /c nome_arquivo.bat’);

Enviada por: CarlosKarol

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
802 - Gera Um Thumbnail
procedure CreateThumbnail(InStream,
OutStream: TStream;
Width, Height: integer; FillColor:
TColor);
var
JpegImage: TJpegImage;
Bitmap: TBitmap;
Ratio: double;
ARect: TRect;
AHeight, AHeightOffset: integer;
AWidth, AWidthOffset: integer;
begin
// Check for invalid parameters
if Width < 1 then
raise Exception.Create(‘Invalid
Width’);
if Height < 1 then
raise Exception.Create(‘Invalid
Height’);
JpegImage := TJpegImage.Create;
try
// Load the image
JpegImage.LoadFromStream(InStream);
// Create bitmap, and calculate
parameters
Bitmap := TBitmap.Create;
try
Ratio := JpegImage.Width /
JpegImage.Height;
if Ratio > 1 then
begin
AHeight := Round(Width / Ratio);
AHeightOffset := (Height -
AHeight) div 2;
AWidth := Width;
AWidthOffset := 0;
end
else
begin
AWidth := Round(Height * Ratio);
AWidthOffset := (Width - AWidth)
div 2;
AHeight := Height;
AHeightOffset := 0;
end;
Bitmap.Width := Width;
Bitmap.Height := Height;
Bitmap.Canvas.Brush.Color :=
FillColor;
Bitmap.Canvas.FillRect(Rect(0, 0,
Width, Height));
// StretchDraw original image
ARect := Rect(AWidthOffset,
AHeightOffset, AWidth + AWidthOffset,
AHeight + AHeightOffset);
Bitmap.Canvas.StretchDraw(ARect,
JpegImage);
// Assign back to the Jpeg, and save
to the file
JpegImage.Assign(Bitmap);
JpegImage.SaveToStream(OutStream);
finally
Bitmap.Free;
end;
finally
JpegImage.Free;
end;
end;

procedure MakeThumbnail(const InFileName,


OutFileName: string;
Width, Height: integer; FillColor:
TColor);
var
InStream, OutStream: TFileStream;
begin
InStream :=
TFileStream.Create(InFileName,
fmOpenRead);
try
OutStream :=
TFileStream.Create(OutFileName,
fmOpenWrite or fmCreate);
try
CreateThumbnail(InStream, OutStream,
Width, Height, FillColor);
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
end;

Enviada por: Clériston Martinelo

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
803 - Quebra de String Versão 2
Melhorada
function BreakText(Texto, TextRef: string;
StringList: TStringList): TStringList;
var
z, x: integer;
s: string;
StringList2: TStringList;
begin
StringList2 := TStringList.Create;
try
StringList2.Add(‘1’);
for z := 1 to Length(texto) do
begin
if Copy(Texto, z, Length(TextRef)) =
TextRef then
StringList2.Add(IntToStr(z));
end;
StringList2.Add(IntToStr(Length(Texto)
+ 1));
for x := 0 to StringList2.Count - 2 do
begin
s := Trim(Copy(Texto,
StrToInt(StringList2.Strings[x]),
(StrToInt(StringList2.Strings[x + 1])) -
(StrToInt(StringList2.Strings[x]))));
if s <> ‘' then
StringList.Add(s);
end;
finally
StringList2.Free;
end;
Result := StringList;
end;
Modo de usar

procedure TForm1.Button1Click(Sender: TObject);


var
StringListZ: TStringList;
i: integer;
begin
StringListZ := TStringList.Create;
ListBox1.Clear;
try
StringListZ := BreakText(Edit1.Text, ‘', StringListZ);
for i := 0 to StringListz.Count - 1 do
ListBox1.Items.Add(StringListz.Strings[i]);
finally
StringListz.Free;
end;
end;

Obs.: Isso faz com que a velocidade aumente de modo


surpreendente com textos muito grande.

Enviada por: Gefirson Plínio Duarte

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
804 - Adicionar Fonte No Windows

Em referencia a dica 355:


Oi, sempre acompanho seu trabalho, e já me ajudou
muito, parabens pelo trabalho que vc vem
apresentando. Me chamo Luciano Henrique F. Dantas
sou Professor do SENAC - JP e atraves de suas dicas
notei uma dela não funcionava, creio eu que estou
utilizando de forma errada, mais é a dica de como
instalar uma fonte no windows que é apresentado da
seguinte forma

AddFontResource(PChar(‘c:\MyFonts\Monospac.ttf’)
);

dessa forma eu não consegui colocar, dava erro de


comando
ai mudei para essa forma e deu OK

Screen.Fonts.Add(PChar(‘c:\sgdb\EanBwrP36Tt.ttf’))
;

NOTA: Caro Fábio acredito que ambas as dicas


funcinem!! Vai depender de Qual versão do Delphi e
O.S.
Valeu pela colaboração!!

Enviada por: Luciano Henrique

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
805 - Criando Um Menu Janela e
Listando Nele as Janelas Abertas
Em Tempo de Execução

Muitas vezes, em aplicações MDI profissionais,


podemos ver um menu janela, que possui a relação de
todas as janelas abertas no sistema. Sempre achei isso
interessante. Recentemente, implementei este recurso
em um sistema que estou desenvolvendo.
Primeiramente, em sua aplicação MDI, crie um menu
janela, ou outro qualquer do seu agrado. Será
necessário criar em cada uma das janelas-filho o
seguinte código na procedure create do form :

procedure Tfrm_valida1.FormCreate(Sender:
TObject);
var
MyMenu: TMenuItem;
begin
frm_main.Janela1.Tag := frm_main.Janela1.Tag + 1;
Mymenu := TMenuItem.Create(frm_main.Janela1);
MyMenu.Caption := Caption;
MyMenu.OnClick := FormToFront;
MyMenu.Tag := frm_main.Janela1.Tag;
Tag := MyMenu.Tag;
frm_main.Janela1.Add(MyMenu);
end;

Detalhe : será necessário incluir a Unit Menus na


cláusula uses do seu form. O Form filho também terá de
Ter na cláusula uses o form principal, pois será dela o
menu que será alterado.
Em segundo lugar, é necessário criar a procedure que
realizará a ação de dar foco à janela já aberta. Se temos
um menu, é interessante que ele execute alguma ação.

procedure Tfrm_valida1.FormToFront(Sender:
TObject);
begin
BringToFront;
end;

Finalmente, quando encerrarmos a janela em questão,


temos de destruir o menu, caso contrário, a seleção do
mesmo irá gerar um erro. A procedure a seguir deve ser
colocada no evento OnDestroy do form-filho.

procedure Tfrm_valida1.FormDestroy(Sender:
TObject);
var
I: Integer;
begin
for I := 0 to frm_main.Janela1.Count - 1 do
begin
if frm_main.Janela1.Items[i].Tag = Tag then
begin
frm_main.Janela1.Delete(I);
Break;
end;
end;
end;

Enviada por: José Roberto Marque

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
806 - Envio de E-mail Com Indy

Em uma nova aplicação inclua cinco Edits e dois Memos


(paleta Standard), um SpeedButton e um BitBtn (paleta
Additional), um IdSMTP (paleta IndyClients), um
IdMessage (paleta IndyMisc), um OpenDialog (paleta
Dialogs).
Veremos agora as propriedades a serem alteradas:

No Memo1 altere a propriedade Name para


MmMensagem, limpe sua propriedade Lines e altere a
propriedade ScrollBar para ssVertical. Repita o
procedimento anterior no Memo2, com exceção da
propriedade Name que deve ser MmStatus.

Altere o nome do IdSMTP para smtp.

Vamos agora ao código:

O procedimento abaixo é responsável por enviar as


informações para o smtp e para o IdMessage, anexar o
arquivo desejado e enviar a mensagem. Adicione o
código abaixo no evento OnClick do BitBtn1:

procedure TForm1.BitBtn1Click(Sender: TObject);


begin
with smtp do
begin
//Nome do host
Host := edit1.Text;
//Nome do usuário, normalmente o e-mail
Username := edit2.Text;
//Conecta com o servidor smtp
Connect();
end;
with IdMessage do
begin
//O seu endereço de e-mail
From.Address := edit2.Text;
//Aqui vai o endereço de e-mail para o qual você
quer mandar o e-mail
Recipients.EMailAddresses := edit3.Text;
//O assunto da mensagem
Subject := edit4.Text;
//A mensagem que você quer mandar
Body.Text := MmMensagem.Lines.Text;
MessageParts.Clear;
end;
//Aqui para poder anexar um arquivo
TIdAttachment.Create(IdMessage.MessageParts,
edit5.Text);
//Envia a mensagem
SMTP.Send(IdMessage);
SMTP.Disconnect;
end;

O procedimento a seguir insere no MmStatus as


mensagens sobre o status do envio dos e-mails
Adicione o código abaixo no evento OnStatus do smtp

procedure TForm1.smtpStatus(ASender: TObject;


const AStatus: TIdStatus; const AStatusText: string);
begin
mmStatus.Lines.Add(AStatusText);
end;

O próximo procedimento tem como objetivo selecionar


(através do OpenDialog1)
o arquivo a ser atachado ao e-mail.
Copie o código abaixo no evento OnClick do
SpeedButton1

procedure TForm1.SpeedButton1Click(Sender:
TObject);
begin
if OpenDialog1.Execute then
edit5.Text := OpenDialog1.FileName;
end;

Rulio Vangellis - Manda vê caro amigo…

Enviada por: Rulio Vangellis

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
807 - Copiando Um Arquivo Com Um
Gauge

Muitas vezes, quando temos a necessidade de copiar


um arquivo de um lugar para outro, é interessante
mostrar ao usuário o andamento da cópia.
Para tal, coloque em sua aplicação um gauge (optei por
um gauge, mas poderia muito bem ser uma
progressbar) e um botão para iniciar a cópia. No código
onClick do botão, coloque este código. Neste exemplo, o
programa cria um diretório de back-up cujo nome do
mesmo é a data da cópia no formato AAAAMMDD. No
nosso exemplo, chamei o gauge de ga_copia.

procedure Tfrm_Manut.bt_backupClick(Sender:
TObject);
var
strArqOrigem, // Nome do arquivo de origem da cópia
strArqDestino: string; // Nome do arquivo de destino
da cópia
wDia,wMes,wAno: Word;
begin
try
// Aciona o indicativo de progresso da cópia
ga_copia.Visible := True;
ga_copia.Progress := 0;
// Monta os nomes de arquivo - Primeiro recupera de
um AdoConnection
// o nome do arquivo a ser copiado
strArqOrigem :=
dm_spark.ADO_Spark.Properties[7].Value;
// Agora vai montar o nome do arquivo de destino.
DecodeDate(Date, wAno, wMes, wDia);
strArqDestino := ‘C:\prodata\copia' +
FormatFloat(‘0000’, WAno);
strArqDestino := strArqDestino + FormatFloat(‘00’,
wMes);
strArqDestino := strArqDestino + FormatFloat(‘00’,
wDia);
strArqDestino := strArqDestino + ‘' +
ExtractFileName(strArqOrigem);
// Desconecta o banco de dados
dm_spark.ADO_Spark.Close;
Repaint;
// Inicia a cópia
CopyFile(strArqOrigem, strArqDestino);
finally
// Reconecta o banco de dados
dm_spark.ADO_Spark.Open;
ga_copia.Visible := False;
end;
end;

Agora que já definimos como e quando a cópia será


disparada, vamos definir a procedure copyfile que é o
motor da nossa cópia de arquivo. Esta procedure é que
vai fazer a cópia e incrementar o Gauge.

procedure Tfrm_Manut.CopyFile(Source, Destination:


string);
var
FromF,ToF: file of byte;
Buffer: array[0..4096] of char;
NumRead: Integer;
FileLength: LongInt;
NewPath: string;
begin
// Antes de copiar, verifica se já existe o diretório
// Caso o diretório não exista, o mesmo vai ser criado
NewPath := ExtractFilePath(Destination);
if not DirectoryExists(NewPath) then
begin
CreateDir(NewPath);
end
else
begin
if FileExists(Destination) then
begin
if Application.MessageBox(‘O arquivo-destino da
cópia de segurança já existe ‘ + #13#10 +
‘Deseja sobrepôr o mesmo com a nova cópia ?’,
‘Segurança’,
MB_YESNO + MB_ICONQUESTION) = MRNO
then
Exit;
end;
end;
// Copia o arquivo
// Abre o arquivo de origem e cria o arquivo destino
AssignFile(FromF, Source);
Reset(FromF);
AssignFile(ToF, Destination);
ReWrite(ToF);
FileLength := FileSize(FromF);
with ga_copia do
begin
MinValue := 0;
MaxValue := FileLength;
while FileLength > 0 do
begin
BlockRead(FromF, Buffer[0], SizeOf(Buffer),
NumRead);
FileLength := FileLength - NumRead;
BlockWrite(ToF, Buffer[0], NumRead);
AddProgress(NumRead);
end;
CloseFile(FromF);
CloseFile(ToF);
end;
end;

Enviada por: José Roberto Marque

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
808 - Como Verificar Se Uma Porta
Serial Está Em Uso

Usando APIs do Windows, veja abaixo:

procedure VerificaPorta(Porta: string);


var
portHandle: Integer;
begin
portHandle := 0;
portHandle := CreateFile(Pchar(Porta),
GENERIC_READ or GENERIC_WRITE, 0, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
0);
if portHandle > 0 then
ShowMessage(‘Porta em uso!’)
else
raise Exception.Create(‘Não consegui abrir a
porta!’);
end;

Enviada por: Amilton Maciel

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
809 - Como Imprimir Escolhendo
Uma Faixa de Paginas No Qr

Problema:
O problema é que quando chamo a Caixa de Dialogo de
Impressão e escolho um determinado intervalo do
relatório ocorre um erro. Ao invés de ser impresso o
intervalo desejado é impresso o relatório completo. Já
tentei setar de todas as maneiras as propriedades
MaxPage, MinPage, FromPage e ToPage do
componente PrintDialog. Também já tentei setar as
propriedades FirstPage e LastPage de meu componente
QuickReport. Mas a impressão sempre sai completa.
Detalhe: quando seto as propriedades FirstPage e
LastPage do componente QuickRep com o intervalo
desejado em tempo de projeto, o relatório é impresso
corretamente.

Solução:

if PrintDialog1.Execute then
begin
QuickRep1.PrinterSettings.FirstPage :=
PreviewDialog1.FromPage;
QuickRep1.PrinterSettings.LastPage :=
PreviewDialog1.ToPage;
QuickRep1.PrinterSettings.PrinterIndex :=
Printer.PrinterIndex;
QuickRep1.PrinterSettings.Copies := Printer.Copies;
QuickRep1.Print;
end;

Enviada por: Carlos Alberto Ribeiro


Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
810 - Como Bloquear Mouse e
Teclado

Para testar essa dica coloque um Timer sete o interval


para 5000 e um Botão e coloque o código abaixo!
o código travará o mouse e teclado por 5 segundos!

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure BlockInput(ABlockInput : boolean);
stdcall; external ‘USER32.DLL’;
var
Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);


begin
BlockInput(True);
Timer1.Enabled:=True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);


begin
BlockInput(false);
Timer1.Enabled:=false;
end;

end.

Enviada por: Hildeberto Melo

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
811 - Como Colorir os Itens de Um
Tchecklistbox

Voce pode usar o próprio CheckListBox que vem com o


Delphi para fazer isso. Para isso, defina a propriedade
Style para lbOwnerDrawFixed e implemente o seguinte
código:
no evento OnDrawItem:

procedure TForm1.CheckListBox1DrawItem(Control:
TWinControl;
Index: Integer; Rect: TRect; State:
TOwnerDrawState);
begin
with (Control as TCheckListBox) do
begin
if Checked[Index] then
Canvas.Font.Color := clRed
else
begin
if Selected[Index] then
Canvas.Font.Color := clWhite
else
Canvas.Font.Color := clBlack;
end;
Canvas.FillRect(Rect);
Canvas.TextOut(Rect.Left, Rect.Top, (Control as
TCheckListBox).Items[Index]);
end;
end;

Voce vai reparar que ao selecionar outro item ele


mantera a cor branca do item antigo e portanto o tornara
invisível, para evitar isso, chame o método
CheckListBox1.Invalidate nos eventos OnClick e
OnKeyDown
Até mais
Adriano Santos

Enviada por: Adriano Santos

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
812 - Usando as Apis Para Procurar
e Mover Janelas do Windows

Neste artigo vou mostar como usar algumas APIs do


Windows para mover a caixa de Diálogo chamada pela
função SelectDirectory.
A caixa de diálogo em questão, quando chamada, se
abre alinhada ao canto direito inferior do Windows,
próximo ao relógio. Com algumas técnicas, vamos poder
movê-la em tempo de execução para uma nova posição.
Para isso vamos usar as seguintes APIS:

FindWindow : Usada para localizar a janela.


GetWindowRect : Usada para recuperar a posição em
que a janela foi aberta.
MoveWindow : Para mover a caixa de diálogo para a
posição desejada, no nosso caso, centro do desktop.

A primeira coisa que devemos fazer é desenhar o form


de exemplo.
Abra o Delphi e em um novo projeto insira os seguintes
componentes:

1 TButton. Mude sua propriedade Name para


btnSelecionar e Caption para Selecionar Diretório.
1 TEdit com o Name de edCaminho. Limpe a
propriedade Text.
1 TTimer da paleta System com o nome de tmAjustar.
Configure o form como no exemplo da figura 1.
Mude a propriedade Enabled do TTimer para False e
Interval coloque 100.

Feito isso, declare na cláusula “uses” do form a unit


FileCtrl.
Para o evento onClick do btnSelecionar digite o
algoritimo abaixo;
procedure TForm1.btnSelecionar1Click(Sender:
TObject);
var
Dir : String;
begin
tmAjustar.Enabled := True;
if SelectDirectory(‘Selecione um diretório.’,”,Dir)
then
edCaminho.Text := Dir;
end;

No evento onTimer do objeto TTimer digite o código da


Listagem 2;

procedure TForm1.tmAjustarTimer(Sender: TObject);


var
tmHandle : THandle;
tmRect : TRect;
tmAltura, tmLargura, tmNovoLeft, tmNovoTop :
Integer;
begin
{Declare a unit FileCtrl no uses do Form}
tmHandle := FindWindow(Nil,‘Procurar Pasta’);
if tmHandle > 0 then
begin
{Aqui eu pego os valores do Rect da Janela
localizada, desta forma eu posso
obter Left, Top, Bottom, Rigth e Etc}
GetWindowRect(tmHandle,tmRect);
{Aqui eu pego a altura e largura da Janela
localizada}
tmAltura := tmRect.Right-tmRect.Left;
tmLargura := tmRect.Bottom-tmRect.Top;
{Aqui eu defino o novo left e top, que serão no meio
da tela do “WINDOWS”}
tmNovoLeft := (Screen.Width div 2) - (tmLargura
div 2);
tmNovoTop := (Screen.Height div 2) - (tmAltura div
2);
{Aqui eu envio uma mensagem para a janela
indicando qual o novo destino}
MoveWindow(tmHandle,tmNovoLeft,tmNovoTop,t
mRect.Right-tmRect.Left,
tmRect.Bottom-tmRect.Top,True);
tmAjustar.Enabled := False;
end;
Screen.Cursor := crDefault;
end;

Vamos as explicações:
Primeiro nós precisamos de um manipulador do tipo
THandle, obtido através da api FindWindow:

tmHandle := FindWindow(Nil,‘Procurar Pasta’);

A variável tmHandle recebe o “handle” da janela cujo o


Caption é:
Procurar Pasta. O primeiro parâmetro de FindWindow é
a classe da janela procurada. Como não sabemos
passamos Nil.
Depois disso verificamos se o tmHandle é maior que
zero, ou seja, se a janela foi encontrada. Em caso
positivo, usamos a API GetWindowRect. Essa api
armazena em uma variável do tipo TRect a informações
suficientes para mais tarde movermos a janela.

GetWindowRect(tmHandle,tmRect);

O primeiro parâmetro, como podemos ver, é o


manipulador Handle obtido mais acima. O segundo é a
própria variável TRect.
Isso foi feito porque para mover a janela com
MoveWindow, que veremos logo adiante, são
necessários os novos Tamanhos e Posições. Para
sabermos essas informações efetuamos alguns
cálculos, veja:

{Aqui eu pego a altura e largura da Janela localizada}


tmAltura := tmRect.Right-tmRect.Left;
tmLargura := tmRect.Bottom-tmRect.Top;
{Aqui eu defino o novo left e top, que serão no meio da
tela do “WINDOWS”}
tmNovoLeft := (Screen.Width div 2) - (tmLargura div
2);
tmNovoTop := (Screen.Height div 2) - (tmAltura div
2);

Com base nas informações recebidas em tmRect,


calculamos a largura e altura da janela. Depois
calculamos o novo left e top, usando o tamanho do
Screen. Neste caso estamos enviando a janela para o
centro do Desktop.
Agora só nos resta fazer a chamada a API
MoveWindow, veja:

{Aqui eu envio uma mensagem para a janela indicando


qual o novo destino}
MoveWindow(tmHandle,tmNovoLeft,tmNovoTop,tmR
ect.Right-tmRect.Left,
tmRect.Bottom-tmRect.Top,True);

Explicando: o primeiro parâmetro é o manipulador


Handle, ou seja, a própria janela. Os parâmetros
seguintes são, respectivamente, Left, Top, Largura,
Altura e se a janela deve ser “repintada”.
Por fim, desativamos o Timer, usado somente no
instante em que a janela é chamada.

Enviada por: Adriano Santos

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
813 - Imprimir Na Vertical No
Quickreport
procedure ImprimirNaVertical(AQuick:
TQuickRep; ABanda: TQrBand;
ATexto: string);
var
lf: TLogFont;
tf: TFont;
xQrImage: TQrImage;
begin
xQrImage := TQrImage.Create(AQuick);
xQrImage.Parent := ABanda;
xQrImage.Align := alLeft;
xQrImage.Width := 10;
xQrImage.BringToFront;
with xQrImage.Canvas do
begin
Font.Name := ‘Arial’;
Font.Size := 7;
tf := TFont.Create;
tf.Assign(Font);
GetObject(tf.Handle, Sizeof(lf), @lf);
lf.lfEscapement := 900;
lf.lfOrientation := 450;
tf.Handle := CreateFontIndirect(lf);
Font.Assign(tf);
tf.Free;
TextOut(0, xQrImage.Height div 2,
ATexto);
end;
end;
Enviada por: Adriano Santos

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
814 - Alinhar Panel Ao Centro do
Formulário
procedure AlinharPanel(AForm: TForm;
APanel: TPanel; ACentro: Boolean);
begin
if ACentro then
begin
APanel.Left := (AForm.ClientWidth div
2) - (APanel.Width div 2);
APanel.Top := (AForm.ClientHeight div
2) - (APanel.Height div 2);
end
else
begin
APanel.Left := (AForm.ClientWidth +
100);
APanel.Top := (AForm.ClientHeight +
100);
end;
APanel.Update;
AForm.Update;
end;

Enviada por: Adriano Santos

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
815 - Como Desenhar Uma Linha
Na Diagonal Usando Canvas
procedure TForm1.Button1Click(Sender:
TObject);
var
bm: TBitmap;
begin
bm := TBitmap.Create;
bm.Width := 100;
bm.Height := 100;
bm.Canvas.Brush.Color := clRed;
bm.Canvas.FillRect(Rect(0, 0, 100,
100));
bm.Canvas.MoveTo(0, 0);
bm.Canvas.LineTo(100, 100);
Canvas.StretchDraw(ClientRect, Bm);
bm.Free;
end;

Enviada por: Adriano Santos

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
816 - Gerar Código de Barras
Ean13
unit UnCriaCodBarras;

interface

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Printers;

type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender:
TObject);
private
procedure GeraBarrasEAN13(CodBarras:
string; Imagem: TCanvas);
procedure DesenhaBarras(SequenciaHexa:
string; Imagem: TCanvas);
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses UnCriaCodBarrasImpressao;

{$R *.dfm}
//––––––––––––––––––––––––––
//
// .––––––––––––.
// | | Tabela A | Tabela B | Tabela C |
// |–+–––-+–––-+–––-|
// | 0 | 0001101 | 0100111 | 1110010 |
// | 1 | 0011001 | 0110011 | 1100110 |
// | 2 | 0010011 | 0011011 | 1101100 |
// | 3 | 0111101 | 0011011 | 1000010 |
// | 4 | 0100011 | 0011101 | 1011100 |
// | 5 | 0110001 | 0111001 | 1001110 |
// | 6 | 0101111 | 0000101 | 1010000 |
// | 7 | 0111011 | 0010001 | 1000100 |
// | 8 | 0110111 | 0001001 | 1001000 |
// | 9 | 0001011 | 0010111 | 1110100 |
// .––––––––––––.
// Tabela Auxiliar
// .–––––––—.
// | Algarismo | Seqüência |
// |–––—+–––—|
// | 0 | AAAAAA |
// | 1 | AABABB |
// | 2 | AABBAB |
// | 3 | AABBBA |
// | 4 | ABAABB |
// | 5 | ABBAAB |
// | 6 | ABBBAA |
// | 7 | ABABAB |
// | 8 | ABABBA |
// | 9 | ABBABA |
// .–––––––—.
//
// Gerae código de barras padrão EAN13

procedure
TForm1.GeraBarrasEAN13(CodBarras: string;
Imagem: TCanvas);
const
TabelaA: array[0..9] of string[7] =
(‘0001101’, ‘0011001’, ‘0010011’,
‘0111101’, ‘0100011’, ‘0110001’,
‘0101111’, ‘0111011’, ‘0110111’,
‘0001011’);
TabelaB: array[0..9] of string[7] =
(‘0100111’, ‘0110011’, ‘0011011’,
‘0011011’, ‘0011101’, ‘0111001’,
‘0000101’, ‘0010001’, ‘0001001’,
‘0010111’);
TabelaC: array[0..9] of string[7] =
(‘1110010’, ‘1100110’, ‘1101100’,
‘1000010’, ‘1011100’, ‘1001110’,
‘1010000’, ‘1000100’, ‘1001000’,
‘1110100’);
TabAux: array[0..9] of string[6] =
(‘AAAAAA’, ‘AABABB’, ‘AABBAB’, ‘AABBBA’,
‘ABAABB’, ‘ABBAAB’, ‘ABBBAA’, ‘ABABAB’,
‘ABABBA’, ‘ABBABA’);
var
Codigo: string;
Formato: string;
PegaDaTabela: string;
DecimoTerceiroDig: Byte;
Cont: Byte;
begin
Formato := ”;
Codigo := CodBarras;
DecimoTerceiroDig :=
StrToIntDef(CodBarras[1], 0);
{–––––––––––––––––––––––––-}
{ Tendo o 13º dígito definido, posso
definir o padrão de impressão das barras}
{ no primeiro conjunto de 6 dígitos
baseado na tabela Auxiliar. }
{–––––––––––––––––––––––––-}
PegaDaTabela :=
TabAux[DecimoTerceiroDig] + ‘CCCCCC’;
Formato := Formato + ‘101’; //—> Barra
Auxiliar de Guarda ‘Esquerda’
for Cont := 1 to Length(PegaDaTabela) do
begin

case PegaDaTabela[Cont] of
‘A’: Formato := Formato +
TabelaA[StrToInt(Codigo[Cont + 1])];
‘B’: Formato := Formato +
TabelaB[StrToInt(Codigo[Cont + 1])];
‘C’: Formato := Formato +
TabelaC[StrToInt(Codigo[Cont + 1])];
end;

if Cont = 6 then
Formato := Formato + ‘01010’; //—>
Barra Auxiliar de Guarda ‘Central’

end;
Formato := Formato + ‘101’; //—> Barra
Auxiliar de Guarda ‘Direita’

//–– Desenha o código alfa-numérico na


imagem
Imagem.Font.Size := 10;
Imagem.Brush.Color := ClWhite;
Imagem.Pen.Color := ClBlack;
Imagem.TextOut(02, 51, Copy(CodBarras,
01, 01));
Imagem.TextOut(13, 51, Copy(CodBarras,
02, 06));
Imagem.TextOut(60, 51, Copy(CodBarras,
08, 06));
//–– Desenha as barras na imagem
DesenhaBarras(Formato, Imagem);
end;
procedure
TForm1.DesenhaBarras(SequenciaHexa:
string; Imagem: TCanvas);
var
X, Y, H: LongInt;
A, B, C, D: TPoint;
I: Boolean;
begin

Imagem.Brush.Color := ClWhite;
Imagem.Pen.Color := ClBlack;
x := 10;
i := True;
for y := 1 to Length(SequenciaHexa) do
begin
if SequenciaHexa[y] = ‘0’ then
Imagem.Pen.Color := ClWhite
else
Imagem.Pen.Color := ClBlack;
h := 1;
a.x := x;
a.y := 0;
b.x := x;
b.y := 50;
c.x := x + h - 1;
c.y := 50;
d.x := x + h - 1;
d.y := 0;
case Y of
1..3, 46..50, 93..95:
begin
b.y := 55;
c.y := 55;
end;
end;
Imagem.Polygon([A, B, C, D]);
i := not (i);
x := x + h;
end;

end;

procedure TForm1.Button1Click(Sender:
TObject);
begin
GeraBarrasEAN13(‘7891089060350’,
Image1.Canvas);
end;

Enviada por: Marcos das Neves

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
817 - Alinhar Texto do Edit À
Direita

E ai Lloyd? Eu queria elogiar o trabalho que tem feito


com o DTDelphi. É uma ferramenta muito util tanto para
quem está começando, quanto para quem já está na
estrada. Então eu queria dar minha contribuição:

//ALINHAR TEXTO DO EDIT À DIREITA


procedure TForm1.Edit1Exit(Sender: TObject);
var
n: Integer;
c: TCanvas;
h: HWND;
// pode se usar Form1.Canvas se for a mesma fonte do
Edit
begin
c := TCanvas.Create;
c.Handle := GetDeviceContext(h);
c.Font := Edit1.Font;
n := round((Edit1.Width - c.TextWidth(Edit1.Text) -
8) / c.TextWidth(\ ‘ '));
Edit1.Text := stringofchar(\ ‘ ', n) + Edit1.Text;
end;

procedure TForm1.Edit1Enter(Sender: TObject);


begin
Edit1.Text := Trim(Edit1.Text);
end;
Enviada por: A. Varaschin

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
818 - Como Abrir Sempre o Mesmo
Tabsheet Dentro de Um Pagecontrol

Sempre que fazemos um formulário de configuração,


dependendo do software, colocamos um PageControl
com vários TabSheet, quando nós fechamos um form
com o foco em um outro TabSheet que não seja o
primeiro ou o “Geral”, quando abrimos denovo, estará
com foco o mesmo outro TabSheet. Para fazer um dos
TabSheet ser padrão faça isto:

procedure TForm2.FormShow(Sender: TObject);


begin
PageControl1.TabIndex := 0;
TabSheet1.Show;
end;

Eu estava usando o Windows XP quando fiz este


código, possivelmente algo mude no 98.

Qualquer dúvida: mauricio.lima@hotmail.com

Enviada por: Mauricio de Lima

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
819 - Gravando Sons do Microfone
Com o Delphi

Primeiro você deve ter uma placa de som e microfone,


ambos devidamente instalados no seu PC. Se não tiver
um mic, vai lá na SantaIfigênia que você encontra um
bom com 5 reais.

Agora coloque um componente TMediaPlayer que se


encontra na pasta System, depois coloque três botões e
um edit no Form.

Abra o Gravador de som do Windows e sem gravar


nada salve o arquivo vazio como C:\SOM.WAV,
normalmente este arquivo é temporário até salvar o
arquivo pricipal. (somente arquivos WAV são salvos,
alias, se alguém souber qual função de uma das DLL do
Windows Media Player 8.0 que converte WAV para MP3,
ME MANDA UM EMAIL!!!)

Agora coloque os seguintes comandos:

Na propriedade Text do Edit1 coloque o arquivo wave


que você salvou - C:\SOM.WAV

procedure TForm1.Button1Click(Sender: TObject);


begin
MediaPlayer1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);


begin
MediaPlayer1.Save;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
MediaPlayer1.FileName := Edit1.Text;
end;

Agora compile o programa e abra-o, clique no Button3


para associar o arquivo que você criou ao MCI, feche
todos os aplicativos de midía que estiverem abertos
(eles impedem de que abra o MCI) e clique no Button1
para abrir o dispositivo MCI, se algo estiver errado ele
não vai abrir, depois de abrir, 4 botões vão ser liberados
no TMediaPlayer1, com o microfone ligado clique na
bola vermelha para começar à gravar, para pausar a
gravação clique no segundo botão o amarelo, e para
ouvir o som gravado clique no primeiro botão verde o
Play, agora para salvar o arquivo clique no Button2, vá
ver o arquivo C:\SOM.WAV, antes ele estava vazio
agora está com sua gravação.

Eu estava usando o Windows XP quando fiz este


código, é bem provável que as configurações sejam
diferentes no 98.

Qualquer dúvida: mauricio.lima@hotmail.com

Enviada por: Mauricio de Lima

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
820 - Chamar a Lista de Tarefas e
Menu Iniciar

Inclua na seção uses: Windows

Uma vez tentei fazer meu programa chamar a lista do


Ctrl+Alt+Del fazendo o seguinte:

keybd_event(VK_CONTROL, 0,
KEYEVENTF_EXTENDEDKEY or 0, 0);
keybd_event(VK_MENU, 0,
KEYEVENTF_EXTENDEDKEY or 0, 0);
keybd_event(VK_DELETE, 0,
KEYEVENTF_EXTENDEDKEY or 0, 0);
{ pressiona Ctrl + Alt(Menu) + Del }

mas não aconteceu nada, então fiz o seguinte:

{ Chama a lista Ctrl+Alt+Del }


SendMessage(Application.Handle,
WM_SYSCOMMAND, SC_TASKLIST, -1);
{ Chama o menu Iniciar }
SendMessage(Application.Handle,
WM_SYSCOMMAND, SC_TASKLIST, 0);

Fiz esse código no Windows XP, é provável que em


outras versões você tenha que mudar o último
parâmentro.
Enviada por: Mauricio de Lima

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
821 - Como Alterar Uma Imagem
Desenhada Na Statusbar

Coloque uma StatusBar, um Button e um ImageList, na


ImageList coloque as imagens que deseja colocar na
StatusBar.
declare a seguinte variável:

var
bmp: integer;

e faça:

procedure TForm1.FormCreate(Sender: TObject);


begin
bmp := 0;
end;

procedure TForm1.StatusBar1DrawPanel(StatusBar:
TStatusBar; Panel: TStatusPanel; const Rect: TRect);
begin
with StatusBar1.Canvas do
begin
FillRect(Rect);
ImageList1.Draw(StatusBar1.Canvas, Rect.Left,
Rect.Top, bmp);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin
bmp := 1; // Aqui você define qual imagem do
ImageList vai ser desenhado na StatusBar.
Form1.StatusBar1.Refresh; // E aqui faz o Repaint da
StatusBar. Essa dica é muito fácil, porque demorou
tanto para sair???
end;

Enviada por: Mauricio de Lima

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
822 - Como Alterar o Volume do
Som do Computador Com o Delphi

a função usada para alterar o som é a


waveOutSetVolume( hwo, dwVolume) que fica na unit
MMSystem.

Não é fácil alterar o volume com o Delphi. Não é só


colocar uma TrackBar e associar com o MCI. Para
alterar o volume no computador você envia uma integer
tipo assim: 0x5555FFFF

Os quatro dígitos F seriam o lado esquerdo do som o os


quatro dígitos 5 seriam o lado direito, em diferentes
computadores eles se invertem, mas este é só um
exemplo.

os valores vão de 0000 até FFFF, assim:


0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

considere o A como um 10, o B como 11, o C como 12 e


assim em diante até o F que seria 15, o volume máximo
ou seja se você colocar 0xFFFFFFFF iria ficar os dois
lados no volume máximo e se colocasse 0x00000000
iria ficar tudo mudo.

Então aqui vai um exemplo:


Insira dois Edits e um Button
na seção uses coloque MMSystem.
faça o botão assim:

procedure TForm1.Button1Click(Sender: TObject);


var
s: string;
begin
s := ‘0x’ + Edit1.Text + Edit2.Text;
MMSystem.waveOutSetVolume(0, StrToInt(s));
end;

o 0 que você vê como primeiro parâmentro é qual o seu


dispositivo de áudio você vai usar, no meu caso é o SIS
7018 Wave.

Agora coloque uma música pra tocar no Windows Media


Player e no Edit1 coloque o valor 0000 e no Edit2 FFFF
e clique no botão, você vai perceber que um lado ficou
mudo e o outro no volume máximo.

Agora tente colocar no Edit1 e no Edit2 o valor 7500 e


clique no botão, você vai perceber que os dois lados
ficaram com o mesmo som no volume médio.

Se quiser usar uma TrackBar para usar essa função,


você terá que ser bom de cálculos.

Enviada por: Mauricio de Lima

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
823 - Executando Sons Contidos
Num Listbox Através de Chamadas
Mci

Isso é muito facil, pois é só largar cada item do ListBox


numa variavel, e mandar executar a variavel, bastando:

procedure TForm1.Button1…
begin
Arquivo := FileListBox1.FileName; // Variavel recebe
item selecionado no ListBox
MCISendString(PChar(‘Play ‘ + Arquivo), nil, 0, 0);
// Executa variavel ‘Arquivo’
Caption := FormCaption +
ExtractFilename(FileListBox1.Filename); // langa o
nome do arquivo e sua
// extensco como Caption do Form
end;

Importante: Inclua ‘MMSystem’ na Uses

PS.:
A mesma chamada MCI pode ser usada para Pausar e
Terminar a execução da musica, bastando trocar ‘Play’
por ‘Pause’ e por ‘Stop’.

Com esse comando é possível rodar arquivos “.mp3”,


“.wav” e “.wma” (neste a qualidade não e muito boa).

Para deixa-lo algo como um Music Match vc pode


incrementar usando os componenetes
TDriveComboBox, TDirectoryListBox, TFilterComboBox,
e TFileListBox configurando-os para que fiquem
interligados e assim filtrar os arquivos musicais pela
extenção.

Enviada por: Diorgenes C. Tavares

Localidade: Gravataí - RS
––––––––––––––––––––—
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
824 - Desenhando Em Delphi Via
Programação
procedure TForm1.Button1Click(Sender:
TObject);
var
i: Integer;
SX: Integer;
SY: Integer;
OldBkMode: integer;
begin
SX := ClientWidth;
SY := ClientHeight;
with Canvas do
begin
SY := Trunc(SY / 8); {a procedure
Trunc, transforma um valor do tipo Real em
tipo Inteiro}
for i := 0 to 6 do
begin
Pen.Width := i + 1;
MoveTo(0, (i * SY) + 20);
LineTo(SX, (i * SY) + 20);
end;
Pen.Width := 2;
{Desenhando um Retângulo}
Brush.Color := clGreen;
Rectangle(0, 0, 150, 150);
{Desenhando um outro Retângulo}
Brush.Style := bsDiagCross;
Brush.Color := clRed;
Rectangle(150, 0, 300, 150);
{Desenhando um circulo}
Brush.Style := bsSolid;
Brush.Color := clBlue;
Ellipse(50, 10, 250, 140);
OldBkMode := SetBkMode(Handle,
TRANSPARENT);
TextOut(125, 70, ‘LloydSoft’);
end;
end;

Enviada por: Aldebaran Beloli Martini

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
825 - Enviando Caracter Aleatório
À Uma Janela

Este exemplo manda um caracter aleatório à janela de


textos do Bloco de notas usando a mensagem da API do
windows chamada WM_CHAR.

procedure TfrmMain.btnSendClick(Sender: TObject);


var
notepad, edit: HWND;
begin
notepad := FindWindow(‘notepad’, nil);
edit := FindWindowEx(notepad, FindWindow(‘Edit’,
nil), nil, nil);
SendMessage(edit, WM_CHAR, random(26) + 65, 0);
end;

Enviada por: Daniel Fabiano Correia

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
826 - Como Chamar o Formulario de
Setup Para Impressão de Gráficos

Depois de ter apanhado muito e não ter encontrado


nenhum artigo parecido para descobrir como se faz,
finalmente consegui e resolvi publicar:

uses Teeprevi;

// Self = nome do form


ChartPreview(Self, Nome do Gráfico);

Enviada por: Daniel Arantes de Oliveira

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
827 - Desenhar Um Ícone (bitmap)
Em Células do Dbgrid

A dica abaixo serve para desenhar um ícone(bitmap) em


cada célula de um dbgrid de acordo com o valor de um
determinado campo da tabela… Ex: temos uma tabela
“sexo” com o campo “sexo” que guarda os valores “M”
para masculino e “F” para feminino. Então podemos
fazer o dbgrid mostrar uma ícone(bitmap) de um homem
ou um de uma mulher ao invés dos valores “M” e “F”…

procedure TForm1.DBGrid1DrawColumnCell(Sender:
TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State:
TGridDrawState);
var
Icon: TBitmap;
begin
Icon := TBitmap.Create;
if (Column.FieldName = ‘SHARES’) then
begin
with DBGrid1.Canvas do
begin
Brush.Color := clWhite;
FillRect(Rect);
if (Table1.FieldByName(‘SHARES’).Value > 4500)
then
ImageList1.GetBitmap(1, Icon)
else
ImageList1.GetBitmap(0, Icon);
Draw(round((Rect.Left + Rect.Right - Icon.Width) /
2), Rect.Top, Icon);
end;
end;
end;

Enviada por: Jackson Pires de O. S. Júnior

Téc. em Informática
Paulo Afonso - BA
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
828 - Checar Se a Url Existe

Declare na Uses a unit WinInet

function CheckUrl(url: string): boolean;


var
hSession, hfile, hRequest: hInternet;
dwindex, dwcodelen: dword;
dwcode: array[1..20] of char;
res: pchar;
begin
if pos(‘http://’, lowercase(url)) = 0 then
url := ‘http://’ + url;
Result := false;
hSession := InternetOpen(‘InetURL:/1.0’,
INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if assigned(hsession) then
begin
hfile := InternetOpenUrl(hsession, pchar(url), nil, 0,
INTERNET_FLAG_RELOAD, 0);
dwIndex := 0;
dwCodeLen := 10;
HttpQueryInfo(hfile,
HTTP_QUERY_STATUS_CODE, @dwcode,
dwcodeLen, dwIndex);
res := pchar(@dwcode);
result := (res = ‘200’) or (res = ‘302’);
if assigned(hfile) then
InternetCloseHandle(hfile);
InternetCloseHandle(hsession);
end;
end;
Enviada por: Jackson Pires de O. S. Júnior

Téc. em Informática
Paulo Afonso - BA
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
829 - Verificar Registros Deletados
No Bde/paradox

O BDE não deleta os registros, ele simplesmente os


marca como deletados.

é preciso declarar na uses as units DBIPROCS e


DBITYPES

procedure VerDeletados(Table: TTable; SimNao:


Boolean);
begin
Table.DisableControls;
try
Check(DbiSetProp(hDBIObj(Table.Handle),
curSOFTDELETEON, LongInt(SimNao)));
finally
Table.EnableControls;
end;
Table.Refresh;
end;

Para ver:

VerDeletados(Table1, TRUE);

para esconder:

VerDeletados(Table1, FALSE);

para excluir de vez os registro é preciso dar um PACK


na tabela
Enviada por: Jackson Pires de O. S. Júnior

Téc. em Informática
Paulo Afonso - BA
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
830 - Contar Todos os Itens e
Subintem de Um Menu

Eu criei esta rotina e gostaria de complartilhar com meus


amigos de trabalho esta rotina ela conta todos os itens e
subitem de um mainmenu.

procedure TFrmMenu.GetSubItemMenu(aItemMenu:
TMenuItem);
var
inCountMenu: Integer;
begin
//if aItemMenu.Count > 0 then
for inCountMenu := 0 to aItemMenu.Count - 1 do
begin
GetSubItemMenu(aItemMenu.Items[inCountMenu]);
end;
end;

Enviada por: Flávio Rafael de Oliveira

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
831 - Download Com Thread
uses ExtActns, …

type
TfrMain = class(TForm)

private
procedure
URL_OnDownloadProgress(Sender:
TDownLoadURL;
Progress, ProgressMax: Cardinal;
StatusCode: TURLDownloadStatus;
StatusText: string; var Cancel:
Boolean);

implementation

procedure TfrMain.URL_OnDownloadProgress;
begin
ProgressBar1.Max := ProgressMax;
ProgressBar1.Position := Progress;
end;

function DoDownload;
begin
with TDownloadURL.Create(self) do
try
URL := ‘http://sua url.com.br’;
FileName := ‘local e o nome que quer
salvar’;
OnDownloadProgress :=
URL_OnDownloadProgress;
ExecuteTarget(nil);
finally
Free;
end;
end;

Enviada por: Bizarro

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
832 - Obtendo o Nome das Tabelas
No Access(ado)

Utilize o componente ADOConnection para conectar a


base de dados Access.

Utilize o método GetTableNames do ADOConnection

GetTableNames (List: TStrings; SystemTables:


Boolean = False);

Onde:

List é a string list de um objeto existente onde o nome


das tabelas serão colocados.

SystemTables indica se a lista de nomes das tabelas


deve incluir as tabelas de sistemas do database.

Exemplo:
ADOConnection1.GetTableNames(ListBox1.Items,
False);

Nota: Qualquer conteúdo já existente na string-list do


objecto serão eliminados e sobrescritos pelos dados
produzidos por GetTableNames

Enviada por: Claudemiro Freitas


www.masterspdn.kit.net
Manaus Energia / CEAM
System Analyst Pleno
Phone: +55 92 621-1240 / 621-1230 - Fax:
+55 92 622-1176
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
833 - Obtendo o Nome dos Campos
de Uma Tabela No Access(ado)

Utilize o componente ADOConnection para conectar a


base de dados Access.

Utilize o método GetFieldNames do ADOConnection

GetFieldNames(const TableName: String; List:


TStrings);

Onde:

TableName string indicando o nome da tabela.

List é a string-list de um objeto existente onde o nome


dos campos serão listados.

ADOConnection1.GetFieldNames(‘Funcionarios’,
ListBox1.Items);

Enviada por: Claudemiro Freitas


www.masterspdn.kit.net

Manaus Energia / CEAM


System Analyst Pleno
Phone: +55 92 621-1240 / 621-1230 - Fax:
+55 92 622-1176
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
834 - Exportando Ado Tables Em
Vários Formatos
{
Exportando ADO tables em vários formatos

Nesse artigo eu quero mostrar um


componente que eu fiz para suprimir
a necessidade de exportação de dados do
componente ADOTable. O ADO fornece
uma extensa sintaxes de SQL que permite
exportação de dados em vários
formatos. Eu levei em consideração os
seguintes formatos:

1)Excel
2)Html
3)Paradox
4)Dbase
5)Text

Você pode ver todos os formatos de saídas


suportados no registro:
“HKEY_LOCAL_MACHINE\Software\Microsoft\Jet
\4.0\ISAM formats”

Esse é o código completo do meu componente


}

unit ExportADOTable;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
Db, ADODB;

type
TExportADOTable = class(TADOTable)
private
{ Private declarations }
//Componente TADOCommand usado para
executar os comandos de exportação SQL
FADOCommand: TADOCommand;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:
TComponent); override;

//Procedures de Exportação
//“FieldNames” é uma lista, separada
por vírgula, de nomes dos campos que vc
quer exportar
//“FileName” é o nome do arquivo de
saída (incluindo o path completo)
//Se o dataset é filtrado (Filtered =
true and Filter <> ”), então eu adiciono
//a string de filtro para o comando
sql na diretiva “where”
//Se o dataset ordenado (Sort <> ”)
então eu adiciono a string de ordenação no
comando sql na
//diretiva “order by”

procedure ExportToExcel(FieldNames:
string; FileName: string;
SheetName: string; IsamFormat:
string);
procedure ExportToHtml(FieldNames:
string; FileName: string);
procedure ExportToParadox(FieldNames:
string; FileName: string; IsamFormat:
string);
procedure ExportToDbase(FieldNames:
string; FileName: string; IsamFormat:
string);
procedure ExportToTxt(FieldNames:
string; FileName: string);
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents(‘Claudemiro Freitas’,
[TExportADOTable]);
end;

constructor TExportADOTable.Create(AOwner:
TComponent);
begin
inherited;

FADOCommand := TADOCommand.Create(Self);
end;

procedure
TExportADOTable.ExportToExcel(FieldNames:
string; FileName: string;
SheetName: string; IsamFormat: string);
begin
{Valores de IsamFormat
Excel 3.0
Excel 4.0
Excel 5.0
Excel 8.0
}

if not Active then


Exit;
FADOCommand.Connection := Connection;
FADOCommand.CommandText := ‘Select ‘ +
FieldNames + ‘ INTO ‘ + ‘[‘ +
SheetName + ‘]’ + ‘ IN ‘ + ‘”’ +
FileName + ‘”’ + ‘[‘ + IsamFormat +
‘;]’ + ‘ From ‘ + TableName;
if Filtered and (Filter <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ where ‘ +
Filter;
if (Sort <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ order by ‘ +
Sort;
FADOCommand.Execute;
end;

procedure
TExportADOTable.ExportToHtml(FieldNames:
string; FileName: string);
var
IsamFormat: string;
begin
if not Active then
Exit;

IsamFormat := ‘HTML Export’;

FADOCommand.Connection := Connection;
FADOCommand.CommandText := ‘Select ‘ +
FieldNames + ‘ INTO ‘ + ‘[‘ +
ExtractFileName(FileName) + ‘]’ +
‘ IN ‘ + ‘”’ +
ExtractFilePath(FileName) + ‘”’ + ‘[‘ +
IsamFormat +
‘;]’ + ‘ From ‘ + TableName;
if Filtered and (Filter <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ where ‘ +
Filter;
if (Sort <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ order by ‘ +
Sort;
FADOCommand.Execute;
end;

procedure
TExportADOTable.ExportToParadox(FieldNames
: string;
FileName: string; IsamFormat: string);
begin
{Valores de IsamFormat
Paradox 3.X
Paradox 4.X
Paradox 5.X
Paradox 7.X
}
if not Active then
Exit;

FADOCommand.Connection := Connection;
FADOCommand.CommandText := ‘Select ‘ +
FieldNames + ‘ INTO ‘ + ‘[‘ +
ExtractFileName(FileName) + ‘]’ +
‘ IN ‘ + ‘”’ +
ExtractFilePath(FileName) + ‘”’ + ‘[‘ +
IsamFormat +
‘;]’ + ‘ From ‘ + TableName;
if Filtered and (Filter <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ where ‘ +
Filter;
if (Sort <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ order by ‘ +
Sort;
FADOCommand.Execute;
end;

procedure
TExportADOTable.ExportToDbase(FieldNames:
string; FileName: string;
IsamFormat: string);
begin
{Valores de IsamFormat
dBase III
dBase IV
dBase 5.0
}
if not Active then
Exit;

FADOCommand.Connection := Connection;
FADOCommand.CommandText := ‘Select ‘ +
FieldNames + ‘ INTO ‘ + ‘[‘ +
ExtractFileName(FileName) + ‘]’ +
‘ IN ‘ + ‘”’ +
ExtractFilePath(FileName) + ‘”’ + ‘[‘ +
IsamFormat +
‘;]’ + ‘ From ‘ + TableName;
if Filtered and (Filter <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ where ‘ +
Filter;
if (Sort <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ order by ‘ +
Sort;
FADOCommand.Execute;
end;

procedure
TExportADOTable.ExportToTxt(FieldNames:
string; FileName: string);
var
IsamFormat: string;
begin
if not Active then
Exit;

IsamFormat := ‘Text’;

FADOCommand.Connection := Connection;
FADOCommand.CommandText := ‘Select ‘ +
FieldNames + ‘ INTO ‘ + ‘[‘ +
ExtractFileName(FileName) + ‘]’ +
‘ IN ‘ + ‘”’ +
ExtractFilePath(FileName) + ‘”’ + ‘[‘ +
IsamFormat +
‘;]’ + ‘ From ‘ + TableName;
if Filtered and (Filter <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ where ‘ +
Filter;
if (Sort <> ”) then
FADOCommand.CommandText :=
FADOCommand.CommandText + ‘ order by ‘ +
Sort;
FADOCommand.Execute;
end;

end.

{
Note que você pode usar um database
existente como destino mas não uma tabela
existente no seu database
Se você especificar uma tabela existente
você vai receber uma mensagem de erro.

Talvez você deva inserir um código de


verificação dentro de cada procedure de
exportação em meu componente,
antes da execução do comando de exportação
sql, para fazer um pedido de deleção da
tabela existente
ou abortar o processo de exportação.

Outra Idéia, seria usar componente


TADOQuery, assim a exportação ficaria mais
dinâmica e até usar mais de uma tabela.

Claudemiro Freitas Machado, e-mail:


claudemirofreitas@yahoo.com.br
}

Enviada por: Claudemiro Freitas


www.masterspdn.kit.net

Manaus Energia / CEAM


System Analyst Pleno
Phone: +55 92 621-1240 / 621-1230 - Fax:
+55 92 622-1176
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
835 - Escrever Para Um Db Access
Usando Ado / Sql
// Lendo um database MS-ACCESS usindo ADO
// Verificando se é um arquivo MDB ACCESS
// Escreve um registro para o Database MS-
ACCESS
// Componentes necessários no Form da
Aplicação:-
//
TADOtable,TDataSource,TOpenDialog,TDBGrid,
// TBitBtn,TTimer,TEditTextBox
// Date : 22/01/2002
// Author: Michael Casse.

// Tradução: Claudemiro Freitas

program ADOdemo;

uses
Forms,
uMain in ‘uMain.pas’ {frmMain};

{$R *.RES}

begin
Application.Initialize;
Application.CreateForm(TfrmMain,
frmMain);
Application.Run;
end.
//////////////////////////////////////////
/////////////////////////
unit uMain;

interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
Db, DBTables, ADODB, Grids, DBGrids,
ExtCtrls, DBCtrls, StdCtrls, Buttons,
ComObj;

type
TfrmMain = class(TForm)
DBGridUsers: TDBGrid;
BitBtnClose: TBitBtn;
DSource1: TDataSource;
EditTextBox: TEdit;
BitBtnAdd: TBitBtn;
TUsers: TADOTable;
BitBtnRefresh: TBitBtn;
Timer1: TTimer;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure
ConnectToAccessDB(lDBPathName,
lsDBPassword: string);
procedure
ConnectToMSAccessDB(lsDBName,
lsDBPassword: string);
procedure AddRecordToMSAccessDB;
function CheckIfAccessDB(lDBPathName:
string): Boolean;
function GetDBPath(lsDBName: string):
string;
procedure BitBtnAddClick(Sender:
TObject);
procedure BitBtnRefreshClick(Sender:
TObject);
procedure Timer1Timer(Sender:
TObject);
function GetADOVersion: Double;
procedure Button1Click(Sender:
TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
Global_DBConnection_String: string;
const
ERRORMESSAGE_1 = ‘Nenhum Database
Selecionado’;
ERRORMESSAGE_2 = ‘Acesso Inválido ao
Database’;

implementation

{$R *.DFM}

procedure TfrmMain.FormCreate(Sender:
TObject);
begin
ConnectToMSAccessDB(‘ADODemo.MDB’,
‘123’); // DBName,DBPassword
end;

procedure
TfrmMain.ConnectToMSAccessDB(lsDBName,
lsDBPassword: string);
var
lDBpathName: string;
begin
lDBpathName := GetDBPath(lsDBName);
if (Trim(lDBPathName) <> ”) then
begin
if CheckIfAccessDB(lDBPathName) then
ConnectToAccessDB(lDBPathName,
lsDBPassword);
end
else
MessageDlg(ERRORMESSAGE_1,
mtInformation, [mbOK], 0);
end;

function TfrmMain.GetDBPath(lsDBName:
string): string;
var
lOpenDialog: TOpenDialog;
begin
lOpenDialog := TOpenDialog.Create(nil);
if
FileExists(ExtractFileDir(Application.ExeN
ame) + ‘' + lsDBName) then
Result :=
ExtractFileDir(Application.ExeName) + ‘' +
lsDBName
else
begin
lOpenDialog.Filter := ‘MS Access DB|’
+ lsDBName;
if lOpenDialog.Execute then
Result := lOpenDialog.FileName;
end;
end;

procedure
TfrmMain.ConnectToAccessDB(lDBPathName,
lsDBPassword: string);
begin
Global_DBConnection_String :=
‘Provider=Microsoft.Jet.OLEDB.4.0;’ +
‘Data Source=’ + lDBPathName + ‘;’ +
‘Persist Security Info=False;’ +
‘Jet OLEDB:Database Password=’ +
lsDBPassword; //Senha do MDB

with TUsers do
begin
ConnectionString :=
Global_DBConnection_String;
TableName := ‘Users’;
Active := True;
end;
end;

// Checa se é um DB ACCESS válido antes de


abrí-lo.

function
TfrmMain.CheckIfAccessDB(lDBPathName:
string): Boolean;
var
UnTypedFile: file of Byte;
Buffer: array[0..19] of Byte;
NumRecsRead: Integer;
i: Integer;
MyString: string;
begin
AssignFile(UnTypedFile, lDBPathName);
reset(UnTypedFile, 1);
BlockRead(UnTypedFile, Buffer, 19,
NumRecsRead);
CloseFile(UnTypedFile);
for i := 1 to 19 do
MyString := MyString +
Trim(Chr(Ord(Buffer[i])));
Result := False;
if Mystring = ‘StandardJetDB’ then
Result := True;
if Result = False then
MessageDlg(ERRORMESSAGE_2,
mtInformation, [mbOK], 0);
end;

procedure TfrmMain.BitBtnAddClick(Sender:
TObject);
begin
AddRecordToMSAccessDB;
end;

procedure TfrmMain.AddRecordToMSAccessDB;
var
lADOQuery: TADOQuery;
lUniqueNumber: Integer;
begin
if Trim(EditTextBox.Text) <> ” then
begin
lADOQuery := TADOQuery.Create(nil);
with lADOQuery do
begin
ConnectionString :=
Global_DBConnection_String;
SQL.Text :=
‘SELECT Number from Users’;
Open;
Last;
// Gera um número único
(AutoNumeração no Access)
lUniqueNumber := 1 +
StrToInt(FieldByName(‘Number’).AsString);
Close;
// Insere Registro no MSAccess DB
usindo SQL
SQL.Text :=
‘INSERT INTO Users Values (‘ +
IntToStr(lUniqueNumber) + ‘,’ +
QuotedStr(UpperCase(EditTextBox.Te
xt)) + ‘,’ +
QuotedStr(IntToStr(lUniqueNumber))
+ ‘)’;
ExecSQL;
Close;
// Isso atualiza o Grid
Automaticamente
Timer1.Interval := 5000;
Timer1.Enabled := True;
end;
end;
end;

procedure
TfrmMain.BitBtnRefreshClick(Sender:
TObject);
begin
Tusers.Active := False;
Tusers.Active := True;
end;

procedure TfrmMain.Timer1Timer(Sender:
TObject);
begin
Tusers.Active := False;
Tusers.Active := True;
Timer1.Enabled := False;
end;

function TfrmMain.GetADOVersion: Double;


var
ADO: OLEVariant;
begin
try
ADO :=
CreateOLEObject(‘adodb.connection’);
Result := StrToFloat(ADO.Version);
ADO := Null;
except
Result := 0.0;
end;
end;

procedure TfrmMain.Button1Click(Sender:
TObject);
begin
ShowMessage(Format(‘Versão do ADO = %n’,
[GetADOVersion]));
end;

end.

{
Author: Michael Casse
Tradução: Claudemiro Freitas
}

Enviada por: Claudemiro Freitas


www.masterspdn.kit.net

Manaus Energia / CEAM


System Analyst Pleno
Phone: +55 92 621-1240 / 621-1230 - Fax:
+55 92 622-1176
–––––––––––––
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
836 - Colocando Um Barra
Horizontal Em Um Listbox

Infelizmente o ListBox padrão do Delphi não nos oferece


uma opção para que possamos colocar uma barra
Horizontal no mesmo, por isso sempre que
precisarmos exibir uma barra horizontal será necessário
implementar a procedure abaixo.

Na área public do seu form coloque:

procedure SetHorizontalScrollBar(lb: TListBox);

E logo abaixo da área Implementation coloque:

procedure SetHorizontalScrollBar(lb: TListBox);


var
i, MaxWidth: integer;
begin
MaxWidth := 0;
for i := 0 to lb.Items.Count - 1 do
if MaxWidth < lb.Canvas.TextWidth(lb.Items[i])
then
MaxWidth := lb.Canvas.TextWidth(lb.Items[i]);
SendMessage(lb.Handle,
LB_SETHORIZONTALEXTENT, MaxWidth + 5, 0);
end;

Para que seu ListBox receba a barra Horizontal e só


executar o comando:

SetHorizontalScrollBox(Nome_do_seu_listbox);
Enviada por: Andréa Santos Figueiredo

Aracaju-SE
–––––––––––––
Uma colaboradora da DTDelphi 2.7
Colabore você com a próxima edição!
837 - Simulando Checkbox Em
Dbgrid

Tudo bom, eu não sei se existe algum exemplo assim no


DTDelphi, eu vi essa dica e achei interessante, testei e
aprovei, se existir alguma outra dica me informe, ai vai:
para colocar a figura do check, é só colocar um
ImageList1, e adicionar nele as figuras do Check e do X,
tipo confirmar e cancelar, feito isso crie um campo
boleano para receber os valores para modificar a figura
no grid: essa procedure pinta o Dbgrid com um
checkbox

procedure TForm1.DBGrid1DrawColumnCell(Sender:
TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State:
TGridDrawState);
var
R: TRect;
begin
{pinta checkbox}
if Column.Field = ClientDataSet1ATIVO then
begin
DBGrid1.Canvas.FillRect(Rect);
ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 10,
Rect.Top + 1, 0);
if ClientDataSet1ATIVO.AsBoolean then
ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 10,
Rect.Top + 1, 2)
else
ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 10,
Rect.Top + 1, 1);
end;
end;

essa daqui permite que o usuário clique com o mouse


fazendo o checkbox mudar a figura.

procedure TForm1.DBGrid1CellClick(Column:
TColumn);
begin
if Column.Field = ClientDataSet1ATIVO then
begin
ClientDataSet1.Edit;
ClientDataSet1ATIVO.AsBoolean := not
ClientDataSet1ATIVO.AsBoolean;
end;
end;

essa daqui permite o grid ficar em modo edição para


modificar a figura

procedure TForm1.DBGrid1ColEnter(Sender:
TObject);
begin
if DBGrid1.SelectedField = ClientDataSet1ATIVO
then
DBGrid1.Options := DBGrid1.Options - [dgEditing]
else
DBGrid1.Options := DBGrid1.Options +
[dgEditing];
end;
Enviada por: Renato Arcon Gaio

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
838 - Tratamento de Erro do Banco
Interbase (com Componente Ibx)

Tudo bom, eu não sei se existe algum exemplo assim no


DTDelphi, eu vi essa dica e achei interessante, testei e
aprovei, se existir alguma outra dica me informe, ai vai:
para colocar a figura do check, é só colocar um
ImageList1, e adicionar nele as figuras do Check e do X,
tipo confirmar e cancelar, feito isso crie um campo
boleano para receber os valores para modificar a figura
no grid: essa procedure pinta o Dbgrid com um
checkbox

procedure TForm1.DBGrid1DrawColumnCell(Sender:
TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State:
TGridDrawState);
var
R: TRect;
begin
{pinta checkbox}
if Column.Field = ClientDataSet1ATIVO then
begin
DBGrid1.Canvas.FillRect(Rect);
ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 10,
Rect.Top + 1, 0);
if ClientDataSet1ATIVO.AsBoolean then
ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 10,
Rect.Top + 1, 2)
else
ImageList1.Draw(DBGrid1.Canvas, Rect.Left + 10,
Rect.Top + 1, 1);
end;
end;

essa daqui permite que o usuário clique com o mouse


fazendo o checkbox mudar a figura.

procedure TForm1.DBGrid1CellClick(Column:
TColumn);
begin
if Column.Field = ClientDataSet1ATIVO then
begin
ClientDataSet1.Edit;
ClientDataSet1ATIVO.AsBoolean := not
ClientDataSet1ATIVO.AsBoolean;
end;
end;

essa daqui permite o grid ficar em modo edição para


modificar a figura

procedure TForm1.DBGrid1ColEnter(Sender:
TObject);
begin
if DBGrid1.SelectedField = ClientDataSet1ATIVO
then
DBGrid1.Options := DBGrid1.Options - [dgEditing]
else
DBGrid1.Options := DBGrid1.Options +
[dgEditing];
end;
Enviada por: Marcelo Otone Aguiar

Central Contábil - CPD


(27) 3200-8300
–––––––––––––-
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
839 - Converter Binario Para
Inteiro

Obtive resultados inesperados ao utilizar a função


BinToInt da biblioteca Strings 02. Essa função deveria
converter um número binário para um número inteiro,
mas não o faz corretamente. Estou enviando uma
função alternativa:

{Binário para Inteiro}


function BinToInt(Valor: string): LongInt;
var
i, Tamanho, np: Integer;
begin
Result := 0;
Tamanho := Length(Valor);
for i := 0 to Tamanho - 1 do
begin
np := strtoint(Valor[Tamanho - i]);
Result := Result + np * Trunc(Power(2, i));
end;
end;

OBS: é necessário inlcuir o pacote MATH em Uses para


utilizar a função Power.

Enviada por: Rogério Corrêa Magro

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
840 - Listar Arquivos de Um
Diretório

uma dica sobre como listar qualquer tipo de arquivos de


um diretorio. o toque especial dessa procedure e que ela
pode entrar em todos os diretorios que estão dentro do
diretorio inicial, para procurar arquivos do tipo
especificado.

parametros da procedure:

diretorioinicial - diretorio que a procedure comeca a sua


busca ex: c:\windows\ ou ainda c:\ mascara - mascara
de arquivo ex: *.txt ou ainda *.* listtotaldir - quando true,
ela fornece o caminho completo recursive - quando true,
ativa a busca do arquivo dentro de outros diretorios, que
estao dentro do diretorio inicial

obs.:O form que ira chamar esta função deve possuir


uma variavel global declarada da sequinte forma

listtemp2:Tstrings;

ele deve ser criada com o comando

listtemp2 := TstringList.Create;

depois de chamada a procedure o resultado final estara


nesta variavel

procedure ListarArquivos(diretorioInicial, mascara:


string; listtotaldir: boolean = false; recursive: boolean
= true);
var
i: integer;
listatemp: TStrings;
procedure ListarDiretorios(Folder: string; lista:
Tstrings);
var
Rec: TSearchRec;
i: integer;
temps: string;
begin
lista.Clear;
if SysUtils.FindFirst(Folder + ‘*’, faDirectory, Rec)
= 0 then
try
repeat
lista.Add(rec.Name);
until SysUtils.FindNext(Rec) <> 0;
finally
if lista.count <> 0 then
begin
// deleta o diretorio ..
lista.Delete(1);
// deleta o diretorio .
lista.Delete(0);
i := 0;
//deleta os arquivos isto e fica apenas os diretorios
if lista.count <> 0 then
begin
repeat
temps := lista.Strings[i];
temps := extractfileext(temps);
if temps <> ” then
lista.Delete(i)
else
inc(i);
until i >= lista.Count;
end;
end;
end;
end;

procedure ListarAtahos(Folder, mask: string; Lista:


Tstrings);
var
Rec: TSearchRec;
begin
lista.Clear;
if SysUtils.FindFirst(Folder + mask, faAnyFile, Rec)
= 0 then
try
repeat
lista.Add(rec.Name);
until SysUtils.FindNext(Rec) <> 0;
finally
SysUtils.FindClose(Rec);
end;
end;

procedure AddLIstInOther(ListSource, ListDestino:


TStrings);
var
f: integer;
begin
for f := 0 to ListSource.Count - 1 do
begin
ListDestino.Add(ListSource.Strings[f]);
end;
end;
begin
listatemp := TStringList.Create;
ListarAtahos(diretorioInicial, mascara, listatemp);
if listtotaldir = true then
begin
for i := 0 to listatemp.Count - 1 do
begin
listatemp.Strings[i] := diretorioInicial +
listatemp.Strings[i];
end;
end;
AddLIstInOther(listatemp, listtemp2);
if recursive = true then
begin
ListarDiretorios(diretorioInicial, listatemp);
for i := 0 to listatemp.Count - 1 do
begin
ListarArquivos(diretorioInicial +
listatemp.Strings[i] + ‘', mascara, listtotaldir, recursive);
end;
end;
listatemp.Free;
end;

exemplo:
coloca-se um listbox, e um button no form.
depois declara-se a variavel global no form
ex:

var
Form1: TForm;
listtemp2: TStrings;

e no evento onclick do button a seguinte procedure


listtemp2 := TStringList.Create;
ListarArquivos(‘c:\windows', ‘*.exe’, true, true);
listbox1.items := listtemp2;
listtemp2.free;

Enviada por: Cleiton S. Goulart

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
841 - Cria Um Mainmenu Via Bd
Automaticamente
{
Cria um “MainMenu” via banco de dados
automaticamente
-> Arquivo MENUS.DBF
Campos -> Campo Character 20 -> Nome do
campo
Sequencia Character 1 ->
1,2,3,…
Ordem Character 1 -> 1,2,3,…
Flag Boolean -> .T. ou .F.
CampoNN Character 20 -> Nome
do SubCampo
FlagNN Boolean -> .T. ou .F.
-> Índice = ‘Sequencia + Ordem’
Desenvolvido em Clipper/Dbase, função
Achoice()
Convertido para Delphi 7.0 em
20/Agosto/2004
}
unit MenuPas;

interface

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls,
Menus, Grids, DBGrids,
DB, DBTables, ExtCtrls, DBCtrls,
Buttons;

type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
Button1: TButton;
BitBtn1: TBitBtn;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1: TDataSource;
Table1: TTable;
Table1CAMPO: TStringField;
Table1SEQUENCIA: TStringField;
Table1ORDEM: TStringField;
Table1FLAG: TBooleanField;
Table1CAMPO01: TStringField;
Table1CAMPO02: TStringField;
Table1CAMPO03: TStringField;
Table1CAMPO04: TStringField;
Table1CAMPO05: TStringField;
Table1FLAG01: TBooleanField;
Table1FLAG02: TBooleanField;
Table1FLAG03: TBooleanField;
Table1FLAG04: TBooleanField;
Table1FLAG05: TBooleanField;
procedure Button1Click(Sender:
TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender:
TObject);
var
NewItem: TMenuItem;
X, I, K: integer;
XCampo: string;
XFlag: Boolean;
begin
Table1.First;
K := Table1SEQUENCIA.AsInteger;
while (K <= 1000) and not Table1.Eof do
begin
K := Table1SEQUENCIA.AsInteger;
NewItem :=
TMenuItem.Create(MainMenu1);
try
NewItem.Caption :=
Table1CAMPO.Value;
NewItem.Enabled := Table1FLAG.Value;
MainMenu1.Items.Add(NewItem);
except
NewItem.Free;
raise; { reraise the exception }
end;
Table1.Next;
I := K;
while (I = K) and not Table1.Eof do
begin
NewItem := TMenuItem.Create(Self);
try
NewItem.Caption :=
Table1CAMPO.Value;
NewItem.Enabled :=
Table1FLAG.Value;
MainMenu1.Items[K -
1].Add(NewItem);
X := 1;
while (X <= 5) do
begin
XCampo := ”;
XFlag := False;
if (X = 1) then
begin
XCampo := Table1CAMPO01.Value;
XFlag := Table1FLAG01.Value;
end
else if (X = 2) then
begin
XCampo := Table1CAMPO02.Value;
XFlag := Table1FLAG02.Value;
end
else if (X = 3) then
begin
XCampo := Table1CAMPO03.Value;
XFlag := Table1FLAG03.Value;
end
else if (X = 4) then
begin
XCampo := Table1CAMPO04.Value;
XFlag := Table1FLAG04.Value;
end
else if (X = 5) then
begin
XCampo := Table1CAMPO05.Value;
XFlag := Table1FLAG05.Value;
end;
if XCampo <> ” then
begin
NewItem :=
TMenuItem.Create(Self);
try
NewItem.Caption := XCampo;
NewItem.Enabled := XFlag;
MainMenu1.Items[K -
1].Items[Table1ORDEM.AsInteger -
1].Add(NewItem);
except
NewItem.Free;
raise; { reraise the
exception }
end;
end;
Inc(X);
end;
except
NewItem.Free;
raise; { reraise the exception }
end;
Table1.Next;
K := Table1SEQUENCIA.AsInteger;
end;
end;
end;

end.

Enviada por: Clóvis Vigari Vento

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
842 - Como Salvar o Relatório do
Qr Em Imagens Jpg Ou Bmp

Neste exemplo salvamos as páginas do relatório em


arquivos .JPEG ou .BMP.

uses jpeg;

procedure QrpToImg(QR: TQuickRep; Path: string;


Tipo: Integer);
var
BMP: TBitmap;
JPG: TJPegImage;
aUnits: TQRUnit;
i: Integer;
begin
// Gera o relatório em memória.
QR.Prepare;
// Pega unidade de medida atual no QReport.
aUnits := QR.Units;
// Altera unidade de medida para Pixels.
QR.Units := Pixels;
try
for i := 1 to QR.QRPrinter.PageCount do
begin
// Cria Bitmap.
BMP := TBitMap.Create;
// Cria JPeg.
JPG := TJPegImage.Create;
try
// Define tamanho do Bitmap de acordo com o
tamanho da página do QReport.
BMP.Width := Round(QR.Page.Width);
BMP.Height := Round(QR.Page.Length);
// Pegar página a página.
QR.QRPrinter.PageNumber := i;
// Atribui a página ao Bitmap.
BMP.Canvas.Draw(0, 0, QR.QRPrinter.Page);
// Transfere também para JPeg.
JPG.Assign(BMP);
// Salvar em disco.
if Tipo = 0 then
BMP.SaveToFile(Path + ‘Pagina’ + IntToStr(i) +
‘.bmp’)
else if Tipo = 1 then
JPG.SaveToFile(Path + ‘Pagina’ + IntToStr(i) +
‘.jpg’);
finally
// Libera objetos.
BMP.Free;
JPG.Free;
end;
end;
finally
// Volta unidade de medida.
QR.Units := aUnits;
end;
end;

Exemplo de Uso

procedure TForm1.Button1Click(Sender: TObject);


begin
//Exporta o Quick para BMP
QrpToImg(QuickRep1,‘c:',0);
//Exporta o Quick para JPG
QrpToImg(QuickRep1,‘c:',1);
end;
843 - Compilando a Aplicação Pelo
Ms-dos

Apenas a título de curiosidade, este texto explica como


criar um programa em Delphi a partir do zero, usando
somente o compilador do Delphi utilizado na linha de
comando (dcc32) e o prompt do dos. Para fazer o
programa, você precisará criar dois arquivos : teste.pas
(o programa propriamente dito) e teste.dfm (definicoes
do formulario). Primeiro, crie o programa teste.pas e
teste.dfm.

ARQUIVO: teste.pas
––––––––––––––––––-

program teste;

uses windows,sysutils,classes,forms,stdctrls;

type tfrm = class(tform)


button1 : tbutton;
constructor
create(aowner:tcomponent);override;
procedure button1click(sender:tobject);
end;

constructor tfrm.create(aowner:tcomponent);
begin
inherited create(aowner);
left:=(screen.width div 2)-width div 2;
top:=(screen.height div 2)-height div 2;
end;

procedure tfrm.button1click(sender:tobject);
begin
if button1.caption = ‘Clique’ then
button1.caption:=‘Aperte’
else
button1.caption:=‘Clique’;
end;

{$R *.dfm}

var frm : tfrm;

begin
application.initialize;
application.createform(tfrm,frm);
application.run;
end.

––––––––––––––––––-
ARQUIVO: teste.dfm
––––––––––––––––––-
object frm: tfrm
width = 350
height = 290
caption = ‘programa teste’
object button1: tbutton
caption = ‘Clique’
left = 20
top = 20
width = 100
height = 30
onclick = button1click
end
end
––––––––––––––––––-

Pense no arquivo .dfm como se fosse a janela de


propriedades do objeto. Caso você queira alterar cor,
alinhamento, etc, etc e etc, é só colocar no .dfm. Para
compilar, simplesmente digite na linha do prompt :

dcc32 teste

Pronto. Você terá, no mesmo diretório, um arquivo


chamado teste.exe, que é nada mais que o seu projeto
compilado.
844 - Capturar Erros e Enviar Por
E-mail

Pega todos os erros do Sistema, captura tela do erro,


grava em arquivo e envia por e-mail
Como montar uma rotina para pegar todos os erros do
sistema e capturar tela do erro e gravar em arquivo para
futura inspecao ou envio por e-mail. Coloque esta rotina
no menu principal de seu sistema.

unit Form_Menu;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
Menus, DB, ComCtrls, ExtCtrls, StdCtrls, Buttons,
Mask, DBTables,
DBIPROCS, DBITypes, DBIErrs, Gauges, ImgList,
ToolWin, jpeg, ExtDlgs;

type
TFrm_Menu = class(TForm)
MainMenu1: TMainMenu;

private
{ Private declarations }

procedure ManipulaExcecoes(Sender: TObject; E:


Exception);

public
{ Public declarations }
end;

var
Frm_Menu: TFrm_Menu;

implementation

//––––––––––––//
//…Rotina de manipulaco de erros //
//––––––––––––//

procedure TFrm_Menu.ManipulaExcecoes(Sender:
TObject; E: Exception);
var
BitMap: TBitmap;

begin
//…Captura e salva a tela atual do erro.
BitMap := TBitmap.Create;
BitMap := CaptureScreenRect(Bounds(0, 0,
Screen.Width, Screen.Height));
BitMap.SaveToFile(ExtractFilePath(Application.Exe
Name) + ‘erro.bmp’);
BitMap.Free;

//…Messagem de erro do sistema


MessageDlg(E.Message + #13#13 + ‘Suporte
técnico:’#13 + ‘aceinfo@starknet.com.br’, mtError,
[mbOK], 0);
end;

{$R *.DFM}
procedure TFrm_Menu.FormCreate(Sender: TObject);
begin
Application.OnException := ManipulaExcecoes;
end;

end.

Enviada por: Antônio Carlos

Retirada do E-Zine da Ramos Informática


–––––––––––––-
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
845 - Como Resolver o Erro
Qrstandpreview Already Exists
procedure QRDestroi;
var
nIdx: Integer;
begin
for nIdx := (Screen.FormCount - 1)
downto 0 do
with Screen.Forms[nIdx] do
if ClassName = ‘TQRStandardPreview’
then
Destroy;
end;
846 - Utilizando Threads

Por que utilizar threads ?

Muitas vezes nos deparamos com problemas que


necessitam de um “processamento paralelo” à nossa
aplicação. Seja para complexos controles de conexões
via sockets ou simplesmente fazendo uma bola quicar
pela tela, sempre haverão problemas para quais as
soluções podem ser facilmente encontradas utilizando-
se o recurso de threads. Infelizmente muitos
programadores acabam procurando outras soluções
pelo fato de não conhecê-las. Vemos programadores
utilizando o TTimer para executar funções que poderiam
ser executadas com mais segurança e confiabilidade por
threads, justamente por não estarem habituados a
utilizar este poderoso recurso.

Um exemplo simples

Suponhamos que você deseje criar um contador


completamente independente de sua aplicação, que
imprima em seu formulário esse valor. Criamos então
um objeto que controlará esta função, utilizando-se de
um processamento paralelo a nossa aplicação.

type

TMeuThread = class(TThread)

x: integer;
posx, posy: integer;
numero: integer;
procedure execute; override;
procedure contador;
constructor MeuConstrutor(x, y, numthread:
integer);
destructor destroy; override;

private
public

end;

O que fizemos até agora ?

Nós criamos uma classe chamada TMeuThread,


derivada de Tthread. Declaramos a variavel x, que
servirá para controle do contador. Declaramos então o
procedimento execute, que é na verdade o
procedimento principal de qualquer classe thread.

Uma thread utiliza, basciamente, a seguinte estrutura de


execução automaticamente:

create {constructor}

execute – (chamar nossa função atraves do


synchronize)

destroy {destructor}

Então vamos agora à implementação

constructor TMeuThread.MeuConstrutor(x, y,
numthread: integer);
begin
Create(false); {como definimos nosso construtor
personalizado, solicitamos que seja criada a classe
atraves do construtor padrão e então utilizamos os
métodos que definimos.
O valor (false) refere-se a forma do construtor:
constructor create(createsuspended:boolean);
O qual criará a thread em modo suspenso, ou seja,
devemos iniciar a execução da thread chamando o
metodo tthread.resume; }
freeonterminate := true; {“matar” este objeto
(TMeuThread) quando a thread terminar sua execução}
posx := x; {posicao left de onde imprimiremos o texto
da thread}
posy := y; {posicao top de onde imprimiremos o texto
da thread}
numero := numthread; {numero da thread em
execução}
end;

Em nosso exemplo, criamos um novo constructor


chamado MeuConstrutor. Por que fizemos isso? Porque
neste exemplo, queriamos que toda vez que o botão
fosse pressionado, a thread que estivesse sendo criada
imprimisse seu valor em um lugar diferente do
formulario. Por isso, precisavamos passar parametros
diferentes do parametro padrão do constructor create.

constructor create(createsuspended: boolean);

Como você pode perceber, não existem parâmetros


suficientes para o nosso caso específico, então criamos
nosso proprio construtor, herdando as funcionalidades
do const rutor padrão create.

procedure TMeuThread.execute;
begin
while not terminated do {equanto thread em
execucao…}
begin
synchronize(contador); {chamar o procedimento
contador. Utilize a chamada synchronize quando não
estiver certo de que não haverá mais de uma thread em
execução.}
sleep(10); {aguarde 10 milisegundos e entao
continue o processo. Assim evitamos o uso de 100% do
processador e ainda damos tempo a nossa aplicação
para que processe as mensagens do windows (no nosso
caso, wm_paint)}
end;
end;

Toda vez que chamarmos em nossa aplicação o


construtor MeuConstrutor, um novo objeto TMeuThread
será criado. Quando este objeto for criado, ele iniciaria
sua execução, passando pelo metodo execute. Dentro
do metodo execute, é necessario chamarmos o metodo
synchronize para manipularmos o que nossa thread
deve fazer. Isso é fundamental porque, pelo fato de que
estamos trabalhando com processamento, o que pode
fazer com que nossa thread se “perca” da aplicação
principal, gerando os mais estranhos erros, desde
acessos invalidos a memória até identificadores
invalidos. Esta regra vale para quando trabalhamos com
multi-thread. De qualquer maneira, não nos custa nada
proteger nosso codigo de erros indesejáveis.
procedure TMeuThread.contador;
begin
x := x + 1; {incrementa o valor de x}
form1.Canvas.TextOut(posy, posx, ‘Thread numero ‘
+ inttostr(numero) + ‘ - Valor de X = ‘ + inttostr(x));
{imprime o valor de x na posicao posx,posy e
informando o numero da thread em execução
(parametros passados durante a criação da thread,
atraves de nosso construtor personalizado
MeuConstrutor}
if x = 100000 then {se x= 100000 fim da função da
thread}
terminate;
end;

Pronto. Nossa classe TMeuThread está concluida e


pronta para ser utilizada. Não foi realmente difícil, foi ?
Agora basta utilizarmos.

Em sua classe Tform1 (supondo que seu formulario


principal chame-se FORM1, crie a seguinte variavel:

public

Thread: TMeuThread;


Coloque um TButton em seu formulário, dê um clique
duplo nele (para acessar o evento OnButtonClick).
Então coloque o seguinte código:

procedure TForm1.Button1Click(Sender: TObject);


begin
randomize(); {inicia o gerador de numeros
randomicos}
numthread := numthread + 1; {incrementa o valor de
minha thread}
Thread :=
TMeuThread.MeuConstrutor(random(form1.height),
random(form1.width), numthread); {cria a
classeThread passando por parametros a posx, posy e o
numero da thread que foi criada}
end;

E pronto, acabamos de criar uma programa que cria


threads em tempo de execução. Clicando uma vez no
botão, temos uma thread criada, sendo executada
paralelamente a nossa aplicação.

Enviada por: Snake_Ice

Retirada do E-Zine da Ramos Informática


–––––––––––––-
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
847 - Criando Log Básico Para
Qualquer Aplicação Delphi

Muitas vezes as mensagem de erro apresentada pelo


sistema quando escapou algum tratamento de exceção
fica complicado identificar o que esta acontecendo.
Segue abaixo um exemplo básico de como implementar
Log para apoiar a identificação de um erro que pode ser
empregado em qualquer aplicação.
- Adicionar o TApplicationEvents no Formulário
PRINCIPAL da aplicação.(Paleta:Additional do D7)
- Adicionar o código abaixo no evento onException do
componente.

var
NomeDoLog: string;
Arquivo: TextFile;
begin
NomeDoLog := ChangeFileExt(Application.Exename,
‘.log’);
AssignFile(Arquivo, NomeDoLog);
if FileExists(NomeDoLog) then
Append(arquivo) { se existir, apenas adiciona linhas
}
else
ReWrite(arquivo); { cria um novo se não existir }
try
WriteLn(arquivo, DateTimeToStr(Now) + ‘:’ +
E.Message);
WriteLn(arquivo, ‘–––––––––––––––––––––––-‘);
Application.ShowException(E);
finally
CloseFile(arquivo)
end;
end;

Será criado um arquivo como o nome da Aplicação e a


extensão “.LOG” no mesmo lugar que está alocado o
arquivo EXE.

Enviada por: Jose do Amparo Soares

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
848 - Tabela Para Texto (csv) Num
Piscar de Olhos

Esta Procedure funciona com BDE e DBExpress e com


todos os descendentes do TDataset (TQuery, TTable,
TClientDataSet, TSQLQuery, etc.).

procedure SaveAsCSV(myFileName: string;


myDataSet: TDataSet);
var
myTextFile: TextFile;
i: integer;
s: string;
begin
//cria um novo arquivo (com extensão CSV)
AssignFile(myTextFile, myFileName + ‘.csv’);
Rewrite(myTextFile);
s := ”; //inicializa uma string vazia
try
//coleta os nomes dos campos (cabeçalho das
colunas)
for i := 0 to myDataSet.FieldCount - 1 do
begin
s := s + Format(’”%s”’,
[myDataSet.Fields[i].FieldName]);
if i < (myDataSet.FieldCount - 1) then
s := s + ‘,’;
end;
Writeln(myTextFile, s);
//cria uma linha em branco
Writeln(myTextFile, ”);
//grava os valores dos campos
while not myDataSet.Eof do
begin
s := ”;
for i := 0 to myDataSet.FieldCount - 1 do
begin
s := s + Format(’”%s”’,
[myDataSet.Fields[i].AsString]);
if i < (myDataSet.FieldCount - 1) then
s := s + ‘,’;
end;
Writeln(myTextfile, s);
myDataSet.Next;
end;
finally
CloseFile(myTextFile);
end;
end;

Onde:
myFileName = Nome do Arquivo a ser criado
myDataSet = Nome da tabela ou descendente

Modo de usar:

SaveAsCSV(‘TabelaClientes’, tblClientes);

Dica: Você pode importar os arquivos CSV diretamente


para o EXCEL, por se tratar de um arquivo delimitado
por “,” (vírgula).
Enviada por: Jose do Amparo Soares

Um colaborador da DTDelphi 2.7


Colabore você com a próxima edição!
849 - Mudando o Ip da Máquina Via
Api do Windows

Como posso mudar meu IP? via API?A resposta para


essa pergunta é não neste artigo estou unsando o
Delphi 7, mas pode ser feito com qualquer outra versão
do delphi. nos Windows 2000 e XPexiste um aplicativo
chamado NETSH que faz essa mudança para nós sem
queprecisemos reiniciar o computador. bem vamos por a
mão na massa e brincarmos umpouco com as
configurações de IP.Mudando a Configuração para
DHCP:Crie uma aplicação no Delphi, NEW ->
Application no FormDesigner ponha umTButton e no
evento OnClick escreva o seguinte código:

if Win32Plataform = VER_PLATAFORM_WIN32_NT
then
WinExec(‘cmd /c netsh interface ip set
address”Conexão local” DHCP’,
SW_SHOWNORMAL)
else
MessageBox(Handle, ‘esse Comando não pode ser
rodado fora da plataforma NT’, ‘NETSH’,
MB_ICONWARNING);

onde verifico se a plataforma do Programa é uma


plataforma NT, caso contrárioinformo ao usuário que
esse comando não pode ser rodado fora de uma
plataforma NT.Mudando as Configurações dos IPs da
máquina,menos os DNS:Na mesma aplicação do
exemplo acima Ponha outro TButton e no Evento
OnClick dele escreva:
if Win32Plataform = VER_PLATAFORM_WIN32_NT
then
WinExec(‘cmd /cnetsh interface ip set address
“Conexão local” static 192.168.10.104255.255.255.0
192.168.10.1 1’, SW_SHOWNORMAL)
else
MessageBox(Handle, ‘esse{Comando não pode ser
rodado fora da plataforma NT’, ‘NETSH’,
MB_ICONWARNING);

Pronto seu IP, SubnetMask e Gateway foram mudados.


Para maiores informações sobre o NETSH visite o site
da Microsoft: Suporte Microsoft.

Enviada por: José Roberto F. de Araújo Junior

Programador e Analista de Sistemas da PCA


Sistemas LTDA em Olinda - Pernambuco.
Desenvolvo Aplicações Cliente-Servidor com
Banco de dados Interbase, Firebird1.5 RC4
e MS SQL Server.
Retirada do E-Zine da Ramos Informática
–––––––––––––-
Um colaborador da DTDelphi 2.7
Colabore você com a próxima edição!
850 - Texto Na Diagonal e Girando
procedure TForm1.Button1Click(Sender:
TObject);
var
lf: TLogFont;
tf: TFont;
i: integer;
begin
with Form1.Canvas do
begin
Font.Name := ‘Verdana’;
Font.Size := 16;
tf := TFont.Create;
tf.Assign(Font);
GetObject(tf.Handle, sizeof(lf), @lf);
lf.lfOrientation := 1000;
end;
for i := 900 downto 1 do
begin
lf.lfEscapement := i;
tf.Handle := CreateFontIndirect(lf);
Form1.Canvas.Font.Assign(tf);
Form1.Canvas.TextOut(200, Height div
2, ‘LloydSoft’);
//Sleep(10); //Este pode cria um Delay
na execução
end;
tf.Free;
end;
Lista de Alguns dos Exemplos
Arquivo Descrição

Geral
Calorias Exemplo de como fazer a comunicação entre
dois ListBox
CooCalc Uma calculadora “Pauleira!”
CursorMemo Como obter a posição do cursor em um
componente TMemo
Combinação Exemplo de como retornar o item de um
Combobox
DifData Como obter a diferença entre duas Datas e
Duas horas
Distancia Exemplo de como obter a distância em
metros.
Lista Exemplo de como inserir um item em um
listbox
Marquee Exemplo de como criar um Banner controlado
Selecao Exemplo de como Selecionar um item de um
listbox
SomaMes Exemplo de como somar meses à uma data
especificada
Ultdia Exemplo de como obter o último dia do mês
Mirror Exemplo de um Espelho muito “Doidão”
Calendar Exemplo de um Calendário muito bom
QuickReport Varios exemplos para você fazer relatórios
com o QuickReport
Relatorios Como trabalhar com relatorios via QuickReport
ou Tprinter
NewCal Como chamar uma calculadora
CgiDelphi Exemplo de como usar CGI no delphi
DDE Como fazer dois programas se comunicarem
entre si
HoraSeg Como converter horas em segundos e
segundos em horas
Mensagens Programa de manipulação de mensagens em
rede
CriaComp Como criar um componente em tempo de
execução
Relógio Um Relogio Bacana
CombSgrid Como inserir um ComboBox dentro de um
StringGrid
RunTime Como mover um componente em Run-Time
ScrolList Como colocar um ScrollBar em um
componente ListBox.
FTP Exemplo de um FTP com Delphi
TreeView Como usar um panel no estilo Windows
Explorer
Parser Como enviar o conteúdo de um Edit para um
MEMO
DragDrop Exemplo do método DragDrop
DragDropDem Outro exemplo do método DragDrop
DragDrop1 Outro bom exemplo de como usar o Evento
Drag’n Drop
DragDrop3 Outro bom exemplo de como usar o Evento
Drag’n Drop
DragDropTB Exemplo de como arrastar um botão para a
Barra de ferramentas
MacroSubst Exemplo de Macrosubstituição
Chat Exemplo de chat
Calculadora Um bom exemplo de Calculadora
CodeApp Um utilitário para manipular código fonte
pascal
Cryt Exemplo de um encriptador de dados
DemoCursor Exemplo de como manipular os cursores do
mouse
FlyToolBar Exemplo de como criar uma barra de tarefas
flutuante
Install Exemplo de como criar um programinha de
instalação
LinColMemo Exemplo de como obter linha e coluna em um
Memo
MenuEx97 Exemplo de como fazer um menu igual ao do
Office 97
Register Exemplo de como não permitir que seu demo
rode fora do Delphi
SpeedButton Um bom exemplo com os SpeedButons

Forms
Exemplo de como fazer um banner em um
LabelMovel
form
Exemplo de como passar parâmetros de um
ParametForm
form para outro
Como manipular variaveis entre dois ou mais
VarInvisible
forms
FormDinamic Como criar formulários dinamicos
Exemplo de como colar no form, uma figura da
ClipBoard
area de transferência
DibTest Exemplo de como criar um Form Exótico
Como colocar um bitmap lado a lado no fundo
BitmpaForm
de um form
Exemplo de como bloquear o
RestrictSize
redimensionamento do Form
CircleForm Exemplo de como criar um form circular
FrameForm Exemplo de como colocar frames em um form
Exemplo de como desenhar um poígono em
Poligon
um form
Exemplo de como criar um menu PopUp em
PopUp
um form
DifLinhas Exemplo de como desenhar linhas no form
Como colocar um Bitmap no fundo do Form
FormBitmap
pela API do Windows
Outro exemplo de como colocar um Bitmap no
TBitmaPlus
fundo do Form
Como suspender a animação de minimizar e
FormTake
maximizar o form
Exemplo de como copiar o Form para a área
CopyClipBrd
de transferência
MoveForm Exemplo de como mover um form clicando em
qualquer lugar nele
ScreenSBit Exemplo de como carregar Bitmpas no Form
Como criar um Form que role na tela
RolupForm
semelhante à uma persiana
Exemplo de como criar um cubo rotatório no
RotateCube
form
Como obter posições de figuras no form com o
Region
mouse
Exemplo de como desenhar ondas senoidais
SineWave
no Form

Arquivos

W95Files Um Bom exemplo de como copiar arquivos


Win95Files Mais dois exemplos de como copiar arquivos
TextFile Exemplo de como manipular um arquivo Texto
Exemplo de como procurar um texto em um
Search
arquivo
FileCompare Exemplo de como comparar dois arquivos
Exemplo de como exibir os arquivos em uma
FileList
janela
Exemplo de como criar um arquivo .Avi em
AviCreate
codigo Delphi
Como efetuar uma procura de arquivos em um
DirList
diretorio
Wntdy202 Exemplo de Busca e deleção de arquivos
CopyFiles Um Bom exemplo de como copiar arquivos
Exemplo de um gerenciador de atributos de
Attribute
arquivos
IniFile Exemplo de como gerar um arquivo INI

Sistema
Empresa Como obter o nome do usuário registrado no
windows
TaskList Exemplo de como criar uma lista de tarefas
Como obter os Drives do computador em um
TipoDrv
componente TMemo
Como obter dados da CPU em um
WindFlag
componente TMemo
Exemplo de como enviar mensagems para o
WinMsg
Windows
Como obter os recursos do sistema (Acho que
ResWatch
só roda no Delphi 3)
CriaGrupo Como criar grupo de programa e ícones
SysInfo Exemplo de como obter os dados do sistema
Exemplo de como trocar automaticamente a
ChangeRes
resoluçào do vídeo
CpuIdent Exemplo de como obter dados da CPU
CriaAtalho Exemplo de como criar um atalho no Windows
Exemplo de como Testar a velocidade de um
DiskBeench
drive
MapMemory Exemplo de como A memoria é mapeada
Exemplo de como testar uma porta serial em
PortTest
seu computador
Exemplo de como enviar mensagens para o
SendMessage
Windows
Serial D1 Como obter o numero serial do HD no Delphi 1

Tabelas

Como converter uma tabela paradox em Txt e


DBpTXT
vice versa
Exemplo de como trabalhar com filtros em
Filter
tabelas
Outro exemplo de como trabalhar com filtros
Filtro
em tabelas
TableGenerate Gera um código para criar uma tabelas
TableScanner Outro gerador de código para criar tabelas
GetStructure Extrai a estrutura de tabelas Paradox de um
determinado diretório
Importa dados de um DBF para um Interbase
DbfToSql
SQL
Exemplo de como tratar a Exceção
KeyViolation
KeyViolation
Convet Conterte Tabelas Dbase em Paradox
Pedaço Como filtrar uma tabela por partes de um dado
Exemplo de como relacionar tabelas em
Relaction
Delphi
DBGrid Como retornar a celula ativa de um DBGrid
Como mudar a cor de uma célula de um
CorGrid
DBGrid
Como Navegar por uma tabela com a filosofia
BotNavigator
do DBNavigator
Pequeno programinha para reindexar tabelas
Reindex
(C/Interface e tudo)
Exemplo do método DragDrop aplicado em
DBDragDrop
uma tabela
Exemplo do método DragDrop aplicado em
DBDragDrop2
uma tabela
LiveQuery Exemplo de Uso de Filtro em um Query
MSelDBGrid Exemplo de multiseleção em um DBGrid
CopySort Exemplo de como copiar tabelas cheias
CreateData Exemplo de como criar uma tabela
Exemplo de como manipular a integridade
IReferencial
referencial de uma tabela

Variáveis

Maior Exemplo de como comparar dois números


Round Como manipular variáveis de ponto flutuante
Exemplo que retorna o valor Ascii de um
AsciiConv
caractere
Exemplo de como converter um Numero em
Translate
seu extenso
Multimídia

Exemplo de como trabalhar com o


MPlayer
componente Media Player
Outro exemplo de como trabalhar com o
XPlayer
componente Media Player
CD-Player Exemplo de como fazer um CD-Player
Exemplo de como incomporar um Arquivo Wav
SoundExe
no Executável

Gráficos

Graphics Exemplo de como manipular Gráficos


Exemplo de como colocar Bitmaps em um
MenuBitmap
Menu
Exemplo de como manipular imagens Gif’s
GifManager
inclusive animados
Exemplo de como converter um ícone em um
IconToBmp
Bitmap
Dll para ser inserida no Explorer. Exibe os
BmpProp
dados de um Bitmap
Como colocar bitmaps em um ListBox e em
BtListBox
um ComboBox
MixUp Exemplo de como desmontar um Bitmap
Exemplo de como colocar um Icone animado
MoveIcon
em um form
PieChart Exemplo de como usar o TChart
Imprime um Bitmap e todas as suas
TstPr2Fm
características
Exemplo de como converter uma string em
RtfToBmp
Bitmap
Jogos

Asteroids Copia do Jogo Asteroids


Bloco Copia do famoso Tele-jogo (Alguem lembra?)
Bricks Copia do Jogo Bricks
Cobrinha Famoso jogo da cobrinha
Doom Simulador do Jogo Doom
Jodo da Velha Copia do Jogo da velha :)
Missil Copia do Jogo Missil
Nave Jogo de nave :) (Simples)
Nave 2 Jogo de Nave
Tetris Copia do Jogo Tetris

Outros

CrazyII Sistema para video locadora


SisInfo Sistema para loja de informatica
Biblioteca Sistema para bibliotecas
ACMSys Sistema para Academias
Agenda-
Agenda
Delphi
Estoque Programa de estoque
LivroCaixa Sistema de Livro Caixa
locadora Sistema para video locadora
Vendas Sistema para loja
Hack Como controlar outro computador via rede
Socket Comunicação em rede usando Sockets
Validade Programa com Limitação por data
SendMail Envio de email com Delphi
ScreenSV Proteção de tela
Thread Exemplificando o uso de threads
MP3player Tocador de MP3
CShow Programa igual ao do Show do milhão
E ainda mais 90 exemplos aqui não
relacionados!!!
Voltar
Voltar

Você também pode gostar