Escolar Documentos
Profissional Documentos
Cultura Documentos
programação Delphi.
www.ramosdainformatica.com.br
1
Índice
1
Índice ............................................................................................................................ 2
Descobrindo o código ASCII de uma tecla .................................................................. 6
Função - Retornando o próximo dia útil....................................................................... 6
DBGrid - Colocando em Letras maiúsculas uma coluna selecionada.......................... 7
DBGrid - Mostrando todo conteúdo de um campo Memo........................................... 7
Crítica de datas no objeto Edit sem mensagem de erro do Delphi ............................. 10
Preenchimento de zeros para completar a data........................................................... 14
Multimídia - Fazendo suas aplicações Delphi falar ................................................... 14
Multimídia - Toque um som quando o mouse passar por cima de um botão............. 15
Hints com multiplas linhas ......................................................................................... 15
Multimídia - Usando cursores animados .................................................................... 16
Detectando a versão do Internet Explorer .................................................................. 16
QuickReport - Filtrando registros............................................................................... 17
Evitando efeito de maximização................................................................................. 17
Calcula a quantidade de dias no mês .......................................................................... 18
Calculando abono salárial de modo progressivo ........................................................ 18
Checa se um processo está rodando ........................................................................... 19
Checa se um diretório está vazio ................................................................................ 20
dbExpress - Passando parâmetros com CommandText via programação.................. 20
Corrigindo problemas de instalação do Borland Data Provider For Firebird............. 21
Lendo texto de um arquivo PDF ................................................................................ 21
Deixando seu EXE mais enxuto e rápido e, mais seguro contra decompilação......... 24
Copiando (Upload) um diretório para um servidor FTP ............................................ 26
Trabalhando com arquivos texto no Delphi ............................................................... 29
Criando uma conexão ao DBExpress em tempo de execução.................................... 31
ActiveX - Pegar um texto selecionado no Internet Explorer...................................... 32
Cria um efeito na apresentação de um formulário...................................................... 33
Criando um Menu transparente .................................................................................. 34
Checa se um diretório está vazio ................................................................................ 36
Mostra multiplas linhas de texto em um ComboBox ................................................. 37
Criando atalhos no Windows pelo Delphi.................................................................. 38
Faça suas aplicações Falar.......................................................................................... 39
Imprimindo arquivos PDF sem abrir-los .................................................................... 39
Ler arquivos PDF ....................................................................................................... 39
Inno Setup - Script para criação de conexão 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 executável ser executado somente se chamado por um determinado
executável ................................................................................................................... 42
DBGrid - Focando a célula selecionada mudando sua cor......................................... 43
Verificando a versão do Windows ............................................................................. 43
Rave Report - Alterar a impressora padrão ................................................................ 44
Atribuíndo efeitos para abertura de formulários......................................................... 44
API do Windows - Função 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 página inicial........................................................................... 48
2
InnoSetup - Adicionar um programa no iniciar do Windows .................................... 48
Validando endereço de e-mail no Delphi em aplicações 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 balão para caixas de edição wm WindowsXP ................................ 56
CheckLisBox - Trocar a cor das linhas ...................................................................... 57
Windows - Verificar a impressora padrão.................................................................. 58
RichEdit - Pesquisar um texto, posicionar sobre ele e mostrar ao usuário................. 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 contrário, abre......................................... 60
Função 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 código de barras em modo de programação.................... 64
Gerar planilhas no Excel através 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 execução ......................... 67
ListBox - Colorir ........................................................................................................ 69
Associando um extensão de arquivo a um executável ............................................... 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 título em tempo de execução....................................... 75
Testa se a impressora está funcionando...................................................................... 76
Como implementar um AutoComplete num Edit comum.......................................... 76
Como adicionar um CheckBox em um StringGrig .................................................... 78
Abreviação automática de nomes ............................................................................... 80
Compilando a aplicação pelo MS-DOS ..................................................................... 81
Coloração 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 Conexão com a internet............................................................ 86
3
Função de potenciação - Juros.................................................................................... 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 título 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 máquina via API do Windows ....................................................... 93
Texto na diagonal e girando ....................................................................................... 93
Criar um alias dinamicamente na memória ................................................................ 94
Rodar videos em um panel ......................................................................................... 94
Como colocar uma coluna do DBGrid em maiuscula ................................................ 95
DBGrid - Alinhando texto conforme condição .......................................................... 95
DBGrid - Colocando CheckBox no grid .................................................................... 96
RichEdit - Como fazer uma pesquisa e substituição em um RichEdit ....................... 97
TForm - Criando formulários 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 padrão............................... 107
Como alterar o caption da janela de preview do quickreport ................................... 107
Como passar parâmetros 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 movimentação 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 várias linhas em um TCombobox? ............................... 122
Como criar tooltips com balões? .............................................................................. 124
Mostra o total de páginas.......................................................................................... 144
InnoSetup – Verificando a versão do software, se inferior, então, não instalar ....... 144
InnoSetup – Manipulação de arquivos texto ............................................................ 145
Finalizando processos do Windows via programação.............................................. 146
Gravando CDs .......................................................................................................... 147
Quick Report - Obtendo a lista de papeis disponíveis.............................................. 147
DBGrid - Como fazer quebra de linhas .................................................................... 148
Arquivo: Verificar se está ReadOnly........................................................................ 150
Treeview – Foco ....................................................................................................... 151
Rave Report – Indicar página inicial ........................................................................ 151
Desktop do Windows – auto-arranjar icones............................................................ 152
4
Cálculo 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 número da linha e coluna em um DBGrid?............................... 159
Como implementar um log de todos os erros gerados na aplicação?....................... 160
Printers - Como retornar informações das impressoras instaladas na máquina ....... 161
IP – Como retornar o hostname a partir de um endereço IP..................................... 163
Windows – Como criar grupos e subgrupos de programas no menu iniciar............ 164
Windows – Como desabilitar uma combinação de teclas genericamente ................ 165
5
Descobrindo o código ASCII de uma tecla
Para descobrir o código ASCII de uma determinada tecla você pode criar a seguinte
aplicação.
Obtendo o próximo dia útil caso a data informada caia em um fim de semana
6
DBGrid - Colocando em Letras maiúsculas uma coluna
selecionada
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;
7
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;
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;
8
var
Form1: TForm1;
implementation
{$R *.dfm}
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;
9
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
MostraMemo(DBGrid1.DataSource, DBGrid1, DBGrid1.SelectedField);
end;
end.
Foi criado uma procedure para fazer o tratamento das mensagens de erro. Esta
procedure terá o nome de Criticadata:
10
// A matriz M é preenchida com o último dia de cada mês
// A matriz K é preenchida com 1. A posição relativa de cada caracter do campo
// data, dentro da matriz K, será prenchida com zero se o caracter for válido.
// Caso contrário 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 contém os números e / para controle do campo data.
SetLength (Num, 11);
for I := 0 to 9 do
Num[I] := IntToStr(I);
Num[10] := '/';
// Barra controla a posição das duas // do campo data
Barras := 0; // Verifica a quantidade de barras digitadas
Barra1 := 0; // Posição da 1ª barra (pode ser 2 ou 3)
Barra2 := 0; // Posição 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 variável Data não for válido
// 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 válido 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;
11
// Podemos converter as posições 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 crítica do dia se o mês 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;
A mesma procedure CriticaData, mais enxuta, porém, com o controle dos caracteres
feito no evento OnKeyPress:
12
Barra1 := 0; // Posição da 1ª barra (pode ser 2 ou 3)
Barra2 := 0; // Posição 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;
13
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if not (Key = Chr(vk_Back)) then // Este if habilita a tecla Backspace para correção do
objeto
Usuários podem não colocar os zeros de dias e meses menores que dez forçando um
erro de digitação de data. Para resolver este problema, no evento OnCreate do
formulário insira o código a seguir:
Há um tempo atrás inserimos uma dica ensinando o Delphi a falar, no entanto era com
sutaque "americado português". Saiu o SAPI 4.0 com a opção de Português Brasil. A
seguir, links com downloads e exemplos:
14
var
voice: OLEVariant;
begin
voice := CreateOLEObject('SAPI.SpVoice');
voice.Rate := 0;
voice.Volume := 100;
voice.Speak('Ramos da Informática',0);
voice := unassigned;
end;
uses MMSystem;
TYourObject = class(TAnyControl)
...
private
procedure CMMouseEnter(var AMsg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var AMsg: TMessage); message CM_MOUSELEAVE;
...
end;
implementation
15
Multimídia - Usando cursores animados
Cursores animados existem aos montes pela internet, você pode utilizar estes cursores
em suas aplicações, neste pequeno exemplo inserimos o código no evento OnCreate do
formulário, acompanhe:
Para detectar a versão do Internet Explorer, basta consultar uma chave do registro cujo
endereço é:
HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer
- IVer disponível no IE 1, 2 e 3
- Build disponível a partir do IE 2
- Version disponível a partir do IE 4.0
A chave Version contém o número da versão por extenso que não corresponde ao
número da versão que o usuário vê. Na página abaixo tem uma lista detalhada que
relaciona um valor com o outro:
http://www.codeproject.com/shell/detectie.asp
16
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;
Através da versão do IE determina-se qual ActiveX poderá ser carregado para fazer
OLE com o IE. Até a versão 3.0 o componente é o TWebBrowser_V1 e a partir do IE
4.0, o componente é o TWebBrowser.
Se você já desenvolveu uma aplicação MDI com um formulário MDIChild que tem que
ser exibido em estado Maximizado (WindowState=wsMaximized), provavelmente você
já se deparou com aquele deselegante problema em que o usuário acompanha a
maximização do seu formulário. Para evitar isto, faça o seguinte:
Exemplo:
17
Calcula a quantidade de dias no mês
Exemplo de uso:
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;
18
Esta é uma função para calcular de modo progressivo um abono (por exemplo, folha
de pagamento) sem cometer injustiça.
Expl: Digamos que queremos que todos os funcionários que ganham até R$ 299,99
recebam um abono de R$ 50,00 e acima deste valor um abono de R$ 30,00.
Se não 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 função acima corrige estas distorções, e pode ser aplicada num banco de dados para
diversas faixas salariais.
{ .... }
uses TlHelp32;
{ .... }
// Exemplo:
procedure TForm1.Button1Click(Sender: TObject);
begin
if processExists('calc.exe') then
ShowMessage('Processo em execução')
else
19
ShowMessage('O processo NÃO está em execução');
end;
// Exemplo:
20
Corrigindo problemas de instalação do Borland Data Provider
For Firebird
Em alguns casos, o Borland Data Provider For Firebird têm apresentado problemas de
instalação, abaixo segue algumas dicas para tentar auxiliar na resolução dos mesmos:
É o seguinte, esta dica peguei em um site Alemão, fiz aqui sua tradução e alguns testes e
funciou. Para quem precisa criar algum sistema que leia o conteúdo de texto de um
arquivo PDF. Não lembro quem havia pedido, mas aqui está a solução:
{++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++}
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, acrobat_tlb;
type
TForm1 = class(TForm)
Button1: TButton;
21
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;
22
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');
for j := 0 to acrobat.GetNumPages - 1 do
begin
memo1.Lines.Add('----------------------------------------------');
//Primeira página do documento ativa
PDPage := acrobat.acquirePage(j);
PDHili := CreateOleObject('AcroExch.HiliteList');
Result := PDHili.Add(0, 4096);
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 estatística
Size := Size + SizeOf(zeilen);
Inc(stichwortcounter);
23
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.
Geralmente, arquivos EXE criados com Delphi são maiores que os criados com outras
linguagens de programação. O motivo disso são as VCL (Claro que VCL tem muitas
vantagens e devem ser usadas). Porém, é possível deixar os executáveis menores e,
consequentemente, mais rápidos de serem abertos, fácil de distribuição pela Web
(mesmo na era da banda larga), fica mais difícil de piratas de códigos abrir seus
softwares, etc.
Então apresento aqui, 10 passos (ou dicas) para deixar seu executável mais enxuto:
24
03) O que puder ser desenvolvido sem o uso de VCL deve ser feito, pois quanto maior a
quantidade de VCLs, maior será o executável, mas as VCL devem ser usadas, ok.
04) Use a ACL (API Controls Library)
05) Use StripReloc.
06) Desative a opção remote debugging information e TD32 do Delphi.
07) You might want to put code in a dll.
08) Não coloque imagens em Formulários. De preferência, leia em tempo de execução.
09) Use imagens compactas, como por exemplo JPG ao invés de BMP.
******************************************************
01)
http://www.aspack.com/aspack.htm
{****************************************************************}
http://bonanzas.rinet.ru/
{****************************************************************}
03) nonVCL
Delphi possibilita muitos caminhos. Se você quer um executável pequeno, então não
uso a VCL. Isso é possível 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/
25
{****************************************************************}
{****************************************************************}
05) StripReloc Este programa remove a seção de recolocação (".reloc") dos executávies
Win32 PE, reduzindo o tamanho deles. A maioria do compiladores/linkeditores
(inclusive o do Delphi) insere esta seção no executável e é uma seção que nunca será
usada e não tem outra finalidade senão desperdiçar espaço na memória e em disco.
http://www.jrsoftware.org/striprlc.php
{****************************************************************}
{****************************************************************}
08 e 09)
Sobre imagens
Formulários com muitas imagens anexadas são criadas junto ao executável, deixando
ele muito grande e sempre que é executado o tamanho original é multiplicado, o que
torna inviável. O melhor é anexar as imagens e enviar junto ao executável pois assim
não há esta multiplicação.
Use arquivos JPEG ao invés de BMP. Isso ajuda a reduzir o tamanho do EXE.
{****************************************************************}
Essas são apenas algums dicas, não é preciso fazer todas elas, mas caso precise...
Oferecer uma opção de backup para clientes, ou até mesmo alguma outra aplicação, é
sempre um diferencial.
Para esta rotina é necessário ter o componente Indy instalado em seu Delphi.
procedure UploadPerFTP;
procedure GetDir(dir: string);
26
var
SearchRec: TSearchRec;
details, nodetails: TStringList;
k: Integer;
begin
//Pega direito o diretório
if FindFirst(dir + '*.*', faAnyFile, SearchRec) = 0 then
begin
repeat
27
FTPClient.ChangeDirUp;
end
else
begin
//Se é apenas um arquivo, upload o diretório 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 configurações 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;
28
(nodetails.Strings[k] = '.') or
(nodetails.Strings[k] = '..') then
begin
details.Delete(k);
nodetails.Delete(k);
end;
end;
end;
dir := 'C:\your\local\directory\';
if dir[Length(dir)] <> '\' then dir := dir + '\';
GetDir(dir);
FTPClient.Disconnect;
end;
Existem vários métodos em Delphi para gravar arquivos texto a partir de informações
gravadas em bases de dados ou para ler arquivos texto e armazená-los em bases de
dados. Esta dica apresenta um destes métodos: o uso de TextFiles.
Inicialmente para acessar um arquivo de texto, você precisa definir uma variável tipo
TextFile, no local que você achar mais apropriado, da seguinte forma:
29
Antes de se iniciar a leitura do arquivo, precisamos associar a variavel TextFile com um
arquivo fisicamente armazenado no disco:
E também uma rotina quase completa para gravação de um arquivo texto. Esta rotina
recebe como parâmetro o nome do arquivo que será gravado e uma tabela (TTable) de
onde os dados serão lidos:
30
WriteLn ( arq );
tabela.Next;
end;
CloseFile ( arq );
end;
Note nesta segunda rotina, a substituição de Reset por Rewrite logo após o AssignFile.
Rewrite abre o arquivo para escrita, destruindo tudo que houver lá anteriormente .
Note também o uso de Write e WriteLn para gravar dados no arquivo texto.
Finalmente note o uso de AjustaStr e FormatFloat para garantir que campos string e
numericos sejam gravados com um número fixo de caracteres. FormatFloat é uma rotina
do próprio Delphi enquanto AjustaStr está definida abaixo:
O uso da função AjustaStr é fundamental quando você estiver gravando arquivos texto
com registros de tamanho fixo a partir de bases de dados Paradox que usualmente não
preenchem campos string com espaços no final.
{
O caminho normal para se criar uma conexão com o DBExpress no Delphi e no Kylix
é o desenvolvedor colocar um componente TSQLConnection no formulário de com um
duplo clique no componente abrir o editor de conexão e setar os parâmetros (drive,
caminho do banco de dados, nome da conexão, etc) para indicar a conexão.
31
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;
Em defesa do Ctrl+C, Ctrl+V: Eu bem que queria saber quem é que teve a péssima
idéia de condenar a cópia intelectual deslavada, deixando a gente com essa sensação
desconfortável 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 dinâmicas de grupo e de cursos de gestão, as pessoas são pagas para
serem originalíssimas. Estamos na era da tirania da criatividade. A quantidade de
bobagem, de feiúra e de chatice que isso gerou é incalculável. É por isso que, sempre
que posso, tento privar o mundo de minhas desinteressantíssimas particularidades.
Penso que é melhor ter um pouco mais de pudor e não sair mostrando as originalidades
pra todo mundo não. 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ê não tiver esta unit,
visite este site.
32
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;
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;
33
repeat
if hat + (maxy div 24) >= maxy then
begin
hat := maxy
end
else
begin
hat := hat + (maxy div 24);
end;
var
hHookID: HHOOK;
34
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 aplicação.
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);
35
// Window name for menu is #32768
if (lstrcmpi(szClass, MENU_CLASS) = 0) then
begin
MakeWndTrans(cwps.hwnd, N_ALPHA {Alphablending});
end;
end;
end;
end;
// Exemplo de uso:
procedure TForm1.Button1Click(Sender: TObject);
36
begin
if DirectoryIsEmpty('C:\test') then
Label1.Caption := 'empty'
else
Label1.Caption := 'not empty';
end;
Modo de usar:
37
Criando atalhos no Windows pelo Delphi
implementation
uses ShlObj, ActiveX, ComObj;
{$R *.dfm}
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:
38
Faça suas aplicações Falar
Um exemplo que demonstra o uso dos objetos de fala da Microsoft para fazer suas
aplicações tornarem-se falantes.
Para fazer suas aplicações em Delphi FALAR basta baixar o pacote Speech SDK no
site da microsoft.
http://www.microsoft.com/speech
uses Comobj;
http://www.blong.com/Conferences/DCon2002/Speech/SAPI51/SAPI51.htm
Implementation
Uses shellApi;
{$R *.DFM}
39
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.) Faça as devidos ajuste e digite no button:
if opendialog1.execute then
pdf1.src:=opendialog1.filename;
[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]
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
40
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;
}
end;
end;
41
Colocar cursor no final do Edit ao receber o foco
Application.HintColor := clBlack;
42
esta senha, será possível chamar este programa passando-a como parâmetro. Neste caso
sua "trava" estará violada.
Obs. Para que toda a linha fica selecionada você deverá alterar a propriedade Options ->
dgRowSelect para True;
Neste exemplo apresentamos uma rotina para verificar qual a versão do Windows. O
que diferencia esta rotina de outras já apresentadas é que ela consegue distinguir entre
todas as versões do Windows, ou seja, se é Windows 95, 98, ME, NT 4, 2000 ou XP.
43
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;
uses
RpDevice, Printers;
procedure TForm1.Button1Click
(Sender: TObject);
begin
Printer.PrinterIndex := 0;
RPDev.DeviceIndex := Printer.PrinterIndex;
rvTestes.ExecuteReport(‘Rep_Employee’);
end;
{
No terceiro parâmetro da função você pode utilizar uma das opções abaixo
44
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;
implementation
uses ShellApi;
{$R *.dfm}
Usando a Função:
45
end;
end.
O Inno Setup é o instalador oficial do nosso site. Aqui trazemos mais uma dica deste
fantástico gerador de instalações, 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(‘ Não posso instalar! ‘,
mbInformation, MB_OK );
Result := false;
end
else
Result := true;
end;
Isso é muito interessante, por exemplo, para verificar se uma determinada aplicação já
existe no computador do cliente.
Seguindo a linha da automação OLE Office, veja agora como controlar o powerpoint
em uma aplicação delphi
uses
comobj;
46
var
PowerPointApp: OLEVariant;
begin
try
PowerPointApp := CreateOleObject('PowerPoint.Application');
except
ShowMessage('Error...');
Exit;
end;
// Torna o Powerpoint visivel
PowerPointApp.Visible := True;
// Roda a apresentação
PowerPointApp.ActivePresentation.SlideShowSettings.Run;
// Fecha o Powerpoint
PowerPointApp.Quit;
PowerPointApp := UnAssigned;
end;
47
Rave Report - Indicar página inicial
O Rave Reports permite ter várias páginas de relatório (cada página com um layout)
para um mesmo relatório. Neste exemplo, iremos demonstrar como definir via
programação qual página será apresentada como inicial.
uses
RVClass, RVProj, RVCsStd;
procedure TForm1.btnChamaRelClick
(Sender: TObject);
var
Pagina: TRavePage;
Report: TRaveReport;
QualPagina: String;
begin
end;
[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.
48
[Files]
{ Exemplo:
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;
49
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
Como usar:
begin
MemoRedondo(Memo1);
end;
Vamos adicionar em um menu, uma imagem no estilo “banner”. Para isso, adicione no
formulário um Image e carregue uma imagem de sua preferência. Selecione todos os
itens do menu e no evento OnDrawItem digite o seguinte código:
50
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;
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);
51
end;
end;
Imaginemos que o nosso ComboBox possui três ítens. E para cada ítem colocaremos
uma imagem diferente.
No nosso exemplo, serão três elementos. Este vetor deve ser criado como uma variável
"private" (em "private declarations" do form).
private
Img: Array[0..2] of TBitmap;
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;
52
begin
Cmb := (Control as TComboBox);
Off := 0;
Bmp := TBitmap(ComboBox1.Items.Objects[Index]);
Neste mesmo evento fizemos uma chamada a função "BrushCopy", onde o último
parâmetro é 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, porém, uma sugestão é que todas tenham
o mesmo tamanho para que se mantenha um padrão dentro do seu ComboBox.
53
Result := FileExists(FileName);
End;
Exemplo:
ExportRegistry('c:\\windows\\desktop\\teste.reg','HKEY_CURRENT_USER\\Software\\
Borland');
end;
As colunas da DBGrid tem uma propriedade chamada PickList, que permite colocar as
opções numa lista, que serão mostradas quando a coluna é editada.
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, além de gerar um tráfego desnecessário no site, tende a ser desabilitado nos
mailers, por ser um risco de segurança. Outra maneira é embutir a imagem na
mensagem como anexo e ligar o link a ela.
Porém, 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:
54
Imagem := TIdAttachment.Create(MessageParts,
'c:\windows\cafezinho.bmp');
// Aqui estou preenchendo o Content-ID
Imagem.ExtraHeaders.Values['Content-ID'] := '<minhaimagem>';
Imagem.ContentType := 'image/jpeg';
Uma solução para isto é enviar o texto da mensagem como uma parte de texto, com
conteúdo html. Isto é feito criando-se uma variável do tipo TIdText, que será
preenchida com o texto que queremos. Na realidade, iremos criar duas partes de texto na
mensagem: uma normal, não html, que será mostrada em leitores de e-mail não html, e
outra html. Isto é feito da seguinte maneira:
Desta maneira, temos a mensagem com anexos formatada corretamente, podendo ser
vista tanto em leitores texto como html.
55
Mostrando dicas balão para caixas de edição wm WindowsXP
Para mostrar uma dica balão para uma caixa de edição, devemos mandar uma
mensagem EM_SHOWBALLOONTIP para ela. O texto, título e ícone da dica são
mandados prenchendo um record do tipo TEditBalloonTip, definida como:
Uma vez preenchido record, passamos como o terceiro parâmetro para a função
SendMessageW:
var
Form1: TForm1;
implementation
56
{$R *.dfm}
Nota: Esta dica só funciona com os estilos do XP ativados. Assim, você precisa colocar
um componente TXpManifest na sua Form.
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 código 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
57
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]);
implementation
uses Printers;
{$R *.dfm}
58
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;
Verifica se o componente que está com o foco é da classe do TEdit, se for envia um
Texto para esse componente.
59
Verifica se um programa está aberto, caso contrário, abre
Existe uma forma que é pegando o nome da janela. Veja o exemplo abaixo que trabalha
com a calculadora do Windows.
60
Result := TimerLo / (1000.0 * DelayTime);
end;
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 Inscrição'; // campo Inscrição
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
Veja como implementar uma lista Push and Pop (Last In First Out) usando Array e
TList.
61
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
//=============================================================
=================
62
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');
PopItem(List,Nome);
ShowMessage('Retirando '+Nome+' da lista ');
PopItem(List,Nome);
ShowMessage('Retirando '+Nome+' da lista ');
63
PushItem(List,'Carlos');
// Destroi a lista
DestroyList(List);
end;
// Uses rpBars
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 ('Versão do Ms-Excel'+
64
'Incompatível','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 relação do
Excel
begin
valor:= Consulta.Fields[coluna-1].AsString;
excel.cells [linha+2,coluna]:=valor;
end;
Consulta.Next;
end;
65
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}
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;
66
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Screen.OnActiveControlChange := Nil;
end;
Verifica se o componente que está com o foco é da classe do TEdit, se for envia um
Texto para esse componente.
{ Primeiramente temos que ter declarado as variáveis onde serão criado os Objetos
Fields. }
public
Table1Name: TStringField;
Table1Capital: TStringField;
Table1Continent: TStringField;
Table1Area: TFloatField;
Table1Population: TFloatField;
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
67
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;
68
Table1.Open;
except
ShowMessage('Adicione os campos...')
end;
end;
ListBox - Colorir
69
CriaChave(Ext, ‘’, NomeDoc);
CriaChave(NomeDoc+‘\shell\open\command’,‘’,NomeEXE);
CriaChave(NomeDoc + ‘\DefaultIcon’,‘’, NomeIcone);
end;
Nesta dica iremos demonstrar como obter as contas de email registradas na Máquina,
verificando as informações
armazenadas do registrador do Windows.
implementation
uses Registry;
{$R *.DFM}
70
Reg.CloseKey;
Reg.Free;
end;
end;
HKEY, Registry
implementation
uses registry;
71
end;
end;
72
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;
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;
implementation
uses Registry;
{$R *.DFM}
73
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;
Para fazer uma pesquisa incremental no ListBox você irá precisar também de um
componente Edit.
74
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;
Vá em Control Panel -> System -> Clique na aba Advanced -> Clique no botão
Environment Variables. Altere o caminho da variável TMP para um
caminho menor, como por exemplo c:\temp. Confirme se este diretório já está criado.
75
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;
var
nResult : Byte;
begin
asm
mov ah,StRq;
mov dx,Lpt;
Int $17;
mov nResult,ah;
end;
Modo de utilização:
if PrinterOK(0) then
ShowMessage('Impressora OK')
else
ShowMessage('Impressora sem papel ou desligada');
Esta dica vou publicar sem tradução, primeiro porque no original é bem melhor e
segundo para não haver erros.
76
// 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.
77
SelLength := length(text) - selStart;
break; // Match found, so quit search
end;
end; // for
end; // case
end; // with
end;
Esta é uma maneira bem simples de adicionar um checkbox, ou qualquer outro objeto,
num StringGrid
procedure TForm1.AdicionarCheckBoxes;
var i: Integer;
NovoCheckBox: TCheckBox;
begin
limpaBuffer; //é bom não esquecer de limpar controles não 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;
78
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 destruído
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 posição 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;
79
begin
if not (gdFixed in State) then
AlinhaCheck;
end;
80
end;
end;
Apenas a título de curiosidade, este texto explica como criar um programa em Delphi a
partir do zero, usando somente o compilador do Delphi utilizado na linha de comando
(dcc32) e o prompt do dos. Para fazer o programa, você precisará criar dois arquivos :
teste.pas (o programa propriamente dito) e teste.dfm (definicoes do formulario).
Primeiro, crie o programa teste.pas e teste.dfm.
ARQUIVO: teste.pas
-------------------------------------------------------
program teste;
uses windows,sysutils,classes,forms,stdctrls;
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}
begin
application.initialize;
application.createform(tfrm,frm);
application.run;
end.
-------------------------------------------------------
81
ARQUIVO: teste.dfm
-------------------------------------------------------
object frm: tfrm
width = 350
height = 290
caption = 'programa teste'
object button1: tbutton
caption = 'Clique'
left = 20
top = 20
width = 100
height = 30
onclick = button1click
end
end
-------------------------------------------------------
Pense no arquivo .dfm como se fosse a janela de propriedades do objeto. Caso você
queira alterar cor, alinhamento, etc, etc e etc, é só colocar no .dfm. Para compilar,
simplesmente digite na linha do prompt :
dcc32 teste
Pronto. Você terá, no mesmo diretório, um arquivo chamado teste.exe, que é nada mais
que o seu projeto compilado.
82
Usar perfeitamente o LookupComboBox
O campo de ligação entre as duas tabelas pode ser um campo código, pois é este campo
que manterá os valores iguais entre as duas tabelas.
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
83
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 }
84
Escondendo a barra de tarefas do Windows
var
Jan: HWnd;
begin
Jan:= FindWindow(Nil,'Nome_do_projeto');
if Jan <> 0 then ShowWindow(Jan,SW_Hide);
end;
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 }
public
{ Public declarations }
end;
var
Frm_Menu: TFrm_Menu;
implementation
//------------------------------------//
//...Rotina de manipulaco de erros //
//------------------------------------//
85
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;
{$R *.DFM}
End.
uses Wininet
86
ShowMessage('Modem Busy');
end;
end;
Segue abaixo uma função para efetuar a potenciação. É útil para compor formulas
financeiras, como a de VP ("PV" valor presente) VF ("FV" valor futuro)
Exemplo:
Calcular o valor de um produto para o prazo de 30 dias com a taxa de juros de 5% mês.
var
i: Real; // taxa de juros
valor: Real; // valor base para calculo do valor futuro.
pz: Integer // prazo em dias
begin
i := 5//100;
valor:= 1000.00
pz := 30
Result:= valor*( Pot( (1+i), (pz/30) ) //Resultado 1.050,00
end;
no excel a Pot é substituída pelo sinal ^ Ex. =E18*((1+C19)^(C20/30))
Dica: Não amplie o nome da função, pois as funções financeiras costumam ser bem
extensas.
87
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;
Criptografando Imagens
88
P^[w] := P^[w] xor Random(256);
end;
end;
Agora vamos ao evento onclick do Button chamar a nossa procedure cripto, basta
digitar o seguinte código:
No caso, somente os registros com salário maior que R$ 10.000,00 ficarão com cor
vermelha e em negrito.
89
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;
Para testar este exemplo inclua no seu form alguns componentes. Nestes componentes
coloque informações na propriedade Hint de cada componente e altere a propriedade
ShowHint para True.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
90
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}
Var
91
F:TextFile;
Begin
AssignFile(f,'c:\qq_arquivo.txt');
Rewrite(f); //abre o arquivo para escrita
var
f:TextFile;
linha:String;
begin
AssignFile(f,'c:\qq_arquivo.txt');
Reset(f); //abre o arquivo para leitura;
Closefile(f);
end;
92
Mudando o IP da máquina via API do Windows
A resposta para essa pergunta é não neste artigo estou unsando o Delphi 7,
mas pode ser feito com qualquer outra versão do delphi. nos Windows 2000 e XP
existe um aplicativo chamado NETSH que faz essa mudança para nós sem que
precisemos reiniciar o computador. bem vamos por a mão na massa e brincarmos um
pouco com as configurações de IP.
if Win32Plataform =
VER_PLATAFORM_WIN32_NT then WinExec('cmd /c netsh interface ip set address
"Conexão local" DHCP', SW_SHOWNORMAL) else MessageBox(Handle, 'esse
Comando não pode ser rodado fora da plataforma NT', 'NETSH',
MB_ICONWARNING);
{onde verifico se a plataforma do Programa é uma plataforma NT, caso contrário
informo ao usuário que esse comando não pode ser rodado fora de uma plataforma
NT.
Pronto seu IP, SubnetMask e Gateway foram mudados. Para maiores informações sobre
o NETSH visite o site da Microsoft:
Suporte Microsoft.
93
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 Informática');
//Sleep(10); Este pode cria um Delay na execução
end;
tf.Free;
end;
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;
94
Como colocar uma coluna do DBGrid em maiuscula
Aqui iremos demonstrar como colorir e alinhar o texto de uma coluna do DBGrid com
base em uma condição.
implementation
implementation
{$R *.DFM}
95
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;
96
if cdsExemplo.State = dsBrowse then
cdsExemplo.Edit;
cdsExemploSituacao.AsBoolean := not cdsExemploSituacao.AsBoolean;
end;
end;
O código 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,
97
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;
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
98
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;
Quando você está trabalhando com um objeto TList e quer ordenar os itens baseados um
critério seu, pode usar o código abaixo.
O exemplo a seguir mostra como ordenar os itens em ordem alfabética baseado nos
nomes. Ele assume que a lista contém apenas referências para as variáveis do tipo
TMyListItem, onde TMyListItem é definida como:
type
TMyListItem = record
Points : Integer;
Name: string[255] ;
end;
99
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.
}
100
Executando o programa shutdown.exe do Windows:
run %Windir%\system32\shutdown.exe
Example :
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}
101
result := False;
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;
end.
102
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 alguém queira pegar a versão que também trabalha com o FastReport recomendo
que acesse o site do fabricante no seguinte link: http://usuarios.lycos.es/isma
Na janela que será aberta indique o caminho onde estão os arquivos .pas do componente
e depois clique em Add e em seguida em Ok.
Para isso podemos colocar um botão no form de preview e neste botão colocar a
seguinte instrução:
Esses códigos acima podem ser encontrados no projeto de Exemplo1 que acompanha o
componente ExportQR.
103
Outros formatos:
A exportação dos relatórios para os demais formatos é bastante simples também, veja
abaixo as sintaxes utilizadas para cada tipo:
JPG
EXQR.ExportQRJPG(edFileName.Text);
BMP
EXQR.ExportQRBMP(edFileName.Text);
WMF
EXQR.ExportQRWMF(edFileName.Text);
EMF
EXQR.ExportQREMF(edFileName.Text);
Esses códigos acima podem ser encontrados no projeto de Exemplo3 que acompanha o
componente ExportQR.
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);
104
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
Onde:
105
Memo1.Handle = manipulador da janela do Memo1.
WM_VSCROLL = Mensagem do Windows - rolagem vertical.
SB_PAGEDOWN = Comanndo de rolagem - página para baixo.
Outros exemplos:
Observações: Além desta técnica existem API's do Windows que fazem um trabalho
equivalente.
O componente DBGrid não tem o evento OnClick no Object Inspector. Mas podemos
utilizá-lo através de uma instancia da classe THack.
type
THack = class(TControl);
Depois na seção Private declare a nova procedure que utilizaremos no evento OnClick:
private
{ Private declarations }
procedure DBGridClick(Sender: TObject);
Agora crie a procedure que declaramos na seção private.
procedure TForm1.DBGridClick
(Sender: TObject);
begin
ShowMessage(‘O conteúdo desta célula é ‘
+TDBGrid(Sender).SelectedField.AsString);
end;
Para utilizarmos esta procedure temos que fazer a sua ligação no evento OnCreate do
form. Veja o código abaixo:
106
Alterando a cor dos TabSheet de um PageControl
uses UrlMon;
procedure TForm1.Button1Click(Sender: TObject);
begin
HlinkNavigateString(nil, ’http://www.theclub.com.br’);
end;
Para mudar o título da barra de título da janela de Preview de seus relatórios, use o
seguinte comando:
107
type
TDBNewNavigator = class(TDBNavigator);
Suponha que você esteja no Form1 e precise chamar o Form2 passando dois parametros
("Verde" e "Amarelo").
type
TForm2 = class(TForm)
private
Parametro1 : String;
Parametro2 : String;
public
constructor Create(AOwner : TComponent; pPar1, pPar2 : String);
end;
var
108
Form2: TForm2;
implementation
O aumento do tempo de carga do aplicativo pode ser resolvido pela simples remoção do
código que o Delphi gerou para a criação do formulário.
109
Se você quer saber onde está este código, clique em View|Units (ou use Ctrl-F12) e
selecione o seu projeto na lista de units que aparecerá. O código que cria formulários é
algo mais ou menos como se segue:
Application.CreateForm(TForm1, Form1);
Cada formulário auto-criado terá uma linha como esta. Quando o formulário passa para
o painel de ‘Available forms’, a linha correspondente é removida. Você também pode
simplesmente remover a linha manualmente, usando o editor de textos.
Você deve ter extremo cuidado ao usar esta técnica. Se você tirar o código de criação
automática do formulário e tentar executar o Show ou ShowModal você vai receber um
erro do tipo ‘Access Violation’. Tome cuidado e faça isto um formulário por vez.
Atenção! Não faça isto para o seu formulário principal. O formulário principal precisa
ser o primeiro formulário a ser criado. Assim é melhor mantê-lo como auto-criado.
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
110
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
{
}
Const
Servico_Simples = 1;
Servico_Unregister = 1;
111
try
Reg.WriteString
(‘Start Page’,endereco);
result := true;
finally
Reg.CloseKey;
result := True;
end;
except
result := false;
end;
finally
Reg.Free;
end;
end;
112
Arredondar casas decimais de forma personalizada
Function Arredondar
(value: double;casas : integer): double;
Como usar...
Ex:Var valor,Resultado:real;
Valor:=10.005.526
Resultado :=Arredondar(valor,2);
Resultado=10.005,53
113
Obs: O codigo foi escrito em Delphi 6 porém isso não a impede de funcionar no Delphi
4 ou 5, é pouco provavel que ocorra erro.
var
vList: TStringList;
x: Integer;
begin
vList := TStringList.Create;
Session.Open;
Session.GetAliasNames(vList);
if vList.Find(‘NomeDoAlias’, x) then // x receberá a posição do alias na lista
// Alias encontrado
else
// Alias não encontrado
end;
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;
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;
114
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 código 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;
115
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;
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
116
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;
{*****************************************}
// Outra função de print screen function:
// Captura a tela inteira
procedure ScreenShot(x: Integer;
y: Integer;
Width: Integer;
Height: Integer;
bm: TBitMap);
117
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;
118
{****************************************}
// 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,
119
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 solução bem simples é fazer pequenas
capturas e colar o resultado unindo tudo. Não é a velocidade da luz, mas é mais rápido
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,
120
Succ(Y) * cTileSize);
Result.Canvas.CopyRect(R, Canvas, R);
end;
finally
if Locked then
Canvas.Unlock;
ReleaseDC(0, Canvas.Handle);
Canvas.Free;
end;
end;
private
procedure WMNCHitTest(var msg: TWMNCHitTest); message WM_NCHITTEST;
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
121
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;
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
122
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 necessário para o texto com várias linhas
var
i, PosSp: Integer;
strVal: string;
strTmp: string;
begin
if Index >= 0 then
begin
strVal := Combobox1.Items[Index];
// coloque a string em várias linhas,
// cada linha separada por #$D#$A
strTmp := WrapText(strVal, 20);
// Número de separadores de linha
// + 1 = número 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, então sera feito
var
strVal: string;
strTmp: string;
intPos: Integer;
i: Integer;
rc: TRect;
begin
strVal := WrapText(Combobox1.Items[Index], 20);
i := 0;
123
Combobox1.Canvas.FillRect(Rect);
// saída 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;
// faça um retangulo em volta do texto
Combobox1.Canvas.Rectangle(Rect);
end;
end.
{....}
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),
124
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;
125
Como mostrar Menu Item Hints
É comum usar o evento OnHint nas variáveis globais da aplicação, nas aplicações
Delphi, para mostrar os hints do menu como uma barra de status.
Se você quer adicionar itens de menu com popup hints nos menus de sua aplicação
Delphi você precisa “somente” apontar a mensagem WM_MenuSelect corretamente.
Segue como criar a classe TMenuItemHint – uma janela hint que realmente é exibida
nos itens de menu.
type
TForm1 = class(TForm)
...
private
procedure WMMenuSelect(var Msg: TWMMenuSelect) ; message
WM_MENUSELECT;
end
...
implementation
...
procedure TForm1.WMMenuSelect
(var Msg: TWMMenuSelect) ;
var
126
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*)
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
127
(menuItem : TMenuItem) ;
destructor Destroy; override;
end;
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 após um
intervalo específico.
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) ;
128
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
// é atribuído)
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
129
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
//força a remoção 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;
130
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) ;
ActivateHint(r,activeMenuItem.Hint) ;
end;
showTimer.OnTimer := nil;
end; (*ShowTime*)
end
131
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 estão 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;
132
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.
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;
133
procedure TForm1.Button1Click
(Sender: TObject) ;
begin
WBViewSourceDialog(WebBrowser1) ;
end;
Aqui está como chamar um Message Box com timeout, ele irá fechar a si mesmo após
um período de tempo. O truque é chamar uma API não documentada localizada no
user32.dll, a API é a MessageBoxTimeOut.
A função retorna um valor inteiro para MB_TIMEDOUT (indicando que o período de
tempo para o timeout foi alcançado e o Message Box foi automaticamente fechado), ou
um valor representando o botão que o usuário clicou. Observe que o valor retornado é
sempre 1, quando o Message Box tem somente um botão de OK (MB_OKFlag).
//declaração 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’;
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) ;
134
de 5 segundos.’, ‘MessageBoxTimeout
Teste’, iFlags, 0, 5000) ;
case iRet of
IDYES:
ShowMessage(‘Yes’) ;
IDNO:
ShowMessage(‘No’) ;
MB_TIMEDOUT:
ShowMessage(‘TimedOut’) ;
end;
end;
Vamos dizer que você tem um dialog box padrão do Windows mostrando uma pergunta
ao usuário com os botões de “Yes” e “No”. Não seria ótimo se existisse uma barra de
progresso contando o tempo até que o dialog box se feche automaticamente?
Vamos lá então:
Vamos criar um dialog usando CreateMessageDialog. Esta função retornará um form
object com o dialog. Neste objeto podemos adicionar a barra de progresso. Também
podemos adicionar um objeto Timer para uma atualização dinâmica da posição da barra
de progresso. Mostramos o dialog com ShowModal. Apontamos o evento OnTimer do
componente TTimer para ver o número se passou a quantidade de segundos necessária,
se sim, fechamos o dialog ajustando a propriedade ModalResult, no código, para
mrCancel. Se não, usamos StepIt para atualizar a barra de progresso.
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!
135
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;
136
Como imprimir uma página/documento com o TWebBrowser
Você primeiro precisa carregar uma página no TWebBrowser, por exemplo (supondo
que você tem um componente chamado WebBroser1):
WebBrowser1.Navigate(‘http://theclub.activeinterno.com.br’);
Aqui está um código exemplo de como esconder o text cursor no Memo1 dentro do
Form1.
Substitua todo o código pelo que segue abaixo:
137
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;
implementation
{$R *.DFM}
procedure TForm1.WMMYMEMOENTER
(var Message: TMessage) ;
begin
CreateCaret(Memo1.Handle,0,0,0) ;
end;
138
CreateCaret(Memo1.handle,0,0,0) ;
end;
end.
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) ;
Observação: O evento OnKeyPress não faz nada quando o usuário pressiona Delete.
Neste caso deve-se capturar a tecla utilizando-se o evento OnKeyDown.
139
TmpStr: string;
begin
{ primeiro, processe a tecla para obter
a string corrente }
Found := False;
for j := 1 to Items.Count do
if Copy(Items[j-1],1,Length(TmpStr)) =
TmpStr then
begin
140
Text := Items[j-1]; { atualize para a
correspondente que foi encontrada}
ItemIndex := j-1;
Found := True;
Break;
end;
if Found then { selecione o final não
digitado da string }
begin
SelStart := SelSt;
SelLength := Length(Text)-SelSt;
end
else Beep;
end;
end;
// arredondando o Memo1
Memo1.BorderStyle := bsNone;
DrawRounded(Memo1) ;
// arredondando o Edit1
Edit1.BorderStyle := bsNone;
141
DrawRounded(Edit1) ;
end;
As teclas Up e Down são virtualmente inúteis em controles Edit. Então, porque não usá-
las para navegar entre os controles? Se você ajustar a propriedade KeyPreview de um
form para True você pode usar o seguinte código no seu evento OnKeyDown do
formulário para controlar a navegação:
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;
Aqui está o código para você saber qual a palavra que está sob o cursor do mouse.
A variável string WordInRE conterá a palavra.
Observação:
Você precisará de um TRichEdit (RichEdit1), um form (Form1), e o código abaixo no
evento OnMouseMove do RichEdit1.
142
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;
143
Mostra o total de páginas
Você pode fazer este tipo de trabalho, mas ele terá que ser manual. O primeiro passo é
pegar o total de páginas e jogar para uma variável. Para pegar o total de páginas você
pode executar o código abaixo antes de chamar o relatório.
QuickRep1.Prepare;
TotalPaginas := QuickRep1.PageNumber;
procedure TForm1.QRSysData1Print
(sender: TObject; var Value: String); begin
Value := Value + ‘/’ + IntToStr(TotalPaginas) end;
O InnoSetup permite a inclusão de scripts em uma sua seção “CODE” e isso sem
dúvidas permite grande flexibilidade no desenvolvimento de instalações personalizadas.
Abaixo, segue um script para o InnoSettup onde demonstramos como efetuar este tipo
de verificação.
[Setup]
AppName=VerificaVersao
AppVerName=VerificaVersao
DefaultDirName={pf}\VerificaVersao
DisableStartupPrompt=true
Uninstallable=false
DisableDirPage=true
OutputBaseFilename=VerificaVersao
[Code]
144
(‘{win}\notepad.exe’) , sVersion );
Result := sVersion;
end;
[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;
145
{ ‘Regrava’ o arquivo }
SaveStringsToFile(strFilename, a_strTextfile, False);
Result := True;
end;
implementation
Uses Tlhelp32;
{$R *.dfm}
146
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;
end;
Gravando CDs
No caso do QReport, o mesmo possui uma tipagem própria com nomes dos papeis que
não coincidem com os tipos pré-definidos no Windows. Assim sendo, adicione estes
valores “fixos” ao seu ComboBox, pois, estes são dos tipos possível aceitos pelo QR:
implementation
uses QrPrNtr, TypInfo;
{$R *.dfm}
147
begin
Paper := TQRPaperSize(GetEnumValue(TypeInfo
(TQRPaperSize),PaperName));
QR.Page.PaperSize := Paper;
end;
{ 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
148
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 padrão para as linhas }
TGrid(DBGrid1).DefaultRowHeight := 50;
end;
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
149
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;
end.
var
Attributes: Word;
begin
Attributes := FileGetAttr(‘d:\arquivo.txt’);
if (Attributes and faReadOnly) = faReadOnly then
ShowMessage(‘ReadOnly’);
end;
type
TGrid = class(TCustomDBGrid);
var
Form1: TForm1;
150
implementation
{$R *.dfm}
Treeview – Foco
Veja neste exemplo como mandar o foco à um ítem do treeview quando clicar no botão
de expansão (+):
procedure TForm1.TreeView1MouseDown
(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
T: TTreeNode;
begin
// Pega o ítem através das coordenadas do mouse.
T := Treeview1.GetNodeAt(X,Y);
if T <> nil then
Treeview1.Selected := T;
end;
O Rave Reports permite ter várias páginas de relatório (cada página com um layout)
para um mesmo relatório. Neste exemplo, iremos demonstrar como definir via
programação qual página será apresentada como inicial.
uses
RVClass, RVProj, RVCsStd;
procedure TForm1.btnChamaRelClick
(Sender: TObject);
var
Pagina: TRavePage;
Report: TRaveReport;
QualPagina: String;
begin
151
// Abre RvProject.
RvProject1.Open;
// Pega referência do “Report”
// dentro do projeto Rave.
Report := RvProject1.ProjMan.ActiveReport;
// Pega referência da “Page” dentro do “Report”.
Pagina := RvProject1.ProjMan.FindRaveComponent
(‘Report1.’+QualPagina,nil) as TRavePage;
// Indica a página inicial.
Report.FirstPage := Pagina;
// Executa o relatório.
RvProject1.Execute;
end;
Esta dica pode ser útil após a instalação de sua aplicação, onde geralmente é
disponibilizado um ícone na área de trabalho do Windows e em muitos casos sendo
necessário arranjá-los após a instalação.
mplementation
uses CommCtrl;
{$R *.dfm}
152
Cálculo de Parcelas
153
Exit
else
NParc := speParcelas.Value;
Existem APIs do Windows que possibilitam fazer acesso e manutenção à 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
154
ShowMessage(‘Porta em uso!’)
else
raise Exception.Create
(‘Não consegui abrir a porta!’);
end;
Neste exemplo, estamos utilizando o objeto TGifImage que é instalado junto com a
suite de componentes RxLib. Esta suite é gratuíta e possui vários componentes bem
legais e, caso haja interesse, poderá baixar em nosso site, theclub.activeinterno.com.br.
Abaixo, segue a rotina de conversão:
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;
Neste exemplo, iremos demonstrar uma forma bastante simples para criar:
- Grupos de programas
- Items de programas
- Atalhos para programas
Em nossa abordagem, não iremos utilizar a criação via interface DDE por alguns
questões de parametrização e sim, demonstraremos a partir da criação direta de
“folders” na pasta “Programs” do Windows.
155
Primeiramente, vamos criar uma procedure para criação de atalhos:
implementation
uses ShlObj, ActiveX, ComObj;
{$R *.dfm}
IObject := CreateComObject(CLSID_ShellLink);
ISLink := IObject as IShellLink;
IPFile := IObject as IPersistFile;
with ISLink do
begin
SetPath(pChar(TargetName));
SetWorkingDirectory(pChar(ExtractFilePath(TargetName)));
end;
s := InFolder;
LinkName := s + ‘\’ + aPathGroup + ‘\’ +
aNome + ‘.LNK’;
IPFile.Save(PWChar(LinkName), false);
end;
Esta procedure recebe como parâmetro o Nome do atalho a ser apresentado, o caminho
e nome do aplicativo a ser executado, e por último o grupo ao qual ele irá pertencer no
menu Iniciar do Windows.
156
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 parâmetro o nome do grupo (que na realidade
será o nome de um “Folder” e a localização, ou seja, onde ele deverá ser criado.
Exemplo de utilização:
157
Este exemplo está disponível para download em nosso site no endereço:
http://theclub.activeinterno.com.br/revista/download/CriaGrupoAtalho.zip
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}
158
begin
if ssCtrl in Shift then
begin
SetCapture(Button1.Handle);
Capturing := true;
MouseDownSpot.X := x;
MouseDownSpot.Y := Y;
end;
end;
implementation
{$R *.DFM}
type
TMostraProp = class (TDBGrid);
159
{evento OnColEnter do DBGrid}
procedure TForm1.DBGrid1ColEnter(Sender: TObject);
begin
Caption := Format(‘Coluna: %2d; Row: %2d’,
[TMostraProp(DbGrid1).Col, TMostraProp(DbGrid1).Row]);
end;
Para testar, bastará por exemplo em um botão, gerar uma exceção de divisão por zero:
160
procedure TForm1.Button1Click(Sender: TObject);
var
a, b, c: Integer;
begin
a := 10;
b := 0;
c := a div b;
ShowMessage(IntToStr(c));
end;
uses
Printers, WinSpool;
161
end;
end;
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,
162
‘null’,
null’);
Inc(PrinterInfo,SizeOf(TPrinterInfo5));
end;
end;
end;
finally
FreeMem(Buffer, Count);
end;
end;
end;
GetPrinterList(LView);
Em muitas situações, necessitamos saber o nome de uma máquina e temos apenas seu
endereço IP. Na unit WinSock, poderemos encontrar diversas APIs para este tipo de
abordagem, veja abaixo um simples exemplo:
implementation
uses WinSock;
{$R *.dfm}
Result := ‘’;
163
try
Address := Trim(IP);
if Address = ‘’ then
raise Exception.Create
( ‘IP address not entered’ );
except
on E: Exception do begin
Beep();
ShowMessage( E.Message );
end;
end;
WSACleanUp();
end;
Para utilizar:
Uma das formas para fazer a criação de grupos e subgrupos de aplicativos no menu
iniciar do Windows, é obtendo o path de sistema onde o Windows guarda estas
informações e nele criar os grupos. Veja abaixo como proceder:
implementation
uses ShlObj, FileCtrl;
{$R *.dfm}
164
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;
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;
165
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.
Porém, no Windows XP isso é um pouco diferente, pois não há um papel pré-definido como
personalizado, porém temos a opção 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 opção “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!
166
Bom, agora bastará acessar as propriedades da impressora e definir este novo papel nas
configurações de sua impressora, como exemplo:
Poderá utilizar o objeto TSearchRec para obter o número de arquivos em um dado diretório:
implementation
{$R *.dfm}
function GetTotFiles(Diretorio: String): Integer;
var
SRec: TSearchRec;
167
Res: Integer;
begin
Result := 0;
Res := FindFirst(Diretorio+’\*.*’, faAnyFile, SRec);
while Res = 0 do
begin
Res := FindNext(SRec);
Inc(Result);
end;
end;
168