function MacAddress: string;
var
Lib: Cardinal;
Func: function(GUID: PGUID): Longint; stdcall;
GUID1, GUID2: TGUID;
begin
Result := '';
Lib := LoadLibrary('rpcrt4.dll');
if Lib <> 0 then
begin
@Func := GetProcAddress(Lib, 'UuidCreateSequential');
if Assigned(Func) then
begin
if (Func(@GUID1) = 0) and
(Func(@GUID2) = 0) and
(GUID1.D4[2] = GUID2.D4[2]) and
(GUID1.D4[3] = GUID2.D4[3]) and
(GUID1.D4[4] = GUID2.D4[4]) and
(GUID1.D4[5] = GUID2.D4[5]) and
(GUID1.D4[6] = GUID2.D4[6]) and
(GUID1.D4[7] = GUID2.D4[7]) then
begin
Result :=
IntToHex(GUID1.D4[2], 2) + '-' +
IntToHex(GUID1.D4[3], 2) + '-' +
IntToHex(GUID1.D4[4], 2) + '-' +
IntToHex(GUID1.D4[5], 2) + '-' +
IntToHex(GUID1.D4[6], 2) + '-' +
IntToHex(GUID1.D4[7], 2);
end;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
JanelaPrincipal, JanelaFilha: THandle;
I: integer;
Texto: string;
begin
Texto := 'Daniel';
JanelaPrincipal := FindWindow('Notepad', nil);
if JanelaPrincipal > 0 then
begin
JanelaFilha := FindWindowEx(JanelaPrincipal, 0, 'Edit', nil);
if JanelaFilha > 0 then
begin
for I := 1 to Length(Texto) do
PostMessage(JanelaFilha, WM_CHAR, Ord(Texto[I]), 0);
end;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
type
TMeuDBNavigator = class(TDBNavigator);
procedure TForm1.FormCreate(Sender: TObject);
const
Legendas: array[TNavigateBtn] of string = (
'Primeiro', 'Anterior', 'Próximo', 'Último',
'Incluir', 'Excluir', 'Editar', 'Salvar',
'Cancelar', 'Atualizar');
var
Botao: TNavigateBtn;
begin
for Botao := nbFirst to nbRefresh do
begin
with TMeuDBNavigator(DBNavigator1).Buttons[Botao] do
begin
Caption := Legendas[Botao];
Layout := blGlyphTop;
end;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
É muito comum encontrar programadores Delphi que têm dúvidas sobre como arredondar um valor real para "n" casas após o separador decimal. A princípio parece um problema simples, pois o próprio Delphi já possui uma função que arredonda para o inteiro mais próximo, a qual poderia facilmente ser utilizada para arredondar para qualquer quantidade de casas decimais. Exemplo:
{ x receberá o valor de y arredondado para 2 casas após o separador. }
x := Round(y * 100) / 100;
{ z receberá o valor de y arredondado para 3 casas após o separador. }
z := Round(y * 1000) / 1000;
No entanto dois problemas poderão aparecer com os exemplos acima:
A função abaixo resolve estes dois problemas.
{ Esta função faz arredondamento de valores reais para "n" casas
decimais após o separador decimal, seguindo os critérios das
calculadoras financeiras e dos bancos de dados InterBase e FireBird.
}
function TBRound(Value: Extended; Decimals: integer): Extended;
var
Factor, Fraction: Extended;
begin
Factor := IntPower(10, Decimals);
{ A conversão para string e depois para float evita
erros de arredondamentos indesejáveis. }
Value := StrToFloat(FloatToStr(Value * Factor));
Result := Int(Value);
Fraction := Frac(Value);
if Fraction >= 0.5 then
Result := Result + 1
else if Fraction <= -0.5 then
Result := Result - 1;
Result := Result / Factor;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
function CalcAnos(const Data1, Data2: TDateTime): integer;
var
D1, M1, A1,
D2, M2, A2: Word;
begin
DecodeDate(Data1, A1, M1, D1);
DecodeDate(Data2, A2, M2, D2);
Result := A2 - A1;
if (M1 > M2) or ((M1 = M2) and (D1 > D2)) then
Dec(Result);
end;
var DataNasc: TDateTime; begin DataNasc := StrToDate(Edit1.Text); ShowMessage(IntToStr(CalcAnos(DataNasc, Date)) + ' anos'); end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Programe o evento OnDrawColumnCell do DBGrid como abaixo:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
begin
if State = [] then
begin
if Table1.RecNo mod 2 = 1 then
DBGrid1.Canvas.Brush.Color := clAqua
else
DBGrid1.Canvas.Brush.Color := clWhite;
end;
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
Observação:
O objeto Table1 é da classe TTable (relativa ao BDE), mas esta dica poderá ser usada com outros DataSet's, tais como IBDataSet, ClientDataSet, etc.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Tenho um cadastro de clientes com Codigo, Nome, DataNasc, etc.
Preciso fazer uma consulta onde apareceão apenas os clientes
que fazem aniversário em determinado mês. Como fazer?
Solução:
Use uma Query como abaixo:
- Coloque no form os seguintes componentes:
* TQuery
* TDataSource
* TDBGrid
* TEdit
* TButton
- Altere as propriedades dos componentes como abaixo:
* Query1.DatabaseName = (alias do BDE)
* DataSource1.DataSet = Query1
* DBGrid1.DataSource = DataSource1
- Coloque o código abaixo no evento OnClick de Button1:
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select * from dCli');
Query1.SQL.Add('where extract(month from DataNasc) = :Mes');
Query1.ParamByName('Mes').AsInteger := StrToInt(Edit1.Text);
Query1.Open;
- Execute. Digite um número de 1 a 12 no Edit e clique no
botão.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Alguns programas mostram o Edit que está com o foco em uma
cor diferente dos demais. Como fazer isto em Delphi?
Na seção private do form declare o procedimento abaixo:
private
procedure MudancaDeFoco(Sender: TObject);
public
end;
Na seção implementation, escreva o código do procedimento:
{ Esta rotina será chamada através do evento OnExit (perda do foco)
de todos os componentes do tipo TEdit que existirem no form. }
procedure TForm1.MudancaDeFoco(Sender: TObject);
var
I: integer;
Ed: TEdit;
begin
{ Percorre a matriz de componentes do form }
for I := 0 to ComponentCount - 1 do
{ Se o componente é do tipo TEdit... }
if Components[I] is TEdit then
begin
{ Faz um type-casting pata o tipo TEdit }
Ed := Components[I] as TEdit;
{ Se o Edit está com o foco... }
if Ed.Focused then
Ed.Color := clYellow { Amarelo }
else
Ed.Color := clWhite; { Branco }
end;
end;
No evento OnCreate do Form, coloque o código abaixo:
procedure TForm1.FormCreate(Sender: TObject);
var
I: integer;
begin
{ Percorre a lista de componentes do form (matriz de componentes)
e verifica cada componente para saber se é um TEdit. Se for,
associa o evento OnExit do componente com a procedure
"MudancaDeFoco". }
for I := 0 to ComponentCount - 1 do
if Components[I] is TEdit then
(Components[I] as TEdit).OnExit := MudancaDeFoco;
end;
No evento OnActivate coloque:
procedure TForm1.FormActivate(Sender: TObject);
begin
{ Esta chamada é necessária para que o estado inicial seja
controlado. }
MudancaDeFoco(nil);
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Para selecionar um item no ListView via programação use
o código abaixo.
{ Manda o foco para o ListView }
ListView1.SetFocus;
{ Seleciona o quarto item }
ListView1.Items.Item[3].Selected := true;
{ Manda o foco para o quarto item }
ListView1.Items.Item[3].Focused := true;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
1. Coloque no formulário um componente TStringGrid.
2. No evento OnCreate do formulário escreva:
procedure TForm1.FormCreate(Sender: TObject);
begin
{ Número de linhas }
StringGrid1.RowCount := 5;
{ Número de colunas }
StringGrid1.ColCount := 3;
{ Linhas fixas }
StringGrid1.FixedRows := 1;
{ Colunas fixas }
StringGrid1.FixedCols := 0;
{ Largura padrao das colunas (em pontos) }
StringGrid1.DefaultColWidth := 80;
{ Permite editar }
StringGrid1.Options :=
StringGrid1.Options + [goEditing];
{ Cabeçalho }
StringGrid1.Cells[0,0] := 'Esquerda';
StringGrid1.Cells[1,0] := 'Centro';
StringGrid1.Cells[2,0] := 'Direita';
end;
3. No evento OnDrawCell do StringGrid escreva:
var
LarguraTexto, AlturaTexto, X, Y: integer;
Texto: string;
begin
{ Pega o texto da célula }
Texto := StringGrid1.Cells[ACol, ARow];
{ Calcura largura e altura (em pontos) do texto }
LarguraTexto := StringGrid1.Canvas.TextWidth(Texto);
AlturaTexto := StringGrid1.Canvas.TextHeight(Texto);
{ Calcula a posição horizontal do início do texto }
if ACol = 0 then { Esquerda }
X := Rect.Left + 2
else if ACol = 1 then { Centro }
X := Rect.Left + (Rect.Right - Rect.Left) div 2 -
LarguraTexto div 2
else { Direita }
X := Rect.Right - LarguraTexto - 2;
{ Calcula a posição vertical do início do texto para
que seja impresso no centro (verticalmente) da célula }
Y := Rect.Top + (Rect.Bottom - Rect.Top) div 2 -
AlturaTexto div 2;
{ Pinta o texto }
StringGrid1.Canvas.TextRect(Rect, X, Y, Texto);
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
O próprio componente TEdit possui um método para copiar o texto para a área de transferência (clipboard). No entanto este método copia apenas o texto selecionado, de forma que temos que chamar o método SelectAll() antes de chamar CopyToClipboard(). Veja o exemplo: procedure TForm1.Button1Click(Sender: TObject); begin Edit1.SelectAll; Edit1.CopyToClipboard; end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Esta é uma boa dica para quem deseja fazer aplicativos para exibir fotografias.
1. Coloque no form um TButton e um PaintBox.
2. No evento OnClick do Button escreva:
procedure TForm1.Button1Click(Sender: TObject);
var
I, J: integer;
R: TRect;
Bmp: TBitmap;
begin
Bmp := TBitmap.Create;
try
Bmp.LoadFromFile('c:\teste\imagem.bmp');
PaintBox1.ClientWidth := Bmp.Width;
PaintBox1.ClientHeight := Bmp.Height;
PaintBox1.Canvas.FillRect(PaintBox1.ClientRect);
R.Left := 0;
R.Right := Bmp.Width -1;
for I := 1 to 10 do begin
J := I - 1;
while J < (Bmp.Height -1) do begin
R.Top := J;
R.Bottom := J+1;
PaintBox1.Canvas.CopyRect(R, Bmp.Canvas, R);
J := J + 10;
end;
Sleep(50);
end;
finally
Bmp.Free;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
O procedimento abaixo converte um arquivo de imagem JPeg
para Bitmap. O arquivo Bitmap terá o mesmo nome do arquivo JPeg, mas com a extensão bmp.
procedure ConverterJPegParaBmp(Arquivo: string);
var
JPeg: TJPegImage;
Bmp: TBitmap;
begin
JPeg := TJPegImage.Create;
try
JPeg.LoadFromFile(Arquivo);
Bmp := TBitmap.Create;
try
Bmp.Assign(JPeg);
Bmp.SaveToFile(ChangeFileExt(Arquivo, '.bmp'));
finally
Bmp.Free;
end;
finally
JPeg.Free;
end;
end;
Exemplo de uso:
ConverterJPegParaBmp('c:\diretorio\arquivo.jpg');Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
O procedimento abaixo converte um arquivo de imagem Bitmap
para JPeg. O arquivo JPeg terá o mesmo nome do arquivo Bitmap,
mas com a extensão jpg.
procedure ConverterBmpParaJPeg(Arquivo: string);
var
Bmp: TBitmap;
JPeg: TJPegImage;
begin
Bmp := TBitmap.Create;
try
Bmp.LoadFromFile(Arquivo);
JPeg := TJPegImage.Create;
try
JPeg.CompressionQuality := 100; { Qualidade: 100% }
JPeg.Assign(Bmp);
JPeg.SaveToFile(ChangeFileExt(Arquivo, '.jpg'));
finally
JPeg.Free;
end;
finally
Bmp.Free;
end;
end;
Exemplo de uso:
ConverterBmpParaJPeg('c:\diretorio\arquivo.bmp');
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Existem alguns casos em que precisamos levar para a máquina
do usuário, além do EXE, alguns arquivos sem os quais nossa
aplicação teria problema. Normalmente estes casos incluem:
- arquivos com imagem (bmp, jpeg, gif, etc);
- arquivos de fontes (TTF);
- bibliotecas (dll);
- e outros.
A partir desta dica você saberá como incluir tais arquivos
dentro do próprio EXE. Dentro do EXE podemos colocar qualquer
tipo de arquivo que se comportará como um recurso. Vamos aos
passos.
1. Crie um arquivo texto com o nome ARQ_RECURSO.RC e escreva
neste arquivo a linha abaixo:
NOME_DO_RECURSO RCDATA "c:\diretorio\arquivo.ext"
2. Compile este arquivo de recurso com o programa BRCC32.EXE:
BRCC32 ARQ_RECURSO.RC
3. Confira se foi criado um arquivo chamado ARQ_RECURSO.RES.
4. Abra um novo projeto no Delphi.
5. Salve o projeto no mesmo diretório de ARQ_RECURSO.RES.
5. Escreve a linha abaixo após a palavra implementation
{$R ARQ_RECURSO.RES}
6. Escreva o evento OnCreate do form como abaixo:
procedure TForm1.FormCreate(Sender: TObject);
var
Stream: TResourceStream;
begin
Stream := TResourceStream.Create(hInstance,
'NOME_DO_RECURSO', RT_RCDATA);
try
Stream.SaveToFile('c:\diretorio\arquivo_extraido.ext');
finally
Stream.Free;
end;
end;
Pronto! Muito fácil! Vamos agora entender os passos citados.
Primeiro criamos um script (arquivo .rc) para gerar o arquivo
de recurso (.res). No script informamos o nome do recurso,
o tipo e o conteúdo. O conteúdo, neste caso, foi o arquivo
"c:\diretorio\arquivo.ext".
Depois compilamos o script com o compilador de recursos da
Borland (BRCC32.EXE). Este processo gerou o arquivo
ARQ_RECURSO.RES.
A seguir colocamos no código-fonte uma instrução para que
o compilador do Delphi incluísse o arquivo de recurso (.res) no
executável - {$R ARQ_RECURSO.RES}.
No evento OnCreate do form acessamos o recurso como um Stream
e o salvamos em arquivo no disco.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Embora pareça complicada, esta tarefa é muito simples.
O Delphi nos permite controlar totalmente o desenho de cada
célula do DBGrid através do evento OnDrawColumnCell. O que
precisamos fazer neste evento é:
1. Verificar o estado da célula (fixa, selecionada, etc).
2. Verificar se é a coluna do campo da imagem.
3. Criar um objeto bitmap.
4. Copiar o conteúdo do campo da imagem para o bitmap.
5. Desenhar o bitmap na célula do DBGrid.
6. Destruir o bitmap.
Agora que já conhecemos os passos, vamos ao exemplo:
1. Coloque um TTable e ligue ao Alias DBDEMOS e à tabela
animals.dbf.
2. Coloque um TDataSource e ligue-o ao Table1.
3. Coloque um DBGrid e ligue-o ao DataSource1.
3. Mude Table1.Active para true.
4. No evento OnDrawColumnCell escreva o código abaixo:
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
var
Bmp: TBitmap;
begin
if (not (gdFixed in State)) and
(UpperCase(Column.FieldName) = 'BMP') then
begin
Bmp := TBitmap.Create;
try
Bmp.Assign(Table1.FieldByName('Bmp'));
DBGrid1.Canvas.StretchDraw(Rect, Bmp);
finally
Bmp.Free;
end;
end;
end;
Conforme eu disse no início, é muito simples!
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Declare a variavel Bmp na seção private:
private
Bmp: TBitmap;
- Coloque um botão no Form e no evento OnClick digite:
Bmp:= TBitMap.Create;
try
Bmp.LoadFromFile('c:\teste\arquivo.bmp');
Canvas.Draw(0,0, Bmp);
finally
Bmp.Free;
end;
Pronto! Irá aparecer a imagem no Canvas. É útil para fazer
animações.
Dica enviada por: Alisson Viana Jardim
Revisada por: Daniel Pereira GuimarãesAutor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Esta função extrai apenas o nome do arquivo passado,
sem path e extensão }
function Titulo(Nome: String): String;
var
N, D: String;
begin
N := ExtractFileName(Nome); { Retira o path }
D := ChangeFileExt(N,''); { Retira a extensão }
{ Coloca a primeira letra em maiúscula e o resto
em minúscula }
Titulo := UpperCase(Copy(D,1,1)) +
LowerCase(Copy(D,2,Length(D)-1));
end;
{ No OnCreate do form, coloque: }
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := Titulo(ParamStr(0));
end;
- Dica enviada por: Luiz Eduardo.Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Esta função retorna uma string com o nome do tipo de dado
de uma propriedade. Exemplos de retornos:
PropType(Button1, 'Caption'); // Retorna 'TCaption'
PropType(Edit1, 'Width'); // Retorna 'Integer';
PropType(Edit1, 'Color'); // Retorna 'TColor';
}
function PropType(const Obj: TObject; const PropName: string): string;
var
Info: PPropInfo;
begin
Info := GetPropInfo(Obj.ClassInfo, PropName);
if Assigned(Info) then
Result := Info^.PropType^.Name
else
Result := '';
end;
{ Exemplo de uso:
- Coloque um TButton e um TEdit;
- No OnClick do Button1 coloque o código abaixo;
- Execute, digite 'Caption' no Edit1 e clique em Button1.
}
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(PropType(Button1, Edit1.Text));
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Gostaria de pintar imagens de arquivos JPG (JPeg) nos forms
de minha aplicação. Isto é possível? Como?
Solução:
Para trabalhar com arquivos JPG você precisa usar um objeto
TPicture, assim como colocar no uses a unit JPeg. Siga os
passos abaixo para pintar uma imagem JPG no form:
- No evento OnPaint do form coloque o código abaixo:
procedure TForm1.FormPaint(Sender: TObject);
var
Imagem: TPicture;
begin
Imagem := TPicture.Create;
try
Imagem.LoadFromFile('c:\teste\foto.jpg');
Canvas.StretchDraw(ClientRect, Imagem.Graphic);
finally
Imagem.Free;
end;
end;
- E no evento OnResize do form, coloque:
procedure TForm1.FormResize(Sender: TObject);
begin
Repaint;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Usando WinExec você pode executar qualquer comando do DOS.
Para isto chame o COMMAND.COM passando como parâmetro a linha
de comando a ser executada. O parâmetro /C é opcional e faz
com que a janela do DOS seja fechada assim que o comando
terminar. No exemplo abaixo estou executando a seguinte
linha de comando: DIR C:\*.*
WinExec('COMMAND.COM /C DIR C:\*.*', SW_SHOW);
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Esta função forma CEP como: 99.999-999 }
function tbFormataCEP(const CEP: string): string;
var
I: integer;
begin
Result := '';
for I := 1 to Length(CEP) do
if CEP[I] in ['0'..'9'] then
Result := Result + CEP[I];
if Length(Result) <> 8 then
raise Exception.Create('CEP inválido.')
else
Result :=
Copy(Result, 1, 2) + '.' +
Copy(Result, 3, 3) + '-' +
Copy(Result, 6, 3);
end;
=== Para testar ===
- Coloque um Edit e um Button no form;
- No evento OnClick do Button coloque a instrução abaixo:
Edit1.Text := tbFormataCEP(Edit1.Text);
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Em determinadas partes no programa existem processos que podem
demorar vários minutos para serem concluídos. Muitas vezes o
usuário desiste e deseja cancelar o processamento. Como
permitir este cancelamento?
Solução:
Em aplicativos para Windows é comum, em processamentos
demorados, o programa mostrar uma janela de diálogo avisando
que o processo pode levar um tempo extra. Nesta mesma janela
normalmente coloca-se também um botão "Cancelar" que dá ao
usuário a opção aguardar ou desistir do processo. Para fazer
isto em um aplicativo Delphi, siga os passos abaixo:
- Vamos considerar em nosso exemplo que o processamento ocorre
na unit do Form1.
- Declare, na seção public do Form1, uma variável boolean.
public;
Cancelar: boolean;
- Crie um novo form (vou chamá-lo de Form2);
- Coloque um botão neste novo form. Programe o OnClick deste
botão conforme abaixo:
Form1.Cancelar := true;
- Na parte onde ocorre o loop do processamento demorado
coloque algo como:
try
{ Antes de começar o processamento }
Form2.Caption := 'Processamento demorado...';
Form2.Show;
{ No início do loop "Cancelar" precisa ser false }
Cancelar := false;
{ Aqui inicia o loop do processamento demorado }
while {...} do begin
{ ... Processa algo aqui... }
{ Permite que o programa processe mensagens do Windows }
Application.ProcessMessages;
{ Se a variável "Cancelar" foi alterada para true... }
if Cancelar then begin
ShowMessage('Operação cancelada pelo usuário.');
Break; { Sai do loop }
end;
end;
finally
Form2.Close;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Esta função retorna true se a data passada como parâmetro
é fim de mês. Retorna false caso contrário. }
function tbFimDoMes(const Data: TDateTime): boolean;
var
Ano, Mes, Dia: Word;
begin
DecodeDate(Data +1, Ano, Mes, Dia);
Result := Dia = 1;
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{
- Coloque um botão no form;
- Altere o evento OnClick do botão conforme abaixo:
}
procedure TForm1.Button1Click(Sender: TObject);
const
cRegPath = 'System\CurrentControlSet\control\FileSystem';
cRegValue = 'ACDriveSpinDown';
var
Reg: TRegistry;
S: string;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey(cRegPath, false) then begin
case Reg.GetDataType(cRegValue) of
rdUnknown: S := 'Tipo Desconhecido';
rdString: S := 'String';
rdExpandString: S := 'ExpandString';
rdInteger: S := 'Inteiro';
rdBinary: S := 'Binário';
end;
ShowMessage(S);
end else
ShowMessage('Erro ao abrir chave do Registro');
finally
Reg.Free;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Esta procedure pega a linha e coluna da célula onde estiver
o mouse. Valores negativos para Linha ou Coluna indicam que
o mouse está fora da área cliente do StringGrid }
procedure MouseCell(Grid: TStringGrid;
var Coluna, Linha: integer);
var
Pt: TPoint;
begin
GetCursorPos(Pt);
Pt := Grid.ScreenToClient(Pt);
if PtInRect(Grid.ClientRect, Pt) then
Grid.MouseToCell(Pt.X, Pt.Y, Coluna, Linha)
else begin
Coluna := -1;
Linha := -1;
end;
end;
{ Exemplo de uso:
- Coloque um botão no form;
- Altere o evento OnClick deste botão como abaixo:
}
procedure TForm1.Button1Click(Sender: TObject);
var
Coluna, Linha: integer;
begin
MouseCell(StringGrid1, Coluna, Linha);
if (Coluna >= 0) and (Linha >= 0) then
Caption := 'Coluna: ' + IntToStr(Coluna) + ' - ' +
'Linha: ' + IntToStr(Linha);
else
Caption := 'O mouse não está no StringGrid';
end;
{ Para testar:
- Execute o programa;
- Posicione o cursor do mouse sobre alguma célula do
StringGrid;
- Pressione TAB até chegar ao botão e pressione ENTER;
- O resultado será mostrado no Caption do form;
}
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Existem três métodos que podemos aplicar para limpar
um StringGrid.
{ Limpando uma célula de cada vez: }
procedure TForm1.Button1Click(Sender: TObject);
var
I, J: integer;
begin
with StringGrid1 do
for I := 0 to ColCount -1 do
for J := 0 to RowCount -1 do
Cells[I,J] := '';
end;
{ Limpando uma linha de cada vez: }
procedure TForm1.Button2Click(Sender: TObject);
var
I: integer;
begin
with StringGrid1 do
for I := 0 to RowCount -1 do
Rows[I].Clear;
end;
{ Limpando uma coluna de cada vez: }
procedure TForm1.Button3Click(Sender: TObject);
var
I: integer;
begin
with StringGrid1 do
for I := 0 to ColCount -1 do
Cols[I].Clear;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Criei um editor de textos no Delphi. Agora gostaria que o
Windows Explorer usasse este editor para abrir arquivos com
a extensão .dpg e .dan. Como fazer?
Solução:
Para fazer isto será necessária a criação de algumas chaves no
Registro do Windows. O exemplo abaixo cria todas as chaves
necessárias.
- Coloque um TButton e no evento OnClick dele coloque o
código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.LazyWrite := false;
{ Define o nome interno (ArquivoDaniel) e uma legenda
que aparecerá no Windows Explorer (Arquivo do Daniel) }
Reg.OpenKey('ArquivoDaniel', true);
Reg.WriteString('', 'Arquivo do Daniel');
Reg.CloseKey;
{ Define o comando a ser executado quando abrir um
arquivo pelo Windows Explorer (NomeDoExe %1). O símbolo
%1 indica que o arquivo a ser aberto será passado como
primeiro parâmetro para o aplicativo - ParamStr(1). }
Reg.OpenKey('ArquivoDaniel\shell\open\command', true);
Reg.WriteString('', ParamStr(0) + ' %1'); { NomeDoExe %1 }
Reg.CloseKey;
{ Define o ícone a ser usado no Windows Explorer:
0 - primeiro ícone do EXE
1 - segundo ícone do EXE, etc }
Reg.OpenKey('ArquivoDaniel\DefaultIcon', true);
Reg.WriteString('', ParamStr(0) + ',0'); { 0 = primeiro ícone }
Reg.CloseKey;
{ Define as extensões de arquivos que serão abertos pelo
meu aplicativo }
{ *.dpg }
Reg.OpenKey('.dpg', true);
Reg.WriteString('', 'ArquivoDaniel');
Reg.CloseKey;
{ *.dan }
Reg.OpenKey('.dan', true);
Reg.WriteString('', 'ArquivoDaniel');
Reg.CloseKey;
finally
Reg.Free;
end;
end;
- Coloque um TMemo;
- No evento OnShow do Form coloque o código abaixo:
procedure TForm1.FormShow(Sender: TObject);
begin
{ Se o primeiro parâmetro for um nome de arquivo existente... }
if FileExists(ParamStr(1)) then
{ Carrega o conteúdo do arquivo no memo }
Memo1.Lines.LoadFromFile(ParamStr(1));
end;
*** Para testar ***
- Execute este programa;
- Clique no botão para criar as chaves no Registro do Windows;
- Feche o programa;
- Crie alguns arquivos com as extensões .dpg e .dan;
- Vá ao Windows Explorer e procure pelos arquivos criados;
- Experimente dar um duplo-clique sobre qualquer dos arquivos
com uma das extensões acima.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Declare a função abaixo antes da palavra implementation: function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL'; - Coloque dois botões no Form; - No evento OnClick do Button1 coloque: RegisterServiceProcess(GetCurrentProcessID, 1); - No evento OnClick do Button2 coloque: RegisterServiceProcess(GetCurrentProcessID, 0); === Para testar === Clique no Button1 e pressione CTRL+ALT+DEL. O seu programa não aparecerá na lista. Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa aparecerá na lista.
Autor: Luiz Carlos Manzolli
{ Ativa a proteção de tela do Windows,
se estiver configurada. }
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
No Win95 podemos desligar o monitor afim de economizar
energia elétrica. Normalmente este recurso é controlado pelo
próprio Windows. Porém sua aplicação Delphi também pode fazer
isto. O exemplo abaixo desliga o monitor, aguarde 5 segundos
e re-liga monitor.
SendMessage(Application.Handle, WM_SYSCOMMAND,
SC_MONITORPOWER, 0);
Sleep(5000); { Aguarde 5 segundos }
SendMessage(Application.Handle, WM_SYSCOMMAND,
SC_MONITORPOWER, -1);
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Fiz um programa que mostra mensagens de lembrete quando é
chegada determinada data/hora. Porém quando o usuário vai
para o Prompt do MS-DOS em modo tela cheia, a mensagem
não aparece. O que devo fazer?
Solução:
Antes de mostrar a mensagem, coloque sua aplicação na frente
das demais.
SetForegroundWindow(Application.Handle);
ShowMessage('Teste');Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Inclua no implementation de seu programa a seguinte linha: function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL'; e depois no OnCreate ponha a seguinte linha: RegisterServiceProcess(GetCurrentProcessID, 1); Isso vai fazer o programa nao aparecer no CTRL+ALT+DEL, mas seu form principal vai continuar aparecendo. Para ocultar também o form, basta por no OnCreate antes da linha acima a seguinte linha: Application.ShowMainForm:=False; Resposta enviada por: dexter07
Problema:
Quando ocorre uma exceção no Delphi, ele automaticamente
exibe uma mensagem de erro. Gostaria de poder personalizar
estas mensagens, acrescentando, por exemplo, o e-mail do
suporte técnico. Isto é possível?
Solução:
Sim. Siga os passos abaixo:
- Declare um método (procedure) na seção private do
form principal conforme abaixo:
private
procedure ManipulaExcecoes(Sender: TObject; E: Exception);
- Vá até a seção implementation e implemente este método,
conforme o exemplo:
procedure TForm1.ManipulaExcecoes(Sender: TObject; E: Exception);
begin
MessageDlg(E.Message + #13#13 +
'Suporte técnico:'#13 +
'suporte@servidor.com.br',
mtError, [mbOK], 0);
end;
- No evento OnCreate do Form principal escreva o código
abaixo:
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException := ManipulaExcecoes;
end;
=== Para testar ===
- Coloque um Button no form;
- No evento OnClick deste botão coloque o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
begin
StrToInt('ABCD'); { Isto provoca uma exception }
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
O Pascal para DOS possui uma procedure chamada Delay que
serve para pausar o processamento atual em "n" milésimos
de segundo. Como implemento isto no Delphi?
Solução:
Simles. Veja:
procedure Delay(MSec: Cardinal);
var
Start: Cardinal;
begin
Start := GetTickCount;
repeat
Application.ProcessMessages;
until (GetTickCount - Start) >= MSec;
end;
=== Exemplos de uso: ===
Delay(1000); { Aguarda 1 segundo }
Delay(5000); { Aguarda 5 segundos }
Delay(60000); { Aguarda 60 segundos - 1 minuto }
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Gostaria de colocar algums bitmaps em uma DLL e usá-los em
tempo de execução. É possível fazer isto em Delphi?
Solução:
Sim. Siga os passos abaixo para criar a DLL de bitmaps:
- Crie um arquivo de recursos (.RES) contendo os Bitmaps.
Use o Image Editor do Delphi para criar este arquivo.
Salve-o com o nome BMPS.RES na pasta onde será salvo
o projeto do Delphi;
- Crie um novo projeto no Delphi;
- Remova todos os forms do projeto;
- Salve este projeto com o nome DLLBmp.dpr;
- Abra o arquivo de projeto (DLLBmp.dpr) e altere para
ficar somente com as linhas abaixo:
{$R BMPS.RES}
library DLLBmp;
end.
- Compile o projeto (Ctrl+F9). Será criado o
arquivo DLLBmp.DLL.
- Feche o projeto atual e crie um novo projeto;
- Salve-o na mesma pasta que salvou o anterior,
mas com outro nome qualquer;
- Coloque no form um Edit e um Button;
- No evento OnClick do Button coloque o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
Bmp: TBitmap;
HandleDLL: THandle;
begin
{ Carrega a DLL }
HandleDLL := LoadLibrary('DLLBmp.DLL');
if HandleDLL = 0 then
ShowMessage('Não foi possível carregar DLLBmp.DLL')
else
try
Bmp := TBitmap.Create;
try
Bmp.Handle := LoadBitmap(HandleDLL, PChar(Edit1.Text));
if Bmp.Handle = 0 then
ShowMessage('Não foi possível carregar o Bitmap.')
else
{ Pinta o Bitmap no form }
Canvas.Draw(0, 0, Bmp);
finally
Bmp.Free;
end;
finally
{ Libera a DLL }
FreeLibrary(HandleDLL);
end;
end;
=== Para testar ===
- Execute este projeto;
- Digite no Edit1 o nome que foi dado ao Bitmap no arquivo
de recursos (.RES);
- Clique no botão. O bitmap deverá ser pintado no form.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Coloque um TMemo no form
- Coloque um TButton no form e altere seu OnClick
conforme abaixo:
procedure TForm1.Button1Click(Sender: TObject);
const
cBytesPorMb = 1024 * 1024;
var
M: TMemoryStatus;
begin
M.dwLength := SizeOf(M);
GlobalMemoryStatus(M);
Memo1.Clear;
with Memo1.Lines do begin
Add(Format('Memória em uso: %d%%',
[M.dwMemoryLoad]));
Add(Format('Total de memória física: %f MB',
[M.dwTotalPhys / cBytesPorMb]));
Add(Format('Memória física disponível: %f MB',
[M.dwAvailPhys / cBytesPorMb]));
Add(Format('Tamanho máximo do arquivo de paginação: %f MB',
[M.dwTotalPageFile / cBytesPorMb]));
Add(Format('Disponível no arquivo de paginação: %f MB',
[M.dwAvailPageFile / cBytesPorMb]));
Add(Format('Total de memória virtual: %f MB',
[M.dwTotalVirtual / cBytesPorMb]));
Add(Format('Memória virtual disponível: %f MB',
[M.dwAvailVirtual / cBytesPorMb]));
end;
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellAbout(Handle, 'Sistema Financeiro', 'Marcelo Senger',
Application.Icon.Handle);
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
A função IntToHex do Delphi converte inteiro para
hexadecimal. O que preciso, no entanto, é fazer o contrário,
ou seja, converter de hexadecimal para inteiro. Existe
isto pronto no Delphi ou terei que escrever uma função
para isto?
Solução:
A função StrToInt pode receber uma string no formato de um
número decimal ou hexadecimal. Então podemos usá-la assim:
var
I: integer;
begin
I := StrToInt('$' + Edit1.Text);
{...}
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Coloque uma StatusBar no form.
- Adicione dois paineis na StatusBar (propriedade Panels).
- Ajuste as propriedades do primeiro painel conforme abaixo:
Style = psOwnerDraw
Width = 150
- Coloque uma ProgressBar no form e mude sua propriedade
Visible para false.
- No evento OnDrawPanel da StatusBar digite o código abaixo:
procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
begin
{ Se for o primeiro painel... }
if Panel.Index = 0 then begin
{ Ajusta a tamanho da ProgressBar de acordo com
o tamanho do painel }
ProgressBar1.Width := Rect.Right - Rect.Left +1;
ProgressBar1.Height := Rect.Bottom - Rect.Top +1;
{ Pinta a ProgressBar no DC (device-context) da StatusBar }
ProgressBar1.PaintTo(StatusBar.Canvas.Handle, Rect.Left, Rect.Top);
end;
end;
- Coloque um Button no form
- Digite no evento OnClick do Button o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
I: integer;
begin
for I := ProgressBar1.Min to ProgressBar1.Max do begin
{ Atualiza a posição da ProgressBar }
ProgressBar1.Position := I;
{ Repinta a StatusBar para forçar a atualização visual }
StatusBar1.Repaint;
{ Aguarda 50 milisegundos }
Sleep(50);
end;
{ Aguarde 500 milisegundos }
Sleep(500);
{ Reseta (zera) a ProgressBar }
ProgressBar1.Position := ProgressBar1.Min;
{ Repinta a StatusBar para forçar a atualização visual }
StatusBar1.Repaint;
end;
- Execute e clique no botão para ver o resultado.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Coloque o StringGrid no form. - No evento OnCreate do form coloque o código abaixo: procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.RowHeights[0] := 15; StringGrid1.RowHeights[1] := 20; StringGrid1.RowHeights[2] := 50; StringGrid1.RowHeights[3] := 35; end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Meu programa precisa processar algo quando o usuário clicar
no DBGrid em um determinado form. O problema é que o DBGrid não
possui o evento OnClick. É possível adicionar este evento no
DBGrid?
Solução:
É possível sim. Afinal é muito simples. Siga os passos abaixo
para resolver seu problema:
- Monte seu form normalmente, colocando o DBGrid e demais
componentes;
- Vá na seção "private" da unit e declare a procedure abaixo:
private
procedure DBGridClick(Sender: TObject);
- Logo após a palavra "implementation", escreva a procedure:
implementation
{$R *.DFM}
procedure TForm1.DBGridClick(Sender: TObject);
begin
ShowMessage('Clicou no DBGrid.');
end;
- Coloque as instruções abaixo no evento OnCreate do Form:
procedure TForm1.FormCreate(Sender: TObject);
begin
DBGrid1.ControlStyle :=
DBGrid1.ControlStyle + [csClickEvents];
TForm(DBGrid1).OnClick := DBGridClick;
end;
- E pronto. Execute e teste.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
with Edit2 do if Text <> '' then Text := AnsiUpperCase(Text[1]) + Copy(Text, 2, Length(Text)); Isto pode ser colocado, por exemplo, no OnExit do Edit. Você pode também converter durante a digitação. Para isto coloque o código abaixo no evento OnKeyPress do Edit: if Edit1.SelStart = 0 then Key := AnsiUpperCase(Key)[1] else Key := AnsiLowerCase(Key)[1];
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Use a função abaixo:
function StrIsTime(const S: string): boolean;
begin
try
StrToTime(S);
Result := true;
except
Result := false;
end;
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Use uma das funções abaixo, conforme o tipo de dado que se
quer testar:
function StrIsInteger(const S: string): boolean;
begin
try
StrToInt(S);
Result := true;
except
Result := false;
end;
end;
function StrIsFloat(const S: string): boolean;
begin
try
StrToFloat(S);
Result := true;
except
Result := false;
end;
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Problema:
Um processamento em meu sistema é bastante demorado e por isto
colocar apenas o cursor de ampulheta continua deixando o
usuário confuso, pensando que o sistema travou. É possível
exibir uma mensagem enquanto um processamento demorado ocorre?
Sim. E é fácil. Vejamos:
- Crie um form com a mensagem. Um pequeno form com um
Label já é suficiente. Aqui vou chamá-lo de FormMsg.
- Vá em Project|Options e passe o FormMsg de
"Auto-create forms" para "Available forms".
- Abaixo vou simular um processamento demorado, usando a
API Sleep:
procedure TForm1.Button1Click(Sender: TObject);
var
Form: TFormMsg;
I: integer;
begin
Form := TFormMsg.Create(Self);
try
Form.Label1.Caption := 'Processamento demorado...';
Form.Show;
for I := 1 to 5 do begin
Form.UpDate;
Sleep(1000); { Aguarda um segundo }
end;
finally
Form.Free;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Salve o cursor atual
- Defina o novo cursor (crHourGlass é ampulheta)
- Faça o processamento
- Restaure o cursor.
Vejamos:
var
PrevCur: TCursor;
begin
PrevCur := Screen.Cursor;
try
Screen.Cursor := crHourGlass;
{ Coloque aqui as instruções do processamento }
finally
Screen.Cursor := PrevCur;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Coloque no Form:
- três edits;
- dois botões.
Logo abaixo da palavra implementation declare:
type
{ Declara um tipo registro }
TFicha = record
Codigo: integer;
Nome: string[40];
DataCadastro: TDateTime;
end;
- Escreva o evento OnClick do Button1 conforme abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
Ficha: TFicha;
begin
{ Coloca alguns dados na variável Ficha }
Ficha.Codigo := StrToInt(Edit1.Text);
Ficha.Nome := Edit2.Text;
Ficha.DataCadastro := StrToDate(Edit3.Text);
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre uma chave (path). Se não existir cria e abre. }
Reg.OpenKey('Cadastro\Pessoas\', true);
{ Grava os dados (o registro) }
Reg.WriteBinaryData('Dados', Ficha, SizeOf(Ficha));
finally
Reg.Free;
end;
end;
- Escreva o evento OnClick do Button2 conforme abaixo:
procedure TForm1.Button2Click(Sender: TObject);
var
Reg: TRegistry;
Ficha: TFicha;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Se existir a chave (path)... }
if Reg.KeyExists('Cadastro\Pessoas') then
begin
{ Abre a chave (path) }
Reg.OpenKey('Cadastro\Pessoas', false);
{ Se existir o valor... }
if Reg.ValueExists('Dados') then
begin
{ Lê os dados }
Reg.ReadBinaryData('Dados', Ficha, SizeOf(Ficha));
Edit1.Text := IntToStr(Ficha.Codigo);
Edit2.Text := Ficha.Nome;
Edit3.Text := DateToStr(Ficha.DataCadastro);
end else
ShowMessage('Valor não existe no registro.')
end else
ShowMessage('Chave (path) não existe no registro.');
finally
Reg.Free;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
- Coloque um ListBox no form
- Modifique o OnCreate do form assim:
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
DevMode : TDevMode;
begin
i := 0;
while EnumDisplaySettings(nil,i,Devmode) do begin
with Devmode do
ListBox1.Items.Add(Format('%dx%d %d Colors',
[dmPelsWidth,dmPelsHeight, 1 shl dmBitsperPel]));
Inc(i);
end;
end;
- Coloque um botão no form
- Altere o evento OnClick do botão conforme abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
DevMode : TDevMode;
begin
EnumDisplaySettings(nil,Listbox1.ItemIndex,Devmode);
ChangeDisplaySettings(DevMode,0);
end;
- Coloque no form dois edits e dois botões.
- No evento OnClick do Button1 escreva o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre a chave (path). Se não existir, cria e abre. }
Reg.OpenKey('MeuPrograma\Configuração', true);
{ Escreve um inteiro }
Reg.WriteInteger('Numero', StrToInt(Edit1.Text));
{ Escreve uma string }
Reg.WriteString('Nome', Edit2.Text);
finally
Reg.Free;
end;
end;
- No evento OnClick do Button2, escreva:
procedure TForm1.Button2Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
if Reg.KeyExists('MeuPrograma\Configuração') then
begin
Reg.OpenKey('MeuPrograma\Configuração', false);
if Reg.ValueExists('Numero') then
Edit1.Text := IntToStr(Reg.ReadInteger('Numero'))
else
ShowMessage('Não existe valor com o nome "Numero"');
if Reg.ValueExists('Nome') then
Edit2.Text := Reg.ReadString('Nome')
else
ShowMessage('Não existe valor com o nome "Nome"');
end else
ShowMessage('Não existe a chave no registro');
finally
Reg.Free;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ - Coloque um ListBox no form;
- Altere o OnCreate do Form conforme abaixo:
}
procedure TForm1.FormCreate(Sender: TObject);
var
I, Temp, MaxTextWidth: integer;
begin
{ Adiciona algumas linhas no ListBox }
Listbox1.Items.Add('Linha 1');
Listbox1.Items.Add('Linha 2, longa para que seja necessária a barra de rolagem horizontal');
Listbox1.Items.Add('Linha 3');
if Listbox1.Items.Count > 1 then begin
{ Obtém o comprimento, em pixels, da linha mais longa }
MaxTextWidth := 0;
for I := 0 to Listbox1.Items.Count - 1 do begin
Temp := ListBox1.Canvas.TextWidth(ListBox1.Items[I]);
if Temp > MaxTextWidth then
MaxTextWidth := Temp;
end;
{ Acrescenta a largura de um "W" }
MaxTextWidth := MaxTextWidth + Listbox1.Canvas.TextWidth('W');
{ Envia uma mensagem ao ListBox }
SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, MaxTextWidth, 0);
end;
end;
{ Para ocultar use a instrução abaixo: }
SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, 0, 0);
Escreva a função abaixo:
function tbStrIsDate(const S: string): boolean;
begin
try
StrToDate(S);
Result := true;
except
Result := false;
end;
end;
Para testar:
- Coloque um Edit no form;
- Coloque um Button;
- No evento OnClick do botão coloque o código abaixo:
if tbStrIsDate(Edit1.Text) then
ShowMessage(Edit1.Text + ' é data válida.')
else
ShowMessage(Edit1.Text + ' NÃO é data válida.');Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Existem várias formas. Vejamos uma:
function tbStrZero(const I: integer; const Casas: byte): string;
var
Ch: Char;
begin
Result := IntToStr(I);
if Length(Result) > Casas then begin
Ch := '*';
Result := '';
end else
Ch := '0';
while Length(Result) < Casas do
Result := Ch + Result;
end;
{ Exemplo de como usá-la: }
var
S: string;
Numero: integer;
{...}
begin
{...}
S := tbStrZero(Numero, 6);
{...}
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ A versão desta biblioteca determina a aparência de alguns
controles do Delphi, tais como ToolBar e CoolBar. O exemplo
abaixo obtém a versão desta biblioteca.
Para este exemplo, coloque um TEdit e um TButton no Form.
O evento OnClick do botão escreva o código abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Ver: Cardinal;
MaiorVer, MenorVer: Word;
begin
Ver := GetComCtlVersion;
MaiorVer := HiWord(Ver);
MenorVer := LoWord(Ver);
Edit1.Text := IntToStr(MaiorVer) + '.' + IntToStr(MenorVer);
end;
{ O Delphi permite a implementação de rotinas assembly
mescladas ao código Pascal. Não entrarei em detalhes
minuciosos, mas darei alguns exemplos básicos de como
implementar rotinas simples que retornam números inteiros.
}
{ Soma dois inteiros de 8 bits }
function Soma8(X, Y: byte): byte;
asm
mov al, &X
add al, &Y
end;
{ Soma dois inteiros de 16 bits }
function Soma16(X, Y: Word): Word;
asm
mov ax, &X
add ax, &Y
end;
{ Soma dois inteiros de 32 bits }
function Soma32(X, Y: DWord): DWord;
asm
mov eax, &X
add eax, &Y
end;
{ A chamada a estas funções são feitas da mesma forma
que chamamos uma função Pascal. Exemplo: }
var
A: byte;
begin
A := Soma8(30, 25); { A = 55 }
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ About padrão do Windows }
ShellAbout(Handle, 'Windows', '', 0);
{ Personalizada }
ShellAbout(Handle, 'NomePrograma',
'Direitos autorais reservados a'#13'Fulano de Tal',
Application.Icon.Handle);Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ === SOLUÇÃO 1 === }
{ Esta procedure obtém a linha e coluna atual de um TMemo }
procedure tbGetMemoLinCol(Memo: TMemo; var Lin, Col: Cardinal);
begin
with Memo do begin
Lin := Perform(EM_LINEFROMCHAR, SelStart, 0);
Col := SelStart - Perform(EM_LINEINDEX, Lin, 0);
end;
end;
{ Use-a como abaixo: }
var
Lin, Col: Cardinal;
begin
tbGetMemoLinCol(Memo1, Lin, Col);
{ ... }
end;
{ === SOLUÇÃO 2 === }
var
Lin, Col: integer;
begin
Lin := Memo1.CaretPos.y;
Col := Memo1.CaretPos.x;
{...}
end;
- A segunda solução foi apresentada por:
Vanderley Pereira RochaAutor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Você precisa saber:
- Caminho e nome do arquivo;
- A estrutura do arquivo de Help.
No exemplo abaixo abre o arquivo de ajuda da Calculadora
do Windows e vai para o tópico n. 100
}
procedure TForm1.Button1Click(Sender: TObject);
begin
WinHelp(0, 'c:\Win95\Help\Calc.hlp', HELP_CONTEXT, 100);
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Esta função recebe o nome da variável de ambiente
que queremos acessar e retorna uma string com seu
valor, ou uma string vazia se a variável não existir. }
function tbGetEnvVar(const VarName: string): string;
var
I: integer;
begin
Result := '';
{ Obtém o comprimento da variável }
I := GetEnvironmentVariable('PATH', nil, 0);
if I > 0 then begin
SetLength(Result, I);
GetEnvironmentVariable('PATH', PChar(Result), I);
end;
end;
{ Para usá-la, faça como neste exemplo: }
Edit1.Text := tbGetEnvVar('PATH');Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
procedure TForm1.Button1Click(Sender: TObject); begin FatalAppExit(0, 'Erro fatal na aplicação.'); end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Problema:
Gostaria que um determinado programa (Prog1.EXE) fosse
executado apenas através de outro programa (Prog2.EXE).
Solução:
Antes da linha "Application.Initialize;" de Prog1.dpr (programa
a ser chamado), coloque o código abaixo:
}
if ParamStr(1) <> 'MinhaSenha' then begin
{ Para usar ShowMessage, coloque Dialogs no uses }
ShowMessage('Execute este programa através de Prog2.EXE');
Halt; { Finaliza }
end;
{ No Form1 de Prog2 (programa chamador) coloque um botão e
escreva o OnClick deste botão como abaixo:
}
procedure TForm1.Button1Click(Sender: TObject);
var
Erro: Word;
begin
Erro := WinExec('Pro2.exe MinhaSenha', SW_SHOW);
if Erro <= 31 then { Se ocorreu erro... }
ShowMessage('Erro ao executar o programa.');
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Às vezes você precisa considerar apenas duas casas de valores
reais, mas o Delphi não oferece algo pronto para isto. Se
usarmos funções como Round que vem com o Delphi, o valor será
arredondado (e não truncado). Com Round() o valor abaixo será
135.55 (e não 135.54) com duas casas decimais.
}
ValorReal := 135.54658;
{ Somente a parte inteira - nenhuma casa decimal }
X := Trunc(ValorReal); // X será 135
{ Duas casas }
X := Trunc(ValorReal * 100) / 100; // X será 135.54
{ Três casas }
X := Trunc(ValorReal * 1000) / 1000; // X será 135.5465
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Para não correr o risco de surpresas desagradáveis,
é melhor que seu programa em Delphi verifique se
o Windows está ajustado para trabalhar com 4 dígitos
para o ano. Assim seu programa pode alertar o usuário
quando o ano estiver sendo representado com apenas 2 dígitos.
A função abaixo retorna true se estiver ajustado para
4 dígitos.
}
function Is4DigitYear: Boolean;
begin
result:=(Pos('yyyy',ShortDateFormat)>0);
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque um botão no form e altere seu evento OnCkick
como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegIniFile;
S: string;
begin
Reg := TRegIniFile.Create('SOFTWARE\MICROSOFT\MS SETUP (ACME)\');
try
S := Reg.ReadString('USER INFO','DefName','');
S := S + #13;
S := S + Reg.ReadString('USER INFO','DefCompany','');
ShowMessage(S);
finally
Reg.free;
end;
end; Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Você já observou a caixa "Propriedades", aquela que mostra
as propriedades de um arquivo no Windows Explorer, não
aparece na lista do Alt+Tab e tampouco na barra de tarefas?
Isto ocorre porque ela funciona como uma ToolWindow, enquanto
os demais aplicativos funcionam como AppWindow. Porém podemos
mudar o comportamento de nossos programas feito em Delphi
para que se comportem como uma ToolWindow também.
Para experimentar, crie um novo projeto e altere o
Project1.dpr como abaixo (não esqueça do uses):
}
program Project1;
uses
Forms, Windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
var
ExtendedStyle : Integer;
begin
Application.Initialize;
ExtendedStyle := GetWindowLong(Application.Handle, gwl_ExStyle);
SetWindowLong(Application.Handle, gwl_ExStyle, ExtendedStyle or
ws_Ex_ToolWindow and not ws_Ex_AppWindow);
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
{ Reinicia o Windows }
ExitWindowsEx(EWX_REBOOT, 0);
{ Desliga o Windows }
ExitWindowsEx(EWX_SHUTDOWN, 0);
{ Força todos os programa a desligarem-se }
ExitWindowsEx(EWX_FORCE, 0);Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Altere o evento OnCreate do Form conforme abaixo: }
procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.Cursors[1] :=
LoadCursorFromFile('c:\win95\cursors\globe.ani');
Button1.Cursor := 1;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque isto no evento OnClick de um botão: }
WinExec('command.com /c programa.exe',sw_ShowNormal);
{ Se quizer passar parâmetros pasta adicioná-los após o
nome do programa. Exemplo: }
WinExec('command.com /c programa.exe param1 param2',sw_ShowNormal);
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ - Coloque um botão no form e altere seu evento OnClick
conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Janela: HWND;
begin
Janela := FindWindow('OpusApp'), nil);
if Janela = 0 then
ShowMessage('Programa não encontrado')
else
PostMessage(Janela, WM_QUIT, 0, 0);
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ - Coloque um TButton no Form;
- Altere o evento OnCreate do Form como abaixo: }
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Hint := 'Linha 1 da dica' + #13 +
'Linha 2 da dica' + #13 +
'Linha 3 da dica';
Button1.ShowHint := true;
end;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Abaixo da palavra implementation digite: }
type
TChars = set of Char;
function FilterChars(const S: string; const ValidChars: TChars): string;
var
I: integer;
begin
Result := '';
for I := 1 to Length(S) do
if S[I] in ValidChars then
Result := Result + S[I];
end;
{ Para usar a função:
- Coloque um botão no Form;
- Altere o evento OnClick deste botão conforme abaixo: }
procedure TForm1.Button4Click(Sender: TObject);
begin
{ Pega só letras }
ShowMessage(FilterChars('D63an*%i+/e68l13',
['A'..'Z', 'a'..'z']));
{ Pega só números }
ShowMessage(FilterChars('D63an*%i+/e68l13', ['0'..'9']));
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Isto coloca zeros à esquerda do número até completar 6 casas }
S := FormatFloat('000000', 5);
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
procedure TForm1.Button3Click(Sender: TObject);
begin
{ Exibe as cores atuais dos Edit's }
ShowMessage(ColorToString(Edit1.Color));
ShowMessage(ColorToString(Edit2.Color));
{ Altera as cores dos Edit's }
Edit1.Color := StringToColor('clBlue');
Edit2.Color := StringToColor('$0080FF80');
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque um Button no Form e altere o evento OnClick deste
como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
begin
{ Verifica o Delphi }
if FindWindow('TAppBuilder', nil) > 0 then
ShowMessage('O Delphi está aberto')
else
ShowMessage('O Delphi NÃO está aberto');
{ Verifica o Word }
if FindWindow('OpusApp', nil) > 0 then
ShowMessage('O Word está aberto')
else
ShowMessage('O Word NÃO está aberto');
{ Verifica o Excell }
if FindWindow('XLMAIN', nil) > 0 then
ShowMessage('O Excell está aberto')
else
ShowMessage('O Excell NÃO está aberto');
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ - Coloque um botão no Form;
- Altere o evento OnClick do botão conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Word: Variant;
begin
{ Abre o Word }
Word := CreateOleObject('Word.Application');
try
{ Novo documento }
Word.Documents.Add;
try
{ Adiciona tabela de 2 linhas e 3 colunas }
Word.ActiveDocument.Tables.Add(
Range := Word.Selection.Range,
NumRows := 2,
NumColumns := 3);
{ Escreve na primeira célula }
Word.Selection.TypeText(Text := 'Linha 1, Coluna 1');
{ Próxima célula }
Word.Selection.MoveRight(12);
{ Escreve }
Word.Selection.TypeText(Text := 'Linha 1, Coluna 2');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 1, Coluna 3');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 1');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 2');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 3');
{ Auto-Formata }
Word.Selection.Tables.Item(1).Select; { Seleciona a 1º tabela }
Word.Selection.Cells.AutoFit; { auto-formata }
{ Imprime 1 cópia }
Word.ActiveDocument.PrintOut(Copies := 1);
ShowMessage('Aguarde o término da impressão...');
{ Para salvar... }
Word.ActiveDocument.SaveAs(FileName := 'c:\Tabela.doc');
finally
{ Fecha documento }
Word.ActiveDocument.Close(SaveChanges := 0);
end;
finally
{ Fecha o Word }
Word.Quit;
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Muitos programas Windows permitem apenas uma cópia em
execução de cada vez. Isto é interessante principalmente
quando é um grande aplicativo, pois duas cópias ao mesmo
tempo usuaria muito mais memória. Em aplicativos
desenvolvidos em Delphi podemos ter esta característica.
Vejamos:
- Crie um novo projeto;
- Mude o "Name" do Form1 para DPGFormPrinc;
- Altere o código-fonte do arquivo Project1.dpr
conforme abaixo: }
program Project1;
uses
Forms, Windows,
Unit1 in 'Unit1.pas' {DPGFormPrinc};
{$R *.RES}
var
Handle: THandle;
begin
Handle := FindWindow('TDPGFormPrinc', nil);
if Handle <> 0 then begin { Já está aberto }
Application.MessageBox('Este programa já está aberto. A cópia ' +
'anterior será ativada.', 'Programa já aberto', MB_OK);
if not IsWindowVisible(Handle) then
ShowWindow(Handle, SW_RESTORE);
SetForegroundWindow(Handle);
Exit;
end;
Application.Initialize;
Application.CreateForm(TDPGFormPrinc, DPGFormPrinc);
Application.Run;
end.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque um TButton no Form e altere o evento
OnClick deste botão como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Largura: ' + IntToStr(Screen.Width) + #13 +
'Altura: ' + IntToStr(Screen.Height));
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Pegue apostila no download.
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
O evento OnGetEditMask ocorre quando entramos no modo de edição.
Neste momento podemos verificar em qual linha/coluna se
encontra o cursor e então, se quiser, poderá especificar uma
máscara de edição. Exemplo:
procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
if (ARow = 1) and (ACol = 1) then
Value := '(999) 999-9999;1;_'; // Telefone
end;
O evento OnGetEditText ocorre também quando entramos no modo
de edição. Neste momento podemos manipularmos o texto da
célula atual (linha/coluna) e então podemos simular algo tal
como uma tabela onde opções podem ser digitadas através
de números. Exemplo:
procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol,
ARow: Integer; var Value: String);
begin
if (ARow = 1) and (ACol = 2) then begin
if StringGrid1.Cells[ACol, ARow] = 'Ótimo' then
Value := '1'
else if StringGrid1.Cells[ACol, ARow] = 'Regular' then
Value := '2'
else if StringGrid1.Cells[ACol, ARow] = 'Ruim' then
Value := '3';
end;
end;
O evento evento OnSetEditText ocorre quando saímos do modo de
edição. Neste momento podemos manipular a entrada e trocar
por um texto equivalente. Normalmente usamos este evento em
conjunto com o evento OnGetEditText. Exemplo:
procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol,
ARow: Integer; const Value: String);
begin
if (ARow = 1) and (ACol = 2) then begin
if Value = '1' then
StringGrid1.Cells[ACol, ARow] := 'Ótimo'
else if Value = '2' then
StringGrid1.Cells[ACol, ARow] := 'Regular'
else if Value = '3' then
StringGrid1.Cells[ACol, ARow] := 'Ruim'
end;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Muitas vezes precisamos saber qual o nome de classe de uma determinada janela. Quando são janelas desenvolvidas por nós, você olha no código-fonte. Mas e se não for, como é o caso do Delphi? Por exemplo: Para verificar se o Delphi está sendo executado, procuramos no Windows pela janela cujo nome de classe seja TAppBuilder. Mas como verificar então se o Internet Explorer está sendo executado? Precisaremos saber o nome de classe da janela deste programa. Então o que fazer? Use o TBWinName. Pegue-o no download de www.tecnobyte.com.br
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque no Form dois Botões: BotaoOcultar e BotaoExibir.
No evento OnClick do BotaoOcultar escreva: }
procedure TForm1.BotaoOcultarClick(Sender: TObject);
var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_HIDE);
end;
{ No evento OnClick do BotaoExibir escreva: }
procedure TForm1.BotaoExibirClick(Sender: TObject);
var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_SHOW);
end;
{ Execute e teste, clicando em ambos os botões }
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Na seção "private" do Form principal acrescente: }
procedure AppMsg(var Msg: TMsg; var Handled: Boolean);
{ Na seção "implementation" acrescente (troque TForm1 para
o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.Message = wm_SysCommand) and
(Msg.wParam = sc_ScreenSave) then
Handled := true;
end;
{ No evento "OnCreate" do form principal, coloque: }
Application.OnMessage := AppMsg;Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque um TButton no form e escreva o evento OnClick
deste como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Vermelho, Verde, Azul: byte;
MinhaCor: TColor;
begin
Vermelho := 0;
Verde := 200;
Azul := 150;
MinhaCor := TColor(RGB(Vermelho, Verde, Azul));
Form1.Color := MinhaCor;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque o código abaixo no OnClick de um botão }
AddFontResource(PChar('c:\MyFonts\Monospac.ttf'));
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque este código no OnClick de um botão }
with Screen.Fonts do
if IndexOf('Courier New') >= 0 then
ShowMessage('A fonte está instalada.')
else
ShowMessage('A fonte não está instalada.');
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Coloque dois TEdit no form.
Coloque um TButton no form e altere o evento OnClick
deste botão como abaixo:
}
procedure TForm1.Button1Click(Sender: TObject);
var
DataHora: TSystemTime;
Data, Hora: TDateTime;
Ano, Mes, Dia,
H, M, S, Mil: word;
begin
Data := StrToDate(Edit1.Text);
Hora := StrToTime(Edit2.Text);
DecodeDate(Data, Ano, Mes, Dia);
DecodeTime(Hora, H, M, S, Mil);
with DataHora do begin
wYear := Ano;
wMonth := Mes;
wDay := Dia;
wHour := H;
wMinute := M;
wSecond := S;
wMilliseconds := Mil;
end;
SetLocalTime(DataHora);
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ Pausa por 1 segundo }
Sleep(1000);
{ Pausa por 10 segundos }
Sleep(10000);
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
{ se o alias não existir... }
if not Session.IsAlias('MeuAlias') then
begin
{ Adiciona o alias }
Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');
{ Salva o arquivo de configuração do BDE }
Session.SaveConfigFile;
end;
Autor: Daniel P. Guimarães
Home-page: www.tecnobyte.com.br
Página atualizada em 01 de maio de 2007
Todos os direitos reservados
www.tecnobyte.com.br