Você está na página 1de 138

Como?

161- Change the StringGrid's CELL color ?


160 - A listbox in a cell of a stringgrid
159 - Pintar um Bitmap diretamente no Canvas do Form
158 - Verificar se a impressora está ligada
157 - Obter a letra do drive onde está o Windows
156 - Mostrar o nome do EXE no caption do form
155 - Fazer pesquisa incremental apenas com DBGrid
154 - Obter tipo de uma propriedade
153 - Consulta SQL que usa a data do sistema
152 - Abrir uma conecção Dial-Up
151 - Pintar uma imagem JPG no form
150 - Executar comando do MS-DOS
149 - Formatar CEP
148 - Permitir cancelar processo demorado
147 - Descobrir se uma data é fim do mês
146 - Programar teclas de atalho do Windows
145 - Obter o tipo de dado de um valor no Registro do Windows
144 - Obter a célula de um StringGrid que está sob o cursor do mouse
143 - Limpar todas as células de um StringGrid
142 - Programar meu aplicativo para abrir arquivos a partir do Windows Explorer
141 - Consultar por mês de um campo data
140 - Criando tabelas via SQL
139 - Obter nomes dos campos de uma tabela
138 - Nomeando um relatório no spool de impressão do Windows
137 - Obter tamanho de um arquivo
136 - Ocultar aplicação da lista de tarefas - CTRL+ALT+DEL
135 - Obter path de um Alias do BDE
134 - Ativar a proteção de tela do Windows
133 - Desligar/Ligar monitor
132 - Abrir e fechar o drive de CD-ROM
131 - Impedir que o form seja arrastado para fora das margens da tela
130 - Mostrar mensagem mesmo que esteja no Prompt do DOS
129 - Copiar todos os registros de uma tabela para o Clipboard
128 - Copiar um registro de uma tabela para o Clipboard
127 - Criar sub-diretório no diretório do EXE
126 - Ocultar o aplicativo do CTRL+ALT+DEL
125 - Personalizar a caixa de mensagem de exceções (erro) do Delphi
124 - Implementar procedure Delay do Pascal no Delphi
123 - Enviar comandos de rolagem vertical para um TMemo
122 - Criar uma DLL de Bitmaps e usá-la
121 - Construir a barra de título do form com um Panel
120 - Criar form sem título que possa ser arrastado
119 - Obter status da memória do sistema
118 - Definir data/hora de um arquivo
117 - Mostrar o diálogo About (Sobre) do Windows
116 - Ocultar/exibir o cursor do mouse
115 - Converter de Hexadecimal para Inteiro
114 - Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condição
113 - Colocar uma ProgressBar da StatusBar
112 - Executar um programa e aguardar sua finalização antes de continuar
111 - Simular o pressionamento de uma combinação de teclas (ex: Ctrl+F2)
110 - Simular o pressionamento de uma tecla
109 - Ligar/desligar a tecla Caps Lock
108 - Verificar se uma determinada tecla está pressionada
107 - Verificar o estado de NumLock e CapsLock
106 - Configurar linhas de diferentes alturas em StringGrid
105 - Adicionar o evento OnClick do DBGrid
104 - Criar caixas de diálogo em tempo de execução
103 - Converter a primeira letra de um Edit para maiúsculo
102 - Verificar se uma string contém uma hora válida
101 - Verificar se uma string contém um valor numérico válido
100 - Mostrar uma mensagem durante um processamento
99 - Mostrar um cursor de ampulheta durante um processamento
98 - Ler e escrever dados binários no Registro do Windows
97 - Mudar a resolução do vídeo via programação
96 - Ler e escrever dados no Registro do Windows
95 - Adicionar barra de rolagem horizontal no ListBox
94 - Simular um CharCase no DBGrid
93 - Verificar se uma string é uma data válida
92 - Fazer pesquisa incremental com DBGrid e Edit
91 - Adicionar zeros à esquerda de um número
90 - Limpar um campo tipo data via programação
89 - Implementar um campo auto-incremental via programação
88 - Obter o endereço IP do Dial-Up
87 - Exibir a caixa de diálogo padrão de solicitação de senha do banco de dados
86 - Obter a versão da biblioteca ComCtl32.DLL (usada na unit ComCtrls do Delphi)
85 - Implementar rotinas assembly em Pascal
84 - Exibir o diálogo About do Windows
83 - Obter a linha e coluna atual em um TMemo
82 - Exibir um arquivo de ajuda do Windows
81 - Obter o valor de uma variável de ambiente
80 - Determinar se uma janela (form) está maximizada
79 - Determinar se o cursor do mouse está em determinado controle
78 - Determinar se o aplicativo está minimizado
77 - Fechar um aplicativo com uma mensagem de erro fatal
76 - Usar o evento OnGetText de um TField
75 - Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas
74 - Verificar, via programação, se Local Share do BDE está TRUE
73 - Criar um EXE que seja executado apenas através de outro EXE criado por mim
72 - Resolver "Internal error near: IBCheck" do Interbase 5.1.1 Server no NT
71 - Inverter os botões do mouse
70 - Obter/definir o tempo máximo do duplo-click do mouse
69 - Obter os atributos de um arquivo/diretório
68 - Obter o espaço total e livre de um disco
67 - Obter o tipo de um drive (removível, fixo, CD-ROM, unidade de rede, etc)
66 - Obter informações de um volume/disco (label, serial, sistema de arquivos, etc)
65 - Alterar o nome de volume (Label) de um disco
64 - Saber quais as unidades de disco (drives) estão presentes
63 - "truncar" valores reais para apenas n casas decimais
62 - Excluir todos os registros de uma tabela (como DELETE ALL do Clipper)
61 - Saber se o sistema está usando 4 dígitos para o ano
60 - Imprimir caracteres acentuados diretamente para a impressora
59 - Imprimir texto justificado com formatação na impressora Epson LX-300
58 - Formatar um disquete através de um programa Delphi
57 - Alterar (e restaurar) o tamanho da página na impressora
56 - Reproduzir um arquivo de som WAV sem o TMediaPlayer
55 - Obter o nome do usuário e da empresa informado durante a instalação do Windows
54 - Mostrar uma barra de progresso enquanto copia arquivos
53 - Copiar arquivos usando o Shell do Windows
52 - Descobrir o código ASCII de uma tecla
51 - Evitar que seu programa apareça na barra de tarefas
50 - Usar eventos de som do Windows
49 - Mudar a coluna ativa em um DBGrid via programação
48 - Fechar o Windows a partir do seu programa
47 - Carregar um cursor animado (.ani)
46 - Enviar um arquivo para a lixeira
45 - Obter o número do registro atual
44 - Trabalhar com Filter de forma mais prática
43 - Reproduzir um arquivo WAV
42 - Executar um programa DOS e fechá-lo em seguida
41 - Fechar um programa a partir de um programa Delphi
40 - Colocar Hint's de várias linhas
39 - Reproduzir um vídeo AVI em um Form
38 - Separar (filtrar) caracteres de uma string
37 - Colocar zeros à esquerda de números
36 - Copiar arquivos usando curingas (*.*)
35 - Copiar arquivos
34 - Trabalhar com cores no formato string
33 - Verificar se determinado programa está em execução (Word, Delphi, etc)
32 - Excluir arquivos usando curingas (*.*)
31 - Gerar uma tabela no Word através do Delphi
30 - Obter a quantidade de registros total e visível de uma tabela
29 - Evitar que um programa seja executado mais de uma vez
28 - Executar um "COMMIT" no Delphi
27 - Posicionar Form's em relação ao Desktop do Windows
26 - Saber a resolução de tela atual
25 - Verificar se uma unidade de disco (disk-drive) está preparada
24 - Salvar/restaurar o tamanho e posição de Form's
23 - Definir a quantidade de registros a ser impressa em uma página do QuickReport
22 - Onde encontrar tutoriais sobre construção de componentes em Delphi
21 - Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do TStringGrid
20 - Mostrar um Form de LogOn antes do Form principal
19 - Limitar a região de movimentação do mouse
18 - Descobrir o nome de classe de uma janela do Windows
17 - Ocultar/exibir a barra de tarefas do Windows
16 - Evitar a proteção de tela durante seu programa
15 - Fazer a barra de título ficar intermitente (piscante)
14 - Posicionar o cursor do mouse em um controle
13 - Criar cores personalizadas (sistema RGB)
12 - Adicionar uma nova fonte no Windows
11 - Saber se a impressora atual possui determinada fonte
10 - Saber se determinada Font está instalada no Windows
9 - Acertar a data e hora do sistema através do programa
8 - ENTER em vez de TAB no formulário, no DBGrid e no StringGrid
7 - Simular a vírgula através do ponto do teclado numérico
6 - Paralizar um programa durante n segundos
5 - Criar uma tabela (DB, DBF) através do seu programa
4 - Verificar se um diretório existe
3 - Verificar se um arquivo existe
2 - Criar um Alias temporário através do seu programa
1 - Criar um Alias através do seu programa
159 - Pintar um Bitmap diretamente no Canvas do Form

- Declare a variavel Bmp na seção private:

private
Bmp: TBitmap;

- Coloque um botão no Form e no evento OnClick digite:

Bmp:= TBitMap.Create;
try
Bmp.LoadFromFile('c:\teste\arquivo.bmp');
Canvas.Draw(0,0, Bmp);
finally
Bmp.Free;
end;

Pronto! Irá aparecer a imagem no Canvas. É útil para fazer


animações.

Dica enviada por: Alisson Viana Jardim


Revisada por: Daniel Pereira Guimarães

158 - Verificar se a impressora está ligada

Problema:

Faço impressão direta para a porta da impressora e gostaria


testar se a impressora está pronta antes de enviar o
relatório. Isto é possível em Delphi?

Solução:

Usando instruções Assembly podemos fazer isto. A função


abaixo retorna true se a porta informada está pronta.

Os possíveis parâmetros para esta função são:


1- para LPT1
2- para LPT2
3- para LPT3
4- para LPT4

function tbTestLPT(Port: byte): boolean;


var
Pto : Word;
Rdo : byte;
begin
Pto := Port -1;
asm
MOV DX,Pto
MOV AX,$0200 {AH := $02 : Leer el estado de la impresora}
INT $17
MOV Rdo,AH {Guarda el estado en AL}
end;
Result := Rdo = 144;
end;
Observações
Provavelmente esta função não funcionará em Windows NT devido ao acesso em baixo nível.

157 - Obter a letra do drive onde está o Windows


Inclua na seção uses: Windows

Problema:

Como saber em qual unidade de disco (drive) o Windows está


instalado?

Solução:

Esta função retorna a letra do drive onde está instalado o


Windows:

function GetWindowsDrive: Char;


var
S: string;
begin
SetLength(S, MAX_PATH);
if GetWindowsDirectory(PChar(S), MAX_PATH) > 0 then
Result := string(S)[1]
else
Result := #0;
end;

{ Exemplo de uso: }

procedure TForm1.Button1Click(Sender: TObject);


begin
Caption := GetWindowsDrive;
end;

156 - Mostrar o nome do EXE no caption do form

{ Esta função extrai apenas o nome do arquivo passado,


sem path e extensão }

function Titulo(Nome: String): String;


var
N, D: String;
begin
N := ExtractFileName(Nome); { Retira o path }
D := ChangeFileExt(N,''); { Retira a extensão }
{ Coloca a primeira letra em maiúscula e o resto
em minúscula }
Titulo := UpperCase(Copy(D,1,1)) +
LowerCase(Copy(D,2,Length(D)-1));
end;

{ No OnCreate do form, coloque: }

procedure TForm1.FormCreate(Sender: TObject);


begin
Caption := Titulo(ParamStr(0));
end;

- Dica enviada por: Luiz Eduardo.

155 - Fazer pesquisa incremental apenas com DBGrid

Problema:

Gostaria de fazer um formulário de pesquisa que, ao digitar


algo sobre o DBGrid, o registro correspondendo fosse
localizado.

Solução:

- Coloque no form: TTable, TDataSource, TDBGrid e TLabel.

- Ajuste as propriedades do Table1:


DatabaseName =
TableName =
Active = true

- Ajuste as propriedades do DataSource1:


DataSet = Table1

- Ajuste as propriedades do DBGrid1:


DataSource = DataSource1
Options -> dgEditing = false
ReadOnly = true

* Pode também ajustar a propriedades Columns para escolher


as colunas que serão exibidas.

- Na seção private da unit declare:


private
FTexto: string;

- No evento OnCreate do form coloque:


FTexto := '';
Label1.Caption := '';

- No evento OnKeyPress do DBGrid1:


procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if Key in [#8, #32..#255] then begin

if Key = #8 then { BackSpace }


FTexto := Copy(FTexto, 1, Length(FTexto)-1)
else
FTexto := FTexto + Key;

{ Posiciona na coluna Nome }


Table1.FieldByName('Nome').FocusControl;

{ Escolhe o índice e procura }


Table1.IndexFieldNames := 'Nome';
Table1.FindNearest([FTexto]);

{ Mostra o texto procurado }


Label1.Caption := FTexto;
end;
end;
Observações
No nosso exemplo estamos pesquisando através do campo "Nome". Para esta pesquisa
precisamos de um índice com este campo.

154 - Obter tipo de uma propriedade


Inclua na seção uses: TypInfo

{ Esta função retorna uma string com o nome do tipo de dado


de uma propriedade. Exemplos de retornos:

PropType(Button1, 'Caption'); // Retorna 'TCaption'


PropType(Edit1, 'Width'); // Retorna 'Integer';
PropType(Edit1, 'Color'); // Retorna 'TColor';
}

function PropType(const Obj: TObject; const PropName: string): string;


var
Info: PPropInfo;
begin
Info := GetPropInfo(Obj.ClassInfo, PropName);
if Assigned(Info) then
Result := Info^.PropType^.Name
else
Result := '';
end;

{ Exemplo de uso:
- Coloque um TButton e um TEdit;
- No OnClick do Button1 coloque o código abaixo;
- Execute, digite 'Caption' no Edit1 e clique em Button1.
}
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(PropType(Button1, Edit1.Text));
end;
Observações
Verdadeiramente não sei exatamente onde poderíamos aplicar esta dica, mas divulguei-a
porque achei interessante. Acredito que o Object Inspector use algo parecido.

153 - 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.

152 - Abrir uma conecção Dial-Up


Inclua na seção uses: Windows

{ A função abaixo abre a caixa de diálogo de conecção


com a rede Dial-Up. O parâmetro "name" é o nome da
conecção previamente configurada.
}

procedure DialUpConnect(const Name: string);


begin
WinExec(PChar('rundll32.exe rnaui.dll,RnaDial ' + Name), SW_SHOW);
end;

{ Exemplo de uso: }

procedure TForm1.Button1Click(Sender: TObject);


begin
DialUpConnect('NomeDaConecção');
end;
151 - Pintar uma imagem JPG no form
Inclua na seção uses: Graphics, JPeg

Problema:

Gostaria de pintar imagens de arquivos JPG (JPeg) nos forms


de minha aplicação. Isto é possível? Como?

Solução:

Para trabalhar com arquivos JPG você precisa usar um objeto


TPicture, assim como colocar no uses a unit JPeg. Siga os
passos abaixo para pintar uma imagem JPG no form:

- No evento OnPaint do form coloque o código abaixo:

procedure TForm1.FormPaint(Sender: TObject);


var
Imagem: TPicture;
begin
Imagem := TPicture.Create;
try
Imagem.LoadFromFile('c:\teste\foto.jpg');
Canvas.StretchDraw(ClientRect, Imagem.Graphic);
finally
Imagem.Free;
end;
end;

- E no evento OnResize do form, coloque:

procedure TForm1.FormResize(Sender: TObject);


begin
Repaint;
end;
Observações
Não se esqueça de trocar o nome do arquivo JPG conforme sua necessidade. Este exemplo
foi elaborado usando Delphi4.

150 - Executar comando do MS-DOS

Usando WinExec você pode executar qualquer comando do DOS.


Para isto chame o COMMAND.COM passando como parâmetro a linha
de comando a ser executada. O parâmetro /C é opcional e faz
com que a janela do DOS seja fechada assim que o comando
terminar. No exemplo abaixo estou executando a seguinte
linha de comando: DIR C:\*.*

WinExec('COMMAND.COM /C DIR C:\*.*', SW_SHOW);


Observações
Para que a janela do DOS não seja exibida, use SW_HIDE no lugar de SW_SHOW.

149 - 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.

148 - 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.

147 - 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;

146 - Programar teclas de atalho do Windows


Inclua na seção uses: Windows, Dialogs

Problema:

Gostaria de programar algumas teclas de atalho para chamar,


por exemplo, uma calculadora, quando meu aplicativo estiver
aberto. Como fazer?

Solução:

- No evento OnCreate do form coloque o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);


begin
if not RegisterHotkey(Handle, 1, MOD_CONTROL or MOD_ALT, VK_F11) then
ShowMessage('Erro ao programar Ctrl+Alt+F11');

if not RegisterHotkey(Handle, 2, MOD_CONTROL or MOD_ALT, VK_F12) then


ShowMessage('Erro ao programar Ctrl+Alt+F12');
end;

- No evento OnDestroy do form coloque o código abaixo:

procedure TForm1.FormDestroy(Sender: TObject);


begin
UnRegisterHotkey(Handle, 1);
UnRegisterHotkey(Handle, 2);
end;

- Declere a procedure abaixo na seção private:

private
procedure WMHotkey(var Msg: TWMHotkey); message WM_HOTKEY;

- Abaixo da palavra implementation escreva a procedure:

procedure TForm1.WMHotkey(var Msg: TWMHotkey);


begin
case Msg.HotKey of
1: WinExec('calc.exe', SW_SHOW);
2: ShowMessage('Ctrl+Alt+F12 foram pressionadas');
end;
end;

- Execute este programa e experimente pressionar Ctrl+Alt+F11


ou Ctrl+Alt+F12.
Observações
Se a combinação de teclas já estiver em uso (num atalho, por exemplo), não será possível
usá-la em nossa aplicação. Existem outras formas de implementar teclas de atalho em
programas escritos em Delphi, mas a forma apresentada é bastante funcional.

145 - 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\FileSystem';
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.
144 - Obter a célula de um StringGrid que está sob o
cursor do mouse
Inclua na seção uses: Windows

{ Esta procedure pega a linha e coluna da célula onde estiver


o mouse. Valores negativos para Linha ou Coluna indicam que
o mouse está fora da área cliente do StringGrid }

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;

{ Exemplo de uso:
- Coloque um botão no form;
- Altere o evento OnClick deste botão como abaixo:
}

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;

{ Para testar:
- Execute o programa;
- Posicione o cursor do mouse sobre alguma célula do
StringGrid;
- Pressione TAB até chegar ao botão e pressione ENTER;
- O resultado será mostrado no Caption do form;
}
Observações
Note que a procedure MouseCell usa um valor negativo (-1) para coluna e linha se o mouse
não estiver sobre o StringGrid.
143 - Limpar todas as células de um StringGrid

