Você está na página 1de 168

1

Coleo de Dicas sobre


programao Delphi.






Retiradas do E-Zine Grandes
Dicas em Delphi



Por Ramos de Souza Janones






www.ramosdainformatica.com.br


2
ndice

1
ndice............................................................................................................................ 2
Descobrindo o cdigo ASCII de uma tecla.................................................................. 6
Funo - Retornando o prximo dia til....................................................................... 6
DBGrid - Colocando em Letras maisculas uma coluna selecionada.......................... 7
DBGrid - Mostrando todo contedo de um campo Memo........................................... 7
Crtica de datas no objeto Edit sem mensagem de erro do Delphi ............................. 10
Preenchimento de zeros para completar a data........................................................... 14
Multimdia - Fazendo suas aplicaes Delphi falar ................................................... 14
Multimdia - Toque um som quando o mouse passar por cima de um boto............. 15
Hints com multiplas linhas......................................................................................... 15
Multimdia - Usando cursores animados.................................................................... 16
Detectando a verso do Internet Explorer.................................................................. 16
QuickReport - Filtrando registros............................................................................... 17
Evitando efeito de maximizao................................................................................. 17
Calcula a quantidade de dias no ms.......................................................................... 18
Calculando abono salrial de modo progressivo........................................................ 18
Checa se um processo est rodando........................................................................... 19
Checa se um diretrio est vazio................................................................................ 20
dbExpress - Passando parmetros com CommandText via programao.................. 20
Corrigindo problemas de instalao do Borland Data Provider For Firebird............. 21
Lendo texto de um arquivo PDF ................................................................................ 21
Deixando seu EXE mais enxuto e rpido e, mais seguro contra decompilao......... 24
Copiando (Upload) um diretrio para um servidor FTP............................................ 26
Trabalhando com arquivos texto no Delphi ............................................................... 29
Criando uma conexo ao DBExpress em tempo de execuo.................................... 31
ActiveX - Pegar um texto selecionado no Internet Explorer...................................... 32
Cria um efeito na apresentao de um formulrio...................................................... 33
Criando um Menu transparente.................................................................................. 34
Checa se um diretrio est vazio................................................................................ 36
Mostra multiplas linhas de texto em um ComboBox................................................. 37
Criando atalhos no Windows pelo Delphi.................................................................. 38
Faa suas aplicaes Falar.......................................................................................... 39
Imprimindo arquivos PDF sem abrir-los.................................................................... 39
Ler arquivos PDF ....................................................................................................... 39
Inno Setup - Script para criao de conexo OBDC DSN......................................... 40
Colocar cursor no final do Edit ao receber o foco...................................................... 42
Mudar a cor de fundo de um Hint............................................................................... 42
Fazer um executvel ser executado somente se chamado por um determinado
executvel ................................................................................................................... 42
DBGrid - Focando a clula selecionada mudando sua cor......................................... 43
Verificando a verso do Windows............................................................................. 43
Rave Report - Alterar a impressora padro................................................................ 44
Atribundo efeitos para abertura de formulrios......................................................... 44
API do Windows - Funo para excluir uma pasta e todos arquivos desta pasta....... 45
Inno Setup - Verificando se existe determinada Chave no Registro do Windows..... 46
Controlando o PowerPoint no Delphi......................................................................... 46
Rave Report - Indicar pgina inicial........................................................................... 48
3
InnoSetup - Adicionar um programa no iniciar do Windows.................................... 48
Validando endereo de e-mail no Delphi em aplicaes Win32, .Net e Asp.Net...... 49
Memo redondo............................................................................................................ 50
Colocar Banners em Menus........................................................................................ 50
Usando a WebCam no Delphi .................................................................................... 51
Colocando imagens em um ComboBox..................................................................... 52
Importando e Exportando Registro............................................................................ 53
DBGrid - Colocar um ComboBox num DBGrid........................................................ 54
Enviando mensagens HTML com imagens anexadas................................................ 54
Mostrando dicas balo para caixas de edio wm WindowsXP................................ 56
CheckLisBox - Trocar a cor das linhas...................................................................... 57
Windows - Verificar a impressora padro.................................................................. 58
RichEdit - Pesquisar um texto, posicionar sobre ele e mostrar ao usurio................. 58
ActiveControl - Envia um valor para Edit que estiver em foco................................. 59
Registro do Windows - Retorna portas seriais........................................................... 59
Verifica se um programa est aberto, caso contrrio, abre......................................... 60
Funo que verifica a velocidade do processador...................................................... 60
DBGrid - Ao clicar no campo no DBGrid ordenar os registros................................. 61
Criando um lista Push and Pop em Delphi ................................................................. 61
Rave Report - Imprimindo cdigo de barras em modo de programao.................... 64
Gerar planilhas no Excel atravs de uma Query......................................................... 64
Rave Report - Somar valores...................................................................................... 65
Colorir componente focado - Preservando sua cor original ....................................... 66
ActiveControl - Envia valor para Edit que tiver em foco........................................... 67
TFields - Adiciona Fields no Fields Editors em tempo de execuo......................... 67
ListBox - Colorir ........................................................................................................ 69
Associando um extenso de arquivo a um executvel ............................................... 69
Retornar as contas de E-Mail...................................................................................... 70
HKEY, Registry......................................................................................................... 71
Criar e ler chave.......................................................................................................... 72
Retornar lista de hardware via registry....................................................................... 73
Verificar se um valor existe dentro de uma Chave..................................................... 73
Quick Report - Selecionando itens do ComboBox para PapeSize............................. 74
ListBox - Pesquisa incremental .................................................................................. 74
Acertar data e hora com o servidor............................................................................. 75
QuickReport - Access Violation no Windows 2000 e XP ......................................... 75
DBGrid - Alterar as cores do ttulo em tempo de execuo....................................... 75
Testa se a impressora est funcionando...................................................................... 76
Como implementar um AutoComplete num Edit comum.......................................... 76
Como adicionar um CheckBox em um StringGrig.................................................... 78
Abreviao automtica de nomes............................................................................... 80
Compilando a aplicao pelo MS-DOS..................................................................... 81
Colorao gradiente no Form..................................................................................... 82
Usar perfeitamente o LookupComboBox................................................................... 83
Como colocar um codigo para que a aplicacao feche apos XX segundos sem
atividades no teclado ou sem cliques do mouse. ........................................................ 83
Escondendo a barra de tarefas do Windows............................................................... 85
Pega todos os erros do Sistema, captura tela do erro, grava em arquivo e envia por e-
mail ............................................................................................................................. 85
Detectando o tipo de Conexo com a internet............................................................ 86
4
Funo de potenciao - J uros.................................................................................... 87
Para trocar as cores dos botoes do radiogroup........................................................... 87
Como criar uma figura do tipo marca d' gua............................................................ 88
Criptografando Imagens............................................................................................. 88
Alterar a fonte de determinado registro num DBGrid................................................ 89
Alinhar ttulo da barra de titulos do Form a esquerda ou direita................................ 89
Alterar fonte do Hint................................................................................................... 90
Criando arquivo Texto................................................................................................ 91
Como selecionar tudo (Ctrl+A) em um TMemo/TDBMemo..................................... 92
Mudando o IP da mquina via API do Windows....................................................... 93
Texto na diagonal e girando....................................................................................... 93
Criar um alias dinamicamente na memria................................................................ 94
Rodar videos em um panel ......................................................................................... 94
Como colocar uma coluna do DBGrid em maiuscula................................................ 95
DBGrid - Alinhando texto conforme condio.......................................................... 95
DBGrid - Colocando CheckBox no grid.................................................................... 96
RichEdit - Como fazer uma pesquisa e substituio em um RichEdit....................... 97
TForm - Criando formulrios transparentes............................................................... 98
TList - Ordenando os itens......................................................................................... 99
3 formas de dar um shutdown................................................................................... 100
QuickReport e FastReport - Gerando um PDF......................................................... 103
SetVolumeLabel - Mudando o Label do HD............................................................ 104
Memo - Rolagem vertical ......................................................................................... 105
Como adicionar o evento OnClick no DBGrid........................................................ 106
Alterando a cor dos TabSheet de um PageControl................................................... 107
Como chamar uma home page utilizando o seu browse padro............................... 107
Como alterar o caption da janela de preview do quickreport................................... 107
Como passar parmetros entre 2 forms.................................................................... 108
Como reduzir o tempo e carga de um programa...................................................... 109
Escondendo o Programa de Ctrl+Alt+Del................................................................ 110
Verifica se o BDE est instalado.............................................................................. 112
Verificando se um alias est instalado...................................................................... 114
Como prevenir a movimentao do mouse para fora do form?............................... 114
Como criar hints customizados?............................................................................... 114
Como capturar a tela?............................................................................................... 116
Como mostrar um TMenuItem alinhado direita?.................................................. 121
Como mover o form clicando em qualquer lugar?................................................... 121
Como mostrar um texto de vrias linhas em um TCombobox?............................... 122
Como criar tooltips com bales?.............................................................................. 124
Mostra o total de pginas.......................................................................................... 144
InnoSetup Verificando a verso do software, se inferior, ento, no instalar....... 144
InnoSetup Manipulao de arquivos texto............................................................ 145
Finalizando processos do Windows via programao.............................................. 146
Gravando CDs.......................................................................................................... 147
Quick Report - Obtendo a lista de papeis disponveis.............................................. 147
DBGrid - Como fazer quebra de linhas.................................................................... 148
Arquivo: Verificar se est ReadOnly........................................................................ 150
Treeview Foco....................................................................................................... 151
Rave Report Indicar pgina inicial ........................................................................ 151
Desktop do Windows auto-arranjar icones............................................................ 152
5
Clculo de Parcelas................................................................................................... 153
Porta Serial Como verificar se uma porta est em uso.......................................... 154
GIF Como converter uma imagem GIF para BMP............................................... 155
Veja como criar atalhos no menu iniciar do Windows............................................. 155
Como mover um componente em Run-time............................................................. 158
Como apresentar o nmero da linha e coluna em um DBGrid?............................... 159
Como implementar um log de todos os erros gerados na aplicao?....................... 160
Printers - Como retornar informaes das impressoras instaladas na mquina....... 161
IP Como retornar o hostname a partir de um endereo IP..................................... 163
Windows Como criar grupos e subgrupos de programas no menu iniciar............ 164
Windows Como desabilitar uma combinao de teclas genericamente................ 165






































6
Descobrindo o cdigo ASCII de uma tecla

Para descobrir o cdigo ASCII de uma determinada tecla voc pode criar a seguinte
aplicao.
1. Insira um componente Label no form (Label1);
2. Mude a propriedade KeyPreview do form para true;
3. Altere o evento OnKeyDown do form como abaixo:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Label1.Caption :=
Format(O cdigo da tecla pressionada : %d, [Key]);
end;

Para testar execute e observe o Label enquanto pressiona as teclas desejadas.




Funo - Retornando o prximo dia til

Obtendo o prximo dia til caso a data informada caia em um fim de semana

function ProximoDiaUtil(dData : TDateTime) : TDateTime;
begin
if DayOfWeek(dData) =7 then
dData :=dData +2
else
if DayOfWeek(dData) =1 then
dData :=dData +1;
Result :=dData;
end;


7
DBGrid - Colocando em Letras maisculas uma coluna
selecionada
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if DBGrid1.SelectedField.FieldName='NOME' THEN
Key :=AnsiUpperCase(Key)[Length(Key)];
end;

DBGrid - Mostrando todo contedo de um campo Memo

Desenvolvedores em geral utilizam o componente DBGrid para apresentar os dados de
uma tabela ou banco de dados.

Os problemas surgem a partir do momento em que necessrio apresentar o contedo
de um campo Memo. Porm, existe um jeito fcil de resolver este problema. O que
iremos fazer que, ao usurio clicar sobre o contedo de algum campo Memo no
DBGrid, seja apresentada uma janela com todas informaes contidas neste memo.

Primeiro desenvolvida uma funo que realiza este processo:

function TForm1.MostraMemo(Dts: TDataSource; Dbg: TDBGrid; Fld: TField):
Boolean;
var
Frm: TForm;
Ret: Boolean;
Mem: TDBMemo;

begin
Ret :=False;
if Dts.DataSet.RecordCount >0 then
if Dbg.SelectedField =Fld then begin
Ret :=True;
Frm :=TForm.Create(nil);

try
Frm.Width :=240;
Frm.Height :=120;
Frm.Top :=Mouse.CursorPos.Y;
Frm.Left :=Mouse.CursorPos.X;
Frm.BorderStyle :=bsToolWindow;
Frm.Caption :=Fld.DisplayLabel;

Mem :=TDBMemo.Create(nil);
try
Mem.Parent :=Frm;
Mem.Align :=alClient;
8
Mem.DataSource :=Dts;
Mem.DataField :=Fld.FieldName;
Mem.ReadOnly :=True;
Mem.ScrollBars :=ssVertical;

Frm.ShowModal;
finally
Mem.Free;
end;
finally
Frm.Free;
end;
end;

Result :=Ret;
end;


Uma vez desenvolvida nossa funo, preciso colocar em prtica, no evento
OnCellClick do DBGrid, insira o cdigo a seguir:


procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
MostraMemo(DBGrid1.DataSource, DBGrid1, DBGrid1.SelectedField);
end;

Confira como ficou todo exemplo:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGrids, DB, DBTables, StdCtrls, DBCtrls;

type
TForm1 =class(TForm)
Table1: TTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
procedure DBGrid1CellClick(Column: TColumn);
private
function MostraMemo(Dts: TDataSource; Dbg: TDBGrid; Fld: TField): Boolean;

{ Private declarations }
public
{ Public declarations }
end;
9

var
Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.MostraMemo(Dts: TDataSource; Dbg: TDBGrid; Fld: TField):
Boolean;
var
Frm: TForm;
Ret: Boolean;
Mem: TDBMemo;

begin
Ret :=False;
if Dts.DataSet.RecordCount >0 then
if Dbg.SelectedField =Fld then begin
Ret :=True;
Frm :=TForm.Create(nil);

try
Frm.Width :=240;
Frm.Height :=120;
Frm.Top :=Mouse.CursorPos.Y;
Frm.Left :=Mouse.CursorPos.X;
Frm.BorderStyle :=bsToolWindow;
Frm.Caption :=Fld.DisplayLabel;

Mem :=TDBMemo.Create(nil);
try
Mem.Parent :=Frm;
Mem.Align :=alClient;
Mem.DataSource :=Dts;
Mem.DataField :=Fld.FieldName;
Mem.ReadOnly :=True;
Mem.ScrollBars :=ssVertical;

Frm.ShowModal;
finally
Mem.Free;
end;
finally
Frm.Free;
end;
end;

Result :=Ret;
end;
10



procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
MostraMemo(DBGrid1.DataSource, DBGrid1, DBGrid1.SelectedField);
end;

end.

Crtica de datas no objeto Edit sem mensagem de erro do
Delphi
Fazer o tratamento de mensagens de erro em campos de data fundamental. Neste
exemplo, para ilustrar, so inseridos dois componentes Edit. O componente Edit1 o
componente onde sero inseridos as datas e o componente Edit2 apenas para que
possamos fazer a transio entre os componentes.
No evento OnExit do Edit1 foi inserido o cdigo a seguir:
No evento OnExit do objeto
procedure TForm1.Edit1Exit(Sender: TObject);
var Data : string;
begin
Data :=Edit1.text;
CriticaData(Data); // Se no for um campo vlido, a procedure devolve a varivel data
vazia;
if Data ='' then
Edit1.SetFocus
else
Edit1.text :=DateToStr(StrToDate(Edit1.text));
end;
Foi criado uma procedure para fazer o tratamento das mensagens de erro. Esta
procedure ter o nome de Criticadata:
procedure TForm1.CriticaData(var Data: string); //Sem controle dos caracteres
digitados no objeto Edit1
var I, J , Dia, Mes, Ano : Integer;
Barras, Barra1, Barra2 : Integer; // Verifica a posio das barras;
K, M : Array Of Integer;
Num : Array Of String;
Caracter, Erro : String;
begin
Erro:='n'; //Em princpio o campo considerado como correto(vlido).
// Cria-se os Arrays K e M com 13 campos dos quais usaremos do 1 ao 12
SetLength (K, 13);
SetLength (M, 13);
11
// A matriz M preenchida com o ltimo dia de cada ms
// A matriz K preenchida com 1. A posio relativa de cada caracter do campo
// data, dentro da matriz K, ser prenchida com zero se o caracter for vlido.
// Caso contrrio ser setado Erro igual a s
for I :=1 to 12 do begin
K[I] :=1;
M[I] :=31;
end;
M[4] :=30;
M[2] :=28;
M[6] :=30;
M[9] :=30;
M[11] :=30;
//Num contm os nmeros e / para controle do campo data.
SetLength (Num, 11);
for I :=0 to 9 do
Num[I] :=IntToStr(I);
Num[10] :='/';
// Barra controla a posio das duas // do campo data
Barras :=0; // Verifica a quantidade de barras digitadas
Barra1 :=0; // Posio da 1 barra (pode ser 2 ou 3)
Barra2 :=0; // Posio da 2 barra (pode ser 4, 5 ou 6)
for I :=1 to length(Data) do begin
Caracter :=copy(Data,I,1);
if Caracter ='/' then begin
Barras :=Barras +1;
if Barra1 =0 then Barra1 :=I
else Barra2 :=I;
end;
for J :=0 to 10 do
if Num[J ] =Caracter then
K[I] :=0;
end;
//Se Algum elemento da varivel Data no for vlido
// seta o erro com s
for J :=1 to length(Data) do
if K[J ] =1 then Erro :='s';
if (length(data) <6) or (length(data) >10) then Erro :='s';//or
// (length(data) =9) then Erro :='s';
if Barras >2 then Erro :='s';
if (Barra1 >3) or (Barra1 <2) then Erro :='s';
if (Barra2 >6) or (Barra2 <4) then Erro :='s';
// At aqui j sabemos que a data est em formato vlido com barras
if Erro ='n' then begin
Caracter :=Copy(Data,(Barra2 +1),4);
if length(Caracter) <4 then begin
Caracter :='20' +Caracter; // Se a data entrar no formato dd/mm/aa
// fazemos a data ficar dd/mm/20aa
Data :=Copy(Data,1,Barra2)+Caracter;
end;
12
// Podemos converter as posies da string em inteiros sem receio de recebermos
// aquela mensagem de erro do delphi.
Dia :=StrToInt(Copy(Data,1,(Barra1 - 1)));
Mes :=StrToInt(Copy(Data,(Barra1+1),(Barra2 - Barra1 - 1)));
Ano :=StrToInt(Copy(Data,(Barra2 +1),4));
// Verifica se o ano bissexto para a crtica do dia se o ms for fevereiro.
J :=Ano mod 4;
if J =0 then M[2] :=29
else M[2] :=28;
// Critica o mes
if (mes <1) or (mes >12) then Erro :='s';
// Critica o dia
if Erro ='n' then
if (dia <1) or (dia >M[Mes]) then Erro :='s';
// critica o ano (Se quiser)
if ano <2003 then Erro :='s';
end;
if Erro ='s' then begin
Data :='';
messageDlg('Data inconsistente!!!',mtError, // Esta ser a nica mensagem mostrada.
[mbOk],0);
end;
end;

A mesma procedure CriticaData, mais enxuta, porm, com o controle dos caracteres
feito no evento OnKeyPress:
procedure TForm1.CriticaData(var Data: string); //Com controle dos caracteres
//digitados no objeto Edit1 atravs do evento OnKeyPress
var I, J , Dia, Mes, Ano : Integer;
Barras, Barra1, Barra2 : Integer; // Verifica a posio das barras;
M : Array Of Integer;
Caracter, Erro : String;
begin
Erro:='n'; //Em princpio o campo considerado como correto(vlido).
// Cria-se o Array M com 13 campos dos quais usaremos do 1 ao 12
SetLength (M, 13);
// A matriz M preenchida com o ltimo dia de cada ms
for I :=1 to 12 do begin
M[I] :=31;
end;
M[4] :=30;
M[2] :=28;
M[6] :=30;
M[9] :=30;
M[11] :=30;
// Barra controla a posio das duas // do campo data
Barras :=0; // Verifica a quantidade de barras digitadas
13
Barra1 :=0; // Posio da 1 barra (pode ser 2 ou 3)
Barra2 :=0; // Posio da 2 barra (pode ser 4, 5 ou 6)
for I :=1 to length(Data) do begin
Caracter :=copy(Data,I,1);
if Caracter ='/' then begin
Barras :=Barras +1;
if Barra1 =0 then Barra1 :=I
else Barra2 :=I;
end;
end;
if (length(data) <6) or (length(data) >10) then Erro :='s';
if Barras >2 then Erro :='s';
if (Barra1 >3) or (Barra1 <2) then Erro :='s';
if (Barra2 >6) or (Barra2 <4) then Erro :='s';
// Aqui j sabemos se a data numrica e se est em formato vlido com barras
if Erro ='n' then begin
Caracter :=Copy(Data,(Barra2 +1),4);
if length(Caracter) <4 then begin
Caracter :='20' +Caracter; // Se a data entrar no formato dd/mm/aa
// fazemos a data ficar dd/mm/20aa
Data :=Copy(Data,1,Barra2)+Caracter;
end;
// Podemos converter as posies da string em inteiros sem receio de recebermos
// aquela mensagem de erro do delphi.
Dia :=StrToInt(Copy(Data,1,(Barra1 - 1)));
Mes :=StrToInt(Copy(Data,(Barra1+1),(Barra2 - Barra1 - 1)));
Ano :=StrToInt(Copy(Data,(Barra2 +1),4));
// Verifica se o ano bissexto
J :=Ano mod 4;
if J =0 then M[2] :=29
else M[2] :=28;
// Critica o mes
if (mes <1) or (mes >12) then Erro :='s';
// Critica o dia
if Erro ='n' then
if (dia <1) or (dia >M[Mes]) then Erro :='s';
// critica o ano (Se quiser)
if ano <2003 then Erro :='s';
end;
if Erro ='s' then begin
Data :='';
messageDlg('Data inconsistente!!!',mtError,
[mbOk],0);
end;

No evento onKeyPress do Edit1 inserido cdigos para que possa controlar os
caracteres digitados:
14
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (Key =Chr(vk_Back)) then // Este if habilita a tecla Backspace para correo do
objeto
if not (Key in ['0'..'9','/']) then // Este if permite a digitao somente de nmeros e da
barra /
abort;
end;

Preenchimento de zeros para completar a data
Usurios podem no colocar os zeros de dias e meses menores que dez forando um
erro de digitao de data. Para resolver este problema, no evento OnCreate do
formulrio insira o cdigo a seguir:
procedure TForm1.FormCreate(Sender: TObject);
begin
ShortDateFormat :='dd/mm/yyyy'; // pode-se usar dd/mm/yy para exibio no
formato curto
end;
Multimdia - Fazendo suas aplicaes Delphi falar

H um tempo atrs inserimos uma dica ensinando o Delphi a falar, no entanto era com
sutaque "americado portugus". Saiu o SAPI 4.0 com a opo de Portugus Brasil. A
seguir, links com downloads e exemplos:

Para SAPI 4.0
http://www.microsoft.com/msagent/downloads/user.asp
Em Text-to-speech engines, escolha o idioma Portugus Brasil

E mais embaixo faa o download do SAPI 4.0 runtime support

No site http://bdn.borland.com/article/0,1410,29582,00.html voc tem exemplos para
delphi usando o SAPI 4.0.

Download dos exemplos:
http://codecentral.borland.com/codecentral/ccWeb.exe/listing?id=19509

Para SAPI 5.1 tem o site http://bdn.borland.com/article/0,1410,29583,00.html tambm
com exemplos, mas no sei onde encontrar engine em portugues para esta versao.

Um exemplo simples para fazer o seu Delphi falar este:
Primeiro declarada na clusula uses ComObj. Em seguida, no evento onClick do
boto inserido o cdigo a seguir:

procedure TForm1.Button1Click(Sender: TObject);
15
var
voice: OLEVariant;
begin
voice :=CreateOLEObject('SAPI.SpVoice');
voice.Rate :=0;
voice.Volume :=100;
voice.Speak('Ramos da Informtica',0);

voice :=unassigned;
end;

Multimdia - Toque um som quando o mouse passar por cima
de um boto
Neste exemplo iremos utilizar CM_MOUSEENTER quando o mouse entrar no objeto e
CM_MOUSELEAVE quando sair do objeto, a rotina deve ficar assim:

uses MMSystem;

TYourObject =class(TAnyControl)
...
private
procedure CMMouseEnter(var AMsg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var AMsg: TMessage); message CM_MOUSELEAVE;
...
end;

implementation

procedure TYourObject.CMMouseEnter(var AMsg: TMessage);
begin
sndPlaySound('c:\win\media\ding.wav',snd_Async or snd_NoDefault);
end;

procedure TYourObject.CMMouseLeave(var AMsg: TMessage);
begin
sndPlaySound(nil,snd_Async or snd_NoDefault);
end;


Hints com multiplas linhas

muito simples, no evento OnCreate do formulrio insira o cdigo a seguir:
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Hint:='Ramos da'+#13+'Informtica';
end;
16

Multimdia - Usando cursores animados

Cursores animados existem aos montes pela internet, voc pode utilizar estes cursores
em suas aplicaes, neste pequeno exemplo inserimos o cdigo no evento OnCreate do
formulrio, acompanhe:

procedure TForm1.FormCreate(Sender: TObject);
const
MyCursor=1;
begin
Screen.Cursors[MyCursor]:=LoadCursorFromFile('C:\Shuttle.ani');
Screen.Cursor:=MyCursor;
end;


Detectando a verso do Internet Explorer

Para detectar a verso do Internet Explorer, basta consultar uma chave do registro cujo
endereo :

HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer

Existem 3 chaves neste local que determinam a verso do IE:

- IVer disponvel no IE 1, 2 e 3
- Build disponvel a partir do IE 2
- Version disponvel a partir do IE 4.0

possvel consultar a verso do IE atravs da verso da Shdocvw.dll, porm essa DLL
s est disponvel a partir da verso 3.0.

A chave IVer contm os seguintes valores:
100 - IE 1.0
101 - IE para NT 4.0
102 - IE 2.0
103 - IE 3.0

A chave Version contm o nmero da verso por extenso que no corresponde ao
nmero da verso que o usurio v. Na pgina abaixo tem uma lista detalhada que
relaciona um valor com o outro:

http://www.codeproject.com/shell/detectie.asp

E finalmente, o cdigo da funo que obtm a verso:

function GetIEVersion: string;
var Reg: TRegistry;
17
begin
Reg :=TRegistry.Create;
try
Reg.RootKey :=HKEY_LOCAL_MACHINE;
Reg.OpenKey('Software\\Microsoft\\Internet Explorer', False);
try
Result :=Reg.ReadString('Version');
if (Result='') then Result :=Reg.ReadString('IVer');
except
Result :='';
end;
Reg.CloseKey;
finally
Reg.Free;
end;
end;

Atravs da verso do IE determina-se qual ActiveX poder ser carregado para fazer
OLE com o IE. At a verso 3.0 o componente o TWebBrowser_V1 e a partir do IE
4.0, o componente o TWebBrowser.

QuickReport - Filtrando registros

procedure TForm1.QuickReport1Filter(var PrintRecord:Boolean);
begin
PrintRecord:=( Table1.fieldbyname ('idade').value >21 );
end;

Evitando efeito de maximizao
Se voc j desenvolveu uma aplicao MDI com um formulrio MDIChild que tem que
ser exibido em estado Maximizado (WindowState=wsMaximized), provavelmente voc
j se deparou com aquele deselegante problema em que o usurio acompanha a
maximizao do seu formulrio. Para evitar isto, faa o seguinte:

Antes de criar o seu formulrio para a exibio, utilize LockWindowUpdate(Handle);
Aps a criao do formulrio, utilize LockWindowUpdate(0);
Com isto, voc dar um efeito mais profissional s suas aplicaes.

Exemplo:

procedure MainForm.ItemArqCadFor(Sender: TObject);
begin
LockWindowUpdate(Handle);
with TFrmCadFor.Create(self) do Show;
LockWindowUpdate(0);
end;
18

Calcula a quantidade de dias no ms

function DaysInMonth: Integer;
var
Year, Month, Day: Word;
begin
DecodeDate(Now, Year, Month, Day);
Result :=MonthDays[IsLeapYear(Year), Month];
end;

Exemplo de uso:

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(DaysInMonth));
end;


Calculando abono salrial de modo progressivo
function Abono (S, F, A1, A2: Double) : Double;
Begin
If S>=F then
begin
Result:=S+A2
end
else
begin
If S>F-A1 then
Result:=(100-(((F-S)/A1)*100))*A2/100+F
else
Result:=S+A1
end;
end;
Onde S =Salrio (No nosso exemplo R$ 290,00 ou R$ 300,00).
F=Faixa do Abono (No nosso exemplo R$ 300,00).
A1=1 Abono (Valor mais alto, no nosso exemplo R$ 50,00).
A2=2 Abono (Valor mais baixo, no nosso exemplo R$ 30,00).
Result=Retorno da funo com o calculo do novo salrio.
Para executar basta declarar as variveis ou campos do banco de dados exatamente na
ordem acima em modo Double.
19
Esta uma funo para calcular de modo progressivo um abono (por exemplo, folha
de pagamento) sem cometer injustia.
Expl: Digamos que queremos que todos os funcionrios que ganham at R$ 299,99
recebam um abono de R$ 50,00 e acima deste valor um abono de R$ 30,00.
Se no aplicarmos a formula o que vai acontecer quem ganha, por exemplo, R$ 290,00
recebera R$ 340,00 (o correto seria ganhar R$ 324,00) passando a ganhar mais de quem
ganhava R$ 300,00, pois este ter apenas um abono de R$ 30,00 percebendo R$ 330,00.
A funo acima corrige estas distores, e pode ser aplicada num banco de dados para
diversas faixas salariais.
Checa se um processo est rodando

{ .... }

uses TlHelp32;

{ .... }


function processExists(exeFileName: string): Boolean;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
FSnapshotHandle :=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize :=SizeOf(FProcessEntry32);
ContinueLoop :=Process32First(FSnapshotHandle, FProcessEntry32);
Result :=False;
while Integer(ContinueLoop) <>0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
begin
Result :=True;
end;
ContinueLoop :=Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;


// Exemplo:
procedure TForm1.Button1Click(Sender: TObject);
begin
if processExists('calc.exe') then
ShowMessage('Processo em execuo')
else
20
ShowMessage('O processo NO est em execuo');
end;

Checa se um diretrio est vazio
function DirectoryIsEmpty(Directory: string): Boolean;
var
SR: TSearchRec;
i: Integer;
begin
Result :=False;
FindFirst(IncludeTrailingPathDelimiter(Directory) +'*', faAnyFile, SR);
for i :=1 to 2 do
if (SR.Name ='.') or (SR.Name ='..') then
Result :=FindNext(SR) <>0;
FindClose(SR);
end;


// Exemplo:

procedure TForm1.Button1Click(Sender: TObject);
begin
if DirectoryIsEmpty('C:\test') then
Label1.Caption :='empty'
else
Label1.Caption :='not empty';
end;

dbExpress - Passando parmetros com CommandText via
programao
O parametro no adicionado quando criamos o CommandText via programao,
portanto devemos cri-lo da seguinte forma:
procedure TForm1.Button1Click(Sender: TObject);
begin
SQLClientdataSet1.Close;
SQLClientdataSet1.Params.Clear;
SQLClientdataSet1.CommandText :='select * from CLIENTE where CODIGO =
:COD';
SQLClientdataSet1.Params.CreateParam(ftInteger, 'COD', ptInput).AsInteger :=1;
SQLClientdataSet1.Open;
end;

21
Corrigindo problemas de instalao do Borland Data Provider
For Firebird
Em alguns casos, o Borland Data Provider For Firebird tm apresentado problemas de
instalao, abaixo segue algumas dicas para tentar auxiliar na resoluo dos mesmos:
1. Verificar se o D8 est atualizado com Update Pack#2;
2. Se o BDP For Firebird foi instalado 'antes' do D8 ter sido atualizado,desinstalar,
atualizar o D8 e aps isso instalar o BDP For Firebird novamente;
3. Efetuar testes diretamente via 'Data Explorer' a fim de verificar se a conexo
ocorre sem problemas;
4. Copiar o arquivo 'FirebirdSql.Data.Bdp' para a pasta:
C:\Arquivos de programas\Arquivos comuns\Borland
Shared\BDS\Shared\Assemblies\2.0
5. No projeto, acesse 'Project Manager' | 'References' e adicione a referncia ao
'Firebirdsql.Data.Bdp'

Lendo texto de um arquivo PDF
o seguinte, esta dica peguei em um site Alemo, fiz aqui sua traduo e alguns testes e
funciou. Para quem precisa criar algum sistema que leia o contedo de texto de um
arquivo PDF. No lembro quem havia pedido, mas aqui est a soluo:
{++++++++++++++++++++++++++++++++++++++++++++++++++
Esta uma rotina para ler informaes de arquivos PDF.
No formulrio adicione um TMemo, 5 TLabel, 1 TButton e um OpenDialog.
S um detalhe, v oa menu do Delphi e na opo "Import TypeLibrary" escolha a opo
do Adobe Acrobat, seno, no ir funcionar.
Bem, o cdigo completo da aplicao este que segue:

+++++++++++++++++++++++++++++++++++++++++++++++++++}
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, acrobat_tlb;
type
TForm1 =class(TForm)
Button1: TButton;
22
Memo1: TMemo;
OpenDialog1: TOpenDialog;
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;

var
Form1: TForm1;
implementation
uses ComObj;
{$R *.dfm}
{$TYPEDADDRESS OFF} // preciso dazer esta chamada
var
PDDoc: Acrobat_TLB.CAcroPDDoc;
PDPage: Variant;
PDHili: Variant;
PDTextS: Variant;
acrobat: Variant;
Result: Boolean;
NTL, i, j, Pagecount: Integer;
zeilen: string;
stichwortcounter: Integer;
Size: Integer;
gesamtstring: AnsiString;
zwreal: Real;
procedure TForm1.Button1Click(Sender: TObject);
function removecrlf(workstring: string): string;
var
i: Integer;
begin
removecrlf :='';
for i :=0 to Length(workstring) do
begin
if workstring[i] =#13 then
workstring[i] :=' ';
if workstring[i] =#10 then
23
workstring[i] :=' ';
end;
removecrlf :=workstring;
end;
begin
if not opendialog1.Execute then Exit;
memo1.Clear;
gesamtstring :='';
stichwortcounter :=0;
Size :=0;
try
acrobat :=CreateOleObject('AcroExch.pdDoc');
//Identifica arquivos PDF atravs do OLE
Result :=acrobat.Open(opendialog1.FileName);

if Result =False then
begin
messagedlg('O arquivo no pode ser aberto', mtWarning, [mbOK], 0);
Exit;
end;
for j :=0 to acrobat.GetNumPages - 1 do
begin
memo1.Lines.Add('----------------------------------------------');
//Primeira pgina do documento ativa
PDPage :=acrobat.acquirePage(j);
PDHili :=CreateOleObject('AcroExch.HiliteList');
Result :=PDHili.Add(0, 4096);
//Marca sobre o texto
PDTextS :=PDPage.CreatePageHilite(PDHili);
ntl :=PDTextS.GetNumText;
for i :=0 to ntl - 1 do
begin
zeilen :=PDTextS.GetText(i);
if (Length(zeilen) >0) and (zeilen <>'') then
memo1.Lines.Add(removecrlf(zeilen));
gesamtstring :=gesamtstring +removecrlf(zeilen);
//Apenas para estatstica
Size :=Size +SizeOf(zeilen);
Inc(stichwortcounter);
24
Application.ProcessMessages;
end;
//Depois libera
pdhili :=Unassigned;
pdtextS :=Unassigned;
pdpage :=Unassigned;
label2.Caption :=IntToStr(stichwortcounter);
label4.Caption :=IntToStr(Size);
label2.Refresh;
label4.Refresh;
end;

except
on e: Exception do
begin
messagedlg('Erro: ' +e.Message, mtError, [mbOK], 0);
Exit;
end;
end;
if Size >1024 then
begin
zwreal :=Size / 1024;
str(zwreal: 2: 1,zeilen);
label4.Caption :=zeilen;
label5.Caption :='KB';
end;
memo1.Lines.SaveToFile(Extractfilepath(Application.exename) +'\debug.txt');
end;
end.


Deixando seu EXE mais enxuto e rpido e, mais seguro contra
decompilao
Geralmente, arquivos EXE criados com Delphi so maiores que os criados com outras
linguagens de programao. O motivo disso so as VCL (Claro que VCL tem muitas
vantagens e devem ser usadas). Porm, possvel deixar os executveis menores e,
consequentemente, mais rpidos de serem abertos, fcil de distribuio pela Web
(mesmo na era da banda larga), fica mais difcil de piratas de cdigos abrir seus
softwares, etc.
Ento apresento aqui, 10 passos (ou dicas) para deixar seu executvel mais enxuto:
01) Use um EXE-Packer (UPX, ASPack,...)
02) Use o KOL.
25
03) O que puder ser desenvolvido sem o uso de VCL deve ser feito, pois quanto maior a
quantidade de VCLs, maior ser o executvel, mas as VCL devem ser usadas, ok.
04) Use a ACL (API Controls Library)
05) Use StripReloc.
06) Desative a opo remote debugging information e TD32 do Delphi.
07) You might want to put code in a dll.
08) No coloque imagens em Formulrios. De preferncia, leia em tempo de execuo.
09) Use imagens compactas, como por exemplo J PG ao invs de BMP.
******************************************************
01)
UPX um software freeware, Compactao de alto desempenho em linha de comando
(sem interface grfica). Em testes, alguns arquivos chegaram a ficar com apenas 22% de
seu tamanho original. A descompresso tambm muito veloz: mais de 10 MB por
segundo em um pentium 133.
http://upx.sourceforge.net/
ASPack um Compressor de arquivos executveis Win32, capaz de reduzir o tamanho
de programas Windows 32-bit em mais de 70% (bem melhor que o padro industrial
ZIP, que fica em torno de 10 a 20%). Torna menores os programas e suas bibliotecas,
diminuindo o tempo de transferncia atravs de rede e o tempo de download a partir da
Internet. Tambm protege os programas contra engenharia reversa por hackers no
profissionais. Os programas comprimidos pelo ASPack rodam da mesma maneira que
rodavam antes, sem perda de performance do tempo de execuo.

http://www.aspack.com/aspack.htm
{****************************************************************}
02) KOL - Key Objects Library um conjunto de objetos para desenvolvimento de
poderosas aplicaes Windows 32 bit GUI usando Delphi sem o uso de VCL.
distribudo livremente e com o cdigo fonte
http://bonanzas.rinet.ru/
{****************************************************************}
03) nonVCL
Delphi possibilita muitos caminhos. Se voc quer um executvel pequeno, ento no
uso a VCL. Isso possvel usando 100% chamadas APIs, standards resources, etc.
Alguns sites que podem ajudar:
http://nonvcl.luckie-online.de
http://www.erm.tu-cottbus.de/delphi/stuff/Tutorials/nonVCL/index.html
http://www.angelfire.com/hi5/delphizeus/
http://www.tutorials.delphi-source.de/nonvcl/
26

{****************************************************************}
04) ACL (API Controls Library)
Voc tambm pode usar a ACL, o que facilita o uso de APIs, para mais informaes
visite este site: http://www.apress.ru/pages/bokovikov/delphi/index.html/
{****************************************************************}
05) StripReloc Este programa remove a seo de recolocao (".reloc") dos executvies
Win32 PE, reduzindo o tamanho deles. A maioria do compiladores/linkeditores
(inclusive o do Delphi) insere esta seo no executvel e uma seo que nunca ser
usada e no tem outra finalidade seno desperdiar espao na memria e em disco.
http://www.jrsoftware.org/striprlc.php
{****************************************************************}
06) Desativando o Debug Information
Exclusa qualquer informao de debug no final indo ao menu do Delphi Project /
Pptions Compiler - Debugging e Project / Options: Linker EXE e DLL options.
{****************************************************************}
08 e 09)
Sobre imagens
Formulrios com muitas imagens anexadas so criadas junto ao executvel, deixando
ele muito grande e sempre que executado o tamanho original multiplicado, o que
torna invivel. O melhor anexar as imagens e enviar junto ao executvel pois assim
no h esta multiplicao.
Use arquivos J PEG ao invs de BMP. Isso ajuda a reduzir o tamanho do EXE.
{****************************************************************}
Essas so apenas algums dicas, no preciso fazer todas elas, mas caso precise...

Copiando (Upload) um diretrio para um servidor FTP

Oferecer uma opo de backup para clientes, ou at mesmo alguma outra aplicao,
sempre um diferencial.

Para esta rotina necessrio ter o componente Indy instalado em seu Delphi.

procedure UploadPerFTP;
procedure GetDir(dir: string);
27
var
SearchRec: TSearchRec;
details, nodetails: TStringList;
k: Integer;
begin
//Pega direito o diretrio
if FindFirst(dir +'*.*', faAnyFile, SearchRec) =0 then
begin
repeat

if (SearchRec.Name <>'.') and (SearchRec.Name <>'..') then
begin
//Se acharmos a pasta
if (SearchRec.Attr and faDirectory) =faDirectory then
begin
//Pega a pasta que contm do FTP. um com detalhes e outro sem
details :=TStringList.Create;
nodetails :=TStringList.Create;
FTPClient.List(details, '', True);
FTPClient.List(nodetails, '', False);

for k :=details.Count - 1 downto 0 do
begin
if details.Strings[k] <>'' then
begin
if (details.Strings[k][1] <>'d') or
(nodetails.Strings[k] ='.') or
(nodetails.Strings[k] ='..') then
begin
details.Delete(k);
nodetails.Delete(k);
end;
end;
end;

//Se o diretrio no existe no servidor, ento cria
if nodetails.IndexOf(SearchRec.Name) =-1 then
begin
FTPClient.MakeDir(SearchRec.Name);
end;

//Muda o diretrio no servidor
FTPClient.ChangeDir(SearchRec.Name);
details.Free;
nodetails.Free;

//Se achou, vai para o prximo sub-siretrio
GetDir(dir +SearchRec.Name +'\');

//Temos que ir a um diretrio a cima
28
FTPClient.ChangeDirUp;
end
else
begin
//Se apenas um arquivo, upload o diretrio atual
FTPClient.Put(dir +SearchRec.Name, SearchRec.Name);
end;
end;
until FindNext(SearchRec) <>0;
FindClose(SearchRec);
end;
end;
var
dir: string;
details, nodetails: TStringList;
k: Integer;
begin
//Seta as configuraes para acesso ao servidor de FTP(TIdFTPClient)
with FTPClient do
begin
Host :='your_server.com'; // Coloque host
Username :='your_username';
// Colque senha
Password :='your_password';
// Adjust your data here
Passive :=True;
end;
FTPClient.Connect;

//Se for de um computador remoto, ou na rede, faa isso
dir :=StringReplace('your/remote_directory', '\', '/', [rfReplaceAll]);

if dir <>'' then
begin
if dir[1] ='/' then Delete(dir, 1, 1);

if dir[Length(dir)] <>'/' then dir :=dir +'/';

while Pos('/', dir) >0 do
begin
details :=TStringList.Create;
nodetails :=TStringList.Create;
FTPClient.List(details, '', True);
FTPClient.List(nodetails, '', False);

for k :=details.Count - 1 downto 0 do
begin
if details.Strings[k] <>'' then
begin
if (details.Strings[k][1] <>'d') or
29
(nodetails.Strings[k] ='.') or
(nodetails.Strings[k] ='..') then
begin
details.Delete(k);
nodetails.Delete(k);
end;
end;
end;

if nodetails.IndexOf(Copy(dir, 1, Pos('/', dir) - 1)) =-1 then
begin
FTPClient.MakeDir(Copy(dir, 1, Pos('/', dir) - 1));
end;

FTPClient.ChangeDir(Copy(dir, 1, Pos('/', dir) - 1));

Delete(dir, 1, Pos('/', dir));
details.Free;
nodetails.Free;
end;
end;

dir :='C:\your\local\directory\';
if dir[Length(dir)] <>'\' then dir :=dir +'\';
GetDir(dir);
FTPClient.Disconnect;
end;


Trabalhando com arquivos texto no Delphi

Para trabalhar com arquivo texto:

Existem vrios mtodos em Delphi para gravar arquivos texto a partir de informaes
gravadas em bases de dados ou para ler arquivos texto e armazen-los em bases de
dados. Esta dica apresenta um destes mtodos: o uso de TextFiles.

TextFile um tipo de dado pr-definido no Delphi e corresponde ao tipo Text do Turbo
Pascal e do Object Pascal.

Inicialmente para acessar um arquivo de texto, voc precisa definir uma varivel tipo
TextFile, no local que voc achar mais apropriado, da seguinte forma:

var arq: TextFile;
Vamos precisar tambm de uma varivel tipo string para armazenar cada linha lida do
arquivo:

var linha: String;
30
Antes de se iniciar a leitura do arquivo, precisamos associar a variavel TextFile com um
arquivo fisicamente armazenado no disco:

AssignFile ( arq, 'C:\AUTOEXEC.BAT' );
Reset ( arq );
A rotina AssignFile faz a associao enquanto Reset abre efetivamente o arquivo para
leitura. AssignFile corresponde Assign do Turbo Pascal. Em seguida necessrio
fazer uma leitura ao arquivo, para isto utilizaremos a procedure ReadLn:

ReadLn ( arq, linha );
O comando acima l apenas uma linha de cada vez, assim precisamos de um loop para
efetuar vrias leituras at que o arquivo acabe. Para verificar o fim do arquivo,
utilizaremos a funo Eof:

while not Eof ( arq ) do
Agora uma rotina quase completa para fazer a leitura de um arquivo texto. Esta rotina
recebe como parmetro o nome do arquivo que ser lido:

procedure percorreArquivoTexto ( nomeDoArquivo: String );
var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Reset ( arq );
ReadLn ( arq, linha );
while not Eof ( arq ) do
begin
{ Processe a linha lida aqui. }
{ Para particionar a linha lida em pedaos, use a funo Copy. }
ReadLn ( arq, linha );
end;
CloseFile ( arq );
end;

E tambm uma rotina quase completa para gravao de um arquivo texto. Esta rotina
recebe como parmetro o nome do arquivo que ser gravado e uma tabela (TTable) de
onde os dados sero lidos:

procedure gravaArquivoTexto ( nomeDoArquivo: String; tabela: TTable );
var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Rewrite ( arq );
tabela.First;
while not tabela.Eof do
begin
Write ( arq, AjustaStr ( tabela.FieldByName ( 'Nome' ).AsString, 30 ) );
Write ( arq, FormatFloat ( '00000000.00', tabela.FieldByName ( 'Salario' ).AsFloat
) );
31
WriteLn ( arq );
tabela.Next;
end;
CloseFile ( arq );
end;

Note nesta segunda rotina, a substituio de Reset por Rewrite logo aps o AssignFile.
Rewrite abre o arquivo para escrita, destruindo tudo que houver l anteriormente .

Note tambm o uso de Write e WriteLn para gravar dados no arquivo texto.

Finalmente note o uso de AjustaStr e FormatFloat para garantir que campos string e
numericos sejam gravados com um nmero fixo de caracteres. FormatFloat uma rotina
do prprio Delphi enquanto AjustaStr est definida abaixo:

function AjustaStr ( str: String; tam: Integer ): String;
begin
while Length ( str ) <tam do
str :=str +' ';
if Length ( str ) >tam then
str :=Copy ( str, 1, tam );
Result :=str;
end;

O uso da funo AjustaStr fundamental quando voc estiver gravando arquivos texto
com registros de tamanho fixo a partir de bases de dados Paradox que usualmente no
preenchem campos string com espaos no final.


Criando uma conexo ao DBExpress em tempo de execuo
{
O caminho normal para se criar uma conexo com o DBExpress no Delphi e no Kylix
o desenvolvedor colocar um componente TSQLConnection no formulrio de com um
duplo clique no componente abrir o editor de conexo e setar os parmetros (drive,
caminho do banco de dados, nome da conexo, etc) para indicar a conexo.
Veja agora como fazer isso em tempo de execuo.
}
procedure TVCLScanner.PostUser(const Email, FirstName, LastName: WideString);
var
Connection: TSQLConnection;
DataSet: TSQLDataSet;
begin
Connection :=TSQLConnection.Create(nil);
with Connection do
begin
32
ConnectionName :='VCLScanner';
DriverName :='INTERBASE';
LibraryName :='dbexpint.dll';
VendorLib :='GDS32.DLL';
GetDriverFunc :='getSQLDriverINTERBASE';
Params.Add('User_Name=SYSDBA');
Params.Add('Password=masterkey');
Params.Add('Database=milo2:D:\ramosinfo\webservices\umlbank.gdb');
LoginPrompt :=False;
Open;
end;
DataSet :=TSQLDataSet.Create(nil);
with DataSet do
begin
SQLConnection :=Connection;
CommandText :=Format('INSERT INTO kings VALUES("%s","%s","%s")',
[Email, FirstN, LastN]);
try
ExecSQL;
except
end;
end;
Connection.Close;
DataSet.Free;
Connection.Free;
end;

ActiveX - Pegar um texto selecionado no Internet Explorer
Em defesa do Ctrl+C, Ctrl+V: Eu bem que queria saber quem que teve a pssima
idia de condenar a cpia intelectual deslavada, deixando a gente com essa sensao
desconfortvel de ter que fazer as coisas por si mesmo. O sujeito que inventou a patente
era obviamente um chato e provavelmente se chamava Lazinho. Nestes tempos de
subjetivismo, de dinmicas de grupo e de cursos de gesto, as pessoas so pagas para
serem originalssimas. Estamos na era da tirania da criatividade. A quantidade de
bobagem, de feira e de chatice que isso gerou incalculvel. por isso que, sempre
que posso, tento privar o mundo de minhas desinteressantssimas particularidades.
Penso que melhor ter um pouco mais de pudor e no sair mostrando as originalidades
pra todo mundo no. Mais ou menos como barriga de mulher: se feia, melhor nem
mostrar.
Pensando nisso, que tal uma rotina que pega textos selecionados do IE? Pode ser
bastante til:
uses
SHDocVw_TLB; // http://www.euromind.com/iedelphi Se voc no tiver esta unit,
visite este site.
33
function GetSelectedIEtext: string;
var
x: Integer;
Sw: IShellWindows;
IE: HWND;
begin
IE :=FindWindow('IEFrame', nil);
sw :=CoShellWindows.Create;
for x :=SW.Count - 1 downto 0 do
if (Sw.Item(x) as IWebbrowser2).hwnd =IE then begin
Result :=variant(Sw.Item(x)).Document.Selection.createRange.Text;
break;
end;
end;

Cria um efeito na apresentao de um formulrio

procedure TForm1.animin(Sender: TObject);

procedure delay(msec: Longint);
var
start, stop: Longint;
begin
start :=GetTickCount;
repeat
stop :=GetTickCount;
Application.ProcessMessages;
until (stop - start) >=msec;
end;
var
maxx, maxy: Integer;

MyHand: HWND;
MyDc: HDC;
MyCanvas: TCanvas;
hal, hat, hak, haa: Integer;
begin
maxx :=(Sender as TForm).Width;
maxy :=(Sender as TForm).Height;
hal :=2;
hat :=2;

MyHand :=GetDesktopWindow;
MyDc :=GetWindowDC(MyHand);
MyCanvas :=TCanvas.Create;
MyCanvas.Handle :=MyDC;
MyCanvas.Brush.Color :=(Sender as TForm).Color;

34
repeat
if hat +(maxy div 24) >=maxy then
begin
hat :=maxy
end
else
begin
hat :=hat +(maxy div 24);
end;

if hal +(maxx div 24) >=maxx then
begin
hal :=maxx
end
else
begin
hal :=hal +(maxx div 24);
end;
hak :=(Sender as TForm).Left +((Sender as TForm).Width div 2) - (hal div 2);
haa :=(Sender as TForm).Top +((Sender as TForm).Height div 2) - (hat div 2);
MyCanvas.Rectangle(hak, haa, hak +hal, haa +hat);
delay(10);
until (hal =maxx) and (hat =maxy);
(Sender as TForm).Show;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
animin(form2);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
animin(form3);
end;



Criando um Menu transparente

Que tal brincar um pouco com suas aplicaes:

var
hHookID: HHOOK;

// Funo para criar um menu transarente
function MakeWndTrans(Wnd: HWND; nAlpha: Integer =10): Boolean;
type
35
TSetLayeredWindowAttributes =function(hwnd: HWND; crKey: COLORREF; bAlp
ha: Byte;
dwFlags: Longint): Longint; stdcall;
const
// Use crKey para definir a cor como transparente
LWA_COLORKEY =1;
// Use bAlpha para determinar a opacidade do layer do windows
LWA_ALPHA =2;
WS_EX_LAYERED =$80000;
var
hUser32: HMODULE;
SetLayeredWindowAttributes: TSetLayeredWindowAttributes;
i : Integer;
begin
Result :=False;
// imnportante usarmos a DLL USER32.DLL e distribuir na aplicao.
hUser32 :=GetModuleHandle('USER32.DLL');
if hUser32 <>0 then
begin
@SetLayeredWindowAttributes :=GetProcAddress(hUser32,'SetLayeredWindowAtt
ributes');
if @SetLayeredWindowAttributes <>nil then
begin
SetWindowLong(Wnd, GWL_EXSTYLE, GetWindowLong(Wnd, GWL_EXST
YLE) or WS_EX_LAYERED);
SetLayeredWindowAttributes(Wnd, 0, Trunc((255 / 100) * (100 -
nAlpha)), LWA_ALPHA);
Result :=True;
end;
end;
end;

// hook procedure
function HookCallWndProc(nCode: Integer; wParam, lParam: Longint): Longint; stdca
ll;
const
MENU_CLASS ='#32768';
N_ALPHA =60;
var
cwps: TCWPStruct;
lRet: THandle;
szClass: array[0..8] of char;
begin
if (nCode =HC_ACTION) then
begin
CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));
case cwps.message of
WM_CREATE:
begin
GetClassName(cwps.hwnd, szClass, Length(szClass)-1);
36
// Window name for menu is #32768
if (lstrcmpi(szClass, MENU_CLASS) =0) then
begin
MakeWndTrans(cwps.hwnd, N_ALPHA {Alphablending});
end;
end;
end;
end;

Result :=CallNextHookEx(WH_CALLWNDPROC, nCode, wParam, lParam);
end;

// Coloque no evento OnCreate do form
procedure TForm1.FormCreate(Sender: TObject);
var
tpid: DWORD;
begin
tpid :=GetWindowThreadProcessId(Handle, nil);
hHookID :=SetWindowsHookEx(WH_CALLWNDPROC, HookCallWndProc, 0, tpi
d);
end;

// Pare o processo no evento OnDestroy
procedure TForm1.FormDestroy(Sender: TObject);
begin
if (hHookID <>0) then
// Remove o menu transparente
UnhookWindowsHookEx(hHookID);
end;


Checa se um diretrio est vazio

function DirectoryIsEmpty(Directory: string): Boolean;
var
SR: TSearchRec;
i: Integer;
begin
Result :=False;
FindFirst(IncludeTrailingPathDelimiter(Directory) +'*', faAnyFile, SR);
for i :=1 to 2 do
if (SR.Name ='.') or (SR.Name ='..') then
Result :=FindNext(SR) <>0;
FindClose(SR);
end;


// Exemplo de uso:
procedure TForm1.Button1Click(Sender: TObject);
37
begin
if DirectoryIsEmpty('C:\test') then
Label1.Caption :='empty'
else
Label1.Caption :='not empty';
end;

Mostra multiplas linhas de texto em um ComboBox


procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer;
var Height: Integer);
var
ItemString: string;
MyRect: TRect;
MyImage: TImage;
MyCombo: TComboBox;
begin
if (Index >-1) then
begin
MyCombo :=TComboBox(Control);
// Create a temporary canvas to calculate the height
MyImage :=TImage.Create(MyCombo);
try
MyRect :=MyCombo.ClientRect;
ItemString :=MyCombo.Items.Strings[Index];
MyImage.Canvas.Font :=MyCombo.Font;
// Calc. using this ComboBox's font size
Height :=DrawText(MyImage.Canvas.Handle, PChar(ItemString),
- 1, MyRect, DT_CALCRECT or DT_WORDBREAK);
finally
MyImage.Free;
end;
end;
end;

Modo de usar:

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
ItemString: string;
begin
TComboBox(Control).Canvas.FillRect(Rect);
ItemString :=TComboBox(Control).Items.Strings[Index];
DrawText(TComboBox(Control).Canvas.Handle, PChar(ItemString), - 1, Rect,
DT_WORDBREAK);
end;

38

Criando atalhos no Windows pelo Delphi
implementation
uses ShlObj, ActiveX, ComObj;
{$R *.dfm}

procedure CriaShortCut(aNome, aFileName: string; aLocation: integer);
var
IObject : IUnknown;
ISLink : IShellLink;
IPFile : IPersistFile;
PIDL : PItemIDList;
InFolder : array[0..MAX_PATH] of Char;
TargetName : String;
LinkName,s : WideString;
begin
TargetName :=aFileName;

IObject :=CreateComObject(CLSID_ShellLink);
ISLink :=IObject as IShellLink;
IPFile :=IObject as IPersistFile;

with ISLink do
begin
SetPath(pChar(TargetName));
SetWorkingDirectory(pChar(ExtractFilePath
(TargetName)));
end;

SHGetSpecialFolderLocation
(0, aLocation, PIDL);
SHGetPathFromIDList(PIDL, InFolder);

s :=InFolder;
LinkName :=s +'\' +aNome +'.LNK';

if FileExists(LinkName) then
ShowMessage('Atalho j existe!')
else
IPFile.Save(PWChar(LinkName), false);

end;

// Para utilizar:

CriaShortCut('Calculadora', 'c:\windows\system32\calc.exe', CSIDL_DESKTOP);

39

Faa suas aplicaes Falar

Um exemplo que demonstra o uso dos objetos de fala da Microsoft para fazer suas
aplicaes tornarem-se falantes.

Para fazer suas aplicaes em Delphi FALAR basta baixar o pacote Speech SDK no
site da microsoft.

http://www.microsoft.com/speech

Feito isso, use o seguinte cdigo para falar "Hello World".

uses Comobj;

procedure TForm1.Button1Click(Sender: TObject);
var
objVoice: OLEVariant;
begin
objVoice :=CreateOLEObject('SAPI.SpVoice');
objVoice.Speak('Hello World',0);
objVoice :=unassigned;
end;

Veja outros exemplos:

http://www.blong.com/Conferences/DCon2002/Speech/SAPI51/SAPI51.htm


Imprimindo arquivos PDF sem abrir-los

Implementation
Uses shellApi;
{$R *.DFM}

procedure Tform1.Button1Click(Sender: Tobject);
begin
ShellExecute(Handle, 'print',
Pchar('C;\Pasta\Leiame.pdf'), nil,nil,SW_SHOW);
End;


Ler arquivos PDF
Tem que ter o Acrobat instalado no computador.
1.) Coloque um opendialog e um button.
40
2.) V em Project +Import Type Library.
3.) Selecione Acrobat Control para ActveX..... +install ...........
4.) Aparcer uma tela, clique em compilar......
5.) V depois na palheta ActiveX e escolha o componente PDF
6.) Faa as devidos ajuste e digite no button:

if opendialog1.execute then
pdf1.src:=opendialog1.filename;


Inno Setup - Script para criao de conexo OBDC DSN

[Setup]
AppName=ODBC2
AppVerName=ODBC2
Uninstallable=false
UpdateUninstallLogAppName=false
DisableDirPage=false
DisableProgramGroupPage=true
DefaultDirName={pf}\ODBC2
DisableStartupPrompt=true
CreateAppDir=false

[_ISTool]
EnableISX=true

[Tasks]
Name: cfgdsndlg; Description: Config DSN with dialog; GroupDescription:
Configuration:; Flags: unchecked

[Code]

function SQLConfigDataSource(hwndParent: LongInt; fRequest: LongInt;
lpszDriver: String; lpszAttributes: String): LongInt;
external 'SQLConfigDataSource@ODBCCP32.DLL stdcall';

const
ODBC_ADD_DSN =1; // Add data source
ODBC_CONFIG_DSN =2; // Configure (edit) data source
ODBC_REMOVE_DSN =3; // Remove data source
ODBC_ADD_SYS_DSN =4; // add a system DSN
ODBC_CONFIG_SYS_DSN =5; // Configure a system DSN
ODBC_REMOVE_SYS_DSN =6; // remove a system DSN


function CreateDSN( showdlg: Boolean) : LongInt;
var
hwnd : LongInt;
var
41
strDriver, strAttributes, NewLine : String;
begin
// if it is not auto configuration, setting HWND of wizard let show
// DSN setup dialog with attributes specified
if not showdlg then
hwnd :=0
else
hwnd :=StrToInt(ExpandConstant('{wizardhwnd}'));

// MYSQL Sample
{
strDriver :='MySQL';
NewLine :=Chr(0);
strAttributes :='SERVER=localhost' +NewLine +
'DESCRIPTION=MySQL Driver DSN' +NewLine +
'DSN=SAMPLE_DSN' +NewLine +
'DATABASE=test' +NewLine +
'UID=username' +NewLine +
'PASSWORD=password' +NewLine +
'PORT=3306' +NewLine +
'OPTION=3' +NewLine;
}

Result :=SQLConfigDataSource( hwnd, ODBC_ADD_SYS_DSN, strDriver,
strAttributes);
end;


function NextButtonClick(CurPage: Integer): Boolean;
var showdlg : Boolean;
begin

// by default go to next page
Result :=true;

// if curpage is wpSelectTasks check config DSN
if CurPage =wpSelectTasks then
begin

showdlg :=ShouldProcessEntry( '','cfgdsndlg') =srYes ;

if CreateDSN( showdlg ) =0 then
MsgBox( 'DSN not done.', mbError, MB_OK )
else
MsgBox( 'DSN Created !', mbInformation, MB_OK );

end;

end;

42

Colocar cursor no final do Edit ao receber o foco

No evento OnEnter do TEdit coloque:

procedure TForm1.Edit1Enter(Sender: TObject);
begin
Edit1.Selstart:=Length(Edit1.text);
end;


Mudar a cor de fundo de um Hint
Application.HintColor :=clBlack;

Fazer um executvel ser executado somente se chamado por
um determinado executvel
Inclua na seo uses: Windows
Problema: Gostaria que um determinado programa (Prog1.EXE) fosse executado apenas
atravs de outro programa (Prog2.EXE).
Soluo: Antes da linha "Application.Initialize;" de Prog1.dpr (programa a ser
chamado), coloque o cdigo abaixo:
if ParamStr(1) <>'MinhaSenha' then begin
{ Para usar ShowMessage, coloque Dialogs no uses }
ShowMessage('Execute este programa atravs de Prog2.EXE');
Halt; { Finaliza }
end;
No Form1 de Prog2 (programa chamador) coloque um boto e escreva o OnClick deste
boto 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;
Observaes: Aqui o parmetro passado foi 'MinhaSenha'. Voc dever trocar
'MinhaSenha' por algo que apenas voc saiba (uma senha). Caso uma pessoa conhea
43
esta senha, ser possvel chamar este programa passando-a como parmetro. Neste caso
sua "trava" estar violada.

DBGrid - Focando a clula selecionada mudando sua cor

possvel fazer um tratamento no evento onDrawDataCell do DBGrid e verificar a
clula em foco alterando a cor da mesma, veja abaixo simples exemplo:

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
if (gdSelected in State) then
begin
with DBGrid1.Canvas do
begin
Brush.Color :=clAqua;
Font.Color :=clNavy;
FillRect( Rect );
TextOut(Rect.Left, Rect.Top, Field.AsString);
end;
end;
end;

Obs. Para que toda a linha fica selecionada voc dever alterar a propriedade Options ->
dgRowSelect para True;

Verificando a verso do Windows
Neste exemplo apresentamos uma rotina para verificar qual a verso do Windows. O
que diferencia esta rotina de outras j apresentadas que ela consegue distinguir entre
todas as verses do Windows, ou seja, se Windows 95, 98, ME, NT 4, 2000 ou XP.
function GetWinVersion: String;
begin
case Win32MajorVersion of
3: Result :=Windows NT 3.51; // NT 3.51
4: // WIn9x/ME, NT 4
case Win32MinorVersion of
0: Result :=Windows 95;
10: Result :=Windows 98;
90: Result :=Windows ME;
else
if (Win32Platform and VER_PLATFORM_WIN32_NT) <>0 then
Result :=Windows NT 4.0
else
Result :=SO desconhecido;
end;
44
5: // Win2K, XP
case Win32MinorVersion of
0: Result :=Windows 2000;
1: Result :=Windows XP or .NET server;
else
Result :=SO desconhecido;
end;
else
Result :=SO desconhecido;
end;
end;
// Chamada:
{ mostrar em um label }
OSVersion.Caption :=GetWinVersion;
Rave Report - Alterar a impressora padro

Basta informar o ndice da impressora da seguinte forma:

uses
RpDevice, Printers;

procedure TForm1.Button1Click
(Sender: TObject);
begin
Printer.PrinterIndex :=0;
RPDev.DeviceIndex :=Printer.PrinterIndex;
rvTestes.ExecuteReport(Rep_Employee);
end;

Atribundo efeitos para abertura de formulrios

Existe uma funo chamada AnimateWindow. Veja a seguir como chamar:

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.BringToFront;
AnimateWindow(Form2.Handle, 3000, AW_BLEND);
Form2.Show;

{
No terceiro parmetro da funo voc pode utilizar uma das opes abaixo

AW_BLEND : Uses a fade effect
AW_SLIDE : Uses slide animation.
AW_ACTIVATE : Activates the window
AW_HIDE : Hides the window.
45
AW_CENTER : Makes the window appear to collapse inward
AW_HOR_POSITIVE : Animates the window from left to right.
AW_HOR_NEGATIVE : Animates the window from right to left
AW_VER_POSITIVE : Animates the window from top to bottom
AW_VER_NEGATIVE : Animates the window from bottom to top
}
end;


API do Windows - Funo para excluir uma pasta e todos
arquivos desta pasta

implementation
uses ShellApi;

{$R *.dfm}

procedure DeleteDir(hHandle: THandle;
Const sPath : String; Confirm: boolean);
var
OpStruc: TSHFileOpStruct;
FromBuffer, ToBuffer: Array[0..128] of Char;
begin
FillChar( OpStruc, Sizeof(OpStruc), 0 );
FillChar( FromBuffer, Sizeof
(FromBuffer), 0 );
FillChar( ToBuffer, Sizeof(ToBuffer), 0 );
StrPCopy( FromBuffer, sPath);
With OpStruc Do
Begin
Wnd:=hHandle;
wFunc:=FO_DELETE;
pFrom:=@FromBuffer;
pTo:=@ToBuffer;
if not confirm then
begin
fFlags:=FOF_NOCONFIRMATION;
end;
fAnyOperationsAborted:=False;
hNameMappings:=nil;
End;
ShFileOperation(OpStruc);
end;

Usando a Funo:

procedure TForm1.Button1Click(Sender: TObject);
begin
DeleteDir(Self.Handle,C:\TESTE,True)
46
end;
end.


Inno Setup - Verificando se existe determinada Chave no
Registro do Windows

O Inno Setup o instalador oficial do nosso site. Aqui trazemos mais uma dica deste
fantstico gerador de instalaes, onde demonstramos como verificar se uma
determinada chave existe no registro do Windows:

[Setup]
AppName=VerificaChave
AppVerName=VerificaChave
DefaultDirName={pf}\VerificaChave
DisableStartupPrompt=true
Uninstallable=false
DisableDirPage=true
OutputBaseFilename=VerificaChave

[Code]
function InitializeSetup(): Boolean;
begin
if RegKeyExists(HKEY_LOCAL_MACHINE, SOFTWARE\Firebird Project\Firebird
Server) then
begin
MsgBox( No posso instalar! ,
mbInformation, MB_OK );
Result :=false;
end
else
Result :=true;

end;

Isso muito interessante, por exemplo, para verificar se uma determinada aplicao j
existe no computador do cliente.


Controlando o PowerPoint no Delphi

Seguindo a linha da automao OLE Office, veja agora como controlar o powerpoint
em uma aplicao delphi

uses
comobj;

procedure TForm1.Button1Click(Sender: TObject);
47
var
PowerPointApp: OLEVariant;
begin
try
PowerPointApp :=CreateOleObject('PowerPoint.Application');
except
ShowMessage('Error...');
Exit;
end;
// Torna o Powerpoint visivel
PowerPointApp.Visible :=True;

// Mostra verso do PowerPoint
ShowMessage(Format('Powerpoint version: %s',[PowerPointApp.Version]));

// Abre uma apresentao
PowerPointApp.Presentations.Open('c:\\windows\\desktop\\teste.ppt', False, False,
True);