Existem três métodos que podemos aplicar para limpar


um StringGrid.

{ Limpando uma célula de cada vez: }

procedure TForm1.Button1Click(Sender: TObject);


var
I, J: integer;
begin
with StringGrid1 do
for I := 0 to ColCount -1 do
for J := 0 to RowCount -1 do
Cells[I,J] := '';
end;

{ Limpando uma linha de cada vez: }

procedure TForm1.Button2Click(Sender: TObject);


var
I: integer;
begin
with StringGrid1 do
for I := 0 to RowCount -1 do
Rows[I].Clear;
end;

{ Limpando uma coluna de cada vez: }

procedure TForm1.Button3Click(Sender: TObject);


var
I: integer;
begin
with StringGrid1 do
for I := 0 to ColCount -1 do
Cols[I].Clear;
end;
Observações
Em todos os exemplos estamos limpando o StringGrid completamente, inclusive linhas e
colunas fixas. Para preservar linhas ou colunas fixas troque os valores iniciais de I ou J
conforme a necessidade.

142 - 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\command', 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.

141 - 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.

140 - 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.

139 - 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;

138 - 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.

137 - Obter tamanho de um arquivo


Inclua na seção uses: SysUtils

{ A função abaixo retorna o tamanho do arquivo, ou -1


se o arquivo não for encontrado }

function tbFileSize(const FileName: string): integer;


var
SR: TSearchRec;
I: integer;
begin
I := FindFirst(FileName, faArchive, SR);
try
if I = 0 then
Result := SR.Size
else
Result := -1;
finally
FindClose(SR);
end;
end;

136 - Ocultar aplicação da lista de tarefas - CTRL+ALT+DEL

- Declare a função abaixo antes da palavra implementation:

function RegisterServiceProcess(dwProcessID, dwType: Integer):


Integer; stdcall; external 'KERNEL32.DLL';

- Coloque dois botões no Form;


- No evento OnClick do Button1 coloque:

RegisterServiceProcess(GetCurrentProcessID, 1);

- No evento OnClick do Button2 coloque:

RegisterServiceProcess(GetCurrentProcessID, 0);

=== Para testar ===

Clique no Button1 e pressione CTRL+ALT+DEL. O seu programa


não aparecerá na lista.
Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa
aparecerá na lista.

Dica enviada por: Luiz Carlos Manzolli

135 - Obter path de um Alias do BDE


Inclua na seção uses: BDE

{ A função abaixo retorna o path (caminho) de um Alias do


BDE }

function GetAliasPath(AliasName: String):String;


var
dbDes: DBDesc;
begin
Result:='';
DBiInit(Nil);// invoca o BDE , se não inicializado
If DbiGetDatabaseDesc(PChar(AliasName), @dbDes)= DBIERR_NONE then
with dbDes do
Result:=StrPas(szPhyName);
DBiExit;// Libera o BDE
end;

Dica enviada por: Angelo Ricardo Miquelin Neto.


Observações
Se a unit em que essa rotina for colocada utilizar as units DB e DBTABLES, as chamadas a
DbiInit() e DbiExit() poderão ser omitidas.

134 - 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);

133 - 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.

132 - 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);

131 - 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.

130 - 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');

129 - Copiar todos os registros de uma tabela para o


Clipboard
Inclua na seção uses: Clipbrd

Problema:

Gostaria de colocar em minha aplicação o recurso de copiar


todos os registros de uma tabela para a área de transferência,
permitindo ao usuário colar estes dados em outro
aplicativo (ex: MS-Word). Isto é possível?

Solução:

Sim. Siga os passos abaixo:

- Crie seu form normalmente, colocando DataSource, Table e


demais componentes;
- Coloque um botão e no evento OnClick deste botão coloque
o código abaixo:

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.

128 - Copiar um registro de uma tabela para o Clipboard


Inclua na seção uses: Clipbrd

Problema:

Gostaria de colocar em minha aplicação o recurso de copiar


um registro de uma tabela para a área de transferência,
permitindo ao usuário colar estes dados em outro
aplicativo (ex: MS-Word). Isto é possível?

Solução:

Sim. Siga os passos abaixo:

- Crie seu form normalmente, colocando DataSource, Table e


demais componentes;
- Coloque um botão e no evento OnClick deste botão coloque
o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


const
SeparadorCampoValor = ': ';
SeparadorCampo = #13#10; { Quebra de linha }
var
S: string;
I: integer;
begin
S := '';
for I := 0 to Table1.FieldCount -1 do
S := S + Table1.Fields[I].FieldName + SeparadorCampoValor +
Table1.Fields[I].AsString + SeparadorCampo;

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).
127 - 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;

126 - Ocultar o aplicativo do CTRL+ALT+DEL

Inclua no implementation de seu programa a seguinte linha:

function RegisterServiceProcess(dwProcessID, dwType: Integer):


Integer; stdcall; external 'KERNEL32.DLL';

e depois no OnCreate ponha a seguinte linha:

RegisterServiceProcess(GetCurrentProcessID, 1);

Isso vai fazer o programa nao aparecer no CTRL+ALT+DEL,


mas seu form principal vai continuar aparecendo. Para ocultar
também o form, basta por no OnCreate antes da linha acima
a seguinte linha:

Application.ShowMainForm:=False;

Resposta enviada por: dexter07


Observações
Segundo o autor desta resposta, esta solução foi testada em Win95, mas também deve
funcionar em Win98. Não sabe se funciona em NT.

125 - Personalizar a caixa de mensagem de exceções


(erro) do Delphi

Problema:

Quando ocorre uma exceção no Delphi, ele automaticamente


exibe uma mensagem de erro. Gostaria de poder personalizar
estas mensagens, acrescentando, por exemplo, o e-mail do
suporte técnico. Isto é possível?

Solução:

Sim. Siga os passos abaixo:

- 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.

124 - Implementar procedure Delay do Pascal no Delphi


Inclua na seção uses: Windows, Forms

Problema:

O Pascal para DOS possui uma procedure chamada Delay que


serve para pausar o processamento atual em "n" milésimos
de segundo. Como implemento isto no Delphi?

Solução:

Simles. Veja:

procedure Delay(MSec: Cardinal);


var
Start: Cardinal;
begin
Start := GetTickCount;
repeat
Application.ProcessMessages;
until (GetTickCount - Start) >= MSec;
end;
=== Exemplos de uso: ===

Delay(1000); { Aguarda 1 segundo }


Delay(5000); { Aguarda 5 segundos }
Delay(60000); { Aguarda 60 segundos - 1 minuto }
Observações
Além da procedure Delay criada acima, o programador Delphi pode usar também a API do
Windows Sleep. Há porém uma diferença: Delay permite que que o programa continue a
processar as mensagens do Windows (mouse, teclado, etc).

123 - 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, SBPAGEDOWN, 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, SBPAGEUP, 0);

{ Linha para baixo }


SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEDOWN, 0);

{ Linha para cima }


SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEUP, 0);
Observações
Além desta técnica existem API's do Windows que fazem um trabalho equivalente.

122 - Criar uma DLL de Bitmaps e usá-la

Problema:
Gostaria de colocar algums bitmaps em uma DLL e usá-los em
tempo de execução. É possível fazer isto em Delphi?

Solução:

Sim. Siga os passos abaixo para criar a DLL de bitmaps:

- Crie um arquivo de recursos (.RES) contendo os Bitmaps.


Use o Image Editor do Delphi para criar este arquivo.
Salve-o com o nome BMPS.RES na pasta onde será salvo
o projeto do Delphi;
- Crie um novo projeto no Delphi;
- Remova todos os forms do projeto;
- Salve este projeto com o nome DLLBmp.dpr;
- Abra o arquivo de projeto (DLLBmp.dpr) e altere para
ficar somente com as linhas abaixo:

{$R BMPS.RES}
library DLLBmp;
end.

- Compile o projeto (Ctrl+F9). Será criado o


arquivo DLLBmp.DLL.
- Feche o projeto atual e crie um novo projeto;
- Salve-o na mesma pasta que salvou o anterior,
mas com outro nome qualquer;
- Coloque no form um Edit e um Button;
- No evento OnClick do Button coloque o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Bmp: TBitmap;
HandleDLL: THandle;
begin
{ Carrega a DLL }
HandleDLL := LoadLibrary('DLLBmp.DLL');
if HandleDLL = 0 then
ShowMessage('Não foi possível carregar DLLBmp.DLL')
else
try
Bmp := TBitmap.Create;
try
Bmp.Handle := LoadBitmap(HandleDLL, PChar(Edit1.Text));
if Bmp.Handle = 0 then
ShowMessage('Não foi possível carregar o Bitmap.')
else
{ Pinta o Bitmap no form }
Canvas.Draw(0, 0, Bmp);
finally
Bmp.Free;
end;
finally
{ Libera a DLL }
FreeLibrary(HandleDLL);
end;
end;

=== Para testar ===

- Execute este projeto;


- Digite no Edit1 o nome que foi dado ao Bitmap no arquivo
de recursos (.RES);
- Clique no botão. O bitmap deverá ser pintado no form.
Observações
O arquivo DLL poderá ser colocado na pasta onde estiver o EXE, no diretório do Windows ou
ainda no sub-diretório System do Windows. Além de bitmaps podemos colocar qualquer
outro tipo de recurso em DLL's.

121 - Construir a barra de título do form com um Panel

Pegue o arquivo tbtitle.zip na seção Download


do IntereSite: www.ulbrajp.com.br/~tecnobyte

120 - Criar form sem título que possa ser arrastado

Problema:

Fazer um relógio num form é fácil. Porém gostaria que esse


form 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.

119 - Obter status da memória do sistema


Inclua na seção uses: Windows, SysUtils

- Coloque um TMemo no form


- Coloque um TButton no form e altere seu OnClick
conforme abaixo:

procedure TForm1.Button1Click(Sender: TObject);


const
cBytesPorMb = 1024 * 1024;
var
M: TMemoryStatus;
begin
M.dwLength := SizeOf(M);
GlobalMemoryStatus(M);
Memo1.Clear;
with Memo1.Lines do begin
Add(Format('Memória em uso: %d%%',
[M.dwMemoryLoad]));
Add(Format('Total de memória física: %f MB',
[M.dwTotalPhys / cBytesPorMb]));
Add(Format('Memória física disponível: %f MB',
[M.dwAvailPhys / cBytesPorMb]));
Add(Format('Tamanho máximo do arquivo de paginação: %f MB',
[M.dwTotalPageFile / cBytesPorMb]));
Add(Format('Disponível no arquivo de paginação: %f MB',
[M.dwAvailPageFile / cBytesPorMb]));
Add(Format('Total de memória virtual: %f MB',
[M.dwTotalVirtual / cBytesPorMb]));
Add(Format('Memória virtual disponível: %f MB',
[M.dwAvailVirtual / cBytesPorMb]));
end;
end;

118 - 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;
117 - Mostrar o diálogo About (Sobre) do Windows
Inclua na seção uses: ShellApi

procedure TForm1.Button1Click(Sender: TObject);


begin
ShellAbout(Handle, 'Sistema Financeiro', 'Marcelo Senger',
Application.Icon.Handle);
end;
Observações
Dica enviada por: Marcelo Senger

116 - 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 }

115 - Converter de Hexadecimal para Inteiro


Inclua na seção uses: SysUtils

Problema:
A função IntToHex do Delphi converte inteiro para
hexadecimal. O que preciso, no entanto, é fazer o contrário,
ou seja, converter de hexadecimal para inteiro. Existe
isto pronto no Delphi ou terei que escrever uma função
para isto?

Solução:

A função StrToInt pode receber uma string no formato de um


número decimal ou hexadecimal. Então podemos usá-la assim:

var
I: integer;
begin
I := StrToInt('$' + Edit1.Text);
{...}
end;
Observações
No Delphi, um número na notação decimal deve iniciar com o símbolo $.

114 - Mudar a cor de um DBEdit dentro de um DBCtrlGrid


de acordo com uma condição

Problema:

Uso um DBCtrlGrid e gostaria que, quando o valor de um


determinado campo for negativo, o DBEdit ligado a este
campo seja exibido em vermelho e, caso contrário,
em azul. Isto é possível?

Solução:

- Monte o form normalmente colocando DataSource, Table,


DBCtrlGrid e os DBEdit's, DBText's, etc.

- Escreva no manipulador do evento OnPaintPanel do


DBCtrlGrid conforme abaixo:

procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;


Index: Integer);
begin
if Table.FieldByName('NomeDoCampo').AsFloat < 0 then
DBEdit1.Font.Color := clRed
else
DBEdit1.Font.Color := clBlue;
end;
Observações
Neste exemplo mudamos a cor da fonte do componente DBEdit, Porém, pode-se também
mudar a cor do próprio componente (DBEdit1.Color).
113 - Colocar uma ProgressBar da 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.Handle, 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.


Observações
Com um pouco de criatividade podemos fazer outras coisas interessantes usando o evento
OnDrawPanel da StatusBar.

112 - 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,...).
111 - 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.

110 - Simular o pressionamento de uma tecla


Inclua na seção uses: Windows

A API keybd_event do Windows serve para fazer isto. No exemplo


abaixo estamos simulando o pressionamento da tecla F2:

keybd_event(VK_F2, 0, 0, 0);

Para testar faça o exemplo a seguir:

- Mude a propriedade KeyPreview do form para true.


- Escreva no evento OnKeyDown do form como abaixo:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;


Shift: TShiftState);
begin
if Key = VK_F2 then
ShowMessage('F2 pressionada');
end;

- Coloque um botão e escreva no OnClick (do botão) como abaixo:

procedure TForm1.Button1Click(Sender: TObject);


begin
keybd_event(VK_F2, 0, 0, 0);
end;
Observações
Consulte as constantes para os códigos das teclas (ex: VK_RETURN, VK_DOWN, etc).

109 - 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.

108 - 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.
107 - Verificar o estado de NumLock e CapsLock
Inclua na seção uses: Windows

{ Esta função retorna true se a tecla informada estiver


ligada. False em caso contrário }

function tbKeyIsOn(const Key: integer): boolean;


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

{ Exemplo de uso: }

if tbKeyIsOn(VK_NUMLOCK) then
{ ... NumLock está ligada }
else
{ ... NumLock está desligada }
Observações
Qualquer tecla que possua os estados On/Off pode ser verificada. Basta, para isto, saber seu
código. O código de CapsLock é VK_CAPITAL.

106 - Configurar linhas de diferentes alturas em StringGrid

- Coloque o StringGrid no form.


- No evento OnCreate do form coloque o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);


begin
StringGrid1.RowHeights[0] := 15;
StringGrid1.RowHeights[1] := 20;
StringGrid1.RowHeights[2] := 50;
StringGrid1.RowHeights[3] := 35;
end;
Observações
Cuidado para não especificar uma linha inexistente.

105 - 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.

104 - 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).

103 - Converter a primeira letra de um Edit para maiúsculo

with Edit2 do
if Text <> '' then
Text := AnsiUpperCase(Text[1]) + Copy(Text, 2, Length(Text));

Isto pode ser colocado, por exemplo, no OnExit do Edit.

Você pode também converter durante a digitação. Para isto


coloque o código abaixo no evento OnKeyPress do Edit:

if Edit1.SelStart = 0 then
Key := AnsiUpperCase(Key)[1]
else
Key := AnsiLowerCase(Key)[1];

102 - 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;
101 - 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;

100 - Mostrar uma mensagem durante um processamento

Problema:

Um processamento em meu sistema é bastante demorado e por isto


colocar apenas o cursor de ampulheta continua deixando o
usuário confuso, pensando que o sistema travou. É possível
exibir uma mensagem enquanto um processamento demorado ocorre?

Sim. E é fácil. Vejamos:

- Crie um form com a mensagem. Um pequeno form com um


Label já é suficiente. Aqui vou chamá-lo de FormMsg.
- Vá em Project|Options e passe o FormMsg de
"Auto-create forms" para "Available forms".
- Abaixo vou simular um processamento demorado, usando a
API Sleep:

procedure TForm1.Button1Click(Sender: TObject);


var
Form: TFormMsg;
I: integer;
begin
Form := TFormMsg.Create(Self);
try
Form.Label1.Caption := 'Processamento demorado...';
Form.Show;
for I := 1 to 5 do begin
Form.UpDate;
Sleep(1000); { Aguarda um segundo }
end;
finally
Form.Free;
end;
end;
Observações
A função Sleep é uma API do Windows e serve para paralisar a aplicação por um
determinado dempo. Este tempo é em milisegundos.

99 - Mostrar um cursor de ampulheta durante um


processamento

- Salve o cursor atual


- Defina o novo cursor (crHourGlass é ampulheta)
- Faça o processamento
- Restaure o cursor.

Vejamos:

var
PrevCur: TCursor;
begin
PrevCur := Screen.Cursor;
try
Screen.Cursor := crHourGlass;
{ Coloque aqui as instruções do processamento }
finally
Screen.Cursor := PrevCur;
end;
end;
Observações
Existem diversos outros cursores pré-definidos no Delphi. Dê uma olhada na propriedade
Cursor de um componente visual para ver uma lista de todos eles. Você poderá também
criar o seu próprio cursor.

98 - Ler e escrever dados binários no Registro do Windows


Inclua na seção 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), pois isto
prejudicará o desempenho do sistema.

97 - 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.

96 - Ler e escrever dados no Registro do Windows


Inclua na seção uses: Registry

- Coloque no form dois edits e dois botões.


- No evento OnClick do Button1 escreva o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);


var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre a chave (path). Se não existir, cria e abre. }
Reg.OpenKey('MeuPrograma\Configuração', true);
{ Escreve um inteiro }
Reg.WriteInteger('Numero', StrToInt(Edit1.Text));
{ Escreve uma string }
Reg.WriteString('Nome', Edit2.Text);
finally
Reg.Free;
end;
end;

- No evento OnClick do Button2, escreva:

procedure TForm1.Button2Click(Sender: TObject);


var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
if Reg.KeyExists('MeuPrograma\Configuração') then
begin
Reg.OpenKey('MeuPrograma\Configuração', false);

if Reg.ValueExists('Numero') then
Edit1.Text := IntToStr(Reg.ReadInteger('Numero'))
else
ShowMessage('Não existe valor com o nome "Numero"');

if Reg.ValueExists('Nome') then
Edit2.Text := Reg.ReadString('Nome')
else
ShowMessage('Não existe valor com o nome "Nome"');

end else
ShowMessage('Não existe a chave no registro');
finally
Reg.Free;
end;
end;
Observações
User o aplicativo RegEdit.exe do windows para ver o registro. Cuidado para não alterar as
configurações do Windows!

95 - Adicionar barra de rolagem horizontal no ListBox

{ - Coloque um ListBox no form;


- Altere o OnCreate do Form conforme abaixo:
}

procedure TForm1.FormCreate(Sender: TObject);


var
I, Temp, MaxTextWidth: integer;
begin
{ Adiciona algumas linhas no ListBox }
Listbox1.Items.Add('Linha 1');
Listbox1.Items.Add('Linha 2, longa para que seja necessária a barra de rolagem
horizontal');
Listbox1.Items.Add('Linha 3');

if Listbox1.Items.Count > 1 then begin

{ Obtém o comprimento, em pixels, da linha mais longa }


MaxTextWidth := 0;
for I := 0 to Listbox1.Items.Count - 1 do begin
Temp := ListBox1.Canvas.TextWidth(ListBox1.Items[I]);
if Temp > MaxTextWidth then
MaxTextWidth := Temp;
end;

{ Acrescenta a largura de um "W" }


MaxTextWidth := MaxTextWidth + Listbox1.Canvas.TextWidth('W');

{ Envia uma mensagem ao ListBox }


SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, MaxTextWidth, 0);
end;
end;

{ Para ocultar use a instrução abaixo: }

SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, 0, 0);

94 - 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];

93 - 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.');

92 - Fazer pesquisa incremental com DBGrid e Edit

Problema:

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.

91 - Adicionar zeros à esquerda de um número

Existem várias formas. Vejamos uma:

function tbStrZero(const I: integer; const Casas: byte): string;


var
Ch: Char;
begin
Result := IntToStr(I);
if Length(Result) > Casas then begin
Ch := '*';
Result := '';
end else
Ch := '0';

while Length(Result) < Casas do


Result := Ch + Result;
end;

{ Exemplo de como usá-la: }

var
S: string;
Numero: integer;
{...}
begin
{...}
S := tbStrZero(Numero, 6);
{...}
end;
Observações
Se o comprimento desejado (Casas) não for suficiente para conter o número, serão
colocados asteriscos.
90 - 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.

89 - Implementar um campo auto-incremental via


programação
Inclua na seção uses: dbTables

procedure tbAutoInc(Table: TTable; const FieldName: string);


var
Q: TQuery;
begin
if not Table.FieldByName(FieldName).IsNull then
Exit;

Q := TQuery.Create(nil);
try
Q.DatabaseName := Table.DatabaseName;
Q.SQL.Add('select max(' + FieldName + ') from ' + Table.TableName);
Q.Open;
try
Table.FieldByName(FieldName).AsInteger := Q.Fields[0].AsInteger +1;
finally
Q.Close;
end;
finally
Q.Free;
end;
end;

{ Chame esta procedure no evento BeforePost de um Table: }


procedure TForm1.Table1BeforePost(DataSet: TDataSet);
begin
tbAutoInc(Table1, 'Codigo');
end;
Observações
A função acima incrementa o campo somente se estiver vazio. Assim podemos dar ao
usuário a opção de digitar neste campo ou deixá-lo vazio para que seja auto-incrementado.
Existem várias outras formas de implementar este recurso.
88 - 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.

87 - 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.

86 - Obter a versão da biblioteca ComCtl32.DLL (usada na


unit ComCtrls do Delphi)
Inclua na seção uses: ComCtrls

{ A versão desta biblioteca determina a aparência de alguns


controles do Delphi, tais como ToolBar e CoolBar. O exemplo
abaixo obtém a versão desta biblioteca.

Para este exemplo, coloque um TEdit e um TButton no Form.


O evento OnClick do botão escreva o código abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Ver: Cardinal;
MaiorVer, MenorVer: Word;
begin
Ver := GetComCtlVersion;
MaiorVer := HiWord(Ver);
MenorVer := LoWord(Ver);
Edit1.Text := IntToStr(MaiorVer) + '.' + IntToStr(MenorVer);
end;
Observações
Normalmente, a versão 4.72 está presente quando o Internet Explorer 4 está instalado.

85 - 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;

84 - Exibir o diálogo About do Windows


Inclua na seção uses: Windows

{ About padrão do Windows }


ShellAbout(Handle, 'Windows', '', 0);

{ Personalizada }
ShellAbout(Handle, 'NomePrograma',
'Direitos autorais reservados a'#13'Fulano de Tal',
Application.Icon.Handle);

83 - Obter a linha e coluna atual em um TMemo

{ === SOLUÇÃO 1 === }

{ Esta procedure obtém a linha e coluna atual de um TMemo }


procedure tbGetMemoLinCol(Memo: TMemo; var Lin, Col: Cardinal);
begin
with Memo do begin
Lin := Perform(EM_LINEFROMCHAR, SelStart, 0);
Col := SelStart - Perform(EM_LINEINDEX, Lin, 0);
end;
end;

{ Use-a como abaixo: }

var
Lin, Col: Cardinal;
begin
tbGetMemoLinCol(Memo1, Lin, Col);
{ ... }
end;

{ === SOLUÇÃO 2 === }

var
Lin, Col: integer;
begin
Lin := Memo1.CaretPos.y;
Col := Memo1.CaretPos.x;
{...}
end;

- A segunda solução foi apresentada por:


Vanderley Pereira Rocha

82 - Exibir um arquivo de ajuda do Windows


Inclua na seção uses: Windows

{ Você precisa saber:


- Caminho e nome do arquivo;
- A estrutura do arquivo de Help.

No exemplo abaixo abre o arquivo de ajuda da Calculadora


do Windows e vai para o tópico n. 100
}

procedure TForm1.Button1Click(Sender: TObject);


begin
WinHelp(0, 'c:\Win95\Help\Calc.hlp', HELP_CONTEXT, 100);
end;
Observações
Para utilizar um arquivo de ajuda em seu programa desenvolvido em Delphi, basta usar os
recursos do próprio Delphi. O exemplo acima é somente para mostrar o uso de uma API para
este fim.

81 - Obter o valor de uma variável de ambiente


Inclua na seção uses: Windows

{ Esta função recebe o nome da variável de ambiente


que queremos acessar e retorna uma string com seu
valor, ou uma string vazia se a variável não existir. }
function tbGetEnvVar(const VarName: string): string;
var
I: integer;
begin
Result := '';

{ Obtém o comprimento da variável }


I := GetEnvironmentVariable('PATH', nil, 0);

if I > 0 then begin


SetLength(Result, I);
GetEnvironmentVariable('PATH', PChar(Result), I);
end;
end;

{ Para usá-la, faça como neste exemplo: }


Edit1.Text := tbGetEnvVar('PATH');

80 - Determinar se uma janela (form) está maximizada


Inclua na seção uses: Windows

if IsZoomed(Form1.Handle) then
{ Form1 está maximizado }
else
{ Form2 NÃO está maximizado }
Observações
Veja a pergunta n. 78.

79 - Determinar se o cursor do mouse está em


determinado controle
Inclua na seção uses: Windows

{ Os exemplos abaixo verificam se o cursor do mouse está em


Button1: }

{ Solução 1: }
var
Pt: TPoint;
Rct: TRect;
begin
GetCursorPos(Pt);
GetWindowRect(Button1.Handle, Rct);
if PtInRect(Rct, Pt) then
{ Está no botão }
else
{ NÃO está no botão }
end;
{ Solução 2: }
var
Pt: TPoint;
begin
GetCursorPos(Pt);
if WindowFromPoint(Pt) = Button1.Handle then
{ Está no botão }
else
{ Não está no botão }
end;
Observações
A API GetWindowRect obtém o retângulo (TRect) ocupado por uma janela. Podemos usar
GetClientRect para obter o somente da parte cliente da janela. Podemos também usar a
propriedade BoundsRect que existe na maioria dos componentes visuais, ou mesmo
informar qualquer outro retângulo da tela. Se usarmos a propriedade BoundsRect,
precisaremos converter as coordenadas clientes para coordenadas de tela (com a função
ClientToScreen). Um lembrete: a solução 2 só poderá ser aplicada a controles ajanelados.

78 - Determinar se o aplicativo está minimizado


Inclua na seção 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.

77 - 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.
76 - Usar o evento OnGetText de um TField

{ Problema:

Tenho um sistema de contas a receber, onde um campo chamado


"Tipo" contém um número inteiro que indica o tipo do
documento conforme abaixo:

1 - Promissória
2 - Duplicata
3 - Boleto

Gostaria que, ao exibir os dados (num DBGrid por exemplo),


fosse exibido o nome e não o número, ou seja, "Promissória"
em vez de "1".

Solução:

Isto pode ser feito de várias formas, mas aqui vou mostrar
como resolver usando o evento OnGetText do TField. Vejamos:

- Adicione todos os campos no Field Editor;


- Clique no campo "Tipo";
- Vá ao Object Inspector e dê um duplo-click
no evento OnGetText;
- Neste evento, digite o código abaixo:
}

procedure TForm1.Table1TipoGetText(Sender: TField; var Text: String;


DisplayText: Boolean);
begin
if DisplayText then begin
case Table1Tipo.AsInteger of
1: Text := 'Promissória';
2: Text := 'Duplicata';
3: Text := 'Boleto';
else
Text := 'Desconhecido';
end;
end else
Text := Table1Tipo.AsString;
end;
Observações
Ao exibir será exibido os nomes. Mas ao digitar continue com os 1, 2, 3, etc. Para usar este
recurso em relatórios, acesse a propriedade DisplayText em vez de AsString para obter o
valor do campo.

75 - Maximizar um form de forma que cubra toda a tela,


inclusive a barra de tarefas

{ É um "maximizar" com jeitinho brasileiro... mas funciona.


No evento OnShow do form coloque o código abaixo: }

Top := 0;
Left := 0;
Width := Screen.Width;
Height := Screen.Height;
Observações
Nos testes que fiz, mesmo com a barra de tarefas marcada como "Sempre Visível",
funcionou perfeitamente. Fiz os testes usando o Win95. Talvez em novas versões, possa
apresentar problemas.

74 - Verificar, via programação, se Local Share do BDE está


TRUE
Inclua na seção uses: Registry, SysUtils, Windows

{ Esta função retorna true se Local Share estiver "TRUE".


Caso contrário, retorna false. }

function tbBDELocalShare: boolean;


const
BdeKey = 'SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT';
Ident = 'LOCAL SHARE';
var
Reg: TRegistry;
begin
Result := false;
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey(BdeKey, False) then
if Reg.ValueExists(Ident) then
Result := UpperCase(Reg.ReadString(Ident)) = 'TRUE';
finally
Reg.Free;
end;
end;

{ Use-a como abaixo: }


if tbBDELocalShare then
{ Local Share está TRUE }
else
{ Local Share está FALSE }
Observações
A função acima faz a verificação no registro do Windows. Por isto está sujeita a falha caso o
BDE coloque as configurações em outro local (é o caso do BDE salvar as configurações no
formato do Windows 3.x). O ideal seria usar uma API do BDE, mas até o momento não
conheço uma que retorne esta informação. Caso alguém saiba, queira por gentileza nos
informar.
73 - 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.

72 - 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\legacy_interbase_guard
hkey_local_machine\system\controlset001\enum\root\legacy_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

71 - Inverter os botões do mouse


Inclua na seção uses: Windows

{ Para inverter: }
SwapMouseButton(true);

{ Para voltar ao normal: }


SwapMouseButton(false);

70 - Obter/definir o tempo máximo do duplo-click do


mouse
Inclua na seção uses: Windows

{ - Coloque um botão no form e escreva seu OnClick como


abaixo: }

procedure TForm1.Button6Click(Sender: TObject);


var
Tempo: Cardinal;
begin
{ Obtém }
Tempo := GetDoubleClickTime;
ShowMessage(IntToStr(Tempo) + ' milisegundos');

{ Define }
SetDoubleClickTime(300);
end;
Observações
Um duplo-click nada mais é que dois cliques consecutivos (óbvio). Porém estes dois cliques
podem ser interpretados de duas formas: dois cliques isolados ou um duplo-click. Para o
Windows resolver esta situação, ele usa o que chamo de "tempo máximo do duplo-click". Se
o intervalo entre o primeiro e o segundo click for menor ou igual a esse tempo, então houve
duplo-click. E você pode alterar este tempo. O padrão do Windows é 500 milisegundos. Um
tempo muito curto (ex: 100), faz com que o duplo-click tenha que ser muito rápido (quase
impossível), enquanto muito longo (ex: 2000) faz com que o Windows interprete dois clicks
isolados como duplo-click.

69 - Obter os atributos de um arquivo/diretório


Inclua na seção uses: Windows

{ No form:
- Coloque um memo;
- Coloque um edit;
- Coloque um botão e escreva seu OnClick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Attr: DWord;
begin
Memo1.Clear;
Attr := GetFileAttributes(PChar(Edit1.Text));
if Attr > 0 then
with Memo1.Lines do begin
if (Attr and FILE_ATTRIBUTE_ARCHIVE) > 0 then
Add('Archive');
if (Attr and FILE_ATTRIBUTE_COMPRESSED) > 0 then
Add('Compressed');
if (Attr and FILE_ATTRIBUTE_DIRECTORY) > 0 then
Add('Directory');
if (Attr and FILE_ATTRIBUTE_HIDDEN) > 0 then
Add('Hidden');
if (Attr and FILE_ATTRIBUTE_NORMAL) > 0 then
Add('Normal');
if (Attr and FILE_ATTRIBUTE_OFFLINE) > 0 then
Add('OffLine');
if (Attr and FILE_ATTRIBUTE_READONLY) > 0 then
Add('ReadOnly');
if (Attr and FILE_ATTRIBUTE_SYSTEM) > 0 then
Add('System');
if (Attr and FILE_ATTRIBUTE_TEMPORARY) > 0 then
Add('Temporary');
end;
end;

68 - Obter o espaço total e livre de um disco


Inclua na seção uses: Windows

{ - Coloque um memo (TMemo) no form;


- Coloque um botão e altere seu OnClick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
SetoresPorAgrup, BytesPorSetor, AgrupLivres,
TotalAgrup: DWord;
begin
Memo1.Clear;
if GetDiskFreeSpace('C:\', SetoresPorAgrup,
BytesPorSetor, AgrupLivres, TotalAgrup) then
with Memo1.Lines do begin
Add('Setores por agrupamento: ' + IntToStr(SetoresPorAgrup));
Add('Bytes por setor: ' + IntToStr(BytesPorSetor));
Add('Agrupamentos livres: ' + IntToStr(AgrupLivres));
Add('Total de agrupamentos: ' + IntToStr(TotalAgrup));
Add('----- Resumo -----');
Add('Total de bytes: ' +
IntToStr(TotalAgrup * SetoresPorAgrup * BytesPorSetor));
Add('Bytes livres: ' +
IntToStr(AgrupLivres * SetoresPorAgrup * BytesPorSetor));
end;
end;

{ O exemplo acima retorna as medidas em Bytes, Setores e


Agrupamentos. Se preferir algo mais simples,
use funções do Delphi. Veja: }

Memo1.Lines.Add('Total de bytes: ' + IntToStr(DiskSize(3)));


Memo1.Lines.Add('Bytes livres: ' + IntToStr(DiskFree(3)));

{ Onde o parâmetro (3) é o número da unidade, sendo


1=A, 2=B, 3=C, ... }
Observações
Para usar as funções DiskSize e DiskFree coloque SysUtils em uses.

67 - Obter o tipo de um drive (removível, fixo, CD-ROM,


unidade de rede, etc)
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 respectivos tipos, use a função tbGetDrives (da pergunta 64) em conjunto com este
exemplo.

66 - Obter informações de um volume/disco (label, serial,


sistema de arquivos, etc)
Inclua na seção uses: Windows, System

{ - Coloque um memo (TMemo) no form;


- Coloque um botão e escreve seu evento
OnClick como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
SLabel, SSysName: PChar;
Serial, FileNameLen, X: DWord;
begin
Memo1.Clear;
GetMem(SLabel, 255);
GetMem(SSysName, 255);
try
GetVolumeInformation('C:\', SLabel, 255,
@Serial, FileNameLen, X, SSysName, 255);
with Memo1.Lines do begin
Add('Nome do volume (Label): ' + string(SLabel));
Add('Número Serial: ' + IntToHex(Serial, 8));
Add('Tamanho máximo p/ nome arquivo: ' +
IntToStr(FileNameLen));
Add('Sistema de Arquivos: ' + string(SSysName));
end;
finally
FreeMem(SLAbel, 255);
FreeMem(SSysName, 255);
end;
end;

65 - 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');
Observações
Veja a pergunta nº 66.
64 - Saber quais as unidades de disco (drives) estão
presentes
Inclua na seção uses: Windows

{ A função abaixo retorna uma string contendo


as letras de unidades de discos presentes. }

function tbGetDrives: string;


var
Drives: DWord;
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;

{ Para saber se uma determinada unidade está presente,


basta fazer algo como: }
if Pos('A', tbGetDrives) > 0 then
ShowMessage('Unidade A: presente.')
else
ShowMessage('Unidade A: ausente.');
Observações
A string retornada pela função tbGetDrives está sempre em letras maiúsculas.

63 - "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.5465
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.

62 - 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).

61 - 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;

60 - 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.

59 - 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.

58 - Formatar um disquete através de um programa Delphi

{ Coloque o código abaixo imediatamente abaixo da palavra


implementation: }

const
SHFMT_ID_DEFAULT = $FFFF;

{ Opções de formatação }
SHFMT_OPT_QUICKFORMAT = $0000; { Formatação rápida }
SHFMT_OPT_FULL = $0001; { Formatação completa }
SHFMT_OPT_SYSONLY = $0002; { Copia sistema }

{ Códigos de errros }
SHFMT_ERROR = $FFFFFFFF; { Ocorreu erro }
SHFMT_CANCEL = $FFFFFFFE; { Foi cancelado }
SHFMT_NOFORMAT = $FFFFFFFD; { Não formatou }
function SHFormatDrive(Handle: HWND; Drive, ID, Options: Word):
LongInt; stdcall; external 'shell32.dll' name 'SHFormatDrive'

{ Coloque um botão no form e altere o evento OnClick dele


conforme abaixo: }

procedure TForm1.Button3Click(Sender: TObject);


var
Erro: DWord;
Msg: string;
begin
Erro := SHFormatDrive(Handle, 0, SHFMT_ID_DEFAULT, SHFMT_OPT_QUICKFORMAT);
case Erro of
SHFMT_ERROR: Msg := 'Ocorreu um erro.';
SHFMT_CANCEL: Msg := 'A formatação foi cancelada.';
SHFMT_NOFORMAT: Msg := 'Não foi possível formatar.';
else
Msg := 'Disco formatado com sucesso.';
end;
ShowMessage(Msg);
end;
Observações
Para formatação completa troque SHFMT_OPT_QUICKFORMAT por SHFMT_OPT_FULL. O
segundo parâmetro (zero no exemplo) indica a unidade, sendo que A é 0 (zero), B é 1, etc.

57 - Alterar (e restaurar) o tamanho da página na


impressora
Inclua na seção uses: tbPrn

{ - Peque em nosso Download o arquivo tbPrn.zip. Ele contém


a unit tbPrn.pas, onde está a função tbPrnSetPaperSize
usada no exemplo abaixo;

- Adicione a unit tbPrn.pas em seu projeto;

- Siga o exemplo abaixo para criar seus relatórios


usando o TPrinter.
}

procedure TForm1.Button1Click(Sender: TObject);


var
Papel: TtbPrnPaper;
begin
Papel.Size := 256; // 256 é o tam. personalizado
Papel.Width := 2100; // 21 cm
Papel.Height := 1000; // 10 cm
Papel := tbPrnSetPaperSize(Papel);
try
Printer.BeginDoc;
try
{ coloque aqui os comandos para impressão }
finally
Printer.EndDoc;
end;
finally
tbPrnSetPaperSize(Papel); // Restaura o tamanho
end;
end;

{ Papel.Size refere-se ao tamanho do papel. Veja alguns:


0 - Default
1 - Letter
5 - Legal
8 - A3
9 - A4
11 - A5
256 - Custom (personalizado) }
Observações
Só será necessário informar Papel.Height e Papel.Width quando Papel.Size for 256.

56 - Reproduzir um arquivo de som WAV sem o


TMediaPlayer
Inclua na seção uses: MMSystem

{ Síncrona: aguarda terminar a reprodução para continuar: }


SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_SYNC);

{ Assíncrona: a execução continua normalmente enquanto


ocorre a reprodução: }
SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_ASYNC);

{ Contínua: a reprodução é repetida num efeito de loop.


Este tipo de reprodução precisa ser assíncrona: }
SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav',
SND_ASYNC or SND_LOOP);