// SMostra o nmero de slides
ShowMessage(Format('%s
slides.',[PowerPointApp.ActivePresentation.Slides.Count]));

// Roda a apresentao
PowerPointApp.ActivePresentation.SlideShowSettings.Run;

// Vai para o prximo slide
PowerPointApp.ActivePresentation.SlideShowWindow.View.Next;

// Vai para slide 2
PowerPointApp.ActivePresentation.SlideShowWindow.View.GoToSlide(2);

// Vai para o slide anterior
PowerPointApp.ActivePresentation.SlideShowWindow.View.Previous;

// Vai para o ltimo slide
PowerPointApp.ActivePresentation.SlideShowWindow.View.Last;

// Mostra o nome do Slide corrente
ShowMessage(Format('Current slidename:
%s',[PowerPointApp.ActivePresentation.SlideShowWindow.View.Slide.Name]));

// Fecha o Powerpoint
PowerPointApp.Quit;
PowerPointApp :=UnAssigned;
end;



48
Rave Report - Indicar pgina inicial

O Rave Reports permite ter vrias pginas de relatrio (cada pgina com um layout)
para um mesmo relatrio. Neste exemplo, iremos demonstrar como definir via
programao qual pgina ser apresentada como inicial.

uses
RVClass, RVProj, RVCsStd;
procedure TForm1.btnChamaRelClick
(Sender: TObject);
var
Pagina: TRavePage;
Report: TRaveReport;
QualPagina: String;
begin

// Nome da pgina dentro do projeto Rave.
QualPagina :=Page2;
// Abre RvProject.
RvProject1.Open;
// Pega referncia do Report
// dentro do projeto Rave.
Report :=RvProject1.ProjMan.ActiveReport;
// Pega referncia da Page dentro do Report.
Pagina :=RvProject1.ProjMan.FindRaveComponent
(Report1.+QualPagina,nil) as TRavePage;
// Indica a pgina inicial.
Report.FirstPage :=Pagina;
// Executa o relatrio.
RvProject1.Execute;

end;


InnoSetup - Adicionar um programa no iniciar do Windows

O InnoSetup uma gerador gratuito de instalaes que vm dia-a-dia se popularizando
meio a comunidade Delphi. A seguir, apresentamos uma dica para adicionar sua
aplicao para iniciar junto com o Windows.

[Code]
[Setup]
AppName=Adicionar no iniciar.
AppVerName=Adicionar no iniciar.
DefaultDirName={pf}\ Adicionar no iniciar.
DisableStartupPrompt=true
Uninstallable=false
DisableDirPage=true
OutputBaseFilename=Adicionar no iniciar.
49
[Files]

Source: C:\teste.exe; DestDir: {userstartup}; DestName: teste.exe

Veja que o segredo est no diretrio de destino da aplicao ou atalho da mesma, o
qual dever ser destinado para {userstartup} que representa um path especial que o
Windows ir buscar no momento que estiver iniciando.


Validando endereo de e-mail no Delphi em aplicaes Win32,
.Net e Asp.Net

{ Exemplo:

If IsValidEMail(Edit1.Text) then ShowMessage('Valid E-Mail!')
Else ShowMessage('Invalid E-Mail!');

}

Function OcorrenciasEm(De, NoTexto:String):LongInt;
Var h,CONT:LongInt;
TEMP:String;
Begin
TEMP:=AnsiReplaceText(NoTexto, '|', '');
TEMP:=AnsiReplaceText(TEMP, De, '|');

CONT:=0;
For h:=1 to Length(TEMP) do
If TEMP[h] ='|' then
CONT:=CONT+1;

Result:=CONT;
End;

Function IsValidEMail(EMail:String):Boolean;
Var h,A_POS:LongInt;
OK:Boolean;
TEMP:String;
Begin
OK:=True;
TEMP:=UpperCase(EMail);
For h:=1 to Length(TEMP) do
Begin
If Not ((ORD(TEMP[h]) >=64) and (ORD(TEMP[h]) <=90)) and
Not (ORD(TEMP[h]) =95) and
Not (ORD(TEMP[h]) =46) then OK:=False;
End;

50
A_POS:=Pos('@', EMail);
If (A_POS =0) or (A_POS <3) then OK:=False;
If Pos('.', Copy(EMail, A_POS, Length(EMail)-A_POS)) =0 then OK:=False;
If OcorrenciasEm('@', EMail) >1 then OK:=False;
If Pos('..', EMail) >0 then OK:=False;
If Pos('@.', EMail) >0 then OK:=False;
If Email[1] ='.' then OK:=False;
If Email[Length(EMail)] ='.' then OK:=False;
If Length(Email) >250 then OK:=False;

Result:=OK;
End;


Memo redondo

Pensando no carnaval, que tal montar o Rei Memo? Veja a rotina:

procedure TForm1.Button1Click(Sender: TObject);

procedure MemoRedondo(QueMemo: TMemo);
var
rect : TRect; rgn : HRGN; begin
rect :=QueMemo.ClientRect;
rgn :=CreateRoundRectRgn( rect.Left,
rect.top,
rect.right,
rect.bottom, 20, 20);
QueMemo.BorderStyle :=bsNone;
QueMemo.Perform(EM_GETRECT, 0, lparam(@rect));
InflateRect(rect, -5, -5);
QueMemo.Perform(EM_SETRECTNP, 0, lparam(@rect));
SetWindowRgn(QueMemo.Handle, rgn, true);
end;

Como usar:

begin
MemoRedondo(Memo1);
end;


Colocar Banners em Menus

Vamos adicionar em um menu, uma imagem no estilo banner. Para isso, adicione no
formulrio um Image e carregue uma imagem de sua preferncia. Selecione todos os
itens do menu e no evento OnDrawItem digite o seguinte cdigo:

51
procedure TForm1.Exit1DrawItem(Sender: TObject;
ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
begin
ACanvas.FillRect(ARect);
ACanvas.TextOut(ARect.Left+48, ARect.Top,
StripHotkey((Sender as TMenuItem).Caption));
ACanvas.Draw(0, 0, Image1.Picture.Graphic);
ImageList1.Draw(ACanvas, ARect.Left+30, ARect.Top,
(Sender as TMenuItem).ImageIndex);
end;


Usando a WebCam no Delphi
Recebo constantemente e-mails pedindo informaes de como usar a WebCam no
Delphi. O primeiro passo baixar o SDK do fabricante da WebCam. Neste exemplo,
que segue, estou utilizando o Quick Cam SDK, que pode ser encontrado no site do
fabricante, que neste caso : http://developer.logitech.com/
O exemplo a seguir mostra como usar o mtodo PictureToMemory da biblioteca Quick
Cam SDK. No site do fabricante tambm h documentaes de como usar a SDK.
type
TMemoryStream =class(Classes.TMemoryStream);

var
MS : TMemoryStream;
lSize : LongInt;
pBuffer : ^Byte;

begin

MS :=TMemoryStream.Create;
bitmap1 :=TBitmap.Create;

try
if VideoPortal1.PictureToMemory(0,24,0,lSize,'') =1 then
begin
pBuffer :=AllocMem(lSize);
if VideoPortal1.PictureToMemory(0,24,integer(pBuffer),lSize,'') =1 then
begin
MS.SetPointer(pBuffer,lSize);
bitmap1.loadfromstream(MS);
end;
end;
finally
MS.Free;
FreeMem(pBuffer);
52
end;
end;

Colocando imagens em um ComboBox

Inicialmente, necessrio setar a propriedade "Style" do ComboBox para
"csOwnerDrawVariable". Desta forma teremos a liberdade para desenharmos o que
quisermos dentro do ComboBox.

Imaginemos que o nosso ComboBox possui trs tens. E para cada tem colocaremos
uma imagem diferente.

Para isso, criaremos um vetor que ter um nmero de elementos correspondente a
quantidade de tens de nosso ComboBox.

No nosso exemplo, sero trs elementos. Este vetor deve ser criado como uma varivel
"private" (em "private declarations" do form).

private
Img: Array[0..2] of TBitmap;

A seguir, no evento "OnCreate" do nosso formulrio colocaremos o seguinte:

procedure TForm1.FormCreate(Sender: TObject);
begin
Img[0] :=TBitmap.Create;
Img[0].LoadFromFile('edit.bmp');
ComboBox1.Items.AddObject('Edit', Img[0]);

Img[1] :=TBitmap.Create;
Img[1].LoadFromFile('delete.bmp');
ComboBox1.Items.AddObject('Delete', Img[1]);

Img[2] :=TBitmap.Create;
Img[2].LoadFromFile('export.bmp');
ComboBox1.Items.AddObject('Export', Img[2]);
end;

Agora o trabalho no evento "OnDrawItem" do ComboBox que dever ter o seguinte:

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
Bmp: TBitmap;
Off: Integer;
Cmb: TComboBox;

53
begin
Cmb :=(Control as TComboBox);

with Cmb.Canvas do begin
FillRect(Rect);

Off :=0;
Bmp :=TBitmap(ComboBox1.Items.Objects[Index]);

if Bmp <>nil then begin
BrushCopy(Bounds(Rect.Left+2, Rect.Top+2, Bmp.Width, Bmp.Height), Bmp,
Bounds(0, 0, Bmp.Width, Bmp.Height), clOlive);
Off :=Bmp.Width+8;
end;

TextOut(Rect.Left +Off, Rect.Top, ComboBox1.Items[Index]);
end;
end;

E, finalmente, no evento "OnMeasureItem" do ComboBox:

procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer;
var Height: Integer);
begin
Height :=20;
end;

Alguma explicao: O evento "OnDrawItem" o responsvel por "desenhar" cada tem
do ComboBox quando clicamos no cone para abr-lo. Simplesmente aproveitamos isto
para desenhar a nossa imagem antes do texto.

Neste mesmo evento fizemos uma chamada a funo "BrushCopy", onde o ltimo
parmetro a cor que deseja que fique transparente. Como eu utilizei imagens que vem
com o Delphi, a cor de fundo destas imagens o amarelo escuro (clOlive).

Da pra frente testar com imagens diferentes, porm, uma sugesto que todas tenham
o mesmo tamanho para que se mantenha um padro dentro do seu ComboBox.


Importando e Exportando Registro
Um tcnica bem simples para exportar/importar o registry em arquivos no formato
.REG.
Function ExportRegistry(FileName:String; ExportKey:String):Boolean;
Begin
ShellExecute(0,nil,'REGEDIT.EXE',PChar('/SC /E '+FileName+'
"'+ExportKey+'"'),nil,sw_hide);
54
Result :=FileExists(FileName);
End;
Function ImportRegistry(FileName:String; ExportKey:String):Boolean;
Begin
Result :=FileExists(FileName);
If Result Then Begin
ShellExecute(0,nil,'REGEDIT.EXE',PChar('/SC /C '+FileName),nil,sw_hide);
End;
End;
Exemplo:
procedure TForm1.Button1Click(Sender: TObject);
begin

ExportRegistry('c:\\windows\\desktop\\teste.reg','HKEY_CURRENT_USER\\Software\\
Borland');
end;

DBGrid - Colocar um ComboBox num DBGrid

As colunas da DBGrid tem uma propriedade chamada PickList, que permite colocar as
opes numa lista, que sero mostradas quando a coluna editada.

Para preench-la, basta abrir o editor de colunas da DBGrid, selecionar a coluna
desejada, abrir o editor da PickList e colocar as opes para aquela coluna. Assim, ao
editar a coluna, abre-se a combobox.

Enviando mensagens HTML com imagens anexadas

Para se enviar uma mensagem html com os componentes Indy basta usar a propriedade
ContentType de TIdMessage, configurando-a para text/html.
Quando se quer mandar uma imagem nesta mensagem, uma maneira que pode ser usada
colocar um link externo para ela: <img src="http://www.meusite.com/imagem.jpg">.
Isto, alm de gerar um trfego desnecessrio no site, tende a ser desabilitado nos
mailers, por ser um risco de segurana. Outra maneira embutir a imagem na
mensagem como anexo e ligar o link a ela.
Porm, como fazer isso ? Qual o link para a mensagem anexa ? Este link dado pelo
Content-Id da imagem. Ao chamar o link para a imagem, faz-se algo como <img
src="cid:minhaimagem">. minhaimagem o content-id da imagem, que definido
quando colocamos a mensagem como anexo:
55
Imagem :=TIdAttachment.Create(MessageParts,
'c:\windows\cafezinho.bmp');
// Aqui estou preenchendo o Content-ID
Imagem.ExtraHeaders.Values['Content-ID'] :='<minhaimagem>';
Imagem.ContentType :='image/jpeg';
Desta maneira, a imagem vai na mensagem e aberta sem problemas.
Ao executar o programa da postagem, notamos um problema: a mensagem enviada
corretamente, com a imagem em anexo, porm o html no gerado corretamente,
aparecendo como texto normal.
Analisando o cabealho da mensagem, vemos que o content-type da mensagem est
como text/plain, mesmo tendo especificado text/html.
O que ocorre que a mensagem, quando tem um anexo, transformada em multipart e
isso faz que o contedo seja enviado como texto.
Uma soluo para isto enviar o texto da mensagem como uma parte de texto, com
contedo html. Isto feito criando-se uma varivel do tipo TIdText, que ser
preenchida com o texto que queremos. Na realidade, iremos criar duas partes de texto na
mensagem: uma normal, no html, que ser mostrada em leitores de e-mail no html, e
outra html. Isto feito da seguinte maneira:

// configura para multipart
ContentType :='Multipart/Alternative';
// parte de texto normal
idText :=TIdText.Create(MessageParts,nil);
idText.ContentType :='text/plain';
idText.Body.Add('Esta parte texto puro e no mostra a imagem');
// parte de texto html
idText :=TIdText.Create(MessageParts,nil);
idText.ContentType :='text/html';
idText.Body.Text :='<html><body>Esta mensagem html tem '+
'imagens<br />'+
'A imagem est como anexo, e no est fora da mensagem:<br />'+
'<img src="cid:MinhaImagem"></body></html>';
// Configura anexos
Imagem :=TIdAttachment.Create(MessageParts,
'c:\windows\cafezinho.bmp');
Imagem.ExtraHeaders.Values['Content-ID'] :='<minhaimagem>';
Imagem.ContentType :='image/jpeg';
Desta maneira, temos a mensagem com anexos formatada corretamente, podendo ser
vista tanto em leitores texto como html.


56
Mostrando dicas balo para caixas de edio wm WindowsXP

Para mostrar uma dica balo para uma caixa de edio, devemos mandar uma
mensagem EM_SHOWBALLOONTIP para ela. O texto, ttulo e cone da dica so
mandados prenchendo um record do tipo TEditBalloonTip, definida como:

TEditBalloonTip =packed record
cbStruct: DWORD ;
pszTitle: LPCWSTR ;
pszText: LPCWSTR;
ttiIcon: Integer;
end;

Uma vez preenchido record, passamos como o terceiro parmetro para a funo
SendMessageW:

procedure ShowBalloonTip(Window : HWnd;
Texto, Titulo : PWideChar;Tipo : Integer);
var
EditBalloonTip : TEditBalloonTip;
begin
EditBalloonTip.cbStruct :=SizeOf(TEditBalloonTip);
EditBalloonTip.pszText :=Texto;
EditBalloonTip.pszTitle :=Titulo;
EditBalloonTip.ttiIcon :=Tipo;
SendMessageW(Window, EM_SHOWBALLOONTIP, 0,
Integer(@EditBalloonTip));
end;

O cdigo completo das funes que mostram e escondem a dica o seguinte:

TEditBalloonTip =packed record
cbStruct: DWORD ;
pszTitle: LPCWSTR ;
pszText: LPCWSTR;
ttiIcon: Integer;
end;
const
ECM_FIRST =$1500;
EM_SHOWBALLOONTIP =(ECM_FIRST +3);
EM_HIDEBALLOONTIP =(ECM_FIRST +4);
TTI_NONE =0;
TTI_INFO =1;
TTI_WARNING =2;
TTI_ERROR =3;

var
Form1: TForm1;

implementation
57

{$R *.dfm}



procedure ShowBalloonTip(Window : HWnd;
Texto, Titulo : PWideChar;Tipo : Integer);
var
EditBalloonTip : TEditBalloonTip;
begin
EditBalloonTip.cbStruct :=SizeOf(TEditBalloonTip);
EditBalloonTip.pszText :=Texto;
EditBalloonTip.pszTitle :=Titulo;
EditBalloonTip.ttiIcon :=Tipo;
SendMessageW(Window, EM_SHOWBALLOONTIP, 0,
Integer(@EditBalloonTip));
end;
procedure HideBalloonTip(Window : HWnd);
begin
SendMessageW(Window, EM_HIDEBALLOONTIP, 0, 0)
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowBalloonTip(Edit1.Handle,'Texto a ser mostrado',
'Ttulo da janela',TTI_INFO);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
HideBalloonTip(Edit1.Handle);
end;

Nota: Esta dica s funciona com os estilos do XP ativados. Assim, voc precisa colocar
um componente TXpManifest na sua Form.


CheckLisBox - Trocar a cor das linhas
Existe uma forma simples de fazer este tipo de trabalho. Inclua alguns itens no seu
CheckListBox, v at a propriedade Style e altere para lbOwnerDrawVariable, agora v
at ao evento OnDrawItem e inclua o cdigo abaixo:
CheckListBox1.Canvas.FillRect(Rect);
if not (odFocused in State) then
begin
if CheckListBox1.Checked[index] then
begin
CheckListBox1.Canvas.Font.Color :=clRed;
CheckListBox1.Canvas.Brush.Color :=clWhite;
end
58
else
begin
CheckListBox1.Canvas.Font.Color :=clBlack;
CheckListBox1.Canvas.Brush.Color :=clWhite;
end;
end;

CheckListBox1.Canvas.TextOut(Rect.Left+2,Rect.Top,CheckListBox1.Items.Strings[In
dex]);

Windows - Verificar a impressora padro

implementation
uses Printers;
{$R *.dfm}

function GetDefaultPrinter: string;
var
ResStr: array[0..255] of Char;
begin
GetProfileString('Windows', 'device', '', ResStr, 255);
Result :=StrPas(ResStr);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Caption :=GetDefaultPrinter;
end;


RichEdit - Pesquisar um texto, posicionar sobre ele e mostrar
ao usurio
No Windows XP somente utilizar o SelStart no mostrou a linha encontrada ao usurio,
foi necessrio utilizar o perform para mostrar a linha onde est o texto encontrado.

procedure TForm1.SpeedButton1Click(Sender: TObject);
var nPos, Linha: Integer;
begin
With RichEdit1 do
begin
SetFocus;
{ Pega a linha atual }
Linha :=Perform(EM_LINEFROMCHAR, SelStart, 0);

nPos :=FindText(Edit1.Text, 0, Length(RichEdit1.Text), []);
{ Posiciona o cursor sobre o texto encontrado na pesquisa }
59
SelStart :=nPos;
SelLength :=Length(Edit1.Text);

{ Pega a quantidade de linhas que separa a ltima linha para essa nova linha
posicionada }
Linha :=Perform(EM_LINEFROMCHAR, SelStart, 0)-Linha;

{ Visualiza a nova linha }
Perform(EM_LINESCROLL, Linha, Linha);
end;
end;

ActiveControl - Envia um valor para Edit que estiver em foco

Verifica se o componente que est com o foco da classe do TEdit, se for envia um
Texto para esse componente.

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if (ActiveControl is TEdit) then
(ActiveControl as TEdit).Text :='Teste';
end;

Funciona para outros componentes, trocando a propriedade Text utilizado neste
exemplo pela propriedade do outro componente.

Registro do Windows - Retorna portas seriais
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
ts : TStrings;
i : Integer;
begin
Reg :=TRegistry.Create;
Reg.RootKey :=HKEY_LOCAL_MACHINE;
Reg.OpenKey('HARDWARE\DEVICEMAP\SERIALCOMM', False);
ts :=TStringList.Create;
Reg.GetValueNames(ts);
for i :=0 to ts.Count -1 do
ListBox1.Items.Add(Reg.ReadString(ts.Strings[i]));
ts.Free;
Reg.CloseKey;
Reg.Free;
end;

60
Verifica se um programa est aberto, caso contrrio, abre

Existe uma forma que pegando o nome da janela. Veja o exemplo abaixo que trabalha
com a calculadora do Windows.

procedure TForm1.Button1Click(Sender: TObject); var
TheWindow: HWND;
begin
{find a handle to the Windows Explorer window}
TheWindow:=FindWindow(nil,'Calculadora');
if TheWindow <>0 then
// Chama calculadora se j estiver carregada
SetForegroundWindow(TheWindow)
else
// Carrega calculadora se estiver fechada
ShellExecute(Handle, 'Open', 'Calc.exe', nil, 'c:\windows', sw_shownormal);
end;


Funo que verifica a velocidade do processador

function GetCPUSpeed: Double;
const
DelayTime =500;
var
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
begin
PriorityClass :=GetPriorityClass(GetCurrentProcess);
Priority :=GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
dw 310Fh // rdtsc
mov TimerLo, eax
mov TimerHi, edx
end;
Sleep(DelayTime);
asm
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx
end;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
61
Result :=TimerLo / (1000.0 * DelayTime);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
CPUSpeed: Double;
begin
CPUSpeed :=GetCPUSpeed;
Label1.Caption :=FormatFloat('0.00 MHz', CPUSpeed);
end;

DBGrid - Ao clicar no campo no DBGrid ordenar os registros

Temos na tabela 04 campos: Empresa, Inscricao, Contador e Telefone

No Evento OnTitleClick do dbgrid:

var
campo:string;
begin
campo:=column.fieldname;
application.processmessages;
query1.sql.clear;
query1.sql.add('select * from Contribuinte order by '+campo);
if not query1.Prepared then
query1.Prepare;
query1.Open;
if campo='Nome' then
label12.caption:='Consulta por ordem de Empresa'; // campo Empresa
if campo='Inscricao' then
label12.caption:='Consulta por ordem de Inscrio'; // campo Inscrio
if campo='Contador' then
label12.caption:='Consulta por ordem de Contador'; // campo Contador
if campo='Telefone' then
label12.caption:='Consulta por ordem de Telefone' // campo Telefone

// Ao clicar em cada campo os registros so ordenados


Criando um lista Push and Pop em Delphi
Veja como implementar uma lista Push and Pop (Last In First Out) usando Array e
TList.
Demonstra ainda a tcnica do uso de Arrays em um TList.
62
Type
TInfo =Record
Nome : String;
End;
PInfo =^TInfo;

//=============================================================
=================
// Coloca itens na lista
//=============================================================
=================
Procedure PushItem(List:TList; Nome:String);
Var Info : PInfo;
Begin
New(Info);
Info.Nome :=Nome;
List.Add(Info);
End;

//=============================================================
=================
// Retira o ultimo item da lista
//=============================================================
=================
Procedure PopItem(List:TList; Var Nome:String);
Begin
If List.Count>0 then Begin
Nome :=PInfo(List[List.Count-1]).Nome;
Dispose(PInfo(List[List.Count-1]));
List.Delete(List.Count-1);
End Else Begin
Nome :='';
End;
End;

//=============================================================
=================
// Retorna um item a partir de sua posicao
//=============================================================
=================
Procedure GetItem(List:TList; Var Info:PInfo; RecordNumber:Integer);
Begin
Info :=PInfo(List[RecordNumber]);
End;

//=============================================================
=================
// Cria o objeto de lista
//=============================================================
=================
63
Procedure CreateList(Var List:TList);
Begin
If not Assigned(List) then List :=TList.Create Else List.Clear;
End;

//=============================================================
=================
// Destroi a lista e remove os ponteiros
//=============================================================
=================
Procedure DestroyList(List:TList);
Var I : Integer;
Begin
for i :=0 to List.Count-1 do Dispose(PInfo(List[i]));
List.Free;
End;

//=============================================================
=================
// Exemplo de Uso da lista
//=============================================================
=================
procedure TForm1.Button1Click(Sender: TObject);
Var List : TList;
i : Integer;
Info : PInfo;
Nome : String;

begin

CreateList(List);

// Empilha itens
PushItem(List,'Adenilton');
PushItem(List,'Ana');
PushItem(List,'Roberto');
PushItem(List,'Marta');
PushItem(List,'Silvia');
PushItem(List,'Pedro');

// Remove itens comecando pelo ultimo inserido
PopItem(List,Nome);
ShowMessage('Retirando '+Nome+' da lista ');

PopItem(List,Nome);
ShowMessage('Retirando '+Nome+' da lista ');

PopItem(List,Nome);
ShowMessage('Retirando '+Nome+' da lista ');

64
PushItem(List,'Carlos');

// Mostra os demais Itens de baixo para cima
for i :=List.Count-1 downto 0 do Begin
GetItem(List,Info,i);
ShowMessage(Info.Nome);
End;

// Destroi a lista
DestroyList(List);

end;


Rave Report - Imprimindo cdigo de barras em modo de
programao

// Uses rpBars

procedure TForm1.RvSystem1Print(Sender: TObject);
begin
With TRPBars2of5.Create(Sender as TBaseReport) do Begin
BarHeight :=1.5;
BarWidth :=0.065;
WideFactor :=BarWidth;
Text :='27596000000000000000902900000124000341010150';
PrintXY(1,1);
Free;
end;
end;


Gerar planilhas no Excel atravs de uma Query

Procedimento que recebe um Query e gera um planilha do Excel.

procedure GerarExcel(Consulta:TQuery);
var
coluna, linha: integer;
excel: variant;
valor: string;
begin
try
excel:=CreateOleObject('Excel.Application');
excel.Workbooks.add(1);
except
Application.MessageBox ('Verso do Ms-Excel'+
65
'Incompatvel','Erro',MB_OK+MB_ICONEXCLAMATION);
end;

Consulta.First;
try
for linha:=0 to Consulta.RecordCount-1 do
begin
for coluna:=1 to Consulta.FieldCount do // eliminei a coluna 0 da relao do
Excel
begin
valor:=Consulta.Fields[coluna-1].AsString;
excel.cells [linha+2,coluna]:=valor;
end;
Consulta.Next;
end;

for coluna:=1 to Consulta.FieldCount do // eliminei a coluna 0 da relao do Excel
begin
valor:=Consulta.Fields[coluna-1].DisplayLabel;
excel.cells[1,coluna]:=valor;
end;
excel.columns.AutoFit; // esta linha para fazer com que o Excel dimencione as
clulas adequadamente.
excel.visible:=true;
except
Application.MessageBox ('Aconteceu um erro desconhecido durante a
converso'+
'da tabela para o Ms-Excel','Erro',MB_OK+MB_ICONEXCLAMATION);
end;
end;


Rave Report - Somar valores

Existe um componente chamado "CalcTotal" o qual faz praticamente as mesmas
operaes que o QRExpr. Para utilizar, faa o seguinte:

1. Adicione um CalcOp em sua banda de totalizao;
2. Configure suas propriedades:
- DataView, apontando para seu DataView
- DataField, campo a ser totalizado
- Controller, banda "detalhe"
- DestPIVar, uma varivel criada na propriedade PIVars da "page"
- CalcType, ctSum

3. Adicione um componente DataText e configure sua propriedade DataField apontando
para a varivel que recebeu o valor no item acima.

Com isso, o ser efetuada a soma do campo e apresentado no referido DataText.
66
Colorir componente focado - Preservando sua cor original

public
procedure ColorControl(Sender: TObject);
end;


type
TControlaCor =Record
Objeto: TComponent;
Cor: TColor;
end;


var
Form1: TForm1;
ControlaCor: TControlaCor;


implementation
{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveControlChange :=ColorControl;
end;


{Procedure que altera a cor}
procedure TForm1.ColorControl(Sender: TObject);
begin
if Screen.ActiveControl is TForm then
Exit;

if (ControlaCor.Objeto =Nil) or
(not TComboBox(ControlaCor.Objeto).Showing) then
begin
ControlaCor.Objeto :=Screen.ActiveControl;
ControlaCor.Cor :=TComboBox(Screen.ActiveControl).Color;
end;

With Screen.ActiveForm do
begin
TComboBox(ControlaCor.Objeto).Color :=ControlaCor.Cor;
ControlaCor.Objeto :=Screen.ActiveControl;
ControlaCor.Cor :=TComboBox(Screen.ActiveControl).Color;
TComboBox(Screen.ActiveControl).Color :=clInfoBk
end;
end;
67


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Screen.OnActiveControlChange :=Nil;
end;


ActiveControl - Envia valor para Edit que tiver em foco

Verifica se o componente que est com o foco da classe do TEdit, se for envia um
Texto para esse componente.

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if (ActiveControl is TEdit) then
(ActiveControl as TEdit).Text :='Teste';
end;

Funciona para outros componentes, trocando a propriedade Text utilizado neste
exemplo pela propriedade do outro componente.


TFields - Adiciona Fields no Fields Editors em tempo de
execuo

{ Primeiramente temos que ter declarado as variveis onde sero criado os Objetos
Fields. }
public
Table1Name: TStringField;
Table1Capital: TStringField;
Table1Continent: TStringField;
Table1Area: TFloatField;
Table1Population: TFloatField;
{ Public declarations }
end;

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

{ Agora criamos os Objetos e configuramos suas propriedades }
procedure TForm1.Button1Click(Sender: TObject);
begin
Table1.Close;
Button1.Enabled :=False;
Button2.Enabled :=True;
68

Table1Name :=TStringField.Create(Table1);
Table1Name.FieldName :='Name';
Table1Name.DataSet :=Table1;
Table1Name.FieldKind :=fkData;
Table1Name.Size :=24;

Table1Capital :=TStringField.Create(Table1);
Table1Capital.FieldName :='Capital';
Table1Capital.DataSet :=Table1;
Table1Capital.FieldKind :=fkData;
Table1Capital.Size :=24;

Table1Continent :=TStringField.Create(Table1);
Table1Continent.FieldName :='Continent';
Table1Continent.DataSet :=Table1;
Table1Continent.FieldKind :=fkData;
Table1Continent.Size :=24;

Table1Area :=TFloatField.Create(Table1);
Table1Area.FieldName :='Area';
Table1Area.DataSet :=Table1;

Table1Population :=TFloatField.Create(Table1);
Table1Population.FieldName:='Population';
Table1Population.DataSet :=Table1;
Table1.Open;
end;

{ Aqui destruimos todos os objetos Fields criados }
procedure TForm1.Button2Click(Sender: TObject);
begin
Table1.Close;
Button1.Enabled :=True;
Button2.Enabled :=False;
Table1Name.Free;
Table1Capital.Free;
Table1Continent.Free;
Table1Area.Free;
Table1Population.Free;
Table1.Open;
end;

{ Um simples exemplo de como configurar a mscara via programao }
procedure TForm1.Button3Click(Sender: TObject);
begin
try
Table1.Close;
Table1Area.DisplayFormat :='###,###,##0';
Table1Population.DisplayFormat :='###,###,##0';
69
Table1.Open;
except
ShowMessage('Adicione os campos...')
end;
end;


ListBox - Colorir

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
if StrToInt(ListBox1.Items[Index]) >5 then
begin
ListBox1.Canvas.Font.Color :=clBlue;
ListBox1.Canvas.Font.Style :=[fsBold];
ListBox1.Canvas.Brush.Color :=clYellow;
end;
ListBox1.Canvas.FillRect(Rect);
ListBox1.Canvas.TextOut(Rect.Left, Rect.Top, Listbox1.Items[Index]);
end;

*** Alterar a propriedade Style para onDrawVariable

Associando um extenso de arquivo a um executvel

{ necessrio declarar a unit abaixo }
Registry

procedure CriaChave(const Chave, Nome, Valor: string);
var
K: TRegistry;
begin
K :=TRegistry.Create;
try
K.RootKey :=HKEY_CLASSES_ROOT;
K.OpenKey(Chave, true);
K.WriteString(Nome, Valor);
finally
K.Free;
end;
end;


procedure CriaAssociacao(const NomeDoc, NomeApp, NomeEXE, NomeIcone, Ext:
string);
begin
CriaChave(NomeDoc, , NomeApp);
70
CriaChave(Ext, , NomeDoc);
CriaChave(NomeDoc+\shell\open\command,,NomeEXE);
CriaChave(NomeDoc +\DefaultIcon,, NomeIcone);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
Button1.Enabled :=false;
Try
// EdDoc.Text =Nome do arquivo Exemplo: Doc01
// EdNome.Text =Nome do programa Exemplo:NotePad
// EdExe.Text =Executvel Exemplo:
// c:\windows\notepad.exe %1
// EdIcone.Text =cone Exemplo:
// c:\windows\notepad.exe
// EdExt.Text =Extenso Exemplo: .xxx
// CriaAssociacao(EdDoc.Text, EdNome.Text,
// EdEXE.Text, EdIcone.Text, EdExt.Text);
finally
Button1.Enabled :=true;
end;
end;



Retornar as contas de E-Mail

Nesta dica iremos demonstrar como obter as contas de email registradas na Mquina,
verificando as informaes
armazenadas do registrador do Windows.

Neste exemplo iremos utilizar um componente TListBox e um TButton...

implementation
uses Registry;
{$R *.DFM}

{ Evento OnShow do Formulrio }
procedure TForm1.FormShow(Sender: TObject);
var Reg: TRegistry;
begin
Reg :=TRegistry.Create;
try
Reg.RootKey :=HKEY_CURRENT_USER;
Reg.OpenKey(\Software\Microsoft\Internet
Account Manager\Accounts, False);
Reg.GetKeyNames(ListBox1.Items);
finally
71
Reg.CloseKey;
Reg.Free;
end;
end;

{ evento OnClick do TButton }
procedure TForm1.Button1Click(Sender: TObject);
var Reg: TRegistry;
sKey : String;
begin
if ListBox1.ItemIndex =-1 then
Exit;
Reg :=TRegistry.Create;
try
Reg.RootKey :=HKEY_CURRENT_USER;
sKey :=\Software\Microsoft\Internet Account Manager\Accounts\;
sKey :=sKey +ListBox1.Items[ListBox1.ItemIndex];
Reg.OpenKey(sKey, False);
if Reg.ValueExists(SMTP Server) then
ShowMessage( O SMTP da conta selecionada
:+#13+Reg.ReadString(SMTP Server) )
else
ShowMessage(SMTP no existe para esta conta);
finally
Reg.CloseKey;
Reg.Free;
end;
end;



HKEY, Registry
implementation
uses registry;


{ Atribui um informacao para o Registry }
procedure TForm1.BitBtn2Click(Sender: TObject);
Var Reg : TRegistry;
begin
Reg :=Tregistry.Create;
With TRegistry.Create do
begin
RootKey:=HKEY_USERS;
OpenKey(RamosInformatica\curso\teste', True);
WriteString('Teste_Reg1','Teste Teste');
Free;
end;
72
end;

{ Recupera um valor do Registry }
procedure TForm1.BitBtn7Click(Sender: TObject);
Var Reg : TRegistry;
Value : string;
begin
Reg :=Tregistry.Create;
With TRegistry.Create do
begin
RootKey:=HKEY_USERS;
OpenKey('Ramosinformatica\curso\teste', True);
Caption :=ReadString('Teste_Reg1');
Free;
end;

end;

Criar e ler chave

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
S: String;
begin
Reg :=TRegistry.Create;
Reg.RootKey :=HKey_Classes_Root;
if Reg.Openkey('RamosDaInformatica',True) then { Cria ou Abre a chave principal }
begin
Reg.CreateKey('Empresa'); { Cria Sub-Chave dentro de RamosDaInformatica}
Reg.CreateKey('Chave'); { Cria Sub-Chave dentro de RamosDaInformatica}
ShowMessage('Chave Criada...')
end
else
ShowMessage('Erro na criao da Chave...');
// S :=Reg.ReadString('(Padro)');
Reg.free;
end;


//L informaes da Empresa cadastrado na mquina
procedure TForm1.Button1Click(Sender: TObject);
var
Info: TRegDataInfo;
Reg: TRegistry;
begin
Reg :=TRegistry.Create;
Reg.RootKey :=HKEY_LOCAL_MACHINE;
73
if not Reg.OpenKey('\SOFTWARE\Microsoft\Windows\CurrentVersion', FALSE)
then
Reg.GetDataInfo('RegisteredOrganization', Info);
Label1.Caption :='Empresa...: ' +Reg.ReadString('RegisteredOrganization');
Label2.Caption :='Usuario...: ' +Reg.ReadString('RegisteredOwner');
end;


Retornar lista de hardware via registry

var
Reg: TRegistry;
Chs, tmp: TStringList;
i, t: integer;
begin
Chs :=TStringList.Create;
tmp :=TStringList.Create;

Reg :=TRegistry.Create;
Reg.RootKey :=HKEY_LOCAL_MACHINE;
Reg.OpenKey('hardware\devicemap\', false);

Reg.GetKeyNames(Chs);

for i :=0 to Chs.Count -1 do
begin
Reg.Free;
Reg :=TRegistry.Create;
Reg.RootKey :=HKEY_LOCAL_MACHINE;
Reg.OpenKey('hardware\devicemap\' +Chs[i], false);
Reg.GetKeyNames(tmp);
if tmp.Count =0 then
Reg.GetValueNames(tmp);
Memo1.Lines.Add('--->' +Chs[i]);
Memo1.Lines.Add(tmp.Text);
Memo1.Lines.Add('------------------------');
end;
Chs.Free;
tmp.Free;
Reg.CloseKey;
Reg.Free;
end;

Verificar se um valor existe dentro de uma Chave

implementation
uses Registry;
{$R *.DFM}
74

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg :=TRegistry.Create;
Reg.RootKey :=HKEY_LOCAL_MACHINE;
Reg.OpenKey('\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\',
False);
if Reg.ValueExists('DSQUERY') then
Showmessage('Existe!');
end;


Quick Report - Selecionando itens do ComboBox para
PapeSize

procedure TForm1.ComboBox1Click(Sender: TObject);
var i : integer;
begin
//Atribui o item selecionado no ComboBox a prop. PaperSize
For i :=1 to ComboBox1.Items.Count-1 do
begin
if ComboBox1.Items[ComboBox1.ItemIndex] ='Letter' then
QuickRep1.Page.PaperSize :=Letter
else if ComboBox1.Items[ComboBox1.ItemIndex] ='Custom' then
QuickRep1.Page.PaperSize :=Custom
else if ComboBox1.Items[ComboBox1.ItemIndex] ='A4' then
QuickRep1.Page.PaperSize :=A4;
end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
// Atribui os nomes ao ComboBox
ComboBox1.Items.ADD('Letter');
ComboBox1.Items.ADD('Custom');
ComboBox1.Items.ADD('A4');
end;


ListBox - Pesquisa incremental

Para fazer uma pesquisa incremental no ListBox voc ir precisar tambm de um
componente Edit.

Inclua o cdigo abaixo no evento OnChange do componente Edit.
75

procedure TForm1.Edit1Change(Sender: TObject);
var
S: Array[0 ..255] of char;
begin
StrPCopy(S, Edit1.Text);
with ListBox1 do
ItemIndex :=Perform(LB_SELECTSTRING, 0, LongInt(@S));
if (ListBox1.ItemIndex <0) or (ListBox1.Items[ListBox1.ItemIndex] <>
Edit1.Text) then
ListBox1.ItemIndex :=-1;
end;


Acertar data e hora com o servidor

No Windows NT/2000/XP existem APIs especficas para obter a data e hora de um
Servidor, porm com Windows 9x no encontramos APIs com o mesmo efeito, porm
possvel implementar via um utilitrio DOS e com isso acertar a data e hora de uma
mquina com outra da rede.

procedure AcertaHora(ServerName: String);
begin
WinExec(PChar(net time +
ServerName + /set /yes), 0);
end;


QuickReport - Access Violation no Windows 2000 e XP

Ocorre devido ao tamanho do caminho do diretrio temporrio do Windows.

V em Control Panel -> System -> Clique na aba Advanced -> Clique no boto
Environment Variables. Altere o caminho da varivel TMP para um
caminho menor, como por exemplo c:\temp. Confirme se este diretrio j est criado.


DBGrid - Alterar as cores do ttulo em tempo de execuo.

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
I: integer;
begin
for i:=0 to DBGrid1.Columns.count-1 do
begin
DBGrid1.Columns[i].Title.Color :=clBtnFace;
76
DBGrid1.Columns[i].Title.Font.Color :=clBlack;
DBGrid1.Columns[i].Title.Font.Style :=[];
end;
Column.Title.color :=ClYellow;
Column.Title.Font.Style :=[ fsBold, fsItalic];
Column.Title.Font.Color :=clRed;
end;


Testa se a impressora est funcionando

function PrinterOK(Lpt: Word): Boolean;
const
PrnStInt : Byte =$17;
StRq : Byte =$02;

var
nResult : Byte;

begin
asm
mov ah,StRq;
mov dx,Lpt;
Int $17;
mov nResult,ah;
end;

Result :=(nResult and $80) =$80;
end;

Modo de utilizao:

if PrinterOK(0) then
ShowMessage('Impressora OK')
else
ShowMessage('Impressora sem papel ou desligada');

O parmetro da funo equivale ao nmero da porta da impressora.
0- LPT1
1- LPT2


Como implementar um AutoComplete num Edit comum

Esta dica vou publicar sem traduo, primeiro porque no original bem melhor e
segundo para no haver erros.

77
// To add auto-complete capability to a TEdit component
// 1) Declare a global TStringlist object
// 2) Create it on the form create event
// 3) Free it on the form destroy event
// 4) Add new entry to it on the TEdit exit event
// 5) Do the auto-complete on the TEdit keyUp event
// 6) Add a TCheckbox control for enable/disable
// If desired, initialize the list from a database, ini file etc.

procedure TForm1.FormCreate(Sender: TObject);
begin
listValues :=TStringList.create;
listValues.sorted :=true;
listValues.Duplicates :=dupIgnore;
end;

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

procedure TForm1.edtListExit(Sender: TObject);
begin
listValues.add(edtList.text);
end;

procedure TForm1.edtListKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
var
theText: string;
i, p: integer;
begin
if not ckbxList.checked then exit; // User can enable/disable
with edtList do
case key of
8, 13, 46, 37..40: ; // No backspace, enter, delete, or arrows
else
begin
// Search for unselected portion at start of text
p :=selStart; // cursor position
theText :=copy(text, 0, p); // Excludes searched portion
// Match entered text portion
for i :=0 to listValues.count-1 do
begin
// Keep case of listed item
if pos(upperCase(theText), upperCase(listValues[i]))=1 then
if compareText(theText, listValues[i]) <0 then
begin
text :=listValues[i];
selStart :=p;
78
SelLength :=length(text) - selStart;
break; // Match found, so quit search
end;
end; // for
end; // case
end; // with
end;


Como adicionar um CheckBox em um StringGrig

Esta uma maneira bem simples de adicionar um checkbox, ou qualquer outro objeto,
num StringGrid

Para fazer este exemplo, adicione TPanel, e um StringGrid,com 5 colunas e 4 linhas, no
Painel .


procedure TForm1.CheckBox1Click(Sender: TObject);
begin
ShowMessage('Aqui');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
StringGrid1.Cells[0,0] :='Uma Maneira';
StringGrid1.Cells[1,0] :='Simples';
StringGrid1.Cells[2,0] :='Para';
StringGrid1.Cells[3,0] :='Fazer';
StringGrid1.Cells[4,0] :='Marcar';
AdicionarCheckBoxes; //rotina que adiciona os Check
end;

procedure TForm1.AdicionarCheckBoxes;
var i: Integer;
NovoCheckBox: TCheckBox;
begin
limpaBuffer; // bom no esquecer de limpar controles no utilizados
for i :=1 to 4 do
begin
StringGrid1.Cells[0,i] :='a';
StringGrid1.Cells[1,i] :='b';
StringGrid1.Cells[2,i] :='c';
StringGrid1.Cells[3,i] :='d';
NovoCheckBox :=TCheckBox.Create(Application);
NovoCheckBox.Width :=0;
NovoCheckBox.Visible :=false;
NovoCheckBox.Caption :='OK';
NovoCheckBox.Color :=clWindow;
79
NovoCheckBox.Tag :=i;
NovoCheckBox.OnClick := CheckBox1.OnClick; //Associar um evento OnClick j
existente para o Novo CheckBox
NovoCheckBox.Parent :=Panel1;
StringGrid1.Objects[4,i] :=NovoCheckBox;
StringGrid1.RowCount :=i;
end;
AlinhaCheck; // agora vamos alinhar o check na celular
end;

Procedure TForm1.Limpabuffer;
var
NovoCheckBox: TCheckBox;
i: Integer;
begin
for i :=1 to StringGrid1.RowCount do
begin
NovoCheckBox :=(StringGrid1.Objects[4,i] as TCheckBox);
if NovoCheckBox <>nil then // o objeto deve existir para poder ser destrudo
begin
NovoCheckBox.Visible :=false;
StringGrid1.Objects[4,i] :=nil;
end;
end;
end;

Procedure TForm1.AlinhaCheck;
var
NovoCheckBox: TCheckBox;
Rect: TRect;
i: Integer;
begin
for i :=1 to StringGrid1.RowCount do
begin
NovoCheckBox :=(StringGrid1.Objects[4,i] as TCheckBox);
if NovoCheckBox <>nil then
begin
Rect :=StringGrid1.CellRect(4,i); // aqui descobrimos a posio da celula para
utilizarmos no check
NovoCheckBox.Left :=StringGrid1.Left +Rect.Left+2;
NovoCheckBox.Top :=StringGrid1.Top +Rect.Top+2;
NovoCheckBox.Width :=Rect.Right - Rect.Left;
NovoCheckBox.Height :=Rect.Bottom - Rect.Top;
NovoCheckBox.Visible :=True;
end;
end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
80
begin
if not (gdFixed in State) then
AlinhaCheck;
end;


Abreviao automtica de nomes

Abrevia nomes extensos pegando a primeira letra do nome e acrescentando ponto no
final. timo para impresso de etiquetas.

function AbreviaNome(Nome: String): String;
var
Nomes: array[1..20] of string;
i, TotalNomes: Integer;
begin
Nome :=Trim(Nome);
Result :=Nome;
{Insere um espao para garantir que todas as letras sejam testadas}
Nome :=Nome +#32;
{Pega a posio do primeiro espao}
i :=Pos(#32, Nome);
if i >0 then
begin
TotalNomes :=0;
{Separa todos os nomes}
while i >0 do
begin
Inc(TotalNomes);
Nomes[TotalNomes] :=Copy(Nome, 1, i - 1);
Delete(Nome, 1, i);
i :=Pos(#32, Nome);
end;
if TotalNomes >2 then
begin
{Abreviar a partir do segundo nome, exceto o ltimo.}
for i :=2 to TotalNomes - 1 do
begin
{Contm mais de 3 letras? (ignorar de, da, das, do, dos, etc.)}
if Length(Nomes[i]) >3 then
{Pega apenas a primeira letra do nome e coloca um ponto aps.}
Nomes[i] :=Nomes[i][1] +'.';
end;
Result :='';
for i :=1 to TotalNomes do
Result :=Result +Trim(Nomes[i]) +#32;
Result :=Trim(Result);
end;
81
end;
end;


Compilando a aplicao pelo MS-DOS

Apenas a ttulo de curiosidade, este texto explica como criar um programa em Delphi a
partir do zero, usando somente o compilador do Delphi utilizado na linha de comando
(dcc32) e o prompt do dos. Para fazer o programa, voc precisar criar dois arquivos :
teste.pas (o programa propriamente dito) e teste.dfm (definicoes do formulario).
Primeiro, crie o programa teste.pas e teste.dfm.

ARQUIVO: teste.pas
-------------------------------------------------------
program teste;

uses windows,sysutils,classes,forms,stdctrls;

type tfrm =class(tform)
button1 : tbutton;
constructor create(aowner:tcomponent);override;
procedure button1click(sender:tobject);
end;

constructor tfrm.create(aowner:tcomponent);
begin
inherited create(aowner);
left:=(screen.width div 2)-width div 2;
top:=(screen.height div 2)-height div 2;
end;

procedure tfrm.button1click(sender:tobject);
begin
if button1.caption ='Clique' then
button1.caption:='Aperte'
else
button1.caption:='Clique';
end;

{$R *.dfm}

var frm : tfrm;

begin
application.initialize;
application.createform(tfrm,frm);
application.run;
end.
-------------------------------------------------------
82
ARQUIVO: teste.dfm
-------------------------------------------------------
object frm: tfrm
width =350
height =290
caption ='programa teste'
object button1: tbutton
caption ='Clique'
left =20
top =20
width =100
height =30
onclick =button1click
end
end
-------------------------------------------------------
Pense no arquivo .dfm como se fosse a janela de propriedades do objeto. Caso voc
queira alterar cor, alinhamento, etc, etc e etc, s colocar no .dfm. Para compilar,
simplesmente digite na linha do prompt :

dcc32 teste

Pronto. Voc ter, no mesmo diretrio, um arquivo chamado teste.exe, que nada mais
que o seu projeto compilado.


Colorao gradiente no Form

procedure TForm1.FormPaint(Sender: TObject);
var
altura, coluna: Word;
begin
altura :=(ClientHeight +255) div 256;
for coluna :=0 to 255 do
with Canvas do
begin
Brush.Color :=RGB(coluna, 0, 0); { Modifique para obter cores diferentes }
FillRect(Rect(0, coluna * altura, ClientWidth, (coluna +1) * altura)) ;
end;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
Invalidate;
end;


83
Usar perfeitamente o LookupComboBox

O componente DBLookupComboBox utilizado para seleciona registros de uma tabela
e gravar em outra tabela.

As propriedades necessrias para a utilizao so:

DataSource - Ligar a DataSource da Tabela ao qual vai receber o valor do registro
selecionado;
DataField - Ligar o campo de ligao entre as duas tabelas, ao qual vai receber o valor
do registro selecionado;

ListSource - Ligar a DataSource da Tabela ao qual vai Ter o registro selecionado;
ListField - Ligar o campo que ser listado quando o usurio abrir a janela para seleo
do registro;
KeyField - Ligar o campo de ligao entre as duas tabelas, ao qual ter o seu valor
enviado para gravao.

O campo de ligao entre as duas tabelas pode ser um campo cdigo, pois este campo
que manter os valores iguais entre as duas tabelas.


Como colocar um codigo para que a aplicacao feche apos XX
segundos sem atividades no teclado ou sem cliques do mouse.

Ol Ramos, enviei uma duvida no forum do Ramos e nao esperava ter tido tanta
discussao, mas depois
que consegui a resposta ninguem mais comentou sobre o assunto. De qualquer forma
apesar de ter
postado no forum a resposta que recebi de outro camarada, abaixo segue de novo um
exemplo de
como colocar um codigo para que a aplicacao feche apos XX segundos sem atividades
no teclado
ou sem cliques do mouse. Este codigo deve ser colocado no Form principal e fazer os
devidos ajustes.
Nao esquecer de colocar o timer.

Esta dica foi enviada por Cristiano Menusi- Oeste - SC e ele tambem havia encontrado
na Net



unit Unit1;

interface

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

type
TForm1 =class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
procedure AppIdle(Sender: TObject; var Done: Boolean);
procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{ TForm1 }

procedure TForm1.AppIdle(Sender: TObject; var Done: Boolean);
begin
Timer1.Enabled :=True;
end;

procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
Case Msg.message of
WM_LBUTTONDOWN,WM_RBUTTONDOWN,WM_KEYDOWN
:Timer1.Enabled :=False;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage :=AppMessage;
Application.OnIdle :=AppIdle;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Application.Terminate;
end;


85
Escondendo a barra de tarefas do Windows

var
J an: HWnd;
begin
J an:=FindWindow(Nil,'Nome_do_projeto');
if J an <>0 then ShowWindow(J an,SW_Hide);
end;


Pega todos os erros do Sistema, captura tela do erro, grava em
arquivo e envia por e-mail

Como montar uma rotina para pegar todos os erros do sistema e capturar tela do erro e
gravar em arquivo para futura inspecao ou envio por e-mail. Coloque esta rotina no
menu principal de seu sistema.

unit Form_Menu;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, DB, ComCtrls, ExtCtrls, StdCtrls,Buttons, Mask, DBTables,
DBIPROCS, DBITypes, DBIErrs, Gauges, ImgList, ToolWin, jpeg, ExtDlgs;

type
TFrm_Menu =class(TForm)
MainMenu1: TMainMenu;

PRIVATE
{ Private declarations }

Procedure ManipulaExcecoes(Sender: TObject; E: Exception);

public
{ Public declarations }
end;

var
Frm_Menu: TFrm_Menu;

implementation

//------------------------------------//
//...Rotina de manipulaco de erros //
//------------------------------------//
86
Procedure TFrm_Menu.ManipulaExcecoes(Sender: TObject; E: Exception);
Var BitMap : TBitmap;

Begin
//...Captura e salva a tela atual do erro.
BitMap :=TBitmap.Create;
BitMap :=CaptureScreenRect(Bounds(0,0,Screen.Width,Screen.Height));
BitMap.SaveToFile(ExtractFilePath(Application.ExeName)+'erro.bmp') ;
BitMap.Free;

//...Messagem de erro do sistema
MessageDlg(E.Message +#13#13 +'Suporte tcnico:'#13
+'aceinfo@starknet.com.br',mtError, [mbOK], 0);
end;

{$R *.DFM}

procedure TFrm_Menu.FormCreate(Sender: TObject);
Begin
Application.OnException :=ManipulaExcecoes;
end;

End.


Detectando o tipo de Conexo com a internet
uses Wininet

function ConnectionKind: Boolean;
var
flags: DWORD;
begin
Result :=InternetGetConnectedState(@flags, 0);
if Result then
begin
if (flags and INTERNET_CONNECTION_MODEM) =
INTERNET_CONNECTION_MODEM
then
ShowMessage('Modem');
if (flags and INTERNET_CONNECTION_LAN) =
INTERNET_CONNECTION_LAN then
ShowMessage('LAN');
if (flags and INTERNET_CONNECTION_PROXY) =
INTERNET_CONNECTION_PROXY
then
ShowMessage('Proxy');
if (flags and INTERNET_CONNECTION_MODEM_BUSY) =
INTERNET_CONNECTION_MODEM_BUSY then
87
ShowMessage('Modem Busy');
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ConnectionKind;
end;

Funo de potenciao - Juros

Segue abaixo uma funo para efetuar a potenciao. til para compor formulas
financeiras, como a de VP ("PV" valor presente) VF ("FV" valor futuro)

Exemplo:

Calcular o valor de um produto para o prazo de 30 dias com a taxa de juros de 5% ms.

var
i: Real; // taxa de juros
valor: Real; // valor base para calculo do valor futuro.
pz: Integer // prazo em dias
begin
i :=5//100;
valor:=1000.00
pz :=30
Result:=valor*( Pot( (1+i), (pz/30) ) //Resultado 1.050,00
end;
no excel a Pot substituda pelo sinal ^Ex. =E18*((1+C19)^(C20/30))

Function Pot( base, expoente: real ):real; // Potenciao
begin
{ utiliza a funo de exponencial e de logaritmo }
Result:=Exp((expoente * Ln( base )));
end;

Dica: No amplie o nome da funo, pois as funes financeiras costumam ser bem
extensas.


Para trocar as cores dos botoes do radiogroup
No Object Inspector na propriedade Font coloque a cor verde.
procedure TForm1.RADIOGROUP1Click(Sender: TObject);
Var
i : Integer;
88
begin
// Para trocar as cores dos botoes do RadioGroup
for i :=0 to RADIOGROUP1.Items.Count-1 do begin
TRadioButton(RADIOGROUP1.Controls[i]).Font.Color :=clGreen;
TRadioButton(RADIOGROUP1.Controls[i]).Font.Style :=[fsBold];
end;
TRadioButton(RADIOGROUP1.Controls[RADIOGROUP1.ItemIndex]).Font.Color :=
clRed;
TRadioButton(RADIOGROUP1.Controls[RADIOGROUP1.ItemIndex]).Font.Style :=
[fsBold];
end;

Como criar uma figura do tipo marca d' gua

procedure TForm1.Button1Click(Sender: TObject);
var
X, Y : Integer;
begin
brush.style :=bsClear;
for y:=0 to image1.height-1 do
for x:=0 to image1.width-1 do
begin
if (x mod 2)=(y mod 2) then
image1.canvas.pixels[x,y]:=clWhite;
end;
end;


Criptografando Imagens

procedure cripto(const BMP: TBitmap; Key: Integer);
var
BytesPorScan: Integer;
w, h: integer;
p: pByteArray;
begin
try
BytesPorScan :=Abs(Integer(BMP.ScanLine[1]) -
Integer(BMP.ScanLine[0]));
except
raise Exception.Create('Erro !');
end;
RandSeed :=Key;
for h :=0 to BMP.Height - 1 do
begin
P :=BMP.ScanLine[h];
for w :=0 to BytesPorScan - 1 do
89
P^[w] :=P^[w] xor Random(256);
end;
end;

Agora vamos ao evento onclick do Button chamar a nossa procedure cripto, basta
digitar o seguinte cdigo:

procedure TForm1.Button1Click(Sender: TObject);
begin
cripto(Image1.Picture.Bitmap, 1);
Image1.Refresh;
end;

Ao chamar a rotina passamos como parmetro o caminho da imagem que no exemplo
foi utilizado o componente image e 1 como um valor inteiro para retornamos a imagem
normal, logo aps a execuo da nossa procedure atualizamos o image para que ele
possa exibir nossa imagem criptografada.


Alterar a fonte de determinado registro num DBGrid

Para trocar a fonte de um DBGrid, utilize a rotina abaixo no evento OnDrawDataCell:

if Tabela.FieldByName ('Salario').Value >=10000 then
begin
DbGrid1.Canvas.Font.Color :=clRed;
DbGrid1.Canvas.Font.Style :=[fsBold];
end;
DbGrid1.DefaultDrawDataCell(Rect, Field, State);

No caso, somente os registros com salrio maior que R$ 10.000,00 ficaro com cor
vermelha e em negrito.

Nota: No necessrio mover o ponteiro da tabela para colorir os registros.


Alinhar ttulo da barra de titulos do Form a esquerda ou direita

//Deve ser usada assim:
//Procedure TForm1.Titulo(Titulo: Pchar;pos,wParam: Integer);
//e declarada na clausua private.

procedure Titulo(Titulo: Pchar;pos,wParam: Integer);
var
DC: THandle;
R1, R2: TRect;
begin
DC :=GetWindowDC(Handle);
90
try
SetWindowText(Handle, nil);
GetWindowRect(Handle, R2);
R1.Left :=GetSystemMetrics(SM_CXSIZE) +
GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXFRAME);
R1.Top :=GetSystemMetrics(SM_CYFRAME);
R1.Right :=R2.Right - R2.Left - R1.Left - 2 * GetSystemMetrics(SM_CXSIZE);
R1.Bottom :=R1.Top +GetSystemMetrics(SM_CYSIZE);
if wParam =1 then
begin
SetBkColor(DC, GetSysColor(COLOR_ACTIVECAPTION));
end
else
begin
SetBkColor(DC, GetSysColor(COLOR_INACTIVECAPTION));
end;
SetTextColor(DC, GetSysColor(COLOR_CAPTIONTEXT));
if pos =1 then
begin
DrawText(DC, Titulo, -1, R1, DT_LEFT or DT_VCENTER);
end
else
begin
DrawText(DC, Titulo, -1, R1, DT_RIGHT or DT_VCENTER);
end;
finally
ReleaseDC(Handle, DC);
end;
end;


Alterar fonte do Hint

Para testar este exemplo inclua no seu form alguns componentes. Nestes componentes
coloque informaes na propriedade Hint de cada componente e altere a propriedade
ShowHint para True.

unit Unit1;

interface

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

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

var
Form1: TForm1;

implementation

{$R *.DFM}

// Funo que ir alterar a fonte do Hint
procedure TForm1.MyShowHint(var HintStr: string; var CanShow: Boolean; var
HintInfo: HintInfo);
var
i : integer;
begin
for i :=0 to Application.ComponentCount - 1 do
if Application.Components[i] is THintWindow then
with THintWindow(Application.Components[i]).Canvas do
begin
Font.Name :='Arial';
Font.Size :=18;
Font.Style :=[fsBold];
HintInfo.HintColor :=clWhite;
end;
end;

// Evento OnCreate do Form
procedure TForm1.FormCreate(Sender: TObject);
begin
// Ativa a funo que ir alterar o formato do Hint
Application.OnShowHint :=MyShowHint;
end;


Criando arquivo Texto

Veja abaixo os passos bsicos para criao de arquivos texto:

Var
92
F:TextFile;

Begin
AssignFile(f,'c:\qq_arquivo.txt');
Rewrite(f); //abre o arquivo para escrita

Writeln(f,'Testando'); escreve no arquivo e desce uma linha

Write(f,'Linha de Cdigo - www.linhadecodigo.com.br'); //escreve no arquivo sem
descer a linha
Closefile(f); //fecha o handle de arquivo
End;

///Rotina para ler de um arquivo texto:

var
f:TextFile;
linha:String;

begin
AssignFile(f,'c:\qq_arquivo.txt');
Reset(f); //abre o arquivo para leitura;

While not eof(f) do begin
Readln(f,linha); //le do arquivo e desce uma linha. O contedo lido transferido para
a varivel linha
Memo1.lines.add(linha);
End;

Closefile(f);
end;


Como selecionar tudo (Ctrl+A) em um TMemo/TDBMemo

Voc pode selecionar todo o contedo de um TMemo ou TDBMemo utilizando as
teclas de atalho Crtl+A adicionando no evento OnKeyDownEvent destes componentes
o cdigo a seguir:

procedure OnKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState) ;
begin
if (Key =Ord('A')) and (ssCtrl in Shift) then
begin
TMemo(Sender).SelectAll;
Key :=0;
end;
end;

93

Mudando o IP da mquina via API do Windows

{Como posso mudar meu IP? via API?

A resposta para essa pergunta no neste artigo estou unsando o Delphi 7,
mas pode ser feito com qualquer outra verso do delphi. nos Windows 2000 e XP
existe um aplicativo chamado NETSH que faz essa mudana para ns sem que
precisemos reiniciar o computador. bem vamos por a mo na massa e brincarmos um
pouco com as configuraes de IP.

Mudando a Configurao para DHCP:

Crie uma aplicao no Delphi, NEW -> Application no FormDesigner ponha um
TButton e no evento OnClick escreva o seguinte cdigo:}




if Win32Plataform =
VER_PLATAFORM_WIN32_NT then WinExec('cmd /c netsh interface ip set address
"Conexo local" DHCP', SW_SHOWNORMAL) else MessageBox(Handle, 'esse
Comando no pode ser rodado fora da plataforma NT', 'NETSH',
MB_ICONWARNING);
{onde verifico se a plataforma do Programa uma plataforma NT, caso contrrio
informo ao usurio que esse comando no pode ser rodado fora de uma plataforma
NT.

Mudando as Configuraes dos IPs da mquina,
menos os DNS:
Na mesma aplicao do exemplo acima Ponha outro TButton e no Evento OnClick
dele escreva:}

if Win32Plataform = VER_PLATAFORM_WIN32_NT then WinExec('cmd /c
netsh interface ip set address "Conexo local" static 192.168.10.104
255.255.255.0 192.168.10.1 1', SW_SHOWNORMAL) else MessageBox(Handle, 'esse
{Comando no pode ser rodado fora da plataforma NT', 'NETSH',
MB_ICONWARNING);


Pronto seu IP, SubnetMask e Gateway foram mudados. Para maiores informaes sobre
o NETSH visite o site da Microsoft:
Suporte Microsoft.


Texto na diagonal e girando

Procedure TForm1.Button1Click(Sender: TObject);
94
var
lf : TLogFont;
tf : TFont;
i : integer;
begin
with Form1.Canvas do
begin
Font.Name :='Verdana';
Font.Size :=16;
tf :=TFont.Create;
tf.Assign(Font);
GetObject(tf.Handle, sizeof(lf), @lf);
lf.lfOrientation :=1000;
end;
For i:=50000 Downto 1 do
Begin
lf.lfEscapement :=i;
tf.Handle :=CreateFontIndirect(lf);
Form1.Canvas.Font.Assign(tf);
Form1.Canvas.TextOut(200, Height div 2, 'Ramos da Informtica');
//Sleep(10); Este pode cria um Delay na execuo
end;
tf.Free;

end;

Criar um alias dinamicamente na memria

procedure TForm1.FormCreate(Sender: TObject);
begin
if not Session.IsAlias(Teste) then
session.AddStandardAlias(Teste,
ExtractFilePath(Application.ExeName),PARADOX);
end;

Rodar videos em um panel
begin
if opendialog1.execute then
begin
mediaplayer1.filename:=opendialog1.filename;
mediaplayer1.open;
mediaplayer1.Perform (wm_lbuttondown,0,$00090009);
mediaplayer1.Perform (wm_lbuttonup,0,$00090009);
end;
end;

95
Como colocar uma coluna do DBGrid em maiuscula
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if DBGrid1.SelectedField.FieldName='NOME' THEN
Key :=AnsiUpperCase(Key)[Length(Key)];
end;

DBGrid - Alinhando texto conforme condio

Aqui iremos demonstrar como colorir e alinhar o texto de uma coluna do DBGrid com
base em uma condio.

Estamos utilizando a tabela COUNTRY do alias DBDemos e verificamos o contedo do
campo Continent. Caso seja North America iremos mudar a cor da fonte para verde e
o alinhamento do texto para direita, o qual ser redesenhado atravs da API DrawText.
Este tratamento ser feito no evento OnDrawColumnCell do prprio DBGrid,
acompanha o cdigo abaixo:

{ constantes para o alinhamento }
const
FmtCentered =DT_SingleLine or DT_VCenter or DT_NoClip or DT_Center;
FmtLeft =DT_SingleLine or DT_VCenter or DT_NoClip or DT_Left;
FmtRight =DT_SingleLine or DT_VCenter or DT_NoClip or DT_Right;

implementation

implementation

{$R *.DFM}

procedure TForm1.gridCountryDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
Format: integer;
R: TRect;
begin
if (tabCountryContinent.AsString ='North America') and (DataCol =1) then
begin
gridCountry.Canvas.Font.Color :=clGreen;
R :=Rect;
Format :=FmtRight; { poder utilizar: FmtCentered, FmtLeft, FmtRight }
gridCountry.Canvas.FillRect(Rect);
DrawText(gridCountry.Canvas.Handle, PChar(Column.Field.AsString), Length
Column.Field.AsString), R, Format);
end;
if (tabCountryContinent.AsString ='South America') and (DataCol =1) then
begin
96
gridCountry.Canvas.Font.Color :=clRed;
R :=Rect;
Format :=FmtCentered; { poder utilizar: FmtCentered, FmtLeft, FmtRight }
gridCountry.Canvas.FillRect(Rect);
DrawText(gridCountry.Canvas.Handle, PChar(Column.Field.AsString), Length
Column.Field.AsString), R, Format);
end;
end;


DBGrid - Colocando CheckBox no grid

Frequentemente e-mail de nossos visitantes sobre como colocar um CheckBox em uma
coluna referente um campo lgico apresentada no DBGrid. Aqui irei demonstrar uma
abordagem bem simples que desenha uma imagem que ir imitar um CheckBox e caso
o contedo do campo seja verdadeiro, mostraremos uma imagem checada e do
contrrio uma imagem desmarcada.

Neste exemplo, o campo lgico possui o nome de situacao. No evento
OnDrawColumnCell verificamos se a coluna atual situacao e conforme o valor do
referido campo desenhamos a imagem correspondente. No evento OnCellClick
permitimos a alterao do valor do campo que, quando estiver =true ir receber false e
vice-versa. E finalizando, no evento OnEnter do DBGrid efetuamos um tratamento para
no permitir a edio direta na coluna referente o campo lgico.
Neste exemplo iremos codificar os eventos: OnDrawColumnCell, OnCellClick e
OnEnter do DBGrid, alm ainda de um componente ImageList que ser responsvel em
armazenar e fornecer as imagens que sero desenhada referida coluna.

procedure TForm1.grdExemploDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
{ Desenha CheckBox }
if Column.FieldName ='Situacao' then
begin
grdExemplo.Canvas.FillRect(Rect);
Imagens.Draw(grdExemplo.Canvas, Rect.Left+10, Rect.Top+1, 0);
if not cdsExemploSituacao.IsNull then
if cdsExemploSituacao.AsBoolean then
Imagens.Draw(grdExemplo.Canvas, Rect.Left+10, Rect.Top+1, 2)
else
Imagens.Draw(grdExemplo.Canvas, Rect.Left+10, Rect.Top+1, 1);
end;
end;

procedure TForm1.grdExemploCellClick(Column: TColumn);
begin
{ Quando clicar, alterna o valor True/False }
if Column.FieldName ='Situacao' then
begin
97
if cdsExemplo.State =dsBrowse then
cdsExemplo.Edit;
cdsExemploSituacao.AsBoolean :=not cdsExemploSituacao.AsBoolean;
end;
end;

procedure TForm1.grdExemploEnter(Sender: TObject);
begin
{ No permite edio na clula do CheckBox }
with grdExemplo do
begin
if SelectedField =cdsExemploSituacao then
Options :=Options - [dgEditing]
else
Options :=Options +[dgEditing];
end;
end;

procedure TForm1.cdsExemploNewRecord(DataSet: TDataSet);
begin
cdsExemploSituacao.AsBoolean :=True;
end;


RichEdit - Como fazer uma pesquisa e substituio em um
RichEdit

O cdigo abaixo procurar por uma string e a substituir. Tenha certeza que voc tem o
RichEdit1 em seu Form1.

procedure TForm1.RearchAndReplace
(InSearch, InReplace: string) ;
var X, ToEnd : integer;
oldCursor : TCursor;
begin
oldCursor :=Screen.Cursor;
Screen.Cursor :=crHourglass;
with RichEdit1 do
begin
X :=0;
ToEnd :=length(Text) ;
X :=FindText(inSearch, X, ToEnd, []) ;
while X <>-1 do
begin
SetFocus;
SelStart :=X;
SelLength :=length(inSearch) ;
SelText :=InReplace;
X :=FindText(inSearch,
98
X +length(InReplace),
ToEnd, []) ;
end;
end;
Screen.Cursor :=oldCursor;
end;

procedure TForm1.Button1Click
(Sender: TObject) ;
var
SearchText, ReplaceText: string;
begin
SearchText :=Pascal;
ReplaceText :=Delphi;
RearchAndReplace(SearchText, ReplaceText) ;
end;


TForm - Criando formulrios transparentes

private
{ Private declarations }
FullRgn, ClientRgn, CtlRgn: THandle;
procedure MakeTransparent;
procedure UndoTransparent;
end;
{...}
implementation
{...}
procedure TForm1.MakeTransparent;
var
AControl: TControl;
A, Margin, X, Y, CtlX, CtlY: Integer;
begin
Margin :=(Width - ClientWidth) div 2;
FullRgn :=CreateRectRgn(0, 0, Width, Height);
X :=Margin;
Y :=Height - ClientHeight - Margin;
ClientRgn :=CreateRectRgn(X, Y, X +
ClientWidth, Y +ClientHeight);
CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);
for A :=0 to ControlCount - 1 do
begin
AControl :=Controls[A];
if (AControl is TWinControl) or (AControl is
TGraphicControl) then with AControl do
begin
if Visible then
begin
99
CtlX :=X +Left;
CtlY :=Y +Top;
CtlRgn :=CreateRectRgn(CtlX, CtlY, CtlX +
Width, CtlY +Height);
CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
end;
end;
end;
SetWindowRgn(Handle, FullRgn, True);
end;
procedure TForm1.UndoTransparent;
begin
FullRgn :=CreateRectRgn(0, 0, Width, Height);
CombineRgn(FullRgn, FullRgn, FullRgn, RGN_COPY);
SetWindowRgn(Handle, FullRgn, True);
end;

Para usar:

// Teste:
procedure TForm1.Button1Click(Sender: TObject);
begin
MakeTransparent
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
UndoTransparent
end;



TList - Ordenando os itens

Quando voc est trabalhando com um objeto TList e quer ordenar os itens baseados um
critrio seu, pode usar o cdigo abaixo.

O exemplo a seguir mostra como ordenar os itens em ordem alfabtica baseado nos
nomes. Ele assume que a lista contm apenas referncias para as variveis do tipo
TMyListItem, onde TMyListItem definida como:
type
TMyListItem =record
Points : Integer;
Name: string[255] ;
end;

A funo CompareNames faz as comparaes entre os objetos da lista. A lista
ordenada quando o usurio clicar no boto.

100
function CompareNames
(Item1, Item2: Pointer): Integer;

begin
Result :=CompareText((Item1 as TMyListItem).Name,
(Item2 as TMyListItem).Name) ;
end;

procedure TForm1.Button1Click
(Sender: TObject) ;
begin
List1.Sort(@CompareNames) ;
end;


{
Note: the Sort method needs a pointer to a custom function (with the signature below)
that indicates how the items are to be ordered.

type
TListSortCompare =function (Item1,
Item2: Pointer): Integer;

Your sorting / comparison function should return a positive value if Item1 is less than
Item2, 0 if they are equal, and a negative value if Item1 is greater than Item2.
}

3 formas de dar um shutdown

Existem 3 formas distintas de fazer a mesma coisa, so elas:
//------------- Forma 1-----------------



procedure TForm1.Button1Click(Sender: TObject);
begin
ExitWindowsEx(EWX_FORCE and EWX_SHUTDOWN,0);
//EWX_SHUTDOWN para shutdown
//EWX_REBOOT para reboot
//EWX_LOGOFF para logoff
end;




//------------- Forma 2-----------------
101
Executando o programa shutdown.exe do Windows:

run %Windir%\system32\shutdown.exe

Example :

procedure TForm1.Button1Click(Sender: TObject);
begin
WinExec('shutdown.exe -s -f -t 0' , SW_HIDE);
end;




//------------- Forma 3-----------------



unit Unit1;

interface

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

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

var
Form1: TForm1;

implementation

{$R *.dfm}

function SetPrivilege1 (sPrivilegeName: string; bEnabled: Boolean) : Boolean;
var
TPPrev,
TP : TTokenPrivileges;
Token : THandle;
dwRetLen : DWORD;
begin
102
result :=False;

OpenProcessToken (GetCurrentProcess, TOKEN_ADJ UST_PRIVILEGES or
TOKEN_QUERY, Token);

TP.PrivilegeCount :=1;
if LookupPrivilegeValue (nil, PChar (sPrivilegeName), TP.Privileges[0].LUID) then
begin
if bEnabled then
TP.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED
else
TP.Privileges[0].Attributes :=0;

dwRetLen :=0;
result :=AdjustTokenPrivileges (Token, False, TP, SizeOf (TPPrev), TPPrev,
dwRetLen)
end;

CloseHandle (Token)
end;


function WinExit1 (iFlags: integer) : Boolean;
begin
result :=true;
if SetPrivilege1 ('SeShutdownPrivilege', true) then
begin
if (not ExitWindowsEx (iFlags, 0)) then
begin
result :=False
end;
SetPrivilege1 ('SeShutdownPrivilege', False)
end
else
begin
result :=False
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
// 0=Logoff
// 1=Shutdown
WinExit1(1);
end;

end.

103
QuickReport e FastReport - Gerando um PDF
Esse componente ExportQR foi criado para trabalhar com o QuickReport e com o
FastReport, mas aqui vou dar exemplo apenas do QuickReport.
Caso algum queira pegar a verso que tambm trabalha com o FastReport recomendo
que acesse o site do fabricante no seguinte link: http://usuarios.lycos.es/isma
A instalao desse componente bastante simples, abra o arquivo ExPackD6.dpk
(Delphi 6) ou ExPackD7.dpk (Delphi 7) atravs do delphi e em seguida compile e
instale. Esse componente j est trazendo os dois componentes utilizados no primeiro
exemplo, isso , o componente TNPDV e o componente de compactao.
Aps efetuar a instalao acesse o menu Tools, do Delphi, e depois a opo
Environment Options. Selecione a aba Library e depois acesse o boto da Library path.
Na janela que ser aberta indique o caminho onde esto os arquivos .pas do componente
e depois clique em Add e em seguida em Ok.
Agora estando com o componente instalado podemos coloc-lo no form do nosso
projeto que contem o relatrio criado no QuickReport e depois atravs de um boto
colocar a instruo que ir fazer a exportao. A instruo do boto para exportao
ficar da seguinte forma:
procedure TMainForm.BtnExportQRClick(Sender: TObject);
begin
{ Liga o componente do QuickReport ao componente de exportao }
EXQR.Report :=Rep;
{ Faz a exportao }
EXQR.ExportQR;
end;
Este componente tambm nos permite exportar relatrios a partir do componente
QRPreview que o componente ao qual criamos preview personalizado no
QuickReport.
Para isso podemos colocar um boto no form de preview e neste boto colocar a
seguinte instruo:
procedure TFPreviewQR.TBSaveClick(Sender: TObject);
begin
{ Faz a ligao do QRPreview com o componente }
EXQR.Preview :=Preview;
{ Faz a exportao do relatrio }
EXQR.ExportQRFromPreview;
end;
Esses cdigos acima podem ser encontrados no projeto de Exemplo1 que acompanha o
componente ExportQR.
104
Outros formatos:
A exportao dos relatrios para os demais formatos bastante simples tambm, veja
abaixo as sintaxes utilizadas para cada tipo:
PDF com Alta Compresso:
EXQR.ExportQRPDF(edFileName.Text, True);
PDF com Baixa Compresso
EXQR.ExportQRPDF(edFileName.Text, False);
JPG
EXQR.ExportQRJ PG(edFileName.Text);
BMP
EXQR.ExportQRBMP(edFileName.Text);
WMF
EXQR.ExportQRWMF(edFileName.Text);
EMF
EXQR.ExportQREMF(edFileName.Text);
Esses cdigos acima podem ser encontrados no projeto de Exemplo3 que acompanha o
componente ExportQR.


SetVolumeLabel - Mudando o Label do HD

A seguir a rotina completa:

unit Unit1;

interface

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

type
TForm1 =class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
ComboBox1: TComboBox;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
105
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
SetVolumeLabel(pansichar(ComboBox1.Text), pchar(Edit1.Text));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
for i:=Ord('A') to Ord('Z') do
begin
if GetDriveType(pchar(char(i)+':\'))=3 then
ComboBox1.Items.Add(char(i)+':\');
end;
ComboBox1.Text:=ComboBox1.Items.Strings[0];
Button1Click(Self);
end;

end.

Memo - Rolagem vertical
Inclua na seo uses: Windows
Problema: Gostaria que o meu programa rolasse automaticamente o contedo de um
TMemo, simulando o deslizamento da barra de rolagem vertical. Isto possvel no
Delphi?
Soluo: Sim. Utilizando mensagens do Windows isto fcil. Vejamos algums
exemplos:
SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEDOWN, 0);
Onde:
106
Memo1.Handle =manipulador da janela do Memo1.
WM_VSCROLL =Mensagem do Windows - rolagem vertical.
SB_PAGEDOWN =Comanndo de rolagem - pgina para baixo.
Outros exemplos:
{ Pgina 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);
Observaes: Alm desta tcnica existem API's do Windows que fazem um trabalho
equivalente.

Como adicionar o evento OnClick no DBGrid
O componente DBGrid no tem o evento OnClick no Object Inspector. Mas podemos
utiliz-lo atravs de uma instancia da classe THack.
Inclua as duas linhas abaixo da seo Implementation:
type
THack =class(TControl);
Depois na seo Private declare a nova procedure que utilizaremos no evento OnClick:
private
{ Private declarations }
procedure DBGridClick(Sender: TObject);
Agora crie a procedure que declaramos na seo private.
procedure TForm1.DBGridClick
(Sender: TObject);
begin
ShowMessage(O contedo desta clula
+TDBGrid(Sender).SelectedField.AsString);
end;
Para utilizarmos esta procedure temos que fazer a sua ligao no evento OnCreate do
form. Veja o cdigo abaixo:
procedure TForm1.FormCreate(Sender: TObject);
begin
THack(dbgrid1).controlstyle :=
THack(dbgrid1).controlstyle +[csClickEvents];
THack(dbgrid1).OnClick :=DBGridClick;
end;
107
Alterando a cor dos TabSheet de um PageControl
Coloque um PageControl no Form.
- Adicione 6 TabSheet (New Page).
- Agora basta implementar o codigo abaixo no evento OnDrawTab.

procedure TForm1.PageControl1DrawTab(Control: TCustomTabControl;
TabIndex: Integer; const Rect: TRect; Active: Boolean);
begin
case TabIndex of
0: Control.Canvas.Font.Color :=clGreen;
1: Control.Canvas.Font.Color :=clRed;
2: Control.Canvas.Font.Color :=clBlue;
3: Control.Canvas.Font.Color :=clYellow;
4: Control.Canvas.Font.Color :=clMaroon;
5: Control.Canvas.Font.Color :=clWhite;
end;
Control.Canvas.TextOut(Rect.left+5,
Rect.top+3,PageControl1.Pages
[TabIndex].Caption);
PageControl1.Pages[TabIndex].Font.Color :=
Control.Canvas.Font.Color;
end;
Obs.: No esquea de alterar a propriedade OwnerDraw para True.


Como chamar uma home page utilizando o seu browse padro
uses UrlMon;
procedure TForm1.Button1Click(Sender: TObject);
begin
HlinkNavigateString(nil, http://www.theclub.com.br);
end;

Como alterar o caption da janela de preview do quickreport
Para mudar o ttulo da barra de ttulo da janela de Preview de seus relatrios, use o
seguinte comando:
QRPrinter.PreviewCaption :=Visualizao do Relatrio;
Como colocar Captions no DBNavigator
108
type
TDBNewNavigator =class(TDBNavigator);

procedure TForm1.FormCreate(Sender: TObject);
var
B: TNavigateBtn;
begin
for B :=Low(TNavigateBtn) to High(TNavigateBtn) do
with TDBNewNavigator(DBNavigator1).Buttons[B] do
begin
Case Index of
nbFirst : Caption :=Inicio;
nbPrior : Caption :=Anterior;
nbNext : Caption :=Prximo;
nbLast : Caption :=ltimo;
nbInsert : Caption :=Novo;
nbDelete : Caption :=Apagar;
nbEdit : Caption :=Alterar;
nbPost : Caption :=Gravar;
nbCancel : Caption :=Cancelar;
nbRefresh: Caption :=Atualizar;
End;
Hint :=Caption;
ShowHint :=True;
end;
end;
end;

Como passar parmetros entre 2 forms
Suponha que voc esteja no Form1 e precise chamar o Form2 passando dois parametros
("Verde" e "Amarelo").
1. Crie as variveis de instncia do Form2 que recebero os dois parmetros.
2. Reescreva o Construtor desse form, de forma a receber os parmetros e atribu-los s
suas variveis de instncia:
type
TForm2 =class(TForm)
private
Parametro1 : String;
Parametro2 : String;
public
constructor Create(AOwner : TComponent; pPar1, pPar2 : String);
end;

var
109
Form2: TForm2;
implementation

constructor TForm2.Create(AOwner : TComponent; pPar1, pPar2 : String);
begin
inherited Create(AOwner);
Parametro1 :=pPar1;
Parametro2 :=pPar2;
end;
Agora no seu form1, abra o form2 com a seguinte sintaxe:
With TForm2.Create(self, Verde, Amarelo) do
Begin
ShowModal;
Free;
End;
No evento OnShow inclua a seguinte linha:
procedure TForm2.FormShow(Sender: TObject);
begin
Caption :=Parametro1 + - +Parametro2;
end;
Obs: No deixe o Delphi criar automaticamente o formulrio. Crie-o (e o destrua)
manualmente.
Como reduzir o tempo e carga de um programa
comum acontecer um sensvel aumento de tempo de carga de um aplicativo
desenvolvido em Delphi medida que este aplicativo cresce e adquire mais e mais
formulrios. s vezes o tempo de carga se torna totalmente insuportvel.
Os programas se tornam lentos principalmente devido a grande quantidade de
formulrios que so criados e inicializados logo no incio da execuo do programa.
Antes de ser efetivamente utilizado, todo formulrio precisa ser criado. A criao do
formulrio acontece sempre que voc adiciona um novo formulrio ao sistema, o IDE
do Delphi providencia cdigo para que ele seja criado automaticamente. Isto simplifica
a vida do programador que no precisar se preocupar com este detalhe.
O aumento do tempo de carga do aplicativo pode ser resolvido pela simples remoo do
cdigo que o Delphi gerou para a criao do formulrio.
Para remover o cdigo que o Delphi criou automaticamente, selecione Project|Options
no menu. Selecione a aba Forms. Aponte para um dos formulrios e clique no boto
>. Isto faz com que o formulrio passe do painel Auto-create forms para o painel
Available forms.
110
Se voc quer saber onde est este cdigo, clique em View|Units (ou use Ctrl-F12) e
selecione o seu projeto na lista de units que aparecer. O cdigo que cria formulrios
algo mais ou menos como se segue:
Application.CreateForm(TForm1, Form1);
Cada formulrio auto-criado ter uma linha como esta. Quando o formulrio passa para
o painel de Available forms, a linha correspondente removida. Voc tambm pode
simplesmente remover a linha manualmente, usando o editor de textos.
Normalmente usar um formulrio significa mostr-lo na tela. Isto feito invocando-se
os mtodos Show ou ShowModal do formulrio conforme o estilo do aplicativo. Agora
que o formulrio no mais criado automaticamente, isto se torna um pouco mais
complicado, por exemplo:
if Form1 =nil then
Form1 :=TForm1.Create ( Application );
Form1.Show; { ou Form1.ShowModal; }
Alternativamente voc poderia escrever assim:
if Form1 =nil then
Application.CreateForm ( TForm1, Form1 );
Form1.Show; { ou Form1.ShowModal; }
O efeito o mesmo, mas eu, pessoalmente, prefiro a primeira forma.
Voc deve ter extremo cuidado ao usar esta tcnica. Se voc tirar o cdigo de criao
automtica do formulrio e tentar executar o Show ou ShowModal voc vai receber um
erro do tipo Access Violation. Tome cuidado e faa isto um formulrio por vez.
Ateno! No faa isto para o seu formulrio principal. O formulrio principal precisa
ser o primeiro formulrio a ser criado. Assim melhor mant-lo como auto-criado.
Esta tcnica efetivamente distribui o tempo de carga e inicializao do aplicativo pela
execuo do programa. Os formulrios agora so carregados sob-demanda. Os
formulrios nunca utilizados nunca sero criados. Isto tambm melhora o uso de
memria.

Escondendo o Programa de Ctrl+Alt+Del
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 =class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
111
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;

implementation

{$R *.DFM}
{
Para ocultar um programa, deve-se registrar este programa como um servio do
Windows. Normalmente um servio do Windows ativado quando com a inicializao
do sistema (Windows) e permanece ativo at a finalizao deste. Este processo esconde
o programa da lista "Ctrl+Alt+Del"
}
Const
Servico_Simples =1;
Servico_Unregister =1;

Function RegisterServiceProcess(DwProcessID, dwType: DWord): DWord; StdCall;
External KERNEL32.dll;

procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterServiceProcess(GetCurrentProcessID, Servico_Simples);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
RegisterServiceProcess(GetCurrentProcessID, Servico_Unregister);
end;
end.

Alterando a pgina inicial do Internet Explorer via programao

function PaginaInicialIE(endereco : string) : boolean;
Var
Reg : TRegistry;
begin
Reg:=TRegistry.Create;
try
Reg.RootKey:=HKEY_CURRENT_USER;
Reg.OpenKey(Software\Microsoft\
Internet Explorer\Main,false);
try
112
try
Reg.WriteString
(Start Page,endereco);
result :=true;
finally
Reg.CloseKey;
result :=True;
end;
except
result :=false;
end;
finally
Reg.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if PaginaInicialIE(http://www.theclub.com.br) then
ShowMessage(Foi alterado com sucesso)
else
ShowMessage(No foi alterado);
end;


Verifica se o BDE est instalado

// Usando o registrador do Windows
procedure TForm1.Button1Click
(Sender: TObject);
var
Reg: TRegistry;
begin
reg :=TRegistry.create;
try
reg.RootKey :=HKEY_CURRENT_USER;
reg.OpenKey(\Software\Borland, False);
if Reg.KeyExists(BdeAdmin) then
ShowMessage(BDE j instalado)
else
ShowMessage(Sem BDE);
finally
Reg.CloseKey;
Reg.Free;
inherited;
end;
end;
113

Arredondar casas decimais de forma personalizada
Na seo de procedures digite:
Function Arredondar
(value: double;casas : integer): double;

Na seo implementation digite a funo conforme descrita abaixo.
Function Tform1.Arredondar(value: double;casas : integer): double;
Var fracao, Total:real;
decimal:string;
begin
try
fracao:=Frac(value); //Retorna a parte fracionria de um nmero
decimal:=(RightStr(floattostr(fracao),
length(floattostr(fracao))-2)); //decimal recebe a parte decimal
//enquanto o tamanho da variavel decimal for maior que o nmero de casas faa
while length(decimal) >casas do
begin
//Verifica se o ltimo digito da varivel decimal maior que 5
if strtoint(RightStr(decimal,1))>5 then
begin
//Descarta o ltimo digito da varivel Decimal
decimal:=leftstr(decimal,length(decimal)-1);
//Soma o valor nmero da variavel decimal +1
decimal:=floattostr(strtofloat(decimal) +1);
end
else
decimal:=leftstr(decimal,length(decimal)-1); //Descarta o ltimo digito da varivel
Decimal
end;
result:=(int(value) +(strtofloat(decimal)/100)); //devolve o resultado para a funo
except
Raise Exception.Create(Erro no arredondamento);
end;
end;
Como usar...

arredondar(Campo ou vaivel do tipo Real (Float) , nmero de casas decimais
desejado);

Ex:Var valor,Resultado:real;
Valor:=10.005.526
Resultado :=Arredondar(valor,2);
Resultado=10.005,53

114
Obs: O codigo foi escrito em Delphi 6 porm isso no a impede de funcionar no Delphi
4 ou 5, pouco provavel que ocorra erro.


Verificando se um alias est instalado
var
vList: TStringList;
x: Integer;
begin
vList :=TStringList.Create;
Session.Open;
Session.GetAliasNames(vList);
if vList.Find(NomeDoAlias, x) then // x receber a posio do alias na lista
// Alias encontrado
else
// Alias no encontrado
end;

Como prevenir a movimentao do mouse para fora do form?
procedure TForm1.FormMouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);

begin
if Form1.Left <=0 then Form1.Left :=0;
if Form1.Top <=0 then Form1.Top :=0;
if Form1.Left >=Screen.Width - Form1.Width then
Form1.Left :=Screen.Width - Form1.Width;
if Form1.Top >=Screen.Height - Form1.Height then
Form1.Top :=Screen.Height - Form1.Height;
end;
Como criar hints customizados?
type
TGraphicHintWindow =class(THintWindow)
constructor Create(AOwner: TComponent); override;
private
FActivating: Boolean;
public
procedure ActivateHint(Rect: TRect; const AHint: string);
override;
protected
procedure Paint; override;
115
published
property Caption;
end;
{...}
constructor TGraphicHintWindow.Create
(AOwner: TComponent);
begin
inherited Create(AOwner);
{
Aqui voc pode customizar as propriedades da fonte
}
with Canvas.Font do
begin
Name :=Arial;
Style :=Style +[fsBold];
Color :=clBlack;
end;
end;
procedure TGraphicHintWindow.Paint;
var
R: TRect;
bmp: TBitmap;
begin
R :=ClientRect;
Inc(R.Left, 2);
Inc(R.Top, 2);
{***************************************
O cdigo abaixo um exemplo de como crier um objeto Hint customizado:
}
bmp :=TBitmap.Create;
bmp.LoadfromFile(D:\hint.bmp);
with Canvas do
begin
Brush.Style :=bsSolid;
Brush.Color :=clsilver;
Pen.Color :=clgray;
Rectangle(0, 0, 18, R.Bottom +1);
Draw(2,(R.Bottom div 2) - (bmp.Height div 2), bmp);
end;
bmp.Free;
/Cor do Hint customizada
Color :=clWhite;
Canvas.Brush.Style :=bsClear;
Canvas.TextOut(20, (R.Bottom div 2) - (Canvas.Textheight(Caption) div 2), Caption);
{**************************************}
end;
procedure TGraphicHintWindow.ActivateHint
(Rect: TRect; const AHint: string);
begin
FActivating :=True;
116
try
Caption :=AHint;
//Ajuste a propriedade Height do Hint
Inc(Rect.Bottom, 14);
//Ajuste a propriedade Width do Hint
Rect.Right :=Rect.Right +20;
UpdateBoundsRect(Rect);
if Rect.Top +Height >Screen.DesktopHeight then
Rect.Top :=Screen.DesktopHeight -
Height;
if Rect.Left +Width >Screen.DesktopWidth then
Rect.Left :=Screen.DesktopWidth - Width;
if Rect.Left <Screen.DesktopLeft then
Rect.Left :=Screen.DesktopLeft;
if Rect.Bottom <Screen.DesktopTop then Rect.Bottom :=Screen.DesktopTop;
SetWindowPos(Handle, HWND_TOPMOST, Rect.Left,
Rect.Top, Width, Height,
SWP_SHOWWINDOW or SWP_NOACTIVATE);
Invalidate;
finally
FActivating :=False;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
HintWindowClass :=TGraphicHintWindow;
Application.ShowHint :=False;
Application.ShowHint :=True;
end;

Como capturar a tela?
uses
Graphics;
// Captura a tela inteira
procedure ScreenShot(Bild: TBitMap);
var
c: TCanvas;
r: TRect;
begin
c :=TCanvas.Create;
c.Handle :=GetWindowDC(GetDesktopWindow);
try
r :=Rect(0, 0, Screen.Width, Screen.Height);
Bild.Width :=Screen.Width;
Bild.Height :=Screen.Height;
Bild.Canvas.CopyRect(r, c, r);
finally
117
ReleaseDC(0, c.Handle);
c.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Visible :=False;
Sleep(750); // um atraso
ScreenShot(Image1.Picture.BitMap);
Form1.Visible :=True;
end;
// Somente a janela ativa
procedure ScreenShotActiveWindow(Bild: TBitMap);
var
c: TCanvas;
r, t: TRect;
h: THandle;
begin
c :=TCanvas.Create;
c.Handle :=GetWindowDC(GetDesktopWindow);
h :=GetForeGroundWindow;
if h <>0 then
GetWindowRect(h, t);
try
r :=Rect(0, 0, t.Right - t.Left, t.Bottom - t.Top);
Bild.Width :=t.Right - t.Left;
Bild.Height :=t.Bottom - t.Top;
Bild.Canvas.CopyRect(r, c, t);
finally
ReleaseDC(0, c.Handle);
c.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Form1.Visible :=False;
Sleep(750); //um atraso
ScreenShotActiveWindow(Image1.Picture.BitMap);
Form1.Visible :=True;
end;

{*****************************************}
// Outra funo de print screen function:
// Captura a tela inteira
procedure ScreenShot(x: Integer;
y: Integer;
Width: Integer;
Height: Integer;
bm: TBitMap);
118
var
dc: HDC;
lpPal: PLOGPALETTE;
begin
if ((Width =0) or
(Height =0)) then
Exit;
bm.Width :=Width;
bm.Height :=Height;
dc :=GetDc(0);
if (dc =0) then
Exit;
if (GetDeviceCaps(dc, RASTERCAPS) and
RC_PALETTE =RC_PALETTE) then
begin
GetMem(lpPal,
SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)));
FillChar(lpPal^,
SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)), #0);
lpPal^.palVersion :=$300;
lpPal^.palNumEntries :=
GetSystemPaletteEntries(dc,
0,
256,
lpPal^.palPalEntry);
if (lpPal^.PalNumEntries <>0) then
bm.Palette :=CreatePalette(lpPal^);
FreeMem(lpPal, SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)));
end;
BitBlt(bm.Canvas.Handle,
0,
0,
Width,
Height,
Dc,
x,
y,
SRCCOPY);
ReleaseDc(0, dc);
end;

// Examplo:
procedure TForm1.Button1Click(Sender: TObject);
begin
ScreenShot(0,0,Screen.Width, Screen.Height,
Image1.Picture.Bitmap);
end;
119


{****************************************}
// Captura a janela
procedure ScreenShot(hWindow:
HWND; bm: TBitmap);
var
Left, Top, Width, Height: Word;
R: TRect;
dc: HDC;
lpPal: PLOGPALETTE;
begin
if not IsWindow(hWindow) then Exit;
GetWindowRect(hWindow, R);
Left :=R.Left;
Top :=R.Top;
Width :=R.Right - R.Left;
Height :=R.Bottom - R.Top;
bm.Width :=Width;
bm.Height :=Height;
dc :=GetDc(0);
if (dc =0) then
begin
Exit;
end;
if (GetDeviceCaps(dc, RASTERCAPS) and
RC_PALETTE =RC_PALETTE) then
begin
GetMem(lpPal,
SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)));
FillChar(lpPal^,
SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)),
#0);
lpPal^.palVersion :=$300;
lpPal^.palNumEntries :=
GetSystemPaletteEntries(dc,
0,
256,
lpPal^.palPalEntry);
if (lpPal^.PalNumEntries <>0) then
begin
bm.Palette :=CreatePalette(lpPal^);
end;
FreeMem(lpPal, SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)));
end;
BitBlt(bm.Canvas.Handle,
0,
120
0,
Width,
Height,
Dc,
Left,
Top,
SRCCOPY);
ReleaseDc(0, dc);
end;

// Exemplo
procedure TForm1.Button1Click(Sender: TObject);
begin
ScreenShot(GetForeGroundWindow,
Image1.Picture.Bitmap);
end;

{**********************************************}
{As vezes voc quer capturar a tela, no entanto o Windows tem problemas com grande
quantidade de dados e fica muito lento. Uma soluo bem simples fazer pequenas
capturas e colar o resultado unindo tudo. No a velocidade da luz, mas mais rpido
que capturar a tela inteira.}

const
cTileSize =50;
function TForm1.GetSCREENSHOT: TBitmap;
var
Locked: Boolean;
X, Y, XS, YS: Integer;
Canvas: TCanvas;
R: TRect;
begin
Result :=TBitmap.Create;
Result.Width :=Screen.Width;
Result.Height :=Screen.Height;
Canvas :=TCanvas.Create;
Canvas.Handle :=GetDC(0);
Locked :=Canvas.TryLock;
try
XS :=Pred(Screen.Width div cTileSize);
if Screen.Width mod cTileSize >0 then
Inc(XS);
YS :=Pred(Screen.Height div cTileSize);
if Screen.Height mod cTileSize >0 then
Inc(YS);
for X :=0 to XS do
for Y :=0 to YS do
begin
R :=Rect(
X * cTileSize, Y * cTileSize, Succ(X) * cTileSize,
121
Succ(Y) * cTileSize);
Result.Canvas.CopyRect(R, Canvas, R);
end;
finally
if Locked then
Canvas.Unlock;
ReleaseDC(0, Canvas.Handle);
Canvas.Free;
end;
end;

Como mostrar um TMenuItem alinhado direita?
procedure TForm1.FormCreate(Sender: TObject);
const
MenuIndex =3;
var
MII: TMenuItemInfo;
MainMenu: hMenu;
Buffer: array[0..50] of Char;
begin
MainMenu :=GetMenu(Handle);
with MII do
begin
cbSize :=SizeOf(MII);
fMask :=MIIM_TYPE;
dwTypeData :=Buffer;
cch :=SizeOf(Buffer);
GetMenuItemInfo(MainMenu,
MenuIndex, True, MII);
fType :=fType or MFT_RIGHTJ USTIFY;
SetMenuItemInfo(MainMenu,
MenuIndex, True, MII);
DrawMenuBar(Handle);
end;
end;

Como mover o form clicando em qualquer lugar?
private
procedure WMNCHitTest(var msg: TWMNCHitTest); message WM_NCHITTEST;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
122
procedure TForm1.WMNCHitTest(var msg: TWMNCHitTest);
begin
inherited;
if msg.Result =htClient then
msg.Result :=htCaption;
end;
{...}
{ ************************* }
procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
const
SC_DRAGMOVE =$F012;
begin
if Button =mbleft then
begin
ReleaseCapture;
Form1.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0);
end;
end;

Como mostrar um texto de vrias linhas em um TCombobox?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 =class(TForm)
ComboBox1: TComboBox;
procedure FormCreate(Sender: TObject);
procedure ComboBox1MeasureItem
(Control: TWinControl; Index: Integer;
var Height: Integer);
procedure ComboBox1DrawItem(Control:
TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
Combobox1.Style :=csOwnerDrawVariable;
// preencha o combobox com alguns exemplos
123
with Combobox1.Items do
begin
Add(Short, kurzer String);
Add(A long String. / Ein langer String.....);
Add(Another String);
Add(abcd defg hijk lmno);
Add(..-.-.-.-.-.-.-.-.-);
end;
end;
procedure TForm1.ComboBox1MeasureItem(Control:
TWinControl; Index: Integer;
var Height: Integer);
// Calculata o tamanho necessrio para o texto com vrias linhas
var
i, PosSp: Integer;
strVal: string;
strTmp: string;
begin
if Index >=0 then
begin
strVal :=Combobox1.Items[Index];
// coloque a string em vrias linhas,
// cada linha separada por #$D#$A
strTmp :=WrapText(strVal, 20);
// Nmero de separadores de linha
// +1 =nmero de linhas
i :=1;
while Pos(#$D#$A, strTmp) >0 do
begin
i :=i +1;
strTmp :=Copy(strTmp, Pos(#13#10, strTmp) +
2, Length(strTmp));
end;
// calcule o tamanho do texto
Height :=i * Combobox1.ItemHeight;
end;
end;
procedure TForm1.ComboBox1DrawItem(Control:
TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
// Escreva o texto em um combobox. Se o texto muito comprido, ento sera feito
var
strVal: string;
strTmp: string;
intPos: Integer;
i: Integer;
rc: TRect;
begin
strVal :=WrapText(Combobox1.Items[Index], 20);
i :=0;
124
Combobox1.Canvas.FillRect(Rect);
// sada de cada linha
while Pos(#$D#$A, strVal) >0 do
begin
intPos :=Pos(#$D#$A, strVal);
// copie a linha corrente da string
if intPos >0 then
strTmp :=Copy(strVal, 1, intPos - 1)
else
strTmp :=strVal;
rc :=Rect;
rc.Top :=Rect.Top +i * Combobox1.ItemHeight;
ComboBox1.Canvas.TextRect(rc, Rect.Left, Rect.Top +
i * Combobox1.ItemHeight,
strTmp);
// delete a linha da string
strVal :=Copy(strVal, intPos +2, Length(strVal));
Inc(i);
end;
rc :=Rect;
rc.Top :=Rect.Top +i * Combobox1.ItemHeight;
//escreva a ltima linha
ComboBox1.Canvas.TextRect(rc, Rect.Left, Rect.Top +
i * Combobox1.ItemHeight, strVal);
Combobox1.Canvas.Brush.Style :=bsClear;
// faa um retangulo em volta do texto
Combobox1.Canvas.Rectangle(Rect);
end;
end.

Como criar tooltips com bales?
{....}
uses Commctrl;
{....}
const
TTS_BALLOON =$40;
TTM_SETTITLE =(WM_USER +32);
var
hTooltip: Cardinal;
ti: TToolInfo;
buffer : array[0..255] of char;
{....}
procedure CreateToolTips(hWnd: Cardinal);
begin
hToolTip :=CreateWindowEx(0, Tooltips_Class32',
nil, TTS_ALWAYSTIP or TTS_BALLOON,
Integer(CW_USEDEFAULT),
125
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT), hWnd, 0, hInstance, nil);
if hToolTip <>0 then
begin
SetWindowPos(hToolTip, HWND_TOPMOST,
0, 0, 0, 0, SWP_NOMOVE or
SWP_NOSIZE or SWP_NOACTIVATE);
ti.cbSize :=SizeOf(TToolInfo);
ti.uFlags :=TTF_SUBCLASS;
ti.hInst :=hInstance;
end;
end;

procedure AddToolTip(hwnd: DWORD;
lpti: PToolInfo; IconType: Integer;
Text, Title: PChar);
var
Item: THandle;
Rect: TRect;
begin
Item :=hWnd;
if (Item <>0) and (GetClientRect(Item, Rect)) then
begin
lpti.hwnd :=Item;
lpti.Rect :=Rect;
lpti.lpszText :=Text;
SendMessage(hToolTip, TTM_ADDTOOL, 0,
Integer(lpti));
FillChar(buffer, SizeOf(buffer), #0);
lstrcpy(buffer, Title);
if (IconType >3) or (IconType <0) then IconType :=0;
SendMessage(hToolTip, TTM_SETTITLE, IconType,
Integer(@buffer));
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CreateToolTips(Form1.Handle);
AddToolTip(Memo1.Handle, @ti, 1, Tooltip text,
Title);
end;
{IconType pode ser:
0 Sem cone
1 - Informao
2 - Aviso
3 - Erro
}
126



Como mostrar Menu Item Hints
Quando o mouse est sobre um componente (um TButton, por exemplo) se a
propriedade ShowHint True e se houver algum texto na propriedade Hint, o
hint/tooltip ser mostrado para o componente.

Hints para itens de menu?
Por projeto, mesmo se voc colocar algo na propriedade Hint de um Menu Item o popup
hint no ser exibido. No entanto, os Itens do menu Iniciar do Windows mostram hints,
e o menu dos Favoritos do Internet Explorer tambm.

comum usar o evento OnHint nas variveis globais da aplicao, nas aplicaes
Delphi, para mostrar os hints do menu como uma barra de status.

O Windows no expe as mensagens necessrias que suportem o evento tradicional
OnMouseEnter. No entanto, a implementao do WM_MENUSELECT no
TCustomForm (ancestral do TForm) tem o item hint de menu no Application.Hint que
pode ser usado no evento Application.OnHint.

Se voc quer adicionar itens de menu com popup hints nos menus de sua aplicao
Delphi voc precisa somente apontar a mensagem WM_MenuSelect corretamente.

A classe TMenuItemHint hints popup para itens de menu!
Como no podemos depender do mtodo Application.ActivateHint para mostrar a janela
para os itens de menu (o apontamento de menus feito totalmente pelo Windows), para
obter a janela de hint exibida voc precisa criar sua prpria verso da janela hint
derivando uma nova classe a partir de THintWindow.

Segue como criar a classe TMenuItemHint uma janela hint que realmente exibida
nos itens de menu.

Primeiro voc precisa apontar a mensagem WM_MENUSELECT do Windows:
type
TForm1 =class(TForm)
...
private
procedure WMMenuSelect(var Msg: TWMMenuSelect) ; message
WM_MENUSELECT;
end
...
implementation
...
procedure TForm1.WMMenuSelect
(var Msg: TWMMenuSelect) ;
var
127
menuItem : TMenuItem;
hSubMenu : HMENU;
begin
inherited; // from TCustomForm
//(so that Application.Hint is assigned)

menuItem :=nil;
if (Msg.MenuFlag <>$FFFF) or
(Msg.IDItem <>0) then
begin
if Msg.MenuFlag and MF_POPUP =MF_POPUP then
begin
hSubMenu :=GetSubMenu
(Msg.Menu, Msg.IDItem) ;
menuItem :=Self.Menu.FindItem
(hSubMenu, fkHandle) ;
end
else
begin
menuItem :=Self.Menu.FindItem
(Msg.IDItem, fkCommand) ;
end;
end;
miHint.DoActivateHint(menuItem) ;
end; (*WMMenuSelect*)
A mensagem WM_MENUSELECT enviada janela proprietria do menu (Form 1)
quando o usurio seleciona (no quando clica) um item de menu. Usando o mtodo
FindItem da classe TMenu, voc consegue pegar o item de menu que est selecionado
no momento. Os parmetros da funo FindItem relatam as propriedades que a
mensagem recebeu. Uma vez que voc saiba qual o item de menu sobre qual est o
mouse, chamaremos o mtodo DoActivateHint da classe TMenuItemHint. Observe que
a varivel miHint definida como var miHint : TMenuItemHint e criada no evento
OnCreate do Form.

Agora vamos fazer a implementao da classe TMenuItemHint.

Aqui est a parte da interface:
TMenuItemHint =class(THintWindow)
private
activeMenuItem : TMenuItem;
showTimer : TTimer;
hideTimer : TTimer;
procedure HideTime(Sender : TObject) ;
procedure ShowTime(Sender : TObject) ;
public
constructor Create
(AOwner : TComponent) ; override;
procedure DoActivateHint
128
(menuItem : TMenuItem) ;
destructor Destroy; override;

end;
Voc pode ver toda a implementao no projeto exemplo.
Basicamente, a funo DoActivateHint chama o mtodo ActivateHint do THintWindow
usando a propriedade Hint do TMenuItem (se estiver atribuda).

O showTimer usado para se ter certeza que o HintPause (do Application) transcorre
antes do hint ser mostrado.
O hideTimer usa o Application.HintHidePause para esconder a janela do hint aps um
intervalo especfico.

Quando usar os hints nos itens do menu?
Enquanto alguns podem dizer que no uma boa coisa mostrar hints nos itens de menu,
h situaes que mostrar hints no menu muito melhor do que mostrar uma barra de
status.

Segue o cdigo fonte do Form, com a implementao da classe TMenuItemHint.
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms,
Dialogs, Menus, AppEvnts, StdCtrls,
ExtCtrls, ComCtrls;

type
TMenuItemHint =class(THintWindow)
private
activeMenuItem : TMenuItem;
showTimer : TTimer;
hideTimer : TTimer;
procedure HideTime(Sender : TObject) ;
procedure ShowTime(Sender : TObject) ;
public
constructor Create
(AOwner : TComponent) ; override;
procedure DoActivateHint
(menuItem : TMenuItem) ;
destructor Destroy; override;
end;

TForm1 =class(TForm)
...
procedure FormCreate(Sender: TObject) ;
129
procedure ApplicationEvents1Hint
(Sender: TObject) ;
private
miHint : TMenuItemHint;
procedure WMMenuSelect
(var Msg: TWMMenuSelect) ;
message WM_MENUSELECT;
end;

var
Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.FormCreate
(Sender: TObject) ;
begin
miHint :=TMenuItemHint.Create(self) ;
end; (*FormCreate*)

procedure TForm1.ApplicationEvents1Hint
(Sender: TObject) ;
begin
StatusBar1.SimpleText :=App.OnHint :
+Application.Hint;
end; (*Application.OnHint*)

procedure TForm1.WMMenuSelect
(var Msg: TWMMenuSelect) ;
var
menuItem : TMenuItem;
hSubMenu : HMENU;
begin
inherited; // TCustomForm
// (se certifica que o Application.Hint
// atribudo)

menuItem :=nil;
if (Msg.MenuFlag <>$FFFF) or (Msg.IDItem <>0) then
begin
if Msg.MenuFlag and MF_POPUP =MF_POPUP then
begin
hSubMenu :=GetSubMenu
(Msg.Menu, Msg.IDItem) ;
menuItem :=Self.Menu.FindItem
(hSubMenu, fkHandle) ;
end
else
begin
130
menuItem :=Self.Menu.FindItem
(Msg.IDItem, fkCommand) ;
end;
end;

miHint.DoActivateHint(menuItem) ;
end; (*WMMenuSelect*)


{ TMenuItemHint }
constructor TMenuItemHint.Create
(AOwner: TComponent) ;
begin
inherited;

showTimer :=TTimer.Create(self) ;
showTimer.Interval :=Application.
HintPause;

hideTimer :=TTimer.Create(self) ;
hideTimer.Interval :=Application.
HintHidePause;
end; (*Create*)

destructor TMenuItemHint.Destroy;
begin
hideTimer.OnTimer :=nil;
showTimer.OnTimer :=nil;
self.ReleaseHandle;
inherited;
end; (*Destroy*)

procedure TMenuItemHint.DoActivateHint
(menuItem: TMenuItem) ;
begin
//fora a remoo da velha janela
//do hint
hideTime(self) ;

if (menuItem =nil) or
(menuItem.Hint =) then
begin
activeMenuItem :=nil;
Exit;
end;

activeMenuItem :=menuItem;

showTimer.OnTimer :=ShowTime;
hideTimer.OnTimer :=HideTime;
131
end; (*DoActivateHint*)

procedure TMenuItemHint.ShowTime
(Sender: TObject) ;
var
r : TRect;
wdth : integer;
hght : integer;
begin
if activeMenuItem <>nil then
begin
//position and resize
wdth :=Canvas.TextWidth
(activeMenuItem.Hint) ;
hght :=Canvas.TextHeight
(activeMenuItem.Hint) ;

r.Left :=Mouse.CursorPos.X +16;

r.Top :=Mouse.CursorPos.Y +16;
r.Right :=r.Left +wdth +6;
r.Bottom :=r.Top +hght +4;

ActivateHint(r,activeMenuItem.Hint) ;
end;

showTimer.OnTimer :=nil;
end; (*ShowTime*)

procedure TMenuItemHint.HideTime(Sender: TObject) ;
begin
//esconde (destroy) a janela hint
self.ReleaseHandle;
hideTimer.OnTimer :=nil;
end; (*HideTime*)

end

Overwrite no TMemo e Tedit
Os controles do Windows TMemo e TEdit no tm a capacidade overwrite. No entanto,
possvel simular este comportamento, ajustanto a propriedade SelLength do controle
edit ou memo durante o processamento do evento KeyPress. Isso faz com que o
caractere que est na posio corrente seja sobrescrito.

O exemplo a seguir mostra como emular a capacidade de overwrite de um componente
TMemo. O estado do modo de sobrescrever pode ser mudado pressionando a tecla
Insert.
132
type
TForm1 =class(TForm)
Memo1: TMemo;
procedure Memo1KeyDown
(Sender: TObject; var Key: Word;
Shift: TShiftState) ;
procedure Memo1KeyPress
(Sender: TObject; var Key: Char) ;
private
{ Private declarations }
InsertOn : bool;
public
{ Public declarations }
end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Memo1KeyDown
(Sender: TObject; var Key: Word; Shift: TShiftState) ;
begin
if (Key =VK_INSERT) and
(Shift =[]) then
InsertOn :=not InsertOn;
end;

procedure TForm1.Memo1KeyPress
(Sender: TObject; var Key: Char) ;
begin
if ((Memo1.SelLength =0) and
(not InsertOn)) then
Memo1.SelLength :=1;
end;
Algumas vezes precisamos limpar todos os componentes Edit que esto no Form. Esta
tarefa feita facilmente com o seguinte procedimento:
procedure ClearEdits;
var j : Integer;
begin
for j :=0 to ComponentCount-1 do
if (Components[j] is TEdit) then
(Components[j] as TEdit).Text :=;
end;
133

Como chamar o Ver fonte (view source) em um WebBrowser
Aqui est como chamar o Ver fonte do IE (para examinar o HTML) com o componente
TWebBrowser.

Simplesmente arraste uma instncia do componente TWebBrowser em um formulrio e
um boto (Button) e faa como segue:
uses ActiveX;
procedure WBViewSourceDialog
(AWebBrowser: TWebbrowser) ;
const
CGID_WebBrowser: TGUID =
{ED016940-BD5B-11cf-BA4E-00C04FD70816};
HTMLID_VIEWSOURCE =2;

var
CmdTarget : IOleCommandTarget;
vaIn, vaOut: OleVariant;
PtrGUID: PGUID;
begin
New(PtrGUID) ;
PtrGUID^:=CGID_WebBrowser;
if AWebBrowser.Document <>nil then
try
AWebBrowser.Document.
QueryInterface(IOleCommandTarget,
CmdTarget) ;
if CmdTarget <>nil then
try
CmdTarget.Exec(PtrGUID,
HTMLID_VIEWSOURCE, 0, vaIn, vaOut) ;
finally
CmdTarget._Release;
end;
except
end;
Dispose(PtrGUID) ;

end;

procedure TForm1.FormCreate
(Sender: TObject);
begin
WebBrowser1.Navigate
(http://www.delphi.about.com) ;
end;

134
procedure TForm1.Button1Click
(Sender: TObject) ;
begin
WBViewSourceDialog(WebBrowser1) ;
end;

MessageBox com timeout

Aqui est como chamar um Message Box com timeout, ele ir fechar a si mesmo aps
um perodo de tempo. O truque chamar uma API no documentada localizada no
user32.dll, a API a MessageBoxTimeOut.
A funo retorna um valor inteiro para MB_TIMEDOUT (indicando que o perodo de
tempo para o timeout foi alcanado e o Message Box foi automaticamente fechado), ou
um valor representando o boto que o usurio clicou. Observe que o valor retornado
sempre 1, quando o Message Box tem somente um boto de OK (MB_OKFlag).
//declarao de interface
const
MB_TIMEDOUT =32000;

function MessageBoxTimeOut
(hWnd: HWND; lpText: PChar; lpCaption:
PChar; uType: UINT; wLanguageId: WORD; dwMilliseconds: DWORD): Integer;
stdcall;
external user32 name
MessageBoxTimeoutA;

//implementao (Apontamento do evento
//OnClick do Button1 no Form1)

procedure TForm1.Button1Click
(Sender: TObject) ;
var
iRet: Integer;
iFlags: Integer;
begin
iFlags :=MB_OK or MB_SETFOREGROUND or
MB_SYSTEMMODAL or MB_ICONINFORMATION;
MessageBoxTimeout
(Application.Handle, Test a timeout
of 2 seconds., MessageBoxTimeout
Teste, iFlags, 0, 2000) ;

iFlags :=MB_YESNO or MB_SETFOREGROUND or
MB_SYSTEMMODAL or MB_ICONINFORMATION;
iRet :=MessageBoxTimeout
(Application.Handle, Teste de timeout
135
de 5 segundos., MessageBoxTimeout
Teste, iFlags, 0, 5000) ;
case iRet of
IDYES:
ShowMessage(Yes) ;
IDNO:
ShowMessage(No) ;
MB_TIMEDOUT:
ShowMessage(TimedOut) ;
end;
end;
Como colocar uma barra de progresso dentro de um dialog box
padro

Vamos dizer que voc tem um dialog box padro do Windows mostrando uma pergunta
ao usurio com os botes de Yes e No. No seria timo se existisse uma barra de
progresso contando o tempo at que o dialog box se feche automaticamente?

Vamos l ento:
Vamos criar um dialog usando CreateMessageDialog. Esta funo retornar um form
object com o dialog. Neste objeto podemos adicionar a barra de progresso. Tambm
podemos adicionar um objeto Timer para uma atualizao dinmica da posio da barra
de progresso. Mostramos o dialog com ShowModal. Apontamos o evento OnTimer do
componente TTimer para ver o nmero se passou a quantidade de segundos necessria,
se sim, fechamos o dialog ajustando a propriedade ModalResult, no cdigo, para
mrCancel. Se no, usamos StepIt para atualizar a barra de progresso.

Coloque um boto no formulrio e tente este cdigo:
procedure TForm1.Button1Click
(Sender: TObject) ;
var
AMsgDialog : TForm;
AProgressBar : TProgressBar;
ATimer : TTimer;
begin
AMsgDialog :=CreateMessageDialog(Quickly! Answer Yes or
No!, mtWarning, [mbYes, mbNo]) ;
AProgressBar :=TProgressBar.
Create(AMsgDialog) ;
ATimer :=TTimer.Create(AMsgDialog) ;
with AMsgDialog do
try
Tag :=10; //seconds!

Caption :=You have 10 seconds;
Height :=150;

136
with AProgressBar do begin
Name :=Progress;
Parent :=AMsgDialog;
Max :=AMsgDialog.Tag; //seconds
Step :=1;
Top :=100;
Left :=8;
Width :=AMsgDialog.ClientWidth - 16;
end;
with ATimer do
begin
Interval :=1000;
OnTimer:=DialogTimer;
end;

case ShowModal of
ID_YES: ShowMessage(Answered Yes.) ;
ID_NO: ShowMessage(Answered No.) ;
ID_CANCEL: ShowMessage(Time up!)
end;//case
finally
ATimer.OnTimer :=nil;
Free;
end;
end;

//make sure you add this functions
//header in the private part of the TForm1
//type declaration.
procedure TForm1.DialogTimer(Sender:TObject);
var
aPB : TProgressBar;
begin
if NOT (Sender is TTimer) then Exit;

if ((Sender as TTimer).Owner) is TForm then
with ((Sender as TTimer).Owner) as TForm do
begin
aPB :=TProgressBar
(FindComponent(Progress)) ;

if aPB.Position >=aPB.Max then
ModalResult :=mrCancel
else
aPB.StepIt;
end;
end;


137
Como imprimir uma pgina/documento com o TWebBrowser

Voc primeiro precisa carregar uma pgina no TWebBrowser, por exemplo (supondo
que voc tem um componente chamado WebBroser1):
WebBrowser1.Navigate(http://theclub.activeinterno.com.br);
// impresso sem aparecer um dialog
procedure WBPrintNoDialog(WB: TWebBrowser) ;
var
vIn, vOut: OleVariant;
begin
WB.ControlInterface.ExecWB
(OLECMDID_PRINT,
OLECMDEXECOPT_DONTPROMPTUSER,
vIn, vOut) ;
end;

//com chamada do dialog
procedure WBPrintWithDialog(WB: TWebBrowser) ;
var
vIn, vOut: OleVariant;
begin
WB.ControlInterface.ExecWB(OLECMDID_PRINT,
OLECMDEXECOPT_PROMPTUSER, vIn, vOut) ;
end;
// Preview de impresso
procedure WBPrintPreview(WB: TWebBrowser) ;
var
vIn, vOut: OleVariant;
begin
WB.ControlInterface.ExecWB(OLECMDID_PRINTPREVIEW,
OLECMDEXECOPT_DONTPROMPTUSER, vIn, vOut);
end;

//Chama o dialog de setup de pgina
procedure WBPrintPageSetup(WB: TWebBrowser) ;
var
vIn, vOut: OleVariant;
begin WB.ControlInterface.ExecWB(OLECMDID_PAGESETUP,
OLECMDEXECOPT_PROMPTUSER, vIn, vOut) ;
end;
Como esconder o text cursor dentro de um Tmemo

Aqui est um cdigo exemplo de como esconder o text cursor no Memo1 dentro do
Form1.
Substitua todo o cdigo pelo que segue abaixo:
138
unit Unit1;

interface

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

const
WM_MYMEMO_ENTER =WM_USER +500;

type
TForm1 =class(TForm)
Memo1: TMemo;
procedure Memo1Enter(Sender: TObject) ;
procedure Memo1Exit(Sender: TObject) ;
procedure Memo1Change(Sender: TObject);

private
public
procedure WMMYMEMOENTER
(var Message: TMessage) ;
message WM_MYMEMO_ENTER;
end;

var Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.WMMYMEMOENTER
(var Message: TMessage) ;
begin
CreateCaret(Memo1.Handle,0,0,0) ;
end;

procedure TForm1.Memo1Enter(Sender: TObject);
begin
PostMessage
(Handle, WM_MYMEMO_ENTER, 0, 0);
end;

procedure TForm1.Memo1Exit(Sender: TObject);
begin
CreateCaret(Memo1.handle,1,1,1) ;
end;

procedure TForm1.MemoChange(Sender: TObject);
begin
139
CreateCaret(Memo1.handle,0,0,0) ;
end;
end.
Como determinar a posio do cursor dentro de um TrichEdit

Veja o exemplo:
{
Usage:

var sRC:string;

src :=GetPosition(RichEdit1) ;
//src reults in a string
//formated like: Row:Col
}

function GetPosition
(ARichEdit: TRichEdit): string
var
iX,iY : Integer;
begin
iX :=0; iY :=0;
iY :=SendMessage(ARichEdit.Handle,
EM_LINEFROMCHAR,ARichEdit.SelStart,0) ;
iX :=ARichEdit.SelStart -
SendMessage(ARichEdit.Handle,
EM_LINEINDEX, iY, 0) ;

Result :=IntToStr(iY +1) +: +IntToStr(iX +1) ;
end;
Como completer strings parciais digitadas dentro de um
Combo Box
O exemplo abaixo mostra como completar strings parciais digitadas dentro de um
combo box. O cdigo representa o apontamento do evento OnKeyPress do combo box,
que faz a execuo padro das teclas antes de encontrar o item na lista correspondente e
atualizar o texto.

Observao: O evento OnKeyPress no faz nada quando o usurio pressiona Delete.
Neste caso deve-se capturar a tecla utilizando-se o evento OnKeyDown.
procedure TForm1.ComboBox1KeyPress(Sender: TObject; var Key: Char) ;
var
Found: boolean;
j,SelSt: Integer;
140
TmpStr: string;
begin
{ primeiro, processe a tecla para obter
a string corrente }

{ Este cdigo requer que todos os itens
estejam listados em uppercase}
if Key in [a..z] then Dec(Key,32) ;
{Somente Uppercase!}
with (Sender as TComboBox) do
begin
SelSt :=SelStart;
if (Key =Chr(vk_Back)) and
(SelLength <>0) then
TmpStr :=Copy(Text,1,SelStart)+Copy
(Text,SelLength+SelStart+1,255)

else if Key =Chr(vk_Back) then
{SelLength =0}
TmpStr :=Copy(Text,1,SelStart-
1)+Copy(Text,SelStart+1,255)
else {Key in [A..Z, etc]}
TmpStr :=
Copy(Text,1,SelStart)+Key+Copy
(Text,SelLength+SelStart+1,255) ;
if TmpStr = then Exit;
{ atualize SelSt para a posio
corrente de insero }

if (Key =Chr(vk_Back)) and (SelSt >0)
then Dec(SelSt)

else if Key <>Chr(vk_Back) then
Inc(SelSt) ;
Key :=#0; { indica qual tecla foi
apontada }
if SelSt =0 then
begin
Text:=;
Exit;
end;

{Agora que TmpStr a string sendo digitada no momento, veremos se conseguimos
encontrar uma correspondncia }

Found :=False;
for j :=1 to Items.Count do
if Copy(Items[j-1],1,Length(TmpStr)) =
TmpStr then
begin
141
Text :=Items[j-1]; { atualize para a
correspondente que foi encontrada}
ItemIndex :=j-1;
Found :=True;
Break;
end;
if Found then { selecione o final no
digitado da string }
begin
SelStart :=SelSt;
SelLength :=Length(Text)-SelSt;
end
else Beep;
end;
end;
Como arredondar os cantos dos controles
Aqui est como desenhar controles com os cantos arredondados.
Para testar, arraste um TEdit, TPanel e TMemo em um formulrio.
procedure DrawRounded(Control: TWinControl) ;
var
R: TRect;
Rgn: HRGN;
begin
with Control do
begin
R :=ClientRect;
rgn :=CreateRoundRectRgn(R.Left,
R.Top, R.Right, R.Bottom, 20, 20);
Perform(EM_GETRECT, 0, lParam(@r)) ;
InflateRect(r, - 4, - 4) ;
Perform(EM_SETRECTNP, 0, lParam(@r)) ;
SetWindowRgn(Handle, rgn, True) ;
Invalidate;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// arredondando o Panel1
DrawRounded(Panel1) ;

// arredondando o Memo1
Memo1.BorderStyle :=bsNone;
DrawRounded(Memo1) ;

// arredondando o Edit1
Edit1.BorderStyle :=bsNone;
142
DrawRounded(Edit1) ;

end;

Usando as setas do teclado para se mover entre os controles

As teclas Up e Down so virtualmente inteis em controles Edit. Ento, porque no us-
las para navegar entre os controles? Se voc ajustar a propriedade KeyPreview de um
form para True voc pode usar o seguinte cdigo no seu evento OnKeyDown do
formulrio para controlar a navegao:
procedure TForm1.FormKeyDown(
Sender : TObject;
var Key: Word;
Shift : TShiftState
) ;

var
Direction : Integer;

begin
Direction :=-1;
case Key of
VK_DOWN, VK_RETURN : Direction :=0;

{Next}
VK_UP : Direction :=1; {Previous}
end;
if Direction <>-1 then
begin
Perform(WM_NEXTDLGCTL, Direction, 0) ;
Key :=0;
end;

end;

Qual a palavra sob o cursor do mouse em um TRichEdit?

Aqui est o cdigo para voc saber qual a palavra que est sob o cursor do mouse.
A varivel string WordInRE conter a palavra.
Observao:
Voc precisar de um TRichEdit (RichEdit1), um form (Form1), e o cdigo abaixo no
evento OnMouseMove do RichEdit1.
143
uses
RichEdit;

var
WordInRE : string;

procedure TForm1.RichEdit1MouseMove
(Sender: TObject; Shift: TShiftState;
X, Y: Integer) ;

var
ci,
lix,
co,
k, j: Integer;
Pt: TPoint;
s: string;

begin
with TRichEdit(Sender) do
begin
Pt :=Point(X, Y) ;
ci :=Perform(Messages.
EM_CHARFROMPOS, 0, Integer(@Pt)) ;
if ci <0 then Exit;
lix :=Perform
(EM_EXLINEFROMCHAR, 0, ci);
co :=ci - Perform
(EM_LINEINDEX, lix, 0) ;
if -1 +Lines.Count <lix then Exit;
s :=Lines[lix];
Inc(co) ;
k :=co;
while (k >0) and (s[k] <> ) do
k:=k-1;
Inc(co) ;
j :=co;
while (j <=Length(s)) and
(s[j] <> ) do Inc(j) ;
WordInRE :=Copy(s, k, j - i) ;

end;

end;




144
Mostra o total de pginas

Voc pode fazer este tipo de trabalho, mas ele ter que ser manual. O primeiro passo
pegar o total de pginas e jogar para uma varivel. Para pegar o total de pginas voc
pode executar o cdigo abaixo antes de chamar o relatrio.
QuickRep1.Prepare;
TotalPaginas :=QuickRep1.PageNumber;

TotalPaginas mostrada anteriormente uma varivel do tipo inteiro.

Para mostrar isto no QuickReport voc pode utilizar um componente QRSysData
alterando a propriedade Data para PageNumber e colocar a rotina a seguinte no evento
OnPrint.

procedure TForm1.QRSysData1Print
(sender: TObject; var Value: String); begin
Value :=Value +/ +IntToStr(TotalPaginas) end;


InnoSetup Verificando a verso do software, se inferior,
ento, no instalar

O InnoSetup permite a incluso de scripts em uma sua seo CODE e isso sem
dvidas permite grande flexibilidade no desenvolvimento de instalaes personalizadas.
Abaixo, segue um script para o InnoSettup onde demonstramos como efetuar este tipo
de verificao.
[Setup]
AppName=VerificaVersao
AppVerName=VerificaVersao
DefaultDirName={pf}\VerificaVersao
DisableStartupPrompt=true
Uninstallable=false
DisableDirPage=true
OutputBaseFilename=VerificaVersao

[Code]

function GetVersion(): String;
var
sVersion: String;
begin
sVersion :=;
GetVersionNumbersString( ExpandConstant
145
({win}\notepad.exe) , sVersion );
Result :=sVersion;
end;

function InitializeSetup(): Boolean;
begin
if GetVersion() =5.1.2600.0 then
begin
MsgBox( Verso instalada: +GetVersion() +chr(13) +
Voc s poder instalar uma verso superior., mbInformation, MB_OK );
Result :=false;
end
else
Result :=true;
end;

InnoSetup Manipulao de arquivos texto

Utilizando a seo de codificao do InnoSetup possvel implementar a manuteno
em arquivos texto de forma bem simples, acompanhe o script abaixo:
[Setup]
AppName=EditaTexto
AppVerName=EditaTexto
DefaultDirName={pf}\EditaTexto
DisableStartupPrompt=true
Uninstallable=false
DisableDirPage=true
OutputBaseFilename=EditaTexto

[Code]
function AddToText(strFilename, strNewLine:
String): Boolean;
var
strTemp : String;
iLineCounter : Integer;
a_strTextfile : TArrayOfString;
begin
Result :=False;
{ Carrega as linhas do texto em um Array }
LoadStringsFromFile(strFilename,
a_strTextfile);
{ Adiciona uma linha no Array }
SetArrayLength(a_strTextfile, GetArrayLength(a_strTextfile)+1);
{ Escreve o texto }
a_strTextfile[GetArrayLength
(a_strTextfile)-1] :=strNewLine;
146
{ Regrava o arquivo }
SaveStringsToFile(strFilename, a_strTextfile, False);
Result :=True;
end;

function InitializeSetup(): Boolean;
var
Arquivo: String;
begin
Arquivo :=ExpandConstant({pf}\
Firebird\Firebird_1_5\aliases.conf);
if AddToText(Arquivo, THECLUB =D:\THECLUB\THECLUB.FDB) then
begin
MsgBox(Alterao efetuada com
sucesso!, mbInformation, MB_OK );
Result :=false;
end
else
Result :=true;
end;



Finalizando processos do Windows via programao

Segue abaixo instruo para finalizar um processo do Windows, via Delphi.
implementation
Uses Tlhelp32;

{$R *.dfm}

function KillTask(ExeFileName: string): Integer;
const
PROCESS_TERMINATE=$0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
Result :=0;
FSnapshotHandle :=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize :=Sizeof(FProcessEntry32);
ContinueLoop :=Process32First
(FSnapshotHandle, FProcessEntry32);
while integer(ContinueLoop) <>0 do
begin
147
if ((UpperCase(ExtractFileName
(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName))
or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase (ExeFileName))) then
Result :=Integer(TerminateProcess
(OpenProcess(PROCESS_TERMINATE,
BOOL(0),FProcessEntry32.
th32ProcessID), 0));
ContinueLoop :=Process32Next
(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
KillTask( Outlook.exe );

end;

Gravando CDs

No endereo: http://sourceforge.net/projects/delphineroapi/ encontrar um pacote de
APIs para Delphi que possibilitam efetuar a gravao de CDs.


Quick Report - Obtendo a lista de papeis disponveis

No caso do QReport, o mesmo possui uma tipagem prpria com nomes dos papeis que
no coincidem com os tipos pr-definidos no Windows. Assim sendo, adicione estes
valores fixos ao seu ComboBox, pois, estes so dos tipos possvel aceitos pelo QR:

TQRPaperSize =(Default, Letter, LetterSmall, Tabloid, Ledger, Legal, Statement,
Executive, A3, A4, A4Small, A5, B4, B5, Folio, Quarto, qr10X14, qr11X17, Note,
Env9, Env10, Env11, Env12, Env14, CSheet, DSheet, ESheet, Custom)

Para pegar o valor do ComboBox e alterar no QReport, utilize o seguinte:
implementation
uses QrPrNtr, TypInfo;
{$R *.dfm}

procedure SetPaper(const PaperName: string; QR: TQuickRep);
var
Paper : TQRPaperSize;
148
begin
Paper :=TQRPaperSize(GetEnumValue(TypeInfo
(TQRPaperSize),PaperName));
QR.Page.PaperSize :=Paper;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SetPaper(LetterSmall, QuickRep1);
// ou
SetPaper(ComboBox.Items[ComboBox.ItemIndex], QuickRep1);
end;

DBGrid - Como fazer quebra de linhas
Iremos demonstrar aqui como fazer quebra de linhas no texto apresentado em um
DBGrid. Para isso, ser necessrio declararmos um tipo para poder acessar propriedades
protegidas do mesmo.
{ tipo para acessar propriedades protegidas }
type
TGrid =class(TCustomDBGrid);

{ Flags de alinhamento }
const
AlignFlags : array [TAlignment] of Integer =
( DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or
DT_NOPREFIX, DT_RIGHT or DT_WORDBREAK or
DT_EXPANDTABS or DT_NOPREFIX, DT_CENTER or
DT_WORDBREAK or DT_EXPANDTABS or
DT_NOPREFIX );
RTL: array [Boolean] of Integer =(0, DT_RTLREADING);
var
Form1: TForm1;
implementation
{$R *.dfm}
{
Evento OnDrawColumnCell do DBGrid.
}
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
R: TRect;
begin
with DBGrid1 do
begin
if DataCol =1 then { Verifica se a 2 coluna}
begin
149
CopyRect(R, Rect);
Canvas.FillRect(Rect);
{
Ajusta limite para Quebrar o texto, neste caso, verifica a largura da coluna
}
R.Right :=R.BottomRight.X;
{ desenha o texto na "rea" determinada em "R" }
DrawText(Canvas.Handle, PChar(Column.Field.AsString),
StrLen(PChar(Column.Field.AsString)), R,
DT_EXPANDTABS or DT_WORDBREAK );
end;
end;
end;
{ Evento OnCreate do Form }
procedure TForm1.FormCreate(Sender: TObject);
begin
{ Ajusta altera padro para as linhas }
TGrid(DBGrid1).DefaultRowHeight :=50;
end;

Mensagens: Alterar a cor da fonte de um ShowMessage

Neste dica, utilizamos um evento do objeto Application para verificar que houve
mudana de formulrio e se o formulrio que foi chamado for do tipo TmessageForm (o
qual indica que uma caixa de mensagem), ir alterar a cor da fonte do texto da mesma.
Vamos ao cdigo:
type
TForm1 =class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
public
procedure FormFoco(Sender: TObject);
end;

var
Form1: TForm1;

implementation
{$R *.dfm}
procedure TForm1.FormFoco(Sender: TObject);
var Comp: TLabel;
begin
{ Verifica se o form que est com o
150
foco o form de mensagem }
if Screen.ActiveForm.ClassName =TMessageForm then
begin
{ Pesquisa o componente label de mensagem }
Comp :=TLabel(Screen.ActiveForm.
FindComponent(Message));
if Comp <>Nil then
Comp.Font.Color :=clBlue; { Altera a sua cor }
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveFormChange :=FormFoco;
end;

procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Screen.OnActiveFormChange :=Nil;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(THE CLUB - O maior clube de programadores do Brasil);
end;

end.
Arquivo: Verificar se est ReadOnly
var
Attributes: Word;
begin
Attributes :=FileGetAttr(d:\arquivo.txt);
if (Attributes and faReadOnly) =faReadOnly then
ShowMessage(ReadOnly);
end;
DBGrid: Como alterar a altura das linhas

Existem propriedades protegidas no DBGrid que para podermos acess-las somos
obrigados a derivar uma nova classe. Veja o cdigo abaixo:
type
TGrid =class(TCustomDBGrid);

var
Form1: TForm1;

151
implementation

{$R *.dfm}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
{ ajusta altura padro para as linhas }
TGrid(DBGrid1).RowHeights[1] :=50;
end;

Treeview Foco
Veja neste exemplo como mandar o foco um tem do treeview quando clicar no boto
de expanso (+):
// evento OnMouseDown do Treeview.

procedure TForm1.TreeView1MouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
T: TTreeNode;
begin
// Pega o tem atravs das coordenadas do mouse.
T :=Treeview1.GetNodeAt(X,Y);
if T <>nil then
Treeview1.Selected :=T;

end;
Rave Report Indicar pgina inicial
O Rave Reports permite ter vrias pginas de relatrio (cada pgina com um layout)
para um mesmo relatrio. Neste exemplo, iremos demonstrar como definir via
programao qual pgina ser apresentada como inicial.
uses
RVClass, RVProj, RVCsStd;
procedure TForm1.btnChamaRelClick
(Sender: TObject);
var
Pagina: TRavePage;
Report: TRaveReport;
QualPagina: String;
begin

// Nome da pgina dentro do projeto Rave.
QualPagina :=Page2;
152
// Abre RvProject.
RvProject1.Open;
// Pega referncia do Report
// dentro do projeto Rave.
Report :=RvProject1.ProjMan.ActiveReport;
// Pega referncia da Page dentro do Report.
Pagina :=RvProject1.ProjMan.FindRaveComponent
(Report1.+QualPagina,nil) as TRavePage;
// Indica a pgina inicial.
Report.FirstPage :=Pagina;
// Executa o relatrio.
RvProject1.Execute;

end;
Desktop do Windows auto-arranjar icones
Esta dica pode ser til aps a instalao de sua aplicao, onde geralmente
disponibilizado um cone na rea de trabalho do Windows e em muitos casos sendo
necessrio arranj-los aps a instalao.
mplementation
uses CommCtrl;
{$R *.dfm}

function GetDesktopListViewHandle: THandle;
var
S: String;
begin
Result :=FindWindow(ProgMan, nil); Result :=
GetWindow(Result,GW_CHILD);
Result :=GetWindow(Result, GW_CHILD);
SetLength(S, 40);
GetClassName(Result, PChar(S), 39);
if PChar(S) <>SysListView32 then
Result :=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessage(GetDesktopListViewHandle,
LVM_ARRANGE, 0, 0);
end;

153
Clculo de Parcelas
Neste simples exemplo iremos demonstrar como fazer a diviso de um valor em
parcelas, fazendo o tratamento da diferena, jogando para a primeira ou ltima parcela,
na figura 1 poder verificar o layout sugerido para o formulrio deste exemplo.

Figura 1 Layout sugerido

Acompanha agora o cdigo do boto Gerar:
procedure TForm1.btnGerarClick(Sender: TObject);
var
Total, ValorParc, TotParc: Extended;
NParc: Integer;
Parcelas: Array of Extended;
i: Integer;
begin
{ Variveis auxiliares }
Total :=0;
ValorParc :=0;
TotParc :=0;
NParc :=0;
ListParcelas.Clear;

{ tenta converter o valor do Edit }
try
Total :=StrToFloat(edValor.Text);
except
ShowMessage(Valor Invlido!);
Abort;
end;

{ Verifca nmero de parcelas }
if speParcelas.Value <2 then
154
Exit
else
NParc :=speParcelas.Value;

{ Pega somente a parte inteira da diviso }
ValorParc :=Trunc(Total / NParc);

{ Ajusta array que guardar o }
{valor de cada parcela }
SetLength(Parcelas, NParc);

{ Atribui valor de cada parcela e acumula total }
for i :=Low(Parcelas) to High(Parcelas) do
begin
Parcelas[i] :=0;
Parcelas[i] :=ValorParc;
TotParc :=TotParc +Parcelas[i];
end;

{ Verifica em qual parcela ser jogada a }
{ diferena }
if rg_diferenca.ItemIndex =0 then
Parcelas[Low(Parcelas)] :=
Parcelas[Low(Parcelas)] +(Total - TotParc)
else
Parcelas[High(Parcelas)] :=
Parcelas[High(Parcelas)] +(Total - TotParc);

{ mostra parcelas no ListBox }
for i :=Low(Parcelas) to High(Parcelas) do
ListParcelas.Items.Add(FormatFloat(###,##0.00, Parcelas[i]));
end;
O exemplo referente esta dica est disponvel para download em:
http://theclub.activeinterno.com.br/revista/downloads/CalcParcelas.zip

Porta Serial Como verificar se uma porta est em uso
Existem APIs do Windows que possibilitam fazer acesso e manuteno portas seriais,
veja abaixo:
var
portHandle: Integer;
begin
portHandle :=0;
portHandle :=CreateFile(Pchar(ComboCOM.Text), GENERIC_READ or
GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if portHandle >0 then
155
ShowMessage(Porta em uso!)
else
raise Exception.Create
(No consegui abrir a porta!);

end;

GIF Como converter uma imagem GIF para BMP
Neste exemplo, estamos utilizando o objeto TGifImage que instalado junto com a
suite de componentes RxLib. Esta suite gratuta e possui vrios componentes bem
legais e, caso haja interesse, poder baixar em nosso site, theclub.activeinterno.com.br.
Abaixo, segue a rotina de converso:
implementation
uses RxGif;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
GIF: TGIFImage;
BMP: TBitmap;
begin
GIF :=TGIFImage.Create;
BMP :=TBitmap.Create;
try
GIF.LoadFromFile(c:\banner_theclub.gif);
BMP.Assign(GIF);
BMP.SaveToFile(c:\theclub.bmp);
finally
GIF.Free;
BMP.Free;
end;

end;

Veja como criar atalhos no menu iniciar do Windows
Neste exemplo, iremos demonstrar uma forma bastante simples para criar:
- Grupos de programas
- Items de programas
- Atalhos para programas
Em nossa abordagem, no iremos utilizar a criao via interface DDE por alguns
questes de parametrizao e sim, demonstraremos a partir da criao direta de
folders na pasta Programs do Windows.
156
Primeiramente, vamos criar uma procedure para criao de atalhos:
implementation
uses ShlObj, ActiveX, ComObj;
{$R *.dfm}

procedure CriaShortCut(aNome, aFileName, aPathGroup: string; aLocation: integer);
var
IObject : IUnknown;
ISLink : IShellLink;
IPFile : IPersistFile;
PIDL : PItemIDList;
InFolder : array[0..MAX_PATH] of Char;
TargetName : String;
LinkName,s : WideString;
begin
TargetName :=aFileName;

IObject :=CreateComObject(CLSID_ShellLink);
ISLink :=IObject as IShellLink;
IPFile :=IObject as IPersistFile;

with ISLink do
begin
SetPath(pChar(TargetName));
SetWorkingDirectory(pChar(ExtractFilePath(TargetName)));
end;

SHGetSpecialFolderLocation(0, aLocation, PIDL);
SHGetPathFromIDList(PIDL, InFolder);

s :=InFolder;
LinkName :=s +\ +aPathGroup +\ +
aNome +.LNK;
IPFile.Save(PWChar(LinkName), false);

end;
Esta procedure recebe como parmetro o Nome do atalho a ser apresentado, o caminho
e nome do aplicativo a ser executado, e por ltimo o grupo ao qual ele ir pertencer no
menu Iniciar do Windows.
Agora vamos para a procedure responsvel em criar o Grupo e o tem de Programa:
function CreateFolder(Foldername: string; aLocation: integer): boolean;
var
pIdl: PItemIDList;
hPath: PChar;
begin
Result :=False;
157
if SUCCEEDED(SHGetSpecialFolderLocation(0, aLocation, pidl)) then
begin
hPath :=StrAlloc(max_path);
SHGetPathFromIDList(pIdl, hPath);
SetLastError(0);
if ForceDirectories(PChar(hPath +\\ +Foldername)) then
Result :=true;
StrDispose(hPath);
end;
end;
Observe que esta procedure recebe como parmetro o nome do grupo (que na realidade
ser o nome de um Folder e a localizao, ou seja, onde ele dever ser criado.
Exemplo de utilizao:
procedure TForm1.Button1Click(Sender: TObject);
begin
// cria Grupo principal.
CreateFolder(The Club, CSIDL_PROGRAMS);
// cria sub-grupo dentro do The Club
CreateFolder(The Club\Grupo 1, CSIDL_PROGRAMS);
// cria sub-grupo dentro do The Club
CreateFolder(The Club\Grupo 2, CSIDL_PROGRAMS);
// cria sub-grupo dentro do The Club
CreateFolder(The Club\Grupo 3, CSIDL_PROGRAMS);
// cria sub-grupo dentro do The Club\Grupo 1
CreateFolder(The Club\Grupo 1\Sub Grupo 1,
CSIDL_PROGRAMS);
// cria sub-grupo dentro do The Club\Grupo 2
CreateFolder(The Club\Grupo 2\Sub Grupo 1,
CSIDL_PROGRAMS);
// cria sub-grupo dentro do The Club\Grupo 3
CreateFolder(The Club\Grupo 3\Sub Grupo 4,
CSIDL_PROGRAMS);
// cria atalho para os programas
CriaShortCut(Calculadora, c:\windows\system32\calc.exe , The Club\Grupo
1, CSIDL_PROGRAMS);
CriaShortCut(Bloco de Notas, c:\windows\system32\notepad.exe, The Club\Grupo
2, CSIDL_PROGRAMS);
CriaShortCut(WordPad, C:\Program Files\Windows NT\Accessories\wordpad.exe,
The Club\Grupo 3, CSIDL_PROGRAMS);
end;
Dica: A constante CSIDL_PROGRAMS indica a pasta padro onde os tens do menu
iniciar do Windows ficam armazenados. Trabalhando com esta constante, independente
da verso e linguagem do Windows, a pasta ir ser criada no local correto.
Observe que primeiramente criamos um grupo principal, chamado The Club.
Seguindo, dentro de The Club criamos sub-grupos e dentro dos sub-grupos os atalhos
que iro chamar os aplicativos em questo.
158
Este exemplo est disponvel para download em nosso site no endereo:
http://theclub.activeinterno.com.br/revista/download/CriaGrupoAtalho.zip


Como mover um componente em Run-time
Para montar este exemplo vamos incluir um componente Button. Para testar este exemplo
mantenha a tecla CTRL pressionada clique com o mouse sobre o componente Button e
arraste-o para qualquer lugar do form.
unit Unit1;

interface

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

type
TForm1 =class(TForm)
Button1: TButton;
procedure Button1MouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1MouseMove(Sender: TObject;
Shift: TShiftState; X,
Y: Integer);
procedure Button1MouseUp(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
MouseDownSpot : TPoint;
Capturing : bool;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

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

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

// Evento OnMouseUp do boto
procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Capturing then
begin
ReleaseCapture;
Capturing :=false;
Button1.Left :=Button1.Left -
(MouseDownSpot.x -x);
Button1.Top :=Button1.Top -
(MouseDownSpot.y - y);
end;
end;
Como apresentar o nmero da linha e coluna em um DBGrid?
O DBGrid possui estas informaes, porm elas no esto visveis para acesso direto. Contudo,
podemos derivar uma classe a partir de TDBGrid e utiliz-las sem problemas...
implementation

{$R *.DFM}

type
TMostraProp =class (TDBGrid);
160
{evento OnColEnter do DBGrid}
procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
Caption :=Format(Coluna: %2d; Row: %2d,
[TMostraProp(DbGrid1).Col, TMostraProp(DbGrid1).Row]);
end;

{ evento OnDataChange do DataSource }
procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField);
begin
DBGrid1ColEnter(Sender);
end;
Como implementar um log de todos os erros gerados na
aplicao?
Isso poder ser implementado utilizando um componente TApplicationEvents (aba Additional),
interceptando seu evento OnException e gerando um arquivo texto com as mensagens de erros
geradas durante a execuo do aplicativo. Para isso, adicione um componente
TapplicationEvents no Form principal de sua aplicao e abra o evento OnExxception onde
iremos programar o seguinte:
procedure TFormLog.LogException(Sender: TObject; E: Exception);
var
NomeDoLog: string;
Arquivo: TextFile;
begin
{
preparar o arquivo de log
utiliza o nome da aplicao, trocando a extenso para .log.
}
NomeDoLog :=ChangeFileExt(Application.Exename, .log);
{ pega ponteiro para o arquivo }
AssignFile(Arquivo, NomeDoLog);
{ verifica se existe }
if FileExists(NomeDoArquivo) then
Append(Arquivo) { se existir, apenas adiciona linhas }
else
ReWrite(Arquivo); { cria um novo se no existir }
try
{ grava Data e Hora +Mensagem de erro }
WriteLn(Arquivo, DateTimeToStr(Now) +: +E.Message);
{ mostra mensagem original de erro }
Application.ShowException(E);
finally
{ fecha o arquivo }
CloseFile (LogFile);
end;
end;
Para testar, bastar por exemplo em um boto, gerar uma exceo de diviso por zero:
161
procedure TForm1.Button1Click(Sender: TObject);
var
a, b, c: Integer;
begin
a :=10;
b :=0;
c :=a div b;
ShowMessage(IntToStr(c));
end;

Printers - Como retornar informaes das impressoras
instaladas na mquina
Nesta dica, demonstraremos como retornar informaes teis das impressoras instaladas na
mquina, como por exemplo, o caminho da rede, seu nome de compartilhamento, porta, etc.

Insira um componente ListView e um boto, como mostra a figura 1.


Na lista de uses, declare:
uses
Printers, WinSpool;

{ Procedure que ir adicionar as informaes ao ListView }
procedure AdicionaImpressoras(LV: TListView; Servidor, NomeImpressora,
Compartilhamento, Porta, NomeDriver, Comentario: String);
var
i: integer;
begin
with LV do
begin
Items.Add;
i :=Items.Count-1;
Items[i].Caption :=Servidor;
Items[i].SubItems.Add(NomeImpressora);
Items[i].SubItems.Add(Compartilhamento);
Items[i].SubItems.Add(Porta);
Items[i].SubItems.Add(NomeDriver);
Items[i].SubItems.Add(Comentario);
162
end;
end;
O retorno das informaes ser feito atravs da API EnumPrinters:
procedure GetPrinterList(List: TListView);
var
Buffer, PrinterInfo: PChar;
Flags, Count, NumInfo: DWORD;
i: Integer;
Level: Byte;
begin
Flags :=PRINTER_ENUM_CONNECTIONS or PRINTER_ENUM_LOCAL;
Level :=2;

Count :=0;
EnumPrinters(Flags, nil, Level, nil, 0, Count, NumInfo);
if Count >0 then
begin
GetMem(Buffer, Count);
try
if not EnumPrinters(Flags, nil, Level, PByte(Buffer), Count, Count, NumInfo) then
Exit;
PrinterInfo :=Buffer;
for i :=0 to NumInfo - 1 do
begin
case Level of
2: begin
AdicionaImpressoras(List, PPrinterInfo2(PrinterInfo)^.pServerName,
PrinterInfo2(PrinterInfo)^.pPrinterName,
PPrinterInfo2(PrinterInfo)^.pShareName,
PPrinterInfo2(PrinterInfo)^.pPortName,
PPrinterInfo2(PrinterInfo)^.pDriverName,
PPrinterInfo2(PrinterInfo)^.pComment);
Inc(PrinterInfo, SizeOf(TPrinterInfo2));
end;
4: begin
AdicionaImpressoras(List, PPrinterInfo4(PrinterInfo)^.pServerName,
PPrinterInfo4(PrinterInfo)^.pPrinterName,
null,
null,
null,
null);
Inc(PrinterInfo, SizeOf(TPrinterInfo4));
end;
5: begin
AdicionaImpressoras(List, null,
PPrinterInfo5(PrinterInfo)^.pPrinterName,
null,
PPrinterInfo2(PrinterInfo)^.pPortName,
163
null,
null);
Inc(PrinterInfo,SizeOf(TPrinterInfo5));
end;
end;
end;
finally
FreeMem(Buffer, Count);
end;
end;
end;

{ abaixo, fazemos a chamada da procedure no evento OnClick do boto }

GetPrinterList(LView);
O projeto completo referente esta dica est disponvel para download em
http://theclub.activeinterno.com.br/revista/download/ListaImpressoras.zip


IP Como retornar o hostname a partir de um endereo IP
Em muitas situaes, necessitamos saber o nome de uma mquina e temos apenas seu
endereo IP. Na unit WinSock, poderemos encontrar diversas APIs para este tipo de
abordagem, veja abaixo um simples exemplo:
implementation
uses WinSock;
{$R *.dfm}

function ResolveHostByIp(IP: string): String;
type
TAPInAddr =Array[0..100] of PInAddr;
PAPInAddr =^TAPInAddr;
var
WSAData: TWSAData;
Address: String;
InetAddr: u_long;
HostEntPtr: PHostEnt;
HostEnt: THostEnt;
HostName: String;
len, struct: Integer;
i: Integer;
begin

Result :=;

WSAStartUp( $101, WSAData );
164

try
Address :=Trim(IP);
if Address = then
raise Exception.Create
( IP address not entered );

// Convert textual IP address to binary format
InetAddr :=inet_addr( PChar(Address) );
if InetAddr =SOCKET_ERROR then
raise Exception.Create
( Invalid address entered );

// Get hist entry by IP
HostEntPtr :=GetHostByAddr( @InetAddr, len, struct );
if HostEntPtr =NIL then
raise Exception.Create( WinSock error: +IntToStr(
WSAGetLastError() ) );

// Insert hostname into list
HostName :=String( HostEntPtr^.h_name );
Result :=HostName;

except
on E: Exception do begin
Beep();
ShowMessage( E.Message );
end;
end;

WSACleanUp();

end;
Para utilizar:
Edit.Text :=ResolveHostByIp(200.210.71.16); // retorna o nome da mquina

Windows Como criar grupos e subgrupos de programas no
menu iniciar
Uma das formas para fazer a criao de grupos e subgrupos de aplicativos no menu
iniciar do Windows, obtendo o path de sistema onde o Windows guarda estas
informaes e nele criar os grupos. Veja abaixo como proceder:
implementation
uses ShlObj, FileCtrl;
{$R *.dfm}
165

function GetProgramFolder: string;
var
pidl: PItemIDList;
Path: array[0..MAX_PATH] of char;
begin
SHGetSpecialFolderLocation(Application.Handle, CSIDL_PROGRAMS,
pidl);
SHGetPathFromIDList(pidl,path);
Result :=path;
Result :=Result +\;
end;

function CriaGrupo(Path: string): Boolean;
begin
Result :=ForceDirectories(GetProgramFolder+Path);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if CriaGrupo(TheClub\Grupo 1) then
ShowMessage(Grupo TheClub\Grupo 1 criado com sucesso!);
if CriaGrupo(TheClub\Grupo 2) then
ShowMessage(Grupo TheClub\Grupo 2 criado com sucesso!);
if CriaGrupo(TheClub\Grupo 3) then
ShowMessage(Grupo TheClub\Grupo 3 criado com sucesso!);
end;

Windows Como desabilitar uma combinao de teclas
genericamente
Para desabilitar uma combinao de teclas vlida para todos os formulrios da aplicao, ser
necessrio fazer um tratamento de mensagens do Windows. O exemplo abaixo demonstra
como desabilitar a combinao CTRL+P:
type
TForm1 =class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure ProcessaMsg(var Msg: TMsg; var Handled:
Boolean);
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
166

implementation

{$R *.DFM}

{ procedure de tratamento }
procedure TForm1.ProcessaMsg(var Msg: TMsg; var Handled:
Boolean);
begin
if Msg.message =WM_KEYDOWN then
begin
if (GetASyncKeyState(VK_CONTROL) <>0) and
(GetASyncKeyState(Ord(P)) <>0) then // Ctrl+P
begin
ShowMessage(Ctrl+P est sendo desabilitado!);
Msg.wParam :=VK_CLEAR;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
{ liga a procedure }
Application.OnMessage :=ProcessaMsg;
end;
end.
Veja como definir o papel de impresso personalizado no
Windows XP/2000/NT

No Windows 9x, para definirmos um papel como personalizado basta acessar as propriedades
da impressora que iremos encontrar este tipo de papel.

Porm, no Windows XP isso um pouco diferente, pois no h um papel pr-definido como
personalizado, porm temos a opo de criar um novo tipo de papel nas medidas que
desejarmos.

Para isso, abra o item Impressoras & Faxes de seu Windows e sem selecionar NENHUMA
impressora acesse o menu Arquivo ( ou File) e neste selecione a opo Propriedades do
Servidor (ou Server Properties) como mostra a imagem ao lado.

Agora, bastar clicar em Create a new form e criar o seu papel personalizado e salvar logo
em seguida e clicar em OK para finalizar!
167

Bom, agora bastar acessar as propriedades da impressora e definir este novo papel nas
configuraes de sua impressora, como exemplo:


funo que me retorne a quantidade de arquivos existentes em um dado diretrio?

Poder utilizar o objeto TSearchRec para obter o nmero de arquivos em um dado diretrio:
implementation
{$R *.dfm}
function GetTotFiles(Diretorio: String): Integer;
var
SRec: TSearchRec;
168
Res: Integer;
begin
Result :=0;
Res :=FindFirst(Diretorio+\*.*, faAnyFile, SRec);
while Res =0 do
begin
Res :=FindNext(SRec);
Inc(Result);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Caption :=IntToStr( GetTotFiles(d:\testes) );
end;

Você também pode gostar