{ Interrompe uma reprodução contínua: }


SndPlaySound(nil, 0);
Observações
A reprodução contínua pode ser usada, por exemplo, para altertar o usuário em uma
situação extremamente crítica. Se o equipamento não possuir placa de som, o arquivo não
será reproduzido.

55 - Obter o nome do usuário e da empresa informado


durante a instalação do Windows
Inclua na seção uses: Registry

{ Coloque um botão no form e altere seu evento OnCkick


como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Reg: TRegIniFile;
S: string;
begin
Reg := TRegIniFile.Create('SOFTWARE\MICROSOFT\MS SETUP (ACME)\');
try
S := Reg.ReadString('USER INFO','DefName','');
S := S + #13;
S := S + Reg.ReadString('USER INFO','DefCompany','');
ShowMessage(S);
finally
Reg.free;
end;
end;

54 - Mostrar uma barra de progresso enquanto copia


arquivos

Veja a pergunta nº 53.

53 - Copiar arquivos usando o Shell do Windows


Inclua na seção 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.
52 - 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.

51 - Evitar que seu programa apareça na barra de tarefas


Inclua na seção uses: Windows

{ Você já observou a caixa "Propriedades", aquela que mostra


as propriedades de um arquivo no Windows Explorer, não
aparece na lista do Alt+Tab e tampouco na barra de tarefas?

Isto ocorre porque ela funciona como uma ToolWindow, enquanto


os demais aplicativos funcionam como AppWindow. Porém podemos
mudar o comportamento de nossos programas feito em Delphi
para que se comportem como uma ToolWindow também.

Para experimentar, crie um novo projeto e altere o


Project1.dpr como abaixo (não esqueça do uses):
}

program Project1;

uses
Forms, Windows,
Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

var
ExtendedStyle : Integer;
begin
Application.Initialize;

ExtendedStyle := GetWindowLong(Application.Handle, gwl_ExStyle);


SetWindowLong(Application.Handle, gwl_ExStyle, ExtendedStyle or
ws_Ex_ToolWindow and not ws_Ex_AppWindow);

Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Observações
Ao executar observe a barra de tarefas e teste o Alt+Tab (seu programa não estará lá!).

50 - 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);

49 - Mudar a coluna ativa em um DBGrid via programação

{ Usando número da coluna (zero é a primeira coluna): }


DBGrid1.SelectedIndex := 0;

{ Usando o nome do campo }


DBGrid1.SelectedField := Table1.FieldByName(Edit2.Text);
Observações
Aconselho usar o nome do campo quando o que importa é o campo e não a posição. Use o
número da coluna somente quando o que importa é a posição, e não o campo.

48 - Fechar o Windows a partir do seu programa

{ Reinicia o Windows }
ExitWindowsEx(EWX_REBOOT, 0);

{ Desliga o Windows }
ExitWindowsEx(EWX_SHUTDOWN, 0);

{ Força todos os programa a desligarem-se }


ExitWindowsEx(EWX_FORCE, 0);

47 - Carregar um cursor animado (.ani)


{ Altere o evento OnCreate do Form conforme abaixo: }

procedure TForm1.FormCreate(Sender: TObject);


begin
Screen.Cursors[1] :=
LoadCursorFromFile('c:\win95\cursors\globe.ani');
Button1.Cursor := 1;
end;
Observações
Para este exemplo é necessário ter o arquivo de cursor conforme apontado e também ter,
no form, um Button1. Para usar este cursor em outros componentes basta atribuir à
propriedade Cursor do componente em questão o valor 1 (um). Exemplo: Edit1.Cursor := 1;
Form1.Cursor := 1;, etc.

46 - Enviar um arquivo para a lixeira


Inclua na seção uses: ShellApi

{ Coloque a procedure abaixo na seção implementation }

procedure ArqParaLixeira(const NomeArq: string; var MsgErro: string);


var
Op: TSHFileOpStruct;
begin
MsgErro := '';
if not FileExists(NomeArq) then begin
MsgErro := 'Arquivo não encontrado.';
Exit;
end;
FillChar(Op, SizeOf(Op), 0);
with Op do begin
wFunc := FO_DELETE;
pFrom := PChar(NomeArq);
fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT;
end;
if ShFileOperation(Op) <> 0 then
MsgErro := 'Não foi possível enviar o arquivo para a lixeira.';
end;

{ - Coloque um botão no Form;


- Altere o evento OnClick do botão conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
S: string;
begin
ArqParaLixeira('c:\Diretorio\Teste.doc', S);
if S = '' then
ShowMessage('O arquivo foi enviado para a lixeira.')
else
ShowMessage(S);
end;
45 - Obter o número do registro atual

Table1.RecNo()

44 - 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.

43 - 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.

42 - Executar um programa DOS e fechá-lo em seguida

{ Coloque isto no evento OnClick de um botão: }

WinExec('command.com /c programa.exe',sw_ShowNormal);

{ Se quizer passar parâmetros pasta adicioná-los após o


nome do programa. Exemplo: }

WinExec('command.com /c programa.exe param1 param2',sw_ShowNormal);


Observações
Se quizer que a janela do programa não apareça, troque sw_ShowNormal por sw_Hide.
41 - Fechar um programa a partir de um programa Delphi

{ - Coloque um botão no form e altere seu evento OnClick


conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


var
Janela: HWND;
begin
Janela := FindWindow('OpusApp'), nil);
if Janela = 0 then
ShowMessage('Programa não encontrado')
else
PostMessage(Janela, WM_QUIT, 0, 0);
end;
Observações
Este exemplo fecha o MS Word 97 se estiver aberto. A mensagem WM_QUIT fecha o
programa da forma "ignorante". Isto significa que se houver dados não salvos, o programa a
ser fechado não oportunidade para salvá-los. Uma alternativa mais suave é trocar a
mensagem WM_QUIT por WM_CLOSE. Veja as perguntas 18 e 36.

40 - Colocar Hint's de várias linhas

{ - Coloque um TButton no Form;


- Altere o evento OnCreate do Form como abaixo: }

procedure TForm1.FormCreate(Sender: TObject);


begin
Button1.Hint := 'Linha 1 da dica' + #13 +
'Linha 2 da dica' + #13 +
'Linha 3 da dica';
Button1.ShowHint := true;
end;

39 - Reproduzir um vídeo AVI em um Form

{ - Crie um novo projeto. Este já deverá ter o Form1;


- Adicione um novo Form (Form2);
- Coloque, no Form1, um TMediaPlayer (paleta System)
e um botão;
- Altere o evento OnClick do botão como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
with MediaPlayer1 do begin
FileName := 'c:\speedis.avi';
Open;

{ Ajusta tamanho do Form }


with MediaPlayer1.DisplayRect do begin
Form2.ClientHeight := Bottom - Top;
Form2.ClientWidth := Right - Left;
end;

Display := Form2;
Form2.Show;
Play;
end;
end;
Observações
Em vez de ajustar o Form ao vídeo, podemos ajustar o vídeo ao Form. Para isto troque o
trecho with..end; por MediaPlayer1.DisplayRect := Form2.ClientRect;

38 - 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.
37 - Colocar zeros à esquerda de números

{ Isto coloca zeros à esquerda do número até completar 6 casas }


S := FormatFloat('000000', 5);

Observações
"S" precisa ser uma variável string.

36 - 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!
Veja as perguntas nº 35 e 53.

35 - Copiar arquivos

{ - Coloque um Button no Form;


- Altere o evento OnClick deste Button conforme abaixo: }

procedure TForm1.Button2Click(Sender: TObject);


var
Origem, Destino: string;
begin
Origem := 'c:\Origem\NomeArq.txt';
Destino := 'c:\Destino\NomeArq.txt';
if not CopyFile(PChar(Origem), PChar(Destino), true) then
ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino);
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!
Veja as perguntas nº 36 e 53.

34 - Trabalhar com cores no formato string

procedure TForm1.Button3Click(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;

33 - 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. Veja a pergunta nº 18.

32 - 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. Veja a pergunta nº 46.

31 - 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.

30 - 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.

29 - Evitar que um programa seja executado mais de uma


vez

{ Muitos programas Windows permitem apenas uma cópia em


execução de cada vez. Isto é interessante principalmente
quando é um grande aplicativo, pois duas cópias ao mesmo
tempo usuaria muito mais memória. Em aplicativos
desenvolvidos em Delphi podemos ter esta característica.
Vejamos:

- Crie um novo projeto;


- Mude o "Name" do Form1 para DPGFormPrinc;
- Altere o código-fonte do arquivo Project1.dpr
conforme abaixo: }

program Project1;

uses
Forms, Windows,
Unit1 in 'Unit1.pas' {DPGFormPrinc};

{$R *.RES}

var
Handle: THandle;
begin
Handle := FindWindow('TDPGFormPrinc', nil);
if Handle <> 0 then begin { Já está aberto }
Application.MessageBox('Este programa já está aberto. A cópia ' +
'anterior será ativada.', 'Programa já aberto', MB_OK);
if not IsWindowVisible(Handle) then
ShowWindow(Handle, SW_RESTORE);
SetForegroundWindow(Handle);
Exit;
end;
Application.Initialize;
Application.CreateForm(TDPGFormPrinc, DPGFormPrinc);
Application.Run;
end.
Observações
Para testar este programa você deverá compilar o projeto e fechar o Delphi. Depois, procure
o Project1.exe (projeto compilado) usando o Windows Explorer e tente executá-lo mais de
uma vez e veja o que acontece. Mas porque alterar o name do form principal para
"DPGFormPrinc"? Este poderia ser qualquer outro nome, mas preferi usar as iniciais do meu
nome (DPG). Procurei deixar um nome bem pessoal para não correr o risco de colocar um
nome que possa ser encontrado em outro aplicativo do Windows. Por exemplo: se deixar
Form1, será bem fácil encontrar outro aplicativo feito em Delphi que possua uma janela com
este nome, o que causaria problema.

28 - Executar um "COMMIT" no Delphi


Inclua na seção uses: DbiProcs

{ Se estiver usando TTable, coloque nos eventos


AfterPost e AfterDelete a seguinte linha: }

dbiSaveChanges(Table1.Handle);

{ Para TQuery, a instrução é semelhante: }

dbiSaveChanges(Query1.Handle);

27 - Posicionar Form's em relação ao Desktop do Windows

{ Quando usamos a propridade Position de um Form para


centralizá-lo estamos sujeitos a um inconveniente:
dependendo da posição/tamanho da barra de tarefas do
Windows, o nosso Form poderá ficar parcialmente coberto
por ela. Uma forma eficaz de resolver este problema é
posicionar o form considerando apenas a área livre do
Desktop. Vejamos este exemplo:

- Crie um novo projeto;


- Na seção implementation digite a procedure abaixo:
}

procedure FormPos(Form: TForm; const Horz, Vert: byte);


{ Horz: 1=esquerda, 2=centro, 3=direita
Vert: 1=topo, 2=centro, 3=em baixo }
var
R: TRect;
begin
if not SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0) then
R := Rect(0, 0, Screen.Width, Screen.Height);
with Form do
case Horz of
1: Form.Left := 0;
2: Form.Left := (R.Right - R.Left - Width) div 2;
3: Form.Left := R.Right - Width;
end;
with Form do
case Vert of
1: Form.Top := 0;
2: Form.Top := (R.Bottom - R.Top - Height) div 2;
3: Form.Top := R.Bottom - Height;
end;
end;

{ - Coloque dois TEdit's: Edit1 e Edit2;


- Coloque um TButton e altere o evento OnClick deste
conforme abaixo:
}

procedure TForm1.Button1Click(Sender: TObject);


begin
FormPos(Form1, StrToInt(Edit1.Text), StrToInt(Edit2.Text));
end;
Observações
Para testar, execute este exemplo e experimente digitar números de 1 a 3 em ambos os
Edit's e clique no Button para ver o resultado. O Edit1 indica a posição horizontal (esquerda,
centro e direita) e o Edit2 indica a posição vertical (topo, centro e em baixo).

26 - Saber a resolução de tela atual

{ Coloque um TButton no Form e altere o evento


OnClick deste botão como abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
ShowMessage('Largura: ' + IntToStr(Screen.Width) + #13 +
'Altura: ' + IntToStr(Screen.Height));
end;
Observações
O objeto Screen contém várias informações importantes: largura e altura da tela, fontes
instaladas no Windows, etc.

25 - Verificar se uma unidade de disco (disk-drive) está


preparada
Inclua na seção uses: System, SysUtils

{ - Crie um novo projeto;


- Na seção implementation da Unit1 digite a função abaixo: }

function DriveOk(Drive: Char): boolean;


var
I: byte;
begin
Drive := UpCase(Drive);
if not (Drive in ['A'..'Z']) then
raise Exception.Create('Unidade incorreta');
I := Ord(Drive) - 64;
Result := DiskSize(I) >= 0;
end;

{ - Coloque no Form1 um TEdit (Edit1)


- Coloque no Form1 um TButton
- Altere o evento OnClick do Button1 conforme abaixo: }

procedure TForm1.Button1Click(Sender: TObject);


begin
if DriveOk(Edit1.Text[1]) then
ShowMessage('Drive OK')
else
ShowMessage('Drive não preparado');
end;
Observações
Para testar você deverá executar o exemplo e digitar no Edit a letra do drive a ser testado
(não precisa os dois-pontos). Após digitar, clique no Button1.

24 - 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.

23 - Definir a quantidade de registros a ser impressa em


uma página do QuickReport

Ou seja, gostaria que, ao visualizar ou imprimir um relatório


do Quick Report, saia em cada página apenas um registro,
mesmo que o espaço permita mais de um.
Existem pelo menos duas formas de resolver este problema:

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
da 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.

22 - Onde encontrar tutoriais sobre construção de


componentes em Delphi

Pegue apostila no download.

21 - 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!).

20 - 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.

19 - Limitar 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;
Observações
Cuidado! Isto pode irritar o usuário do seu programa.

18 - Descobrir o nome de classe de uma janela do


Windows

Muitas vezes precisamos saber qual o nome de classe


de uma determinada janela. Quando são janelas desenvolvidas
por nós, você olha no código-fonte. Mas e se não for, como
é o caso do Delphi?

Por exemplo:

Para verificar se o Delphi está sendo executado, procuramos


no Windows pela janela cujo nome de classe seja TAppBuilder.
Mas como verificar então se o Internet Explorer está sendo
executado? Precisaremos saber o nome de classe da janela
deste programa. Então o que fazer?

Use o TBWinName. Pegue-o no download de


www.ulbrajp.com.br/usuario/tecnobyte

17 - Ocultar/exibir a barra de tarefas do Windows


Inclua na seção uses: Windows

{ Coloque no Form dois Botões: BotaoOcultar e BotaoExibir.


No evento OnClick do BotaoOcultar escreva: }

procedure TForm1.BotaoOcultarClick(Sender: TObject);


var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_HIDE);
end;

{ No evento OnClick do BotaoExibir escreva: }

procedure TForm1.BotaoExibirClick(Sender: TObject);


var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_SHOW);
end;

{ Execute e teste, clicando em ambos os botões }


Observações
A tarefa mais difícil é descobrir o nome de classe da janela da barra de tarefa do Windows,
mas isto é fácil se você usar o TBWinName. Pegue-o no link download de
www.ulbrajp.com.br/usuario/tecnobyte O resto é usar as APIs do Windows para manipulação
de Janelas. Veja a pergunta nº 18.

16 - 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;

15 - 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;

14 - 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.

13 - Criar cores personalizadas (sistema RGB)

{ Coloque um TButton no form e escreva o evento OnClick


deste como abaixo: }
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;
Observações
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(...)).

12 - Adicionar uma nova fonte no Windows

{ Coloque o código abaixo no OnClick de um botão }


AddFontResource(PChar('c:\MyFonts\Monospac.ttf'));
Observações
Troque o nome do arquivo do exemplo anterior pelo nome desejado. Arquivos de fonte
possuem uma das seguintes extensões: FON, FNT, TTF, FOT. Veja também a pergunta nº 10.

11 - 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. Veja também a pergunta nº 10.

10 - 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.');
Observações
Veja também a pergunta nº 11.

9 - Acertar a data e hora do sistema através do programa

{ Coloque dois TEdit no form.


Coloque um TButton no form e altere o evento OnClick
deste botão como abaixo:
}
procedure TForm1.Button1Click(Sender: TObject);
var
DataHora: TSystemTime;
Data, Hora: TDateTime;
Ano, Mes, Dia,
H, M, S, Mil: word;
begin
Data := StrToDate(Edit1.Text);
Hora := StrToTime(Edit2.Text);
DecodeDate(Data, Ano, Mes, Dia);
DecodeTime(Hora, H, M, S, Mil);
with DataHora do begin
wYear := Ano;
wMonth := Mes;
wDay := Dia;
wHour := H;
wMinute := M;
wSecond := S;
wMilliseconds := Mil;
end;
SetLocalTime(DataHora);
end;
Observações
No Edit1 digite a nova data e no Edit2 digite a nova hora.
8 - ENTER em vez de TAB no formulário, no DBGrid e no
StringGrid

{ Mude a propriedade "KeyPreview" do Form para true. }

{ No evento "OnKeyPress" do Form acrescente o código abaixo: }

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);


begin
if Key = #13 then begin
Key := #0;
Perform(WM_NEXTDLGCTL, 1, 0);
end;
end;

{ Em StringGrid, escreva o evento OnKeyPress como abaixo: }

procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);


begin
if Key = #13 then
StringGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;

{ Em DBGrid, escreva o evento OnKeyPress como abaixo: }

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);


begin
if Key = #13 then
DBGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;
Observações
É bom lembrar que a tecla ENTER no Windows tem seu papel já bem definido quando se
trata de caixa de diálogo: executar a ação padrão, normalmente o botão OK. Se não tomar
cuidado poderá confundir o usuário, em vez de ajudá-lo.

7 - Simular a vírgula através do ponto do teclado numérico

{ 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_KEYDOWN then
if Msg.wParam = 110 then
Msg.wParam := 188;
end;

{ No evento "OnCreate" do form principal, coloque: }


Application.OnMessage := AppMsg;
{ Uma segunda alternativa (José Geraldo - ES):
Coloque o código abaixo no evento OnKeyPress do componente
onde se quer a conversão (Edit, DBEdit, etc). Neste caso
a conversão funcionará apenas neste componente (óbvio). }

if Key = '.' then Key = DecimalSeparator;


Observações
Na primeira alternativa, sempre que for pressionado o ponto do teclado numérico (da direita
do teclado), este será convertido para vírgula, independentemente do controle que estiver
em foco. Já na segunda, o ponto pode ser de qualquer lugar do teclado.

6 - Paralizar um programa durante n segundos


Inclua na seção uses: Windows

{ Pausa por 1 segundo }


Sleep(1000);

{ Pausa por 10 segundos }


Sleep(10000);
Observações
Esta pausa não é interrompida pelo pressionamento de alguma tecla, como acontecia com
InKey() do Clipper.

5 - Criar uma tabela (DB, DBF) através do seu programa


Inclua na seção uses: dbTables, DB

procedure CriaTabelaClientes;
var
Tabela: TTable;
begin
Tabela := TTable.Create(Application);
try
Tabela.DatabaseName := 'C:\';
{ ou Tabela.DatabaseName := 'NomeAlias'; }

Tabela.TableName := 'Clientes.DB';
Tabela.TableType := ttParadox; { ou ttDBase }

{ Somente Delphi4 }
if Tabela.Exists then { Se a tabela já existe... }
Exit;
{***}

{ Cria a tabela }
Tabela.FieldDefs.Add('Codigo', ftInteger, 0, true);
Tabela.FieldDefs.Add('Nome', ftString, 30, true);
Tabela.FieldDefs.Add('DataNasc', ftDate, 0, false);
Tabela.FieldDefs.Add('RendaMes', ftCurrency, 0, false);
Tabela.FieldDefs.Add('Ativo', ftBoolean, 0, true);
{ etc, etc, etc }
Tabela.CreateTable;

{ Cria os Índices }
Tabela.AddIndex('ICodigo', 'Codigo', [ixPrimary, ixUnique]);
Tabela.AddIndex('INome', 'Nome', [ixCaseInsensitive]);
{ etc, etc, etc }
finally
Tabela.Free;
end;
end;
Observações
Para verificar se o arquivo já existe na versão 3 ou anterior do Delphi, você deverá usar a
função "FileExists" do Delphi.

4 - Verificar se um diretório existe


Inclua na seção uses: FileCtrl, Dialogs

if DirectoryExists('C:\MEUSDOCS') then
ShowMessage('O diretório existe')
else
ShowMessage('O diretório não existe');

3 - Verificar se um arquivo existe


Inclua na seção uses: SysUtils, Dialogs

if FileExists('c:\carta.doc') then
ShowMessage('O arquivo existe')
else
ShowMessage('O arquivo não existe');

2 - Criar um Alias temporário através do seu programa


Inclua na seção uses: DB

{ Enxergar somente configurações da sessão atual }


Session.ConfigMode := cmSession;
{ Adicionar o Alias }
Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');
Observações
Veja a pergunta nº 1.

1 - Criar um Alias através do seu programa


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;
Observações
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á seu
.EXE. Neste último caso será necessário incluir na seção uses: SysUtils, System.

A listbox in a cell of a stringgrid


Here's another great trick by programmer illusionists. What appears as embedded
comboboxes within a stringgrid is actually just a combobox floating above the stringgrid,
and it just so happens to be the exact same size as the stringgrid cell underneath it.

Here's the basics:

procedure TfrmMain.FormCreate(Sender: TObject);


begin
StringGrid1.DefaultRowHeight := ComboBox1.Height;
end;

procedure TfrmMain.StringGrid1DrawCell(Sender: TObject; Col, Row:


Integer; Rect: TRect; State: TGridDrawState);
var
R: TRect;
begin
if (Col >= StringGrid1.FixedCols) and
(Row >= StringGrid1.FixedRows) and
(gdFocused in State) then
with ComboBox1 do
begin
BringToFront;
CopyRect(R, Rect);
R.TopLeft := frmMain.ScreenToClient(
StringGrid1.ClientToScreen(R.TopLeft));
R.BottomRight := frmMain.ScreenToClient(
StringGrid1.ClientToScreen(R.BottomRight));
SetBounds(R.Left, R.Top, R.Right-R.Left, R.Bottom-R.Top);
end;
end;

procedure TfrmMain.StringGrid1TopLeftChanged(Sender: TObject);


var
R: TRect;
begin
with StringGrid1 do
CopyRect(R, CellRect(Col, Row));

with ComboBox1 do
begin
Visible := False;
R.TopLeft := frmMain.ScreenToClient(
StringGrid1.ClientToScreen(R.TopLeft));
R.BottomRight := frmMain.ScreenToClient(
StringGrid1.ClientToScreen(R.BottomRight));
SetBounds(R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top);
end;

with StringGrid1 do
if (TopRow <= Row) and (TopRow + VisibleRowCount > Row) then
ComboBox1.Show;
end;

procedure TfrmMain.ComboBox1Change(Sender: TObject);


begin
with StringGrid1 do
Cells[Col, Row] := ComboBox1.Text;
end;

In essence, the main routine here is the stringgrid's OnDrawCell event handler. Of course, I
also set the stringgrid's DefaultRowHeight property to be the same height as the
combobox. In addition, the stringgrid's OnTopLeftChanged event handler is used to hide the
combobox when the user scrolls out of view. Also, when the user selects an item from the
combobox, simply place the text in the current Col/Row.
You can also do a couple other little tricks such as setting the stringgrid's Objects[] property
to point to the combobox, as well as possibly setting the combobox's Parent property to
point to the stringgrid. However, I've had problems with the Parent approach -- namely, that
of dropping down the listbox associated with the combobox.

"Change the StringGrid's CELL color ?" by EDDIE SHIPMAN


Here's how:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; Col, Row: Integer;


Rect: TRect; State: TGridDrawState);
var
TempPString:Array [0..255] of char;
begin
If (gdFixed in State){or (gdSelected in State)} then exit;

StringGrid1.Canvas.Brush.Style:=bsSolid;
{You could add some color here, if desired:}
Case Col of
1: StringGrid1.Canvas.Brush.Color:=clRed;
2: StringGrid1.Canvas.Brush.Color:=clWhite;
3: StringGrid1.Canvas.Brush.Color:=clBlue;
end;
{Erase data}
StringGrid1.Canvas.FillRect(Rect);
{Get text in a PChar string}
StrPCopy(TempPString,StringGrid1.Cells[Col,Row]);
{DrawText--see other options in Windows API help;
Change the DT_LEFT to DT_RIGHT for right justified txt!}
DrawText(StringGrid1.Canvas.Handle,TempPString,-1,Rect,DT_LEFT);
end;

Sort a TStringGrid by Columns?


type
TMoveSG = class(TCustomGrid); // reveals protected MoveRow procedure

{...}

procedure SortGridByCols(Grid: TStringGrid; ColOrder: array of Integer);


var
i, j: Integer;
Sorted: Boolean;

function Sort(Row1, Row2: Integer): Integer;


var
C: Integer;
begin
C := 0;
Result := AnsiCompareStr(Grid.Cols[ColOrder[C]][Row1], Grid.Cols[ColOrder[C
]][Row2]);
if Result = 0 then
begin
Inc(C);
while (C <= High(ColOrder)) and (Result = 0) do
begin
Result := AnsiCompareStr(Grid.Cols[ColOrder[C]][Row1],
Grid.Cols[ColOrder[C]][Row2]);
Inc(C);
end;
end;
end;

begin
if SizeOf(ColOrder) div SizeOf(i) <> Grid.ColCount then Exit;

for i := 0 to High(ColOrder) do
if (ColOrder[i] < 0) or (ColOrder[i] >= Grid.ColCount) then Exit;

j := 0;
Sorted := False;
repeat
Inc(j);
with Grid do
for i := 0 to RowCount - 2 do
if Sort(i, i + 1) > 0 then
begin
TMoveSG(Grid).MoveRow(i + 1, i);
Sorted := False;
end;
until Sorted or (j = 1000);
Grid.Repaint;
end;

procedure TForm1.Button1Click(Sender: TObject);


begin
{ Sort rows based on the contents of two or more columns.
Sorts first by column 1. If there are duplicate values
in column 1, the next sort column is column 2 and so on...}
SortGridByCols(StringGrid1, [1, 2, 0, 3, 4]);
end;

...export a TStringGrid to a MS Word table?


uses
ComObj;

procedure TForm1.Button1Click(Sender: TObject);


var
WordApp, NewDoc, WordTable: OLEVariant;
iRows, iCols, iGridRows, jGridCols: Integer;
begin
try
// Create a Word Instance
// Word Instanz erzeugen
WordApp := CreateOleObject('Word.Application');
except
// Error...
// Fehler....
Exit;
end;

// Show Word
// Word anzeigen
WordApp.Visible := True;

// Add a new Doc


// Neues Dok einfügen
NewDoc := WordApp.Documents.Add;

// Get number of columns, rows


// Spalten, Reihen ermitteln
iCols := StringGrid1.ColCount;
iRows := StringGrid1.RowCount;

// Add a Table
// Tabelle einfügen
WordTable := NewDoc.Tables.Add(WordApp.Selection.Range, iCols, iRows);

// Fill up the word table with the Stringgrid contents


// Tabelle ausfüllen mit Stringgrid Daten
for iGridRows := 1 to iRows do
for jGridCols := 1 to iCols do
WordTable.Cell(iGridRows, jGridCols).Range.Text :=
StringGrid1.Cells[jGridCols - 1, iGridRows - 1];

// Here you might want to Save the Doc, quit Word...


// Hier evtl Word Doc speichern, beenden...

// ...

// Cleanup...
WordApp := Unassigned;
NewDoc := Unassigned;
WordTable := Unassigned;
end;

...convert a TStringGrid to HTML?


{ The SGridToHtml() function converts a Stringgrid to a HTML Code.
Parameters: SG: TStringGrid to convert
Dest: TMemo to show the HTML Code
BorderSize: Size of border (0 = show no border)
{
Mit der Funktion SGridToHtml() können StringGrids in HTML Code umgewandelt
werden.
SG bezieht sich auf das TStringGrid, welches codiert werden soll.
in Dest (vom Typ TMemo) wird der HTML Code erzeugt.
BorderSize bestimmt, wie dick der Tabellenrahmen sein soll. 0 = kein Rahmen

procedure SGridToHtml(SG: TStringgrid; Dest: TMemo; BorderSize: Integer);


var
i, p: integer;
SStyle1, SStyle2, Text: string;
begin
Dest.Clear;
Dest.Lines.Add('<html>');
Dest.Lines.Add('<body>');
Dest.Lines.Add(' <table border="' + IntToStr(BorderSize) + '" width="' +
IntToStr(SG.Width) + '" height="' + IntToStr(SG.Width) + '">');

for i := 0 to SG.RowCount - 1 do
begin
Dest.Lines.Add(' <tr>');
for p := 0 to SG.ColCount - 1 do
begin
SStyle1 := '';
SStyle2 := '';
if fsbold in SG.Font.Style then
begin
SStyle1 := SStyle1 + '<b>';
SStyle2 := SStyle2 + '</b>';
end;
if fsitalic in SG.Font.Style then
begin
SStyle1 := SStyle1 + '<i>';
SStyle2 := SStyle2 + '</i>';
end;
if fsunderline in SG.Font.Style then
begin
SStyle1 := SStyle1 + '<u>';
SStyle2 := SStyle2 + '</u>';
end;
Text := sg.Cells[p, i];
if Text = '' then Text := ' ';
Dest.Lines.Add(' <td width="' + IntToStr(sg.ColWidths[p]) +
'" height="' + IntToStr(sg.RowHeights[p]) +
'"><font color="#' + IntToHex(sg.Font.Color, 6) +
'" face="' + SG.Font.Name + '">' + SStyle1 +
Text + SStyle2 + '</font></td>');
end;
Dest.Lines.Add(' </tr>');
end;
Dest.Lines.Add(' </table>');
Dest.Lines.Add('</body>');;
Dest.Lines.Add('</html>');
end;

// Example, Beispiel
procedure TFormCSVInport.Button6Click(Sender: TObject);
begin
SGridToHtml(StringGrid1, Memo1, 1);
Memo1.Lines.SaveToFile('c:\test.html');
end;

...export a StringGrid to an Excel-File?


{1. With OLE Automation }

uses
ComObj;

function RefToCell(ARow, ACol: Integer): string;


begin
Result := Chr(Ord('A') + ACol - 1) + IntToStr(ARow);
end;

function SaveAsExcelFile(AGrid: TStringGrid; ASheetName, AFileName: string):


Boolean;
const
xlWBATWorksheet = -4167;
var
Row, Col: Integer;
GridPrevFile: string;
XLApp, Sheet, Data: OLEVariant;
i, j: Integer;
begin
// Prepare Data
Data := VarArrayCreate([1, AGrid.RowCount, 1, AGrid.ColCount], varVariant);
for i := 0 to AGrid.ColCount - 1 do
for j := 0 to AGrid.RowCount - 1 do
Data[j + 1, i + 1] := AGrid.Cells[i, j];
// Create Excel-OLE Object
Result := False;
XLApp := CreateOleObject('Excel.Application');
try
// Hide Excel
XLApp.Visible := False;
// Add new Workbook
XLApp.Workbooks.Add(xlWBatWorkSheet);
Sheet := XLApp.Workbooks[1].WorkSheets[1];
Sheet.Name := ASheetName;
// Fill up the sheet
Sheet.Range[RefToCell(1, 1), RefToCell(AGrid.RowCount,
AGrid.ColCount)].Value := Data;
// Save Excel Worksheet
try
XLApp.Workbooks[1].SaveAs(AFileName);
Result := True;
except
// Error ?
end;
finally
// Quit Excel
if not VarIsEmpty(XLApp) then
begin
XLApp.DisplayAlerts := False;
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end;

// Example:

procedure TForm1.Button1Click(Sender: TObject);


begin
if SaveAsExcelFile(stringGrid1, 'My Stringgrid Data', 'c:\MyExcelFile.xls')
then
ShowMessage('StringGrid saved!');
end;

{**************************************************************}
{2. Without OLE }

procedure XlsWriteCellLabel(XlsStream: TStream; const ACol, ARow: Word;


const AValue: string);
var
L: Word;
const
{$J+}
CXlsLabel: array[0..5] of Word = ($204, 0, 0, 0, 0, 0);
{$J-}
begin
L := Length(AValue);
CXlsLabel[1] := 8 + L;
CXlsLabel[2] := ARow;
CXlsLabel[3] := ACol;
CXlsLabel[5] := L;
XlsStream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));
XlsStream.WriteBuffer(Pointer(AValue)^, L);
end;

function SaveAsExcelFile(AGrid: TStringGrid; AFileName: string): Boolean;


const
{$J+} CXlsBof: array[0..5] of Word = ($809, 8, 00, $10, 0, 0); {$J-}
CXlsEof: array[0..1] of Word = ($0A, 00);
var
FStream: TFileStream;
I, J: Integer;
begin
Result := False;
FStream := TFileStream.Create(PChar(AFileName), fmCreate or fmOpenWrite);
try
CXlsBof[4] := 0;
FStream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));
for i := 0 to AGrid.ColCount - 1 do
for j := 0 to AGrid.RowCount - 1 do
XlsWriteCellLabel(FStream, I, J, AGrid.cells[i, j]);
FStream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));
Result := True;
finally
FStream.Free;
end;
end;

// Example:

procedure TForm1.Button2Click(Sender: TObject);


begin
if SaveAsExcelFile(StringGrid1, 'c:\MyExcelFile.xls') then
ShowMessage('StringGrid saved!');
end;

{**************************************************************}
{3. Code by Reinhard Schatzl }

uses
ComObj;

// Hilfsfunktion für StringGridToExcelSheet


// Helper function for StringGridToExcelSheet
function RefToCell(RowID, ColID: Integer): string;
var
ACount, APos: Integer;
begin
ACount := ColID div 26;
APos := ColID mod 26;
if APos = 0 then
begin
ACount := ACount - 1;
APos := 26;
end;

if ACount = 0 then
Result := Chr(Ord('A') + ColID - 1) + IntToStr(RowID);
if ACount = 1 then
Result := 'A' + Chr(Ord('A') + APos - 1) + IntToStr(RowID);

if ACount > 1 then


Result := Chr(Ord('A') + ACount - 1) + Chr(Ord('A') + APos - 1) + IntToSt
r(RowID);
end;

// StringGrid Inhalt in Excel exportieren


// Export StringGrid contents to Excel
function StringGridToExcelSheet(Grid: TStringGrid; SheetName, FileName: string
;
ShowExcel: Boolean): Boolean;
const
xlWBATWorksheet = -4167;
var
SheetCount, SheetColCount, SheetRowCount, BookCount: Integer;
XLApp, Sheet, Data: OLEVariant;
I, J, N, M: Integer;
SaveFileName: string;
begin
//notwendige Sheetanzahl feststellen
SheetCount := (Grid.ColCount div 256) + 1;
if Grid.ColCount mod 256 = 0 then
SheetCount := SheetCount - 1;
//notwendige Bookanzahl feststellen
BookCount := (Grid.RowCount div 65536) + 1;
if Grid.RowCount mod 65536 = 0 then
BookCount := BookCount - 1;

//Create Excel-OLE Object


Result := False;
XLApp := CreateOleObject('Excel.Application');
try
//Excelsheet anzeigen
if ShowExcel = False then
XLApp.Visible := False
else
XLApp.Visible := True;
//Workbook hinzufügen
for M := 1 to BookCount do
begin
XLApp.Workbooks.Add(xlWBATWorksheet);
//Sheets anlegen
for N := 1 to SheetCount - 1 do
begin
XLApp.Worksheets.Add;
end;
end;
//Sheet ColAnzahl feststellen
if Grid.ColCount <= 256 then
SheetColCount := Grid.ColCount
else
SheetColCount := 256;
//Sheet RowAnzahl feststellen
if Grid.RowCount <= 65536 then
SheetRowCount := Grid.RowCount
else
SheetRowCount := 65536;

//Sheets befüllen
for M := 1 to BookCount do
begin
for N := 1 to SheetCount do
begin
//Daten aus Grid holen
Data := VarArrayCreate([1, Grid.RowCount, 1, SheetColCount], varVaria
nt);
for I := 0 to SheetColCount - 1 do
for J := 0 to SheetRowCount - 1 do
if ((I + 256 * (N - 1)) <= Grid.ColCount) and
((J + 65536 * (M - 1)) <= Grid.RowCount) then
Data[J + 1, I + 1] := Grid.Cells[I + 256 * (N - 1), J + 65536 *
(M - 1)];
//-------------------------
XLApp.Worksheets[N].Select;
XLApp.Workbooks[M].Worksheets[N].Name := SheetName + IntToStr(N);
//Zellen als String Formatieren
XLApp.Workbooks[M].Worksheets[N].Range[RefToCell(1, 1),
RefToCell(SheetRowCount, SheetColCount)].Select;
XLApp.Selection.NumberFormat := '@';
XLApp.Workbooks[M].Worksheets[N].Range['A1'].Select;
//Daten dem Excelsheet übergeben
Sheet := XLApp.Workbooks[M].WorkSheets[N];
Sheet.Range[RefToCell(1, 1), RefToCell(SheetRowCount, SheetColCount)]
.Value :=
Data;
end;
end;
//Save Excel Worksheet
try
for M := 1 to BookCount do
begin
SaveFileName := Copy(FileName, 1,Pos('.', FileName) - 1) + IntToStr(M)
+
Copy(FileName, Pos('.', FileName),
Length(FileName) - Pos('.', FileName) + 1);
XLApp.Workbooks[M].SaveAs(SaveFileName);
end;
Result := True;
except
// Error ?
end;
finally
//Excel Beenden
if (not VarIsEmpty(XLApp)) and (ShowExcel = False) then
begin
XLApp.DisplayAlerts := False;
XLApp.Quit;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end;
//Example
procedure TForm1.Button1Click(Sender: TObject);
begin
//StringGrid inhalt in Excel exportieren
//Grid : stringGrid, SheetName : stringgrid Print, Pfad : c:\Test\ExcelFile
.xls, Excelsheet anzeigen
StringGridToExcelSheet(StringGrid, 'Stringgrid Print', 'c:\Test\ExcelFile.x
ls', True);
end;
GERAL
Strings
copy - Copia uma substring, dentro de uma string
Var
vtexto, Copia: String;
begin
vtexto := Edit1.Text ; // descobriu o valor de texto
Copia := copy(vtexto,2,2); // copia de vtexto, apartir da segunda letra dois caracteres
Label1.Caption := Copia; // o label exibira as duas letras
end;
// delete - Deleta uma substring dentro de uma string.
ex: Delete (Mystring, 2,1) // delete da variável mysring, na segunda posição, 1 caractere
insert - Insereuma substring em uma string .
ex: Insert ("z", mystring, 1 ) //insere a letra z no começo da string
Inttostr - Converte um valor inteiro para string.
ex: 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
ex: 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;
Lowercase( 'SORTE' ); // tranformar para 'sorte'
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;

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.
Uppercase ('casa');// Retorna 'CASA'
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

Format
//Para coloca zeros a esquerda dos números encontrados.
%5 mostra o valor da variável inteira "VNum"
// .5d por que são 5 caracteres
Edit1.text:= Format('%5.5d',[VNum]);

//Colocar zeros a esquerda de um valor Real digitado no Edit


Edit1.Text := FormatFloat(‘000000’,StrToFloat(Edit1.Text));
//Colocar zeros a esquerda de um valor inteiro digitado no Edit
Edit1.Text := FormatFloat(‘000000’,StrToInt(Edit1.Text));
Formatando com estilo de moeda
//Formatando um valor Real
Edit1.Text := FormatFloat(‘#,##0.00’,vSalario);
//Formatando uma String
Edit1.Text := FormatFloat(‘#,##0.00’,StrToFloat(Edit1.Text));
Obs- (#) Cerquilha, para números obcionais. (,) Ponto para separar milhar. (.) Virgula para separar casas decimais.
//A linha abaixo exibe em um label, seu top. Misturando String do Inteiro
Label1.Caption := Format('O top deste label é %d',[Label1.top]);
//Lendo uma variável inteira
Label.Caption := Format ('O número guardado é : %d, [i]);
// Para exibir o valor Hexadecimal de uma variável integer(i)
Label1.Caption := Format('$%x',[i]);
//Formatando uma Data:
dbedit1.text:=formatDateTime('dd/mm/yyyy hh:mm',now);

Delete - Ex:
Delete(MyString) // deleta da variável MyString, na segunda posição, um caractere
Insert - Ex:
Insert ('z',MyString,1) // Insere a letra z no começo da String
InttoStr - Ex:
MyString := InttoStr(Shape1.top)//A variável MyString recebe o valor top do componente Shape1

Mensagens
Menssagem simples
ShowMessage( ' texto da menssagem ' );
Caixa de messagem
MessageDlg( ' aviso ' , mtInformation, [mbOk], 0 );

if MessageDlg('Quer sair do programa',mtInformation,[mbYes,mbNo],0) = mrYes then


Form1.close;

if Application.MessageBox('Confirmar Exclusão','Atenção',mb_YesNo + mb_iconQuestion) = idYes then


{comandos...}

If Application.MessageBox('Confirma Exclusão?','ATENÇÃO',MB_ICONEXCLAMATION + MB_YESNO) =


IDYES Then
DataModule1.Tb_Alunos.Delete;

INPUTBOX e INPUTQUERY
INPUTBOX
//A linha abaixo exibe uma caixa de diálogo onde digitamos um valor que será exibido em um label
Label1.Caption := InputBox('digite','integer','');
<B.INPUTQUERY< b>
//Sensível à maiúsculas e minúsculas. Veja abaixo dois exemplos.
Exemplo1
procedure TForm1.Button3Click(Sender: TObject);
var
NS: string;
clickOK: Boolean; // clickok foi inventado
begin
NS := 'Nome fixo';
Label1.Caption := NS;
clickOK := InputQuery('Input Box', 'digite', NS);
if clickOK then
Label1.Caption := 'The new string is ''' + NS + '''';
end;

Exemplo2
var
r : string
; begin
inputQuery( ' ver ' , ' senha ' , r );
if r = ' s ' then
shape1.Visible := true
else
showmessage( ' senha errada ' );
end;
Tratando Erros
Deletando um registro
try
DMAgenda.tbAgenda.Delete;
except
On E:EDBEngineError do
ShowMessage('Registro em uso por outro USUÁRIO. Exclusão Cancelada';
end;

Datas Inválidas
Try
StrtoDate(Edit1.text);
except
on EconvertError do
ShowMessage('Data Inválida');
end;

Centralizar um componeteNo evento OnResize digite


No evento abaixo, toda vez que o form sor redimencionado, o Button ficara no centro
Button1.Top := Form1.ClientHeight div 2 - Button1.Height div 2;
Button1.Left := Form1.ClientWidth div 2 - Button1.Width div 2;

Senhas
Colocar senha numa tabela Paradox //...e retirar em tempo de execução:
Session.AddPassword('Senha-Da-Tabela');
...
Session.RemovePassword;
outra opção...
Session.AddPassword('Senha');
Table1.Active := True;
// vincule o Table1 ao Session>

Encryptar uma string


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;

Rotina para um janela de Login


...
var
contador : Integer ;
begin
if not DataModule1.Table1.findkey([edit1.text]) then // a coluna senha, na tabela, tem que ser a primeira
begin
ShowMessage( ' senha errada ' ) ;
inc ( contador ) ;
if contador = 3 then
ShowMessage ( ' vc teve 3 chances ' ) ;
exit ;
end ;
formSenha.Close ;
formPrincipal.Enabled := true ;
end ;

findfield
Contador : Integer;//colocar em na área var ou uses
var // no evento onClick do botão OK
s : TstringField; //unit db
begin
s:= DataModlule1.Table1.findfield('senha')as TstringField; // procura na coluna senha
if s.value <> Edit1.text then
begin
ShowMessage('senha invalida');
inc(contador);
if Contador = 3 then
begin
ShowMessage('vc teve 3 chances');
formPrincipal.Close;
end;
exit;
formSenha.Close;
formPrincipal.Enabled := true;
end;

Trabalhando com o teclado


#0=Null #8=Backspace #13=Enter
#27=Escape #32=Espaço #127=Delete
//fazer o Enter, substituir o Tab...
if key = #13 then
Edit1.SetFocus; // o Edit recebe o foco

//fazer o Enter, substituir o Tab...(II)


SelectNext(ActiveControl,true,true);// joga o foco no proximo componente
///Cancelando uma tecla
if (Key = ‘A’) or (Key = 'a') then
Key := #0;

Levar o foco para o componente anterior


// No evento OnKeyDown digite:
if Key = (Vk_Up) then
Perform(Wm_NextDlgCtl,1,0);

Caracteres especiais
// declare uma constante com os caracteres especiais... Const
chrEspecial : Set of Char =['@','#','$','%'];
//no evento OnKeyPress, digite:
If key in ChrEspecial then
ShowMessage('esta letra é especial');

// Para digitar só maiúsculas...


Key := Upcase(Key); //colocar no evento OnKeyPress de um Edit

Emular o pressionamento de um botão


If (key = VK_F1) then btnAjuda.Onclick(Self);//no evento OnKeyPress

Para desabilitar o CTRL+ALT+DEL e ALT+TAB


Var
numero: integer;
begin
SystemParametersInfo(97,Word(true),@numero,0);
end;
{ Para habilitar é só chamar a mesma função com Word(false) }

Trabalhando com a Guia Dialogs


SaveDialog
if SaveDialog1.Execute then
begin
Memo1.Lines.SaveToFile (SaveDialog1.FileName); // pode ser um RichEdit
end;
OpenDialog
if OpenDialog1.Execute then
begin
Memo1.Lines.LoadFromFile(OpenDialog1.FileName) ; // poderia ser um RichEdit
end ;
OpenPictureDialog
if OpenPictureDialog1.Execute then
image1.Picture.LoadFromFile (OpenPictureDialog1.fileName) ; // carrega uma imagem no componente
FontDialog
if FontDialog1.Execute then
begin
Memo1.Font := Font;// poderia ser um RichEdit
end;
ou...
with FontDialog1 dobr> begin
Font := Label1.Font;
if Execute then
Label1.Font := Font;
end;
colordialog
if colordialog1.Execute then
begin
with ColorDialog1 do
begin
Color := Label1.Color;
ou...
if Execute then
Label1.Color := Color;
end;
RichEdit.Color := Color;
end;
PrintDialog
PrintDialog1.Execute;

Trabalhando com Data e Hora


DateToStr(Date) ==> 21/09/01
TimeToStr(Time) ==> 11:50:00
FormatDateTime('d',Date); ==>21
FormatDateTime('d/m/y',Date);==> 21/9/01
FormatDateTime('dd/mm/yy',Date); ==>21/09/01
FormatDateTime('ddd/dd/mm/yy',Date); ==> Sex/05/09/01
FormatDateTime('dddd/dd/mmmm/yyyy',Date); ==> Sexta-feira/Setembro/1999
FormatDateTime('ddddd',Date); ==> 05/09/99
FormatDateTime('dddddd',Date); ==> Sexta=Feria, 21 de Setembro de 2001

Label1.caption := timetostr(time);
Label1.caption := datetostr(date);
// Somar uma data
var
Ts1, ts2 : TTimeStamp;
Data1, Data2 : TDateTime;
Dias : Integer;
begin
Date1 := StrtoDate(edit1.text);
Date2 := StrtoDate(edit2.text);
Ts1 := DateTimetoTimeStamp(Data1);
Ts2 := DateTimetoTimeStamp(Data2);
Dias := Ts2.Date - Ts1.Date;
Edit3.Text := InttoStr(Dias);
if Dias > 10 then
ShowMessage('Passaram-se 10 dias');
end;
O Dia da Semana
function DayOfWeek(Data:TDataTime):Integer;
Ex.:Label1.Caption:= 'Data e Hora Atual' + DateTimeToStr(Now);
- Retorna o dia da semana em um inteiro de 1 a 7.

Métodos e Propriedades do Form


Show // exibe um form
Hide // esconde um form mas não o descarrega
Print // imprime um form
SetFocus // establece o foco para um form ou componente
BringtoFront // envia o frente

Form1.formstyle := fsOntop; // para um formulário aparcer sobre outros sempre

Texto em um form
canvas.textout(0,0,'Este texto aparece no form. Top e Left zerados');

Form Elíptico
No evento OnCreate do form, digite:
var hR : THandle;
begin
{cria uma form de formato elíptico}
hR := CreateEllipticRgn (0,0,Width,Height);
SetWindowRgn (Handle,hR,True);
end;
Obs. Também é bom alterar a propriedade BorderStyle para bsNone. O tamanho da elípse é definido pelo tamanho
do form.

Para criar um form em tempo de execução


NovoForm:= TfmFilho.Create (self);
NovoForm.Parent := self;

Form em tempo de execução II


Application.CreateForm(TForm2, Form2); //Cria o form
Form2.ShowModal ;
Form2.free; // Libera o form da memória

Form em tempo de execução III


Application.CreateForm(TFormTal, FormTal);
FormTal.ShowModal;
FormTal.Free;

Criando um QuickReport em tempo de execução


qrMovCaixa := TqrMovCaixa.Create(self);
DMNL.qrMovCaixa.Open;
qrMovCaixa.Preview;
qrMovCaixa.Free;

evitar que se tente abrir o mesmo Form, duas vezes


if form1 = nil then // se o form1 ainda não foi criado...
... comandos para criar um form...
//colocar no evento OnClose:
form1 := nil;

Para executar um outro aplicativo apartir do Delphi


If Winexec('c:\windows\calc.exe',sw_shownormal)= 2 then showmessage('Arquivo não encontrado');

Diretório do aplicativo
// No evento OnCreate, digite:
var
PathName: string;
begin
PathName := ExtractFilePath (ParamStr (0));
Label1.Caption := 'Estamos em: '+ PathName;
end;

O Componente TComboBox
Para abrir um TComboBox sem clica-lo, digite:
ComboBox1.DroppedDown := True;

StringList - Lista de strings


Colocar na cláusula uses a unit 'Classes'
Declarar a instância da classe
{ Private declarations }
MinhaLista: TStringList;
Executar o método construtor para instanciar a classe
MinhaLista := TStringList.Create();
Depois de instanciada, os métodos e propriedades da classe ficam disponíveis
MinhaLista.Add(Edit1.Text);
Ver o conteúdo...
Label1.Caption := MinhaLista.GetText ;
ou...
var
i : integer;
begin
for i := 0 to MinhaLista.Count-1 do
ListBox1.Items.Add (MinhaLista.Strings[i]);
end;
Último passo: Destruir a instância com o método destrutor
MinhaLista.Destroy;
Trabalhando com Case... of
Criando seleções
var Seletor : char;
begin
Seletor := 'C';
Case Seletor of
'A' : ShowMessage('Escolhido A');
'B' : ShowMessage('Escolhido B');
'C' : Begin
Showmessage('Escolhido C');
Halt; // encerra o programa
end;
else// caso não seja uma destas letras
ShowMessage('Não escolhido um destes ítems');
end;
Trabalhando com Case II
Case RadioGroup1.ItemIndex of
0 : Form2.BorderStyle := bsDialog;
1 : Form2.BorderStyle := dbNone;
end;
Usando o Repeat
var
N : String;
begin
Repeat;
N := Inputbox('GetNumber', 'Insira um número','');
Until N:= '7';
end;
Atribuir Mesmo Valor para Vários Edits em um Form
for i := 0 to ComponentCount - 1 do
if Components[i] is TEdit then
TEdit(Components[i]).Text := Valor;

Testa se há disco no Drive A:


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;

Usando Enter no lugar de TAB


// Coloque no form: keypreview = true. No ONKEYDOWN, digite:
if (Key= VK_RETURN) or (Key= VK_DOWN) then
begin
Key := 0;
Perform(WM_NEXTDLGCTL, 0, 0);
end
else
if (Key= VK_UP) then
begin
Key := 0;
Perform(WM_NEXTDLGCTL, 1, 0);
end;
Close em um Form
OnCloseQuery //No evento OnCloseQuery. A segunda opção ("Não") recebe o foco.
CanClose := Application.MessageBox( 'Confirme Operação','Terminar Aplicação ?',
MB_ICONQUESTION + MB_YESNO + MB_DEFBUTTON2 ) = ID_YES;

Salvar dados antes de fechar:


//no evento OnClose:
if Table1.Modified then
if Application.MessageBox('Gravar alterações?','Dados Alterado',MB_ICONQUESTION + MB_YESNO) = IDYES
then
Table1.Post
else
Table1.Cancel

Obtendo o número 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+':\'),dLabel,12,@Serial,DirLen,Flags,nil,0);
Result := IntToHex(Serial,8);
Except
Result :='';
end;
end;

BANCO DE DADOS
SENHAS
// Senha usadas na maioria dos programas
No Campo Var, Digite :
Contador : integer;
Vs : string
Em Usues, Digite : DB;
No botão Ok, digite
if not Table1.FindKey([edit1.Text]) then // o campo chave é Nome
begin
ShowMessage('UsuárioDesconhecido');
inc (contador);
if contador = 4 then
begin
ShowMessage(‘ Sua chance acabou');
FmPrincipal.Close;
end;
Exit; (* para encerrar *)
end;
vs:=Table1.findField(‘Login’).asString;
if vs<>Edit2.text then
begin
ShowMessage('Senha Errada');
inc(contador);
if contador=4 then
fmPrincipal.close;
Edit2.setFocus;
exit;
end;
fmPrincipal.Enabled:=True;
fmSenha.close;

Criando Tabelas
Através da função FieldDefs.ADD. Parâmetros: nome do campo, tipo, Tamanho, Chave_Primária.
Procedure Cria_Tabela(Alias,Nome_Tabela:String);
Begin
With TTable.Create(Application) do
begin
Active := False;
DatabaseName :=Alias;
TableName := Nome_Tabela;;
TableType := ttDefault;
FieldDefs.Add('CODCLI', ftString, 5, False);
FieldDefs.Add('NOMCLI', ftString, 40, False);
FieldDefs.Add('DATCAD', ftDate, 0, False);
CreateTable;
Free;
end;
end;

Como Usar:
procedure TForm1.Button1Click(Sender: TObject);
begin
Cria_Tabela('C:\Temp','Alunos.db');
end;

LOCALIZAR
//nesta caixa de diálogo, o campo nome tem que ser o primeiro
var // uma variárvel tem que ser criada.
nome : string;

Nome : = inputbox( ' Localizar ' , ' digite o nome ' , ' ' ) ;
if nome <> ' ' then
begin
if not table1.findkey ( [ nome ] ) then
showmessage ( ' nome não encontrado ' ) ;
end;
Simplificando: Table1.findkey([edit1.text])

ou
table1.setkey;
table1.fields[0].AsString := Edit1.text;
Table1.GotoKey;

Apenas a linha abaixo :


Table1.FindKey([Edit1.Text]);
Apenas a linha abaixo :
Table1.FindNearest([Edit1.Text]);
Table1.SetKey; // Primeiro campo é a chave
Table1.FieldName('Cidade') := Edit1.Text;
Table1.GotoKey;

Table1.IndexName := 'NomeCliente'; // procurar em um índice secundário


Table1.Open;
Table1.SetKey;
table1NomeCliente.AsString := Edit1.Text;
Table1.GotoNearest;
.
// Procurar em um índice primário ou secundário
Table1.IndexName := 'Nome'
Table1.Open;
Table1.SetKey;
Table1Nome_Cliente.AsString := Edit1.Text;
Table1.GotoNearest;

Locate// procura em um índice primário ou secundário


Table1.Locate('Nome',Trim(Edit1.text),[LoPartialKey,loCaseInsensitive]);
if not DM.Table1.Locate('Vendedor;Data',VarArrayOf([EditVendedor.text, EditData.text]),[loCaseInsensitive]) then
ShowMessage('O vendedor não realizou venda nesa data');

FindKey
//Procura um nome em um campo. ( no primeiro campo ).
// No evento OnClick do Botão Ok, digite
begin
if not DataModule.tsenha.FindKey ( [ editNome.text ] ) then
beguin
ShowMessage ( ' senha desconhecida ' );
Exit;
end ;

Exceções
Access violation
Decrare a constante:
const
ChaveViolada = 9729;
No evento OnPostError da tabela, digite:
if (E is EDBEngineError) then
if (E as EDBEngineError).Error[0].Errorcode = ChaveViolada then
begin
Table1.Cancel;
ShowMessage('este código já existe');
end;
abort

Outras exceções
if(E is EDBEngineError) then
with EDBEngineError(E) do
case Errors[0].ErrorCode of
DBIERR_KEYVIOL: ShowMessage('Cliente já cadastrado.');
DBIERR_REQDERR: ShowMessage('Campo obrigatório não preenchido.');
end
else
ShowMessage('Erro no banco de dados:' + #13#13 + E.Message);
Action := daAbort;

0 SQL
//Seleciona todos os campos da tabela cliente
Select * from cliente

//Selecione todos os campos da tabela cliente e produto


Select * from cliente, produto

//Selecione o campo nproduto da tabela produto


Select Nproduto form produto

//Selecione os campos nproduto e descrição da tabela produto


Select nprodutos, descrição from produto

//Selecione todos os campos da tabela produto onde nproduto seja igual a 004
Select * from produto where nproduto = 004

//Selecione os campos descrição e preço produto onde nproduto


seja igual a 004
Select descrição, preço from produto Where nproduto = 004

//Selecione todos os campos da tabela cliente onde ncliente


seja maior que 01 e menor que 04
Select * from cliente where ncliente > 01 and ncliente < 04

//Exibir seus dados em ordem ascendente (A a Z, 0 a 9).


SELECT Sobrenome, Nome FROM Funcionários ORDER BY Sobrenome;
SELECT Sobrenome, Nome FROM Funcionários ORDER BY Sobrenome ASC;

//Selecione todos os campos da tabela cliente organizadopor nome


Select * form cliente order by nome

//Selecione os campos nprodutos e descrição da tabela produto organizado por descrição


Select nProdutos, descrição from produto order by descrição

//Selecione todos os campos da tabela produto organizado por nproduto em ordem descendente
Select * from produto order by nproduto desc

//Classificar em ordem descendente (Z a A, 9 a 0), adicione a palavra reservada DESC ao final de cada campo
SELECT Sobrenome, Salário FROM Funcionários ORDER BY Salário DESC, Sobrenome;

//Esse exemplo ordena os registros pelo sobrenome, em ordem descendente (Z-A).


SELECT Sobrenome, Nome FROM Funcionários ORDER BY Sobrenome DESC;

//Esse exemplo ordena, primeiro, por categoria ID e depois por nome do produto.
SELECT CategoriaID, ProdutoNome, PreçoUnit FROM Produtos ORDER BY CategoriaID, NomeProduto;

//Selecione os campos descrição, preço e o valor de preço + 20 de tabela produto onde nproduto = 004
Select descrição, preço, preço + 20 from produto where nproduto = 004

//Selecione todos os campos da tabela Leitores onde o campo nome seja iguas a 'João'
Select * from Leitores where Nome = 'João Cabral'

//Selecione todos os campos da tabela cliente onde o campo nome inicie com Vis* desprezando os outros caracteres
Select * from cliente where nome LIKE 'Vis%'

//Selecione todos os campo da tabela leitor onde o campo CPF é nulo


Select * from Leitor where CPF is Null

Select nproduto + '', '' + descrição AS Itens, preço from produto


Selecione nproduto + '', '' + descrição AS Itens, preço (junte os campos como Itens) da tabela produto
//Qual seria o salário se cada funcionário recebesse um aumento de 10 porcento. Não altera o valor original dos
salários.
SELECT Sobrenome, Salário AS Atual, Salário * 1.1 AS Proposto FROM Funcionários;

//Coloca o título Nome no topo da coluna "Sobrenome". O título Salário, no topo da coluna "Salário".
SELECT Sobrenome AS Nome, Salário FROM Funcionários;

Select nproduto from pedido/ produto where nPedido = 1


Select nproduto from pedido / produto where nProduto = 2
Select nproduto from pedido / produto where npedido = 1 UNION ALL Select
nproduto From pedido/ produto where nProduto = 2

Select * from pedido where nproduto beteeen 2 and 5


Selecione todos os campos da tabela pedido onde o campo nproduto esteja entre 2 e 5

Selecione todos os campos da tabela pedido onde o campo npedido esteja entre 2 e 5
Select * from pedido where nproduto IN ( 2,5 )

Select DISTINCT * from pedido/produto


Selecione retirando as duplicatas do campo nproduto da tabela pedido/produto

Select TOP 3 from produto


Selecione os primeiros 3 registros da tabela produto

Select Ucase ( descrição) from produto


Selecione ( descrição ) o campo descrição em maiúsculo da tabela produto
Select COUNT ( * ) as quantidade from produto where preço > 50,00

//Conta o número de registros que têm uma entrada no campo "CódigoPostal" e nomeia o campo retornado como
"Tcp".
SELECT Count(CódigoPostal) AS Tcp FROM Clientes;

Selecione o campo descrição em maiusculo da tabela produto


Select SUM ( quantidade) from pedido/produto where nproduto = 1
Selecione a soma do campo soma da tabela pedido/produto onde nproduto= 1
Select min ( quantidade ) from pedido/ produto Selecione a menor quantidade do campo quantidade da tabela pedido
/ produto: pedido/produto

Select MAX ( quantidade ) from pedido / produto

//Seleciona Departamento da tabela Funcionários e NomeSupv da tabela Supervisores:


SELECT Funcionários.Departamento, Supervisores.NomeSupv FROM Funcionários INNER JOIN Supervisores
WHERE Funcionários.Departamento = Supervisores.Departamento;
//O exemplo abaixo usa o título Nasc para nomear o objeto Field retornado no objeto Recordset resultante:
SELECT DataNasc AS Nasc FROM Funcionários;
//O exemplo abaixo usa o título Contagem para nomear o objeto Field retornado no objeto Recordset resultante:
SELECT COUNT(FuncionárioID) AS Contagem FROM Funcionários;

SELECT CategoriaID, Sum(UnidadesNoEstoque) FROM Produtos GROUP BY CategoriaID HAVING


Sum(UnidadesNoEstoque) > 100 AND LIKE "BOS*";

// O exemplo abaixo habilita o usuário a ver as informações de salário (mesmo que não tenha outra permissão para
ver a tabela Folha de Pagamentos) desde que o proprietário da consulta tenha tal permissão:
SELECT Sobrenome, Nome, Salário FROM Funcionários ORDER BY Sobrenome WITH OWNERACCESS
OPTION;
//O número de funcionários e os salários médio e máximo.
SELECT Count(*) AS [Total de Funcionários], Avg(Salário) AS [Salário Médio], Max(Salário) AS [Salário
Máximo] FROM Funcionários;

//Para cada registro, mostra Sobrenome e Salário no primeiro e último campos. A seqüência de caracteres "tem um
salário de" é retornada como o campo do meio de cada registro.
SELECT Sobrenome, 'tem um salário de', Salário FROM Funcionários;

//Cria uma lista de nomes de departamentos únicos e o número de funcionários em cada um destes departamentos.
SELECT Departamento, Count([Departamento]) AS Tbc FROM Funcionários GROUP BY Departamento;

//Para cada título de função único, calcula o número de funcionários do departamento de Vendas que têm este
título.
SELECT Título, Count(Título) AS Tbc FROM Funcionários WHERE Departamento = 'Vendas' GROUP BY Título;

//Calcula o número de itens em estoque para cada combinação de número e cor do item.
SELECT Item, Sum(Unidades) AS Tbc FROM ItensEmEstoque GROUP BY Item, Cor;

//Seleciona os títulos de cargos do departamento de Produção atribuídos a mais de 50 funcionários.


SELECT Título, Count(Título) FROM Funcionários WHERE Departamento = 'Produção' GROUP BY Título
HAVING Count(Título) > 50;

//Esse exemplo seleciona os departamentos que tenham mais de 100 funcionários.


SELECT Departamento, Count([Departamento]) FROM Funcionários GROUP BY Departamento HAVING
Count(Departamento) > 100;

//Seleciona todos os registros de "Novos Clientes" e os adiciona à tabela "Clientes" (quando não são designadas
colunas individuais, os nomes das colunas das tabelas SELECT devem corresponder exatamente aos da tabela
INSERT INTO).
INSERT INTO Clientes SELECT [Novos Clientes].* FROM [Novos Clientes];

//Esse exemplo cria um novo registro na tabela "Funcionários"


INSERT INTO Funcionários (Nome,Sobrenome, Título) VALUES ("André", "Pereira", "Estagiário");

Seleciona todos os estagiários de "Estagiários" que foram contratados há mais de 30 dias e adiciona seus registros
à tabela "Funcionários".
INSERT INTO Funcionários SELECT Estagiários.* FROM Estagiários WHERE DataContrato < Now() - 30;

//Aumenta o Valor do Pedido em 10 % e o valor do Frete em 3 % para embarques do Reino Unido:


UPDATE Pedidos SET ValorPedido = ValorPedido * 1.1, Frete = Frete * 1.03 WHERE PaísEmbarque = 'RU';

//Muda os valores no campo "RelatórioPara" para 5 para todos os registros de funcionários que atualmente têm
valores de RelatórioPara de 2.
UPDATE Funcionários SET RelatórioPara = 5 WHERE RelatórioPara = 2;

//Aumenta o "PreçoUnit" de todos os produtos não suspensos do fornecedor 8 em 10 porcento.


UPDATE Produtos SET PreçoUnit = PreçoUnit * 1.1 WHERE FornecedorID = 8 AND Suspenso = No;

//Reduz o PreçoUnit de todos os produtos não suspensos fornecidos pela Tokyo Traders em 5 porcento. As tabelas
"Produtos" e "Fornecedores" têm uma relação um para vários.
UPDATE Fornecedores INNER JOIN Produtos ON Fornecedores.FornecedorID = Produtos.FornecedorID
SET PreçoUnit = PreçoUnit * .95 WHERE NomeEmpresa = 'Tokyo Traders' AND Suspenso = No;

//Exclui todos os registros de funcionários cujo título seja Estagiário. Quando a cláusula FROM inclui apenas uma
tabela, não é necessário indicar o nome da tabela na instrução DELETE.
DELETE *FROM Funcionários WHERE Título = 'Estagiário';

//Exclui todos os registros de funcionários cujo título seja Estagiário e que também tenham um registro na tabela
"FolhadePagamento". As tabelas "Funcionários" e "FolhadePagamento" têm uma relação um por um.
DELETE Funcionários.* FROM Funcionários INNER JOIN FolhaDePagamento
ON Funcionários.FuncionárioID = FolhadePagamento.FuncionárioID
WHERE Funcionários.Título = 'Estagiário';

//Retorna todos os produtos cujo preço unitário é maior que o preço de qualquer produto vendido com um desconto
de 25 % ou mais:
SELECT * FROM Produtos WHERE PreçoUnit > ANY (SELECT PreçoUnit FROM PedidoDetalhes
WHERE Desconto >= .25);

//Retorna todos os produtos com um desconto de 25 % ou mais:


SELECT * FROM Produtos WHERE ProdutoID IN (SELECT ProdutoID FROM PedidoDetalhes WHERE
Desconto >= .25);

//Retorna os nomes dos funcionários cujos salários sejam iguais ou superiores à média de salários de todos os
funcionários na mesma função. Para a tabela Funcionários é dada o alias "T1":
SELECT Sobrenome, Nome, Título, Salário FROM Funcionários AS T1 WHERE Salário >= (SELECT
Avg(Salário) FROM Funcionários WHERE T1. T1.Título = Funcionários.Título) Order by Title;

//Lista o nome, título e salário de todos os representantes de vendas cujos salários sejam superiores aos de todos os
gerentes e diretores.
SELECT Sobrenome, Nome, Título, Salário FROM Funcionários WHERE Título LIKE "*Repr Vendas*"
AND Salário > ALL
(SELECT Salário FROM Funcionários WHERE (Título LIKE "*Gerente*") OR (Título LIKE
"*Diretor*"));

//Lista o nome e preço unitário de todos os produtos cujo preço unitário seja igual ao do Licor de Cacau.
SELECT NomeProduto, PreçoUnit FROM, Produtos WHERE PreçoUnit = (SELECT PreçoUnit FROM
[Produtos]
WHERE NomeProduto = "Licor de Cacau");

//Lista a empresa e o contato de cada empresa de todos os clientes que fizeram pedidos no segundo trimestre de
1995.
SELECT NomeContato, NomeEmpresa, ContatoTítulo, Fone FROM Clientes
WHERE ClienteID IN (SELECT ClienteID FROM Pedidos
WHERE DataPedido BETWEEN #1/04/95# AND #1/07/95#);

//Lista os funcionários cujo salário seja maior que a média dos salários de todos os funcionários.
SELECT Sobrenome, Nome, Título, Salário FROM Funcionários T1 WHERE Salário >= (SELECT
AVG(Salário) FROM Funcionários
WHERE Funcionários.Título = T1.Título) ORDER BY Título;

//Seleciona o nome de todos os funcionários que tenham registrado pelo menos um pedido. Isto também poderia ser
feito com INNER JOIN.
SELECT Nome, Sobrenome FROM Funcionários AS E WHERE EXISTS (SELECT * FROM Pedidos AS O
WHERE O.FuncionárioID = E.FuncionárioID);

//Altera o campo Efetuado do arquivo de serviços para 2 caso o mesmo tenha parecer técnico da entidade
encaminhanhamento diferente de nulo.
UPDATE servico SET efetuado = 2 WHERE numero_servico = ANY (SELECT servico.numero_servico
FROM servico INNER JOIN encaminhamento ON (servico.numero_servico = encaminhamento.
numero_servico)
AND (servico. ano_servico = encaminhamento.ano_servico) WHERE (((servico.efetuado) Is Null) AND
((encaminhamento.parecer_tecnico) Is Not Null))
GROUP BY servico.numero_servico ORDER BY servico.numero_servico);

Query - Parametros
// digitar no SQL do query
{ Select * from geral where Nome like :ord
Na properties Params colocar : Name := Ord, Value := %}

Fields
var s : string;
begin
s := Table1.Fields [0].FieldName; //retorna o nome do primeiro campo da tabela
s := Table1.Fields [1] .asString; // retorna o conteúdo 2º campo da tabela
s := Table1.FieldByName( ' nome ' ).AsString; //retorna o valor na coluna 'nome'
s := Table1['Nome'] ; //retorna o valor do compo selecionado

Label1.Caption := s ; // retorna o valor da string

Indexar uma Tabela


Table1.IndexFieldNames := 'Nomecli';
Table2.IndexFieldNames := 'Data, Vendedor';

ListBox
// esta rotina exibe em um listbox os campos de uma tabela
var
i: Integer;
begin
ListBox1.Clear;
for i := 0 to table1.fieldcount - 1 do
Listbox1.items.add(table1.fields[i].fieldname);
end;

//Faz um ListBox exibir o conteúdo de uma tabela


var
i: Integer;
begin
ListBox1.Clear;
for i := 0 to Table1.FieldCount - 1 do
ListBox2.Items.Add(Table1.Fields[i].AsString);
end;

BOOKMARKS
//guardar uma posição no registro
var
BM :tBookMark;
{...}
// Grava um Registro
if bm = nil then // se bm está vazio então...
bm := table1.GetBookMark; // marque um
ou
if BookMark = nil then
BookMark := Table1.GetBookMark;
{++}

// ir para o registro guardado


if BookMark <> nil then // se o BookMark não está vazio...
begin
table1.GotoBookMark(BookMark) // vá para o marcado
end;
ou..
if BM <> nil then
begin
BM := table1.GetBookMark(BM);

{++}
//limpa da memória o registro guardado
if BookMark <> nil then // se o BookMark não está vazio então faça..
begin
Table1.FreeBookMark (BookMark); // libere o marcado..
BookMark := nil; // deixe-o vazio
end;
ou
if bm <> nil then
begin
Table1.FreeBookMark (bm);
bm := nil;
end;
// conjunto de comandos
if BookMark < > nil then
begin
table1.GotoBookMark(BookMark);
Table1.FreeBookmark(BookMark);
BookMark := nil;
end;
Gravar em um banco de dados
tabel1.edit;// abre o dataset
tabel1['senha'] := 'Marvel'; // edita 'Marvel' no campo senha
tabel1.post; // grava a informação

Filter
Table1.Filtered := false;
Table1.Filter := 'idade > 30 ' ;
(ex: Table1.Filter := 'Nota1>=' + '''' + Edit1.text + ''''';)
Table1.Filtered := true;

Filter II
Table1.SetRangeStart;
Table1.FieldbyName('código') := 100;//Table1Codigo.AsInteger := 100
Table1.KeyExclusive := False;
Table1.SetRageEnd;
Table1.FieldbyName('Codigo') := 200; //Table1Codigo.AsInteger := 200
Table1.KeyExclusive := true;
Table1.ApplyRange

// Aplicar um filtro usando um CHECKBOX


Table1.Filtered := checkbox1.Checked;
// No componente TABLE, no evento OnFilterRecord
Accept := Table1['Nome']= Edit1.Text
// Um botão pode seguir para o próximo ítem procurado
Table1.FindNext

Soma
// RecordCount, conta quantos registros ha na Tabela
Label1.Caption := InttoStr(Table1.Recordcount);

Os estados de um Data Base


if Table1.State = dsEdit then
begin...
Para saber o Estado de um DataBase. Digite no Evento OnStateChange do DataSourse:
Var
S : String; begin
Case Table1.State of
dsInactive : S := 'Inativo';
dsBrownse : S := 'Browse';
dsEdit : S := 'Edição';
dsInsert : S := 'Inserção';
dsSetKey : S := 'SetKey';
dsCalcFields : S := 'CalkFields';
end;
Label1.Caption := S;

//Para digitar só números em um edit


No evento KeyPress, digite:
if not (Key in['0'..'9',Chr(8)]) then Key:= #0;
// Obs: Chr(8), para BackSpace e DecimalSeparator, para a vírgula dentro dos colchetes.
Alias
Criando um alias..
Check(DBiAddAlias(Nil, Pchar('AliasName'),Nil, Pchar('AliasPath), true));
AliasName = nome do alias;
AliasPath = caminho do alias;
Inclua em Uses = BDE e BD;

Criando um alias temporário


// Utilizando o componente TSession
// No evento OnShow, digite:
session1.ConfigMode:=cmSession;
Session1.AddStandardAlias('NomedoAlias','C:\Arquivos de Programas\Arquivos comuns\Borland
Shared\Data','PARADOX');
Table1.OPen;
// No componete TTable, digite o nome do Alias e o nome da tabela

Atualizando as informações em ambiente de rede


Acessando a mesma tabela concorrente com outra estação ou outro objeto Query, Table
a) Crie procedure para uso no evento OnActive:
Procedue TTorm1.FormRefresh(Sender: TObject);
begin
Table1.Refresh;
...
TableN.Refresh;
end;
b)No evento OnActive do formulário acrescente a linha:
Application.OnActive := FormRefresh;
c) No evento OnShow do formulário acreste a linha
FormRefresh(Sender);
d) No evento OnAfterPost de cada objeto TTable acrescente as linhas;
Table.FlushBuffer;
FormRefres(Self);
Salvando os Dados Fisicamente em uma Tabela
USES DBIProcs;
Nos eventos OnAfterPost e OnAfterDelete, digite:
DBISaveChanges(Table1.handle);
Salvando Os dados Visicamente II
USES BDE:
DbiSaveChandges((Dataset as TTable).Handle);
O DBNavigator
//Para pegar o nome do botão que foi pressionado
DBNavigator1.BtnClick(nbNext);

// pegando o botão clicado


if Button in [nbFirst,nbLast,nbPrior,nbNext] then
DBNavigator.DataSource.DataSet.Refresh;

MULTIMIDIA
Imagem no Form
Colocar uma figura bmp, no form sem o Picture
var
BitMap : TBitMap;
Begin
BitMap : = TBitMap.Creat ;
With BitMap do
Biguin
LoadFromFile( ' c : \ figura . bmp' ) ;
Transparent := true ;
Form1. Canvas . Draw (50,50, bitMap);
end:
end;
//Desktop, imagem no form
//Procedure TForm E. 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;

CopyFile, para copiar arquivos


CopyFile(pchar('c:\conto.txt'),('a:\conto.txt'),false);
// no final: true=não regrava o arquivo, se false, ele regrava.

A Tecla Pressionada
//No evento OnKeyDown, digite:
Label1.Caption := Format('O código da tecla é: %d', [Key]);

O componente TMediaPlayer
Para ouvir um som
With MediaPlayer1 do
begin
FileName := 'c:\bettoven.wav'; // pode ser um Mid
Open;
Play;
end;

Para ver um *.avi no form...


with MediaPlayer1 do
begin
FileName := 'c:\super.avi';
Open;
Display := Form2;
Form2.Show;
Play;
end;

Arquivos Texto
Carregando o texto em um RichEdit
RichEdit1.Lines.LoadFromFile('c:\aviso.txt');
//colocando cores
ReachEdit1.Font.Color := clGreen;
Estilos de Texto
//testo em negrito
if CheckNegrito.Checked then //Para o botão Negrito
Memo1.Font.Style := Memo1.Font.Style + [fsBold] // coloca em estilo negrito
else
Memo1.Font.Style := Memo1.Font.Style - [fsBold]; // retira o estilo negrito
//Memo1.Font.Style := Memo1.Font.Style + [fsItalic] // Para o botão Itálico
//Memo1.Font.Style := Memo1.Font.Style + [fsUnderline] // Para o botão Sublinhado

//testo em negrito II
if BoldButton.Down then
CurrText.Style := CurrText.Style + [fsBold]
else
CurrText.Style := CurrText.Style - [fsBold];
end;
function TMainForm.CurrText: TTextAttributes;
begin
if Editor.SelLength > 0 then Result := Editor.SelAttributes
else Result := Editor.DefAttributes;
end;

Alinhamento do texto
{taLeftJustify, taCenter, taRightJustify}
Label1.Alignment := taLeftJustify;
Trabalhando com Arquivos .INI
Acrescente a unit inifiles na guia uses
//declare uma variável inifile:
ArqIni: TIniFile;
//no evento OnCreate, do form, digite:
ArqIni := TIniFile.Create('c:\windows\ArqIni.ini');
lendo um arquivo ini
// lendo um valor string:
EditString.Text := ArqIni.ReadString('String', 'texto', '');
//lendo um valor inteiro:
EditString.Top := ArqIni.ReadInteger('Integer', 'altura', 0);
//lendo um valor boolean
EditString.Visible := ArqIni.ReadBool('Boolean', 'visivel',False);
//lendo um arquivo ini em um meno:
Memo1.Lines.LoadFromFile('c:\inicial.ini');
gravando em um arquivo .ini
//gravando um valor string
ArqIni.WriteString('String', 'texto', EditString.Text);
//gravando um valor inteiro
ArqIni.WriteInteger('Integer', 'altura', SpinEdit1.value);
// gravando um valor boolean
ArqIni.WriteBool('Boolean', 'visivel', CheckBox1.Checked);

//no evento OnDestroy, do form, libere o nosso arquivo


ArqIni.Free;

Movimento
fazer um panel ter seu texto em movimento
var
texto : string;
begin
texto : = panel1.caption;
panel1.caption := copy(texto,2,length (texto)) + texto[1];
end;

ColorGrid
Form1.Color := ColorGrid1.ForegroundColor ; //botão esquerdo do mouse
Form1.Color := ColorGrid1.BackgroundColor ;// botão direito do mouse

Movendo Arquivos
var
origem, destino : string;
begin
origem := 'c:\delete\faq.txt';
destino:= 'c:\games\faq.txt';
if not copyfile(pchar(origem),pchar(destino),true) then
showMessage ( 'problemas com' + origem + 'para' + destino)

MOVENDO UM OBJETO
// Coleque em um objeto ( ex: um Button)
// Na guia VAR, digite
MouseDownSpot : TPoint;
Capturing : bool;
// No evento OnMouseDown
SetCapture(Button1.Handle);
Capturing := true;
MouseDownSpot.X := x;
MouseDownSpot.Y := Y;
// No evento OnMouseMove
if Capturing then
begin
Button1.Left:= Button1.Left-(MouseDownSpot.x -x);
Button1.Top:= Button1.Top - (MouseDownSpot.y -y);
end;
// No evento OnMouseUp
if Capturing then
begin
ReleaseCapture;
Capturing := false;
Button1.Left := Button1.Left - (MouseDownSpot.x -x);
Button1.Top := Button1.Top - (MouseDownSpot.y - y);
end;

Arquivos Help
// digite a linha abaixo para chamar um arquivo help
WinHelp(Form1.handle, 'c:\Ajuda.hlp', HELP_CONTENTES,0);

Randomize
//A linha de comando abaixo faz o label exibir aleatóriamente um número de 1 a 100
Label1.Caption := InttoStr(Random(100));

Hint
//colocar no evento OnCreate do form principal..
Application.HintColor := clYellow; // define a cor de todos os hints
Application.HintPause := 200; // define o tempo de espera de um hint
btnOk.ShowHint := true; // habilita a exibição de um hint
btnOk.Hint := 'Clique aqui';// define o texto
Edit1.hint := 'Primeira linha' + #13 + 'segunda linha';//Hint com quebra de linha

Criar um componente em tempo de execução


var
PictImg1 : TImage;//declarando um TImage
begin
PictImg1 := tImage.Create(self);
PictImg1.Height := 200;
pictImg1.Width := 200;
PictImg1.Picture.LoadFromFile('C:\1.bmp');
PictImg1.parent := Self;
end;

Cores com RGB


//o form abaixo recebe a cor composta por:" red, green e blue"
Form1.Color := Rgb(100, 100, 100);

Progess Bar
Criando um ProgressBar em tempo de execução
//Declare a procedure abaixo
procedure TestProgress(Form: TForm; Count: SmallInt);
var
ProgressBar1: TProgressBar;
i: SmallInt;
begin
ProgressBar1 := TProgressBar.Create(Form);
try
ProgressBar1.Parent := Form;
ProgressBar1.Align := alBottom;
ProgressBar1.Min := 0;
ProgressBar1.Max := Count;
ProgressBar1.Step := 1;
for i := 1 to Count do
ProgressBar1.Stepit;
ShowMessage('Now the ProgressBar control will be freed');
finally
ProgressBar1.Free;
end;
end;
Finalmente, facha a chamada para o ProgessBar...
TestProgress(Self, 1000);
form2.show;

O Componente TCalendar
Calendar1.PrevYear;//para exibir o ano anterior
Calendar1.NextYear;//para exibir o proximo ano
Calendar1.PrevMonth;//para exibir o mês anterior
Calendar1.NextMonth;//para exibir o próximo mês
Calendar1.CalendarDate := CalendarDate - 1;// vai para um dia anterior
Calendar1.CalendarDate := CalendarDate + 1;// vai para o proximo dia

Arquivos .ini
Acresentar em Uses: IniFiles;
Declare:
Tini : TInifile;
Criando do arquivo. No evento OnCreate:
Tini := TInifile.Create('c:\super.ini');
Lendo em um arquivo...
Label1.Caption := Tini.ReadString('Label','titulo','');
Label1.top := Tini.ReadInteger('Label','top',0);
Label1.visible := Tini.ReadBool('Label','ver',true);

Gravando em um arquivo...
Tini.WriteString('label','titulo','Olá Mundo');
Tini.WriteInteger('label','top',10);
Tini.WriteBool('label','ver',true);

Ao findar tudo...
IniFile.Destroy;

Dias da semana
var
WeekDay : array[1..7] of string;
DayNo : integer;
QDay : string;
begin
weekday[1] := 'domingo
weekday[2] := 'segunda';
weekday[3] := 'ter‡a';
weekday[4] := 'quarta';
weekday[5] := 'quinta';
weekday[6] := 'sexta';
weekday[7] := 'sabado'; DayNo := DayofWeek(Date); // pega numero do dia da semana..
// a mensagem exibe o valor do array na posi‡Æo n. da semana
ShowMessage('O dia ‚: ' + WeekDay[DayNo]);

Verificando os dígitoso do ano


Function AnoQuatroDigitos: Boolean;
begin
Result := (Pos('yyyy',SHortDateFormat)>0);
if Result = True then
ShowMessage('O ano esta configurado para quatro dígitos.')
else
ShowMessage('O ano não esta configurado para quatro dígitos.');
end;

Trabalhando com Frames


// No menu File>New, insira um TFrame.
Declare em { Private declarations }
FFrame: TFrame;
// Dois botões usando a mesma variável do frame...
// botão um..
if FFrame <> nil then
FFrame.Free;
FFrame := TFrame1.Create(pnlParent);
FFrame.Align := alClient;
FFrame.Parent := pnlParent;

// botão dois..
if FFrame <> nil then
FFrame.Free;
FFrame := TFrame2.Create(pnlParent);
FFrame.Align := alClient;
FFrame.Parent := pnlParent;

Jogar uma imagem direto para um campo na tabela


var
BMP : TBitMap;
begin
BMP := TBitmap.Create;
if OpenPicutrueDialog1.Execute then
begin
BMP.LoadFromFile(OpenPictureDialog1.FileName);
Table1Graphic.Assign(BMP);
end;
TPrinter
//Uses Printers
BiginDoc = inicia uma impressão
EndDoc = finaliza uma impressão
Abrot = interrompe a impressão
Priting = para saber se esta havendo uma impressão
printers = lista as impressoras instaladas
PrinterIndex = indica a impessora selecionada
Fonts = lista as fontes da impressora
Orientation ( em Portrait ou LandScape) = orientação do papel
PageHeight = Altura da página
PageWidth = Largura da página
PageNumber = Número da página atual

INTERNET

Para executar um página da Web I


Winexec ( 'start c:\windows\index.html',sw_ShowMinimized )

Para executar um página da Web II


ShellExecute(Handle, 'open', HTMLFile, nil, nil, SW_SHOWNORMAL);
Chamando um site utilizando o seu browse padrão. Coloque em USES:UrlMon;
HlinkNavigateString(nil, 'http://www.geocities.com/escolarte');
//Verificando se você está conectado a Internet
//Inclua um componente TCP no Form, e digite o código:
if (TCP1.LocalIP = '0.0.0.0' or
TCP1.LocalIP = '127.0.0.1') then
ShowMessage('Não existe conexão')
else
ShowMessage('Existe Conexão')
Original : http://www.drbob42.com/delphi4/actions.htm

A new and handy feature of Delphi 4 - also present in C++Builder 4 by the way - is the
TActionList component, found in the "Standard" tab of the component palette. With an
ActionList, we can group and manage "actions" (event handling code) between different
components and even re-use them among different applications!
This article shows how to use Actions and ActionLists - without writing a single line of Delphi
or C++ code - and contains some nice gotchas too...

Using TActionList
Start a new application, and drop a TActionList component on the Form. Right-click with the
mouse on the ActionList1 component to get the Action List Editor. The Action List Editor
shows the action categories, and for each action category the individual actions that are
available for the current application.
We can define new actions, or select a number of existing (standard) actions. The latter can
be done by right-clicking with the mouse in the Action List Editor, and selecting the New
Standard Action menu:

This will give us a new dialog with the (current) list of standard actions. Note that we can
select more than one action at the same time by holding down the Ctrl key and clicking on
each individual item (see left figure below).
After we click on OK, we return to the Action List Editor which now shows two categories
(Edit and Window) and four actions in total (Copy, Cut and Paste for the Edit categories, and
MinimizeAll for Windows) - see right figure above.
It's now time to add some controls to the Form and connect them to these actions.

Control Action
Go to the Win32 tab of the component palette, and drop a ToolBar component on the form.
Right-click on it and select "New Button" to add a new button. Repeat this until you have
four buttons next to each other on the toolbar (tip: you may want to insert a separator
between the third and fourth button).
Now, click the left button, and set its Action property to EditCopy1. Set the Action property
of the second button to EditCut1, and the third button to EditPaste1. Finally, set the Action
property of the last button to WindowMinimizeAll1.
Before we compile and run this application, let me remind you that we now have four fully
functional toolbar buttons without having written a single line of code. That's because we're
using standard behavior that's already been provided to us as "standard" re-usable Actions.
But it gets even better, because we can share these actions with multiple components.
Go back to the Standard tab of the component palette, and drop a TMainMenu component
on the Form. Double-click on it (to get into the Menu Designer). Right-click on the Menu
Designer select "Insert from Template" and pick the Edit menu template. This gives us a list
of 10 menu items, while we only need three (Cut, Copy and Paste), but at least it saves us
some typing. You can easily remove the menu items that you don't need, by the way.
Go to the Cut1 menu item, and set its Action property to EditCut1. Set the Action property
of the Copy1 menu item to EditCopy1, and let Paste1 point to EditPaste1. We're now almost
ready to compile and run our application, but we need one more thing. Let's drop three
normal buttons on the form (again from the Standard tab), and connect them to EditCut1,
EditCopy1 and EditPaste1 like we've done twice before already. Note that the "regular"
buttons automatically get captions with "Cut", "Copy" and "Paste", where the speedbuttons
on the ToolBar remain empty (their Hint property it set, but not their caption).
A solution to this potential (confusing) problem can be implemented by assigning an
ImageList to the ActionList, so each action can get associated with a specific image. To do
this, drop a TImageList (from the Win32 tab) on the Form, and right-click on it to fill it with
some images. Set the Images property of the ActionList a component to ImageList1, and
double-click again on the ActionList to get the Action List Editor where we can now specify
which image should be used by which individual Action item by setting the ImageIndex for
each individual action:

Note that the speedbuttons on the toolbar and the images next to the menu texts still don't
show the images from the ImageList1 at design-time. In order to let them "share" the same
images, we must set the Images property of the ToolBar1 component to ImageList1, and do
the same with the Images property of the MainMenu1 component. The ImageIndex
properties will now be copied from the index belonging to the Action components, so each
action will look the same on a speedbutton or as a menu-item.
The really final thing we need to do is drop a TEdit component on the Form (after all, we
would need some Edit control to test the Cut, Copy and Paste actions with, right?). After
that, your application should resemble the following screenshot (at least a little bit, I hope):
Action!
Now, save your work, compile and run the application. Initially, all buttons and menu-items
will be disabled, meaning that we cannot Cut or Copy text, nor can we Paste any text at this
time. If your clipboard is filled with some text, and you select the editbox, then the Paste
buttons and menu-item get enabled automatically (at the same time). We can then select
the Paste menu, for example, and the text from the clipboard will be pasted inside the
editbox. As soon as we select some text from the editbox, the Cut and Copy buttons and
menu-items will get enabled as well (we can only Cut and Copy selected text, of course).
We can now click on the Cut or Copy speedbutton in the toolbar to get the effect we want.
Note that each Action items somehow "knows" when it can be executed (in our case: when
the current control is an editbox or memo, and - in case of Cut and Copy - whether or not
any text is currently selected). The Action items can enable and disable all controls that are
associated with them as soon as something changes that influences them (like selecting
text, or moving the focus from the editbox to another control, for example).

Problems?
This all seems to work fine. However, if you try to Cut, Copy or Paste text inside the editbox
using any of the "normal" buttons, then you will find that they do not appear to work. For
some reason, the big Cut button doesn't cut the text, nor does the bit Paste button paste it.
In fact, they only seem to result in de-selecting the text in the editbox (if any text was
selected), and moving the focus away... Strange!
Well, that last piece of information, regarding the focus, should have been a subtle hint: the
buttons take away the focus before the Action can be executed. In other words: the
Action expects an editbox to have the focus, but by the time the Action it executed, it's the
button that has the focus (if not for the Button's Click method that fires the action, the
action wouldn't even have been fired, since giving the button the focus means disabling the
action and all controls associated with the action).
Of course, the workaround is never to use any controls that can get the focus (like a
TButton which has a Windows handle), so the focus will never be list when we click on any
Action-bound control again. This is not something that's documented too well, however, and
I must admit that even I fell into this trap (while performing my Delphi 4 Workout in
London, by the way), so be aware.

Você também pode gostar