001 - Ativar a proteção de tela do Windows
002 - Desligar/Ligar monitor
003 - Abrir e fechar o drive de CD-ROM
004 - Impedir que o form seja arrastado para fora das margens da tela
005 - Mostrar mensagem mesmo que esteja no Prompt do DOS
006 - Copiar todos os registros de uma tabela para o Clipboard
007 - Copiar um registro de uma tabela para o Clipboard
008 - Criar sub-diretório no diretório do EXE
009 - Hablitar e Desabilitar CTRL+ALT+DEL
010 - Personalizar a caixa de mensagem de exceções (erro) do Delphi
011 - Implementar procedure Delay do Pascal no Delphi
012 - Enviar comandos de rolagem vertical para um TMemo
013 - Criar uma DLL de Bitmaps e usá-la
014 - Como extrair o icone de um excutável
015 - Criar form sem título que possa ser arrastado
016 - Obter status da memória do sistema
017 - Definir data/hora de um arquivo
018 - Mostrar o diálogo About (Sobre) do Windows
019 - Ocultar/exibir o cursor do mouse
020 - Converter de Hexadecimal para Inteiro
021 - Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma
condição
022 - Colocar uma ProgressBar da StatusBar
023 - Executar um programa e aguardar sua finalização antes de continuar
024 - Simular o pressionamento de uma combinação de teclas (ex: Ctrl+F2)
025 - Simular o pressionamento de uma tecla
026 - Ligar/desligar a tecla Caps Lock
027 - Verificar se uma determinada tecla está pressionada
028 - Verificar o estado de NumLock e CapsLock
029 - Configurar linhas de diferentes alturas em StringGrid
030 - Adicionar o evento OnClick do DBGrid
031 - Criar caixas de diálogo em tempo de execução
032 - Converter a primeira letra de um Edit para maiúsculo
033 - Verificar se uma string contém uma hora válida
034 - Verificar se uma string contém um valor numérico válido
035 - Mostrar uma mensagem durante um processamento
036 - Mostrar um cursor de ampulheta durante um processamento
037 - Ler e escrever dados binários no Registro do Windows
038 - Mudar a resolução do vídeo via programação
039 - Ler e escrever dados no Registro do Windows
040 - Adicionar barra de rolagem horizontal no ListBox
041 - Simular um CharCase no DBGrid
042 - Verificar se uma string é uma data válida
043 - Fazer pesquisa incremental
044 - Adicionar zeros à esquerda de um número
045 - Limpar um campo tipo data via programação
046 - Implementar um campo auto-incremental via programação
047 - Obter o endereço IP do Dial-Up
048 - Exibir a caixa de diálogo padrão de solicitação de senha do banco
de dados
049 - Obter a versão da biblioteca ComCtl32.DLL (usada na unit ComCtrls do
Delphi)
050 - Implementar rotinas assembly em Pascal
051 - Exibir o diálogo About do Windows
052 - Obter a linha e coluna atual em um TMemo
053 - Exibir um arquivo de ajuda do Windows
054 - Obter o valor de uma variável de ambiente
055 - Determinar se uma janela (form) está maximizada
056 - Determinar se o cursor do mouse está em determinado controle
057 - Determinar se o aplicativo está minimizado
058 - Fechar um aplicativo com uma mensagem de erro fatal
059 - Usar o evento OnGetText de um TField
060 - Maximizar um form de forma que cubra toda a tela, inclusive a barra de
tarefas
061 - Verificar, via programação, se Local Share do BDE está TRUE
062 - Criar um EXE que seja executado apenas através de outro EXE criado
por mim
063 - Multiplas seleções em um DBGrid
064 - Inverter os botões do mouse
065 - Obter/definir o tempo máximo do duplo-click do mouse
066 - Obter os atributos de um arquivo/diretório
067 - Obter o espaço total e livre de um disco
068 - Obter o tipo de um drive (removível, fixo, CD-ROM, unidade de rede,
etc)
069 - Obter informações de um volume/disco (label, serial, sistema de
arquivos, etc)
070 - Alterar o nome de volume (Label) de um disco
071 - Saber quais as unidades de disco (drives) estão presentes
072 - "truncar" valores reais para apenas n casas decimais
073 - Excluir todos os registros de uma tabela (como DELETE ALL do Clipper)
074 - Saber se o sistema está usando 4 dígitos para o ano
075 - Imprimir caracteres acentuados diretamente para a impressora
076 - Imprimir texto justificado com formatação na impressora Epson LX-300
077 - Formatar um disquete através de um programa Delphi
078 - executar um arquivo com extensão *.LNK
079 - Reproduzir um arquivo de som WAV sem o TMediaPlayer
080 - Obter o nome do usuário e da empresa informado durante a instalação
do Windows
081 - Mostrar uma barra de progresso enquanto copia arquivos
082 - Copiar arquivos usando o Shell do Windows
083 - Descobrir o código ASCII de uma tecla
084 - Evitar que seu programa apareça na barra de tarefas
085 - Usar eventos de som do Windows
086 - Mudar a coluna ativa em um DBGrid via programação
087 - Fechar o Windows a partir do seu programa
088 - Carregar um cursor animado (.ani)
089 - Enviar um arquivo para a lixeira
090 - Obter o número do registro atual
091 - Trabalhar com Filter de forma mais prática
092 - Reproduzir um arquivo WAV
093 - Executar um programa DOS e fechá-lo em seguida
094 - Fechar um programa a partir de um programa Delphi
095 - Colocar Hint's de várias linhas
096 - Reproduzir um vídeo AVI em um Form
097 - Separar (filtrar) caracteres de uma string
098 - Colocar zeros à esquerda de números
099 - Copiar arquivos usando curingas (*.*)
100 - Copiar arquivos
101 - Trabalhar com cores no formato string
102 - Verificar se determinado programa está em execução (Word, Delphi,
etc)
103 - Excluir arquivos usando curingas (*.*)
104 - Gerar uma tabela no Word através do Delphi
105 - Obter a quantidade de registros total e visível de uma tabela
106 - Evitar que um programa seja executado mais de uma vez
107 - Executar um "COMMIT" no Delphi
108 - Posicionar Form's em relação ao Desktop do Windows
109 - Saber a resolução de tela atual
110 - Verificar se uma unidade de disco (disk-drive) está preparada
111 - Salvar/restaurar o tamanho e posição de Form's
112 - Definir a quantidade de registros a ser impressa em uma página do
QuickReport
113 - Colocando um BitMap no Form
114 - Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do
TStringGrid
115 - Mostrar um Form de LogOn antes do Form principal
116 - Limitar a região de movimentação do mouse
117 - Descobrir o nome de classe de uma janela do Windows
118 - Ocultar/exibir a barra de tarefas do Windows
119 - Evitar a proteção de tela durante seu programa
120 - Fazer a barra de título ficar intermitente (piscante)
121 - Posicionar o cursor do mouse em um controle
122 - Criar cores personalizadas (sistema RGB)
123 - Adicionar uma nova fonte no Windows
124 - Saber se a impressora atual possui determinada fonte
125 - Saber se determinada Font está instalada no Windows
126 - Acertar a data e hora do sistema através do programa
127 - ENTER em vez de TAB no formulário, no DBGrid e no StringGrid
128 - Simular a vírgula através do ponto do teclado numérico
129 - Paralizar um programa durante n segundos
130 - Criar uma tabela (DB, DBF) através do seu programa
131 - Verificar se um diretório existe
132 - Verificar se um arquivo existe
133 - Criar um Alias temporário através do seu programa
134 - Criar um Alias através do seu programa
001 - Ativar a proteção de tela do Windows Inclua na seção uses: Windows
{ Ativa a proteção de tela do Windows,
se estiver configurada. }
SendMessage(Application.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);
Inclua na seção uses: Windows
No Win95 podemos desligar o monitor afim de economizar
energia elétrica. Normalmente este recurso é controlado pelo
próprio Windows. Porém sua aplicação Delphi também pode fazer
isto. O exemplo abaixo desliga o monitor, aguarde 5 segundos
e re-liga monitor.
SendMessage(Application.Handle, WM_SYSCOMMAND,
SC_MONITORPOWER, 0);
Sleep(5000); { Aguarde 5 segundos }
SendMessage(Application.Handle, WM_SYSCOMMAND,
SC_MONITORPOWER, -1);
003 - Abrir e fechar o drive de CD-ROM
Inclua na seção uses: MMSystem
{ Para abrir }
mciSendString('Set cdaudio door open wait', nil, 0, handle);
{ Para fechar }
mciSendString('Set cdaudio door closed wait', nil, 0, handle);
004 - Impedir que o form seja arrastado para fora das margens da tela
- Na seção Private declare a procedure abaixo:
private
procedure WMMove(var Msg: TWMMove); message WM_MOVE;
- Abaixo da palavra implementation escreva a procedure
abaixo:
procedure TForm1.WMMove(var Msg: TWMMove);
begin
if Left < 0 then
Left := 0;
if Top < 0 then
Top := 0;
if Screen.Width - (Left + Width) < 0 then
Left := Screen.Width - Width;
if Screen.Height - (Top + Height) < 0 then
Top := Screen.Height - Height;
end;
Para testar:
- Execute o programa e tente arrastar o form para fora
das margens da tela e veja o que acontece.
005 - Mostrar mensagem mesmo que esteja no Prompt do DOS
Inclua na seção uses: Windows
SetForegroundWindow(Application.Handle);
ShowMessage('Teste');
006 - Copiar todos os registros de uma tabela para o Clipboard
Inclua na seção uses: Clipbrd
procedure TForm1.Button1Click(Sender: TObject);
const
SeparadorCampoValor = ': ';
SeparadorCampo = #13#10; { Quebra de linha }
SeparadorRegistro = '===========' + #13#10;
var
S: string;
I: integer;
begin
S := '';
Table1.First;
while not Table1.EOF do begin
for I := 0 to Table1.FieldCount -1 do
S := S + Table1.Fields[I].FieldName + SeparadorCampoValor +
Table1.Fields[I].AsString + SeparadorCampo;
S := S + SeparadorRegistro;
Table1.Next;
end;
Clipboard.AsText := S;
end;
Para testar:
- Execute este aplicativo;
- Clique no botão;
- Vá em outro aplicativo (ex: MS-Word) e mande colar (Ctrl+V).
CUIDADO! Não use este recurso com tabelas grandes, pois poderá usar memória demasiadamente. No teste que fiz, o tamanho da string S atingiu 20K e funcionou normalmente. Mas isto pode variar de uma máquina para outra.
007 - Copiar um registro de uma tabela para o Clipboard
Inclua na seção uses: Clipbrd
procedure TForm1.Button1Click(Sender: TObject);
const
SeparadorCampoValor = ': ';
SeparadorCampo = #13#10; { Quebra de linha }
var
S: string;
I: integer;
begin
S := '';
for I := 0 to Table1.FieldCount -1 do
S := S + Table1.Fields[I].FieldName + SeparadorCampoValor +
Table1.Fields[I].AsString + SeparadorCampo;
Clipboard.AsText := S;
end;
Para testar:
- Execute este aplicativo;
- Clique no botão;
- Vá em outro aplicativo (ex: MS-Word) e mande colar (Ctrl+V).
008 -
Criar sub-diretório no diretório do EXE
Inclua na seção uses: FileCtrl, SysUtils
function CriaSubDir(const NomeSubDir: string): boolean;
var
Caminho: string;
begin
Caminho := ExtractFilePath(ParamStr(0)) + NomeSubDir;
if DirectoryExists(Caminho) then
Result := true
else
Result := CreateDir(Caminho);
end;
Exemplo de uso:
- Chame a função no evento OnCreate do form:
procedure TForm1.FormCreate(Sender: TObject);
begin
if not CriaSubDir('MeuSubDir') then
ShowMessage('Não foi possível criar o sub-diretório MeuSubDir.');
end;
009 - Habilitar e Desabilitar CTRL+ALT+DEL
{ desabilita }
procedure TForm1.Button1Click(Sender:
TObject);
var
numero: integer;
begin
SystemParametersInfo(97,Word(true),@numero,0);
end;
{ habilita }
procedure TForm1.Button2Click(Sender:
TObject);
var
numero: integer;
begin
SystemParametersInfo(97,Word(false),@numero,0);
end;
010 - Personalizar a caixa de mensagem de exceções (erro) do Delphi
- Declare um método (procedure) na seção private do
form principal conforme abaixo:
private
procedure ManipulaExcecoes(Sender: TObject; E: Exception);
- Vá até a seção implementation e implemente este método,
conforme o exemplo:
procedure TForm1.ManipulaExcecoes(Sender: TObject; E: Exception);
begin
MessageDlg(E.Message + #13#13 +
'Suporte técnico:'#13 +
'tecnobyte@ulbrajp.com.br',
mtError, [mbOK], 0);
end;
- No evento OnCreate do Form principal escreva o código
abaixo:
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnException := ManipulaExcecoes;
end;
=== Para testar ===
- Coloque um Button no form;
- No evento OnClick deste botão coloque o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
begin
StrToInt('ABCD'); { Isto provoca uma exception }
end;
011 -
Implementar procedure Delay do Pascal no Delphi
Inclua na seção uses: Windows, Forms
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 }
012 - Enviar comandos de rolagem vertical para um TMemo
Inclua na seção uses: Windows
SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEDOWN, 0);
Onde:
Memo1.Handle = manipulador da janela do Memo1.
WM_VSCROLL = Mensagem do Windows - rolagem vertical.
SB_PAGEDOWN = Comanndo de rolagem - página para baixo.
Outros exemplos:
{ Página para cima }
SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEUP, 0);
{ Linha para baixo }
SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEDOWN, 0);
{ Linha para cima }
SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEUP, 0);
013 - Criar uma DLL de Bitmaps e usá-la
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.
014 Como extrair o icone de um executável
Image1.Picture.Icon.Handle:= ExtractIcon(Handle,PChar('c:\windows\calc.exe'),0);
015 - Criar form sem a barra de título que possa ser arrastado
- Crie um novo projeto;
- Mude as seguintes propriedades do Form1:
BorderStyle = bsNone, FormStyle = fsStayOnTop,
- Coloque um Label;
- Coloque um Timer;
- Altere o evento OnTimer do Timer1 conforme abaixo:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Caption := TimeToStr(Time);
end;
- Altere o evento OnCreate do Form1 conforme abaixo:
procedure TForm1.FormCreate(Sender: TObject);
begin
Width := 80;
Height := 40;
Label1.Left := 10;
Label1.Top := 10;
end;
- Vá na seção private do Form1 e declare a procedure abaixo:
private
procedure WMNCHitTest(var Msg: TMessage);
message WM_NCHitTest;
public
{ Public declarations }
end;
- Vá na seção implementation e escreva a procedure abaixo:
implementation
{$R *.DFM}
procedure TForm1.WMNCHitTest(var Msg: TMessage);
begin
if GetAsyncKeyState(VK_LBUTTON) < 0 then
Msg.Result := HTCAPTION
else
Msg.Result := HTCLIENT;
end;
- Execute e experimente arrastar form com o mouse.
016 - Obter status da memória do sistema
Inclua na seção uses: Windows, SysUtils
- Coloque um TMemo no form
- Coloque um TButton no form e altere seu OnClick
conforme abaixo:
procedure TForm1.Button1Click(Sender: TObject);
const
cBytesPorMb = 1024 * 1024;
var
M: TMemoryStatus;
begin
M.dwLength := SizeOf(M);
GlobalMemoryStatus(M);
Memo1.Clear;
with Memo1.Lines do begin
Add(Format('Memória em uso: %d%%',
[M.dwMemoryLoad]));
Add(Format('Total de memória física: %f MB',
[M.dwTotalPhys / cBytesPorMb]));
Add(Format('Memória física disponível: %f MB',
[M.dwAvailPhys / cBytesPorMb]));
Add(Format('Tamanho máximo do arquivo de paginação: %f MB',
[M.dwTotalPageFile / cBytesPorMb]));
Add(Format('Disponível no arquivo de paginação: %f MB',
[M.dwAvailPageFile / cBytesPorMb]));
Add(Format('Total de memória virtual: %f MB',
[M.dwTotalVirtual / cBytesPorMb]));
Add(Format('Memória virtual disponível: %f MB',
[M.dwAvailVirtual / cBytesPorMb]));
end;
end;
017 - Definir data/hora de um arquivo
Inclua na seção uses: SysUtils
{ Esta função altera a data e hora de um arquivo. Se obter
sucesso retorna true, caso contrário retorna false. }
function DefineDataHoraArq(NomeArq: string; DataHora: TDateTime): boolean;
var
F: integer;
begin
Result := false;
F := FileOpen(NomeArq, fmOpenWrite or fmShareDenyNone);
try
if F > 0 then
Result := FileSetDate(F, DateTimeToFileDate(DataHora)) = 0;
finally
FileClose(F);
end;
end;
{ Exemplo de uso 1: Usa a data atual do sistema (Now) }
if DefineDataHoraArq('c:\teste\logo.bmp', Now) then
ShowMessage('Data/Hora do arquivo definida com sucesso.')
else
ShowMessage('Não foi possível definir data/hora do arquivo.');
{ Exemplo de uso 2: Usa uma data fixa }
var
DataHora: TDateTime;
begin
{ Define a data para 5-Fev-1999 e a hora para 10:30 }
DataHora := EncodeDate(1999, 2, 5) + EncodeTime(10, 30, 0, 0);
if DefineDataHoraArq('c:\teste\logo.bmp', DataHora) then
ShowMessage('Data/Hora do arquivo definida com sucesso.')
else
ShowMessage('Não foi possível definir data/hora do arquivo.');
end;
018 - Mostrar o diálogo About (Sobre) do Windows
Inclua na seção uses: ShellApi
procedure TForm1.Button1Click(Sender: TObject);
begin
ShellAbout(Handle, 'Sistema Financeiro', 'Marcelo Senger',
Application.Icon.Handle);
end;
019 - Ocultar/exibir o cursor do mouse
Inclua na seção uses: Windows
- Escreva a função abaixo:
function MouseShowCursor(const Show: boolean): boolean;
var
I: integer;
begin
I := ShowCursor(LongBool(true));
if Show then begin
Result := I >= 0;
while I < 0 do begin
Result := ShowCursor(LongBool(true)) >= 0;
Inc(I);
end;
end else begin
Result := I < 0;
while I >= 0 do begin
Result := ShowCursor(LongBool(false)) < 0;
Dec(I);
end;
end;
end;
- Exemplos de uso:
MouseShowCursor(false); { Oculta o cursor }
MouseShowCursor(true); { Exibe o cursor }
020 - Converter de Hexadecimal para Inteiro
Inclua na seção uses: SysUtils
var
I: integer;
begin
I := StrToInt('$' + Edit1.Text);
{...}
end;
021 - Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condição
- Monte o form normalmente colocando DataSource, Table,
DBCtrlGrid e os DBEdit's, DBText's, etc.
- Escreva no manipulador do evento OnPaintPanel do
DBCtrlGrid conforme abaixo:
procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid;
Index: Integer);
begin
if Table.FieldByName('NomeDoCampo').AsFloat < 0 then
DBEdit1.Font.Color := clRed
else
DBEdit1.Font.Color := clBlue;
end;
Neste exemplo mudamos a cor da fonte do componente DBEdit, Porém, pode-se também mudar a cor do próprio componente (DBEdit1.Color).
022 - Colocar uma ProgressBar da StatusBar
- Coloque uma StatusBar no form.
- Adicione dois paineis na StatusBar (propriedade Panels).
- Ajuste as propriedades do primeiro painel conforme abaixo:
Style = psOwnerDraw
Width = 150
- Coloque uma ProgressBar no form e mude sua propriedade
Visible para false.
- No evento OnDrawPanel da StatusBar digite o código abaixo:
procedure TForm1.StatusBar1DrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
begin
{ Se for o primeiro painel... }
if Panel.Index = 0 then begin
{ Ajusta a tamanho da ProgressBar de acordo com
o tamanho do painel }
ProgressBar1.Width := Rect.Right - Rect.Left +1;
ProgressBar1.Height := Rect.Bottom - Rect.Top +1;
{ Pinta a ProgressBar no DC (device-context) da StatusBar }
ProgressBar1.PaintTo(StatusBar.Canvas.Handle, Rect.Left, Rect.Top);
end;
end;
- Coloque um Button no form
- Digite no evento OnClick do Button o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
I: integer;
begin
for I := ProgressBar1.Min to ProgressBar1.Max do begin
{ Atualiza a posição da ProgressBar }
ProgressBar1.Position := I;
{ Repinta a StatusBar para forçar a atualização visual }
StatusBar1.Repaint;
{ Aguarda 50 milisegundos }
Sleep(50);
end;
{ Aguarde 500 milisegundos }
Sleep(500);
{ Reseta (zera) a ProgressBar }
ProgressBar1.Position := ProgressBar1.Min;
{ Repinta a StatusBar para forçar a atualização visual }
StatusBar1.Repaint;
end;
- Execute e clique no botão para ver o resultado.
Com um pouco de criatividade podemos fazer outras coisas interessantes usando o evento OnDrawPanel da StatusBar.
023 - Executar um programa e aguardar sua finalização antes de continuar
Inclua na seção uses: Windows
{ Esta função faz isto. }
function ExecAndWait(const FileName, Params: string;
const WindowState: Word): boolean;
var
SUInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
begin
{ Coloca o nome do arquivo entre aspas. Isto é necessário devido
aos espaços contidos em nomes longos }
CmdLine := '"' + Filename + '"' + Params;
FillChar(SUInfo, SizeOf(SUInfo), #0);
with SUInfo do begin
cb := SizeOf(SUInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := WindowState;
end;
Result := CreateProcess(nil, PChar(CmdLine), nil, nil, false,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
PChar(ExtractFilePath(Filename)), SUInfo, ProcInfo);
{ Aguarda até ser finalizado }
if Result then begin
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
{ Libera os Handles }
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;
- Exemplo de uso:
ExecAndWait('c:\windows\notepad.exe', '', SW_SHOW);
Não se esqueça de informar o caminho (path) do arquivo completo. Esta função foi desenvolvida para Delphi 32 bits (2, 3, 4,...).
024 - Simular o pressionamento de uma combinação de teclas (ex: Ctrl+F2)
Inclua na seção uses: Windows
{ Mantém pressionada CTRL }
keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY or 0, 0);
{ Pressiona F2 }
keybd_event(VK_F2, 0, 0, 0);
{ Libera (solta) CTRL }
keybd_event(VK_CONTROL, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
Neste exemplo pressionamos Ctrl+F2. Não se esqueça das teclas que precisam manter pressionadas: Ctrl, Alt, Shift.
025 - Simular o pressionamento de uma tecla
Inclua na seção uses: Windows
A API keybd_event do Windows serve para fazer isto. No exemplo
abaixo estamos simulando o pressionamento da tecla F2:
keybd_event(VK_F2, 0, 0, 0);
Para testar faça o exemplo a seguir:
- Mude a propriedade KeyPreview do form para true.
- Escreva no evento OnKeyDown do form como abaixo:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_F2 then
ShowMessage('F2 pressionada');
end;
- Coloque um botão e escreva no OnClick (do botão) como abaixo:
procedure TForm1.Button1Click(Sender: TObject);
begin
keybd_event(VK_F2, 0, 0, 0);
end;
Consulte as constantes para os códigos das teclas (ex: VK_RETURN, VK_DOWN, etc).
026 - Ligar/desligar a tecla Caps Lock
Inclua na seção uses: Windows
{ Esta função liga/desliga Caps Lock, conforme o parãmetro
State }
procedure tbSetCapsLock(State: boolean);
begin
if (State and ((GetKeyState(VK_CAPITAL) and 1) = 0)) or
((not State) and ((GetKeyState(VK_CAPITAL) and 1) = 1)) then
begin
keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY or 0, 0);
keybd_event(VK_CAPITAL, $45, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);
end;
end;
{ Exemplos de uso: }
tbSetCapsLock(true); { Liga Caps Lock }
tbSetCapsLock(false); { Desliga Caps Lock }
Aparentemente, podemos usar esta mesma técnica para ligar/desligar Num Lock. Neste caso trocaríamos VK_CAPITAL por VK_NUMLOCK. Por incrível que pareça não funcionou (pelo menos no teste que fiz). E tem mais: isto está na documentação do (R)Windows.
027 - Verificar se uma determinada tecla está pressionada
Inclua na seção uses: Windows
{ Esta função retorna true se a tecla informada
estiver pressionada. False em caso contrário. }
function tbKeyIsDown(const Key: integer): boolean;
begin
Result := GetKeyState(Key) and 128 > 0;
end;
{ Exemplos de uso: }
if tbKeyIsDown(VK_CONTROL) then
{ Tecla Ctrl pressionada }
if tbKeyIsDown(VK_MENU) then
{ Tecla Alt pressionada }
if tbKeyIsDown(VK_SHIFT) then
{ Tecla Shift pressionada }
if tbKeyIsDown(VK_F2) then
{ Tecla F2 pressionada }
Qualquer tecla pode ser verificada. Para isto basta saber o código virtual (Virtual Key Code) da tecla.
028 - Verificar o estado de NumLock e CapsLock
Inclua na seção uses: Windows
{ Esta função retorna true se a tecla informada estiver
ligada. False em caso contrário }
function tbKeyIsOn(const Key: integer): boolean;
begin
Result := GetKeyState(Key) and 1 > 0;
end;
{ Exemplo de uso: }
if tbKeyIsOn(VK_NUMLOCK) then
{ ... NumLock está ligada }
else
{ ... NumLock está desligada }
Qualquer tecla que possua os estados On/Off pode ser verificada. Basta, para isto, saber seu código. O código de CapsLock é VK_CAPITAL.
029 - Configurar linhas de diferentes alturas em StringGrid
- Coloque o StringGrid no form. - No evento OnCreate do form coloque o código abaixo: procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.RowHeights[0] := 15; StringGrid1.RowHeights[1] := 20; StringGrid1.RowHeights[2] := 50; StringGrid1.RowHeights[3] := 35; end;
Cuidado para não especificar uma linha inexistente.
030 - Adicionar o
evento OnClick do DBGrid
- 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.
O segredo principal desta dica está OnCreate do Form. A primeira instrução ativa o evento OnClick. A segunda instrução acessa o manipulador do evento OnClick. Para isto precisamos tratar o DBGrid como se fosse Form, pois o evento OnClick está declarado como protegido (protected) na classe TDBGrid.
031 - Criar caixas de diálogo em tempo de execução
Inclua na seção uses: Forms, StdCtrls, Buttons
A função abaixo demonstra a criação de uma caixa de diálogo
que pode ser usada para permitir ao usuário digitar o seu
nome:
{ Esta função retorna true se for pressionado OK e false
em caso contrário. Se for OK, o texto digitado pelo usuário
será copiado para a variável Nome }
function ObterNome(var Nome: string): boolean;
var
Form: TForm; { Variável para o Form }
Edt: TEdit; { Variável para o Edit }
begin
Result := false; { Por padrão retorna false }
{ Cria o form }
Form := TForm.Create(Application);
try
{ Altera algumas propriedades do Form }
Form.BorderStyle := bsDialog;
Form.Caption := 'Atenção';
Form.Position := poScreenCenter;
Form.Width := 200;
Form.Height := 150;
{ Coloca um Label }
with TLabel.Create(Form) do begin
Parent := Form;
Caption := 'Digite seu nome:';
Left := 10;
Top := 10;
end;
{ Coloca o Edit }
Edt := TEdit.Create(Form);
with Edt do begin
Parent := Form;
Left := 10;
Top := 25;
{ Ajusta o comprimento do Edit de acordo com a largura
do form }
Width := Form.ClientWidth - 20;
end;
{ Coloca o botão OK }
with TBitBtn.Create(Form) do begin
Parent := Form;
{ Posiciona de acordo com a largura do form }
Left := Form.ClientWidth - (Width * 2) - 20;
Top := 80;
Kind := bkOK; { Botão Ok }
end;
{ Coloca o botão Cancel }
with TBitBtn.Create(Form) do begin
Parent := Form;
Left := Form.ClientWidth - Width - 10;
Top := 80;
Kind := bkCancel; { Botão Cancel }
end;
{ Exibe o form e aguarda a ação do usuário. Se for OK... }
if Form.ShowModal = mrOK then begin
Nome := Edt.Text;
Result := true;
end;
finally
Form.Free;
end;
end;
Para chamar esta função siga o exemplo abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
begin
if ObterNome(S) then
Edit1.Text := S;
end;
Os componentes Label, Edit (var Edt) e BitBtn's (botões) não são destruídos explicitamente (Componente.Free). Isto não é necessário, pois ao criá-los informei como proprietário o Form (ex: TLabel.Create(Form)). Neste caso, estes componentes são destruídos automaticamente ao destruir o Form (Form.Free).
032 - Converter a primeira letra de um Edit para maiúsculo
with Edit2 do if Text <> '' then Text := AnsiUpperCase(Text[1]) + Copy(Text, 2, Length(Text)); Isto pode ser colocado, por exemplo, no OnExit do Edit. Você pode também converter durante a digitação. Para isto coloque o código abaixo no evento OnKeyPress do Edit: if Edit1.SelStart = 0 then Key := AnsiUpperCase(Key)[1] else Key := AnsiLowerCase(Key)[1];
033 - Verificar se uma string contém uma hora válida
- Use a função abaixo:
function StrIsTime(const S: string): boolean;
begin
try
StrToTime(S);
Result := true;
except
Result := false;
end;
end;
- 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;
- 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;
A função Sleep é uma API do Windows e serve para paralisar a aplicação por um determinado dempo. Este tempo é em milisegundos.
- Salve o cursor atual
- Defina o novo cursor (crHourGlass é ampulheta)
- Faça o processamento
- Restaure o cursor.
var
PrevCur: TCursor;
begin
PrevCur := Screen.Cursor;
try
Screen.Cursor := crHourGlass;
{ Coloque aqui as instruções do processamento }
finally
Screen.Cursor := PrevCur;
end;
end;
Existem diversos outros cursores pré-definidos no Delphi. Dê uma olhada na propriedade Cursor de um componente visual para ver uma lista de todos eles. Você poderá também criar o seu próprio cursor.
Inclua na seção uses: Registry
Coloque no Form:
- três edits;
- dois botões.
Logo abaixo da palavra implementation declare:
type
{ Declara um tipo registro }
TFicha = record
Codigo: integer;
Nome: string[40];
DataCadastro: TDateTime;
end;
- Escreva o evento OnClick do Button1 conforme abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
Ficha: TFicha;
begin
{ Coloca alguns dados na variável Ficha }
Ficha.Codigo := StrToInt(Edit1.Text);
Ficha.Nome := Edit2.Text;
Ficha.DataCadastro := StrToDate(Edit3.Text);
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre uma chave (path). Se não existir cria e abre. }
Reg.OpenKey('Cadastro\Pessoas\', true);
{ Grava os dados (o registro) }
Reg.WriteBinaryData('Dados', Ficha, SizeOf(Ficha));
finally
Reg.Free;
end;
end;
- Escreva o evento OnClick do Button2 conforme abaixo:
procedure TForm1.Button2Click(Sender: TObject);
var
Reg: TRegistry;
Ficha: TFicha;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Se existir a chave (path)... }
if Reg.KeyExists('Cadastro\Pessoas') then
begin
{ Abre a chave (path) }
Reg.OpenKey('Cadastro\Pessoas', false);
{ Se existir o valor... }
if Reg.ValueExists('Dados') then
begin
{ Lê os dados }
Reg.ReadBinaryData('Dados', Ficha, SizeOf(Ficha));
Edit1.Text := IntToStr(Ficha.Codigo);
Edit2.Text := Ficha.Nome;
Edit3.Text := DateToStr(Ficha.DataCadastro);
end else
ShowMessage('Valor não existe no registro.')
end else
ShowMessage('Chave (path) não existe no registro.');
finally
Reg.Free;
end;
end;
Qualquer tipo de dado pode ser gravado e lido de forma binária no registro do Windows. Para isto você precisa saber o tamanho do dado. Para dados de tamanho fixo, use SizeOf(). Lembrete: não grave dados muito extensos no Registro do Windows (ex: imagens), pois isto prejudicará o desempenho do sistema.
- 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;
Nos testes que fiz, nem tudo funcionou adequadamente. Mas vale a pena experimentar.
Inclua na seção uses: Registry
- Coloque no form dois edits e dois botões.
- No evento OnClick do Button1 escreva o código abaixo:
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
{ Define a chave-raiz do registro }
Reg.RootKey := HKEY_CURRENT_USER;
{ Abre a chave (path). Se não existir, cria e abre. }
Reg.OpenKey('MeuPrograma\Configuração', true);
{ Escreve um inteiro }
Reg.WriteInteger('Numero', StrToInt(Edit1.Text));
{ Escreve uma string }
Reg.WriteString('Nome', Edit2.Text);
finally
Reg.Free;
end;
end;
- No evento OnClick do Button2, escreva:
procedure TForm1.Button2Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CURRENT_USER;
if Reg.KeyExists('MeuPrograma\Configuração') then
begin
Reg.OpenKey('MeuPrograma\Configuração', false);
if Reg.ValueExists('Numero') then
Edit1.Text := IntToStr(Reg.ReadInteger('Numero'))
else
ShowMessage('Não existe valor com o nome "Numero"');
if Reg.ValueExists('Nome') then
Edit2.Text := Reg.ReadString('Nome')
else
ShowMessage('Não existe valor com o nome "Nome"');
end else
ShowMessage('Não existe a chave no registro');
finally
Reg.Free;
end;
end;
User o aplicativo RegEdit.exe do windows para ver o registro. Cuidado para não alterar as configurações do Windows!
{ - 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);
Para converter a digitação para maiúsculo, coloque isto no evento OnKeyPress do DBGrid: Key := AnsiUpperCase(Key)[1]; Para converter para minúsculo, troque por: Key := AnsiLowerCase(Key)[1];
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.');
- Crie um índice na tabela com campo a ser usado na pesquisa. Coloque no Form: - Um DataSource - Um Table - Um DBGrid - Um Edit Altere as seguintes propriedades: - DataSource1.DataSet = Table1 - Table1.DatabaseName = 'NomeDoAlias' - Table1.TableName = 'NomeDaTabela' - Table1.IndexFieldNames = 'NomeDoCampo' - Table1.Active = true - DBGrid1.DataSource = DataSource1 Escreva a instrução abaixo no evento OnChange do Edit: Table1.FindNearest([Edit1.Text]);
Este exemplo considera que o campo seja tipo string. Para outros tipos de campos pode ocorrer erro dependendo dos valores digitados no Edit1.
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;
Se o comprimento desejado (Casas) não for suficiente para conter o número, serão colocados asteriscos.
Table1.FieldByName('Data').Clear;
{ ou }
Table1.FieldByName('Data').AsString := '';
Podemos usar este recurso para limpar também campos numéricos, string, etc.
Inclua na seção uses: dbTables
procedure tbAutoInc(Table: TTable; const FieldName: string);
var
Q: TQuery;
begin
if not Table.FieldByName(FieldName).IsNull then
Exit;
Q := TQuery.Create(nil);
try
Q.DatabaseName := Table.DatabaseName;
Q.SQL.Add('select max(' + FieldName + ') from ' + Table.TableName);
Q.Open;
try
Table.FieldByName(FieldName).AsInteger := Q.Fields[0].AsInteger +1;
finally
Q.Close;
end;
finally
Q.Free;
end;
end;
{ Chame esta procedure no evento BeforePost de um Table: }
procedure TForm1.Table1BeforePost(DataSet: TDataSet);
begin
tbAutoInc(Table1, 'Codigo');
end;
A função acima incrementa o campo somente se estiver vazio. Assim podemos dar ao usuário a opção de digitar neste campo ou deixá-lo vazio para que seja auto-incrementado. Existem várias outras formas de implementar este recurso.
Inclua na seção uses: WinSock
{ Esta função retorna o endereço IP do Dial-Up. }
function GetLocalIP : string;
type
TaPInAddr = array [0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe : PHostEnt;
pptr : PaPInAddr;
Buffer : array [0..63] of char;
I : Integer;
GInitData : TWSADATA;
begin
WSAStartup($101, GInitData);
Result := '';
GetHostName(Buffer, SizeOf(Buffer));
phe :=GetHostByName(buffer);
if phe = nil then Exit;
pptr := PaPInAddr(Phe^.h_addr_list);
I := 0;
while pptr^[I] <> nil do begin
result:=StrPas(inet_ntoa(pptr^[I]^));
result := StrPas(inet_ntoa(pptr^[I]^));
Inc(I);
end;
WSACleanup;
end;
Se o endereço IP for designado pelo servidor, a cada conecção teremos um endereço IP diferente e, obviamente, se não estivermos conectados, não conseguiremos obtê-lo.
Inclua na seção uses: DbPwDlg
{ Coloque um botão no form e escreve seu evento OnClick
como abaixo }
procedure TForm1.Button1Click(Sender: TObject);
var
pw: TPasswordDialog;
begin
pw := TPasswordDialog.Create(Self);
try
pw.Caption := 'Banco de Dados';
pw.GroupBox1.Caption := 'Senha';
pw.AddButton.Caption := '&Adicionar';
pw.RemoveButton.Caption := '&Remover';
pw.RemoveAllButton.Caption := 'Remover &Tudo';
pw.OKButton.Caption := '&OK';
pw.CancelButton.Caption := '&Cancelar';
pw.ShowModal;
finally
pw.Free;
end;
end;
As senhas adicionadas nesta caixa de diálogo são adicionadas na sessão (TSession) atual. Isto é útil quando colocamos senha em tabelas Paradox, ou mesmo quando trabalhamos com banco de dados Client Servidor, e queremos que o usuário digite a senha de acesso. Se não fizermos desta forma, nem adicionarmos via programação as senhas necessárias, esta caixa de diálogo será mostrada quando o programa tentar abrir uma tabela com senha. A grande vantagem aqui é que podemos traduzir os Caption's dos componentes.
Inclua na seção uses: ComCtrls
{ A versão desta biblioteca determina a aparência de alguns
controles do Delphi, tais como ToolBar e CoolBar. O exemplo
abaixo obtém a versão desta biblioteca.
Para este exemplo, coloque um TEdit e um TButton no Form.
O evento OnClick do botão escreva o código abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Ver: Cardinal;
MaiorVer, MenorVer: Word;
begin
Ver := GetComCtlVersion;
MaiorVer := HiWord(Ver);
MenorVer := LoWord(Ver);
Edit1.Text := IntToStr(MaiorVer) + '.' + IntToStr(MenorVer);
end;
Normalmente, a versão 4.72 está presente quando o Internet Explorer 4 está instalado.
{ 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;
Inclua na seção uses: Windows
{ About padrão do Windows }
ShellAbout(Handle, 'Windows', '', 0);
{ Personalizada }
ShellAbout(Handle, 'NomePrograma',
'Direitos autorais reservados a'#13'Fulano de Tal',
Application.Icon.Handle);
{ 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;
Inclua na seção uses: Windows
{ Você precisa saber:
- Caminho e nome do arquivo;
- A estrutura do arquivo de Help.
No exemplo abaixo abre o arquivo de ajuda da Calculadora
do Windows e vai para o tópico n. 100
}
procedure TForm1.Button1Click(Sender: TObject);
begin
WinHelp(0, 'c:\Win95\Help\Calc.hlp', HELP_CONTEXT, 100);
end;
Para utilizar um arquivo de ajuda em seu programa desenvolvido em Delphi, basta usar os recursos do próprio Delphi. O exemplo acima é somente para mostrar o uso de uma API para este fim.
Inclua na seção uses: Windows
{ Esta função recebe o nome da variável de ambiente
que queremos acessar e retorna uma string com seu
valor, ou uma string vazia se a variável não existir. }
function tbGetEnvVar(const VarName: string): string;
var
I: integer;
begin
Result := '';
{ Obtém o comprimento da variável }
I := GetEnvironmentVariable('PATH', nil, 0);
if I > 0 then begin
SetLength(Result, I);
GetEnvironmentVariable('PATH', PChar(Result), I);
end;
end;
{ Para usá-la, faça como neste exemplo: }
Edit1.Text := tbGetEnvVar('PATH');
Inclua na seção uses: Windows
if IsZoomed(Form1.Handle) then
{ Form1 está maximizado }
else
{ Form2 NÃO está maximizado }
Inclua na seção uses: Windows
{ Os exemplos abaixo verificam se o cursor do mouse está em
Button1: }
{ Solução 1: }
var
Pt: TPoint;
Rct: TRect;
begin
GetCursorPos(Pt);
GetWindowRect(Button1.Handle, Rct);
if PtInRect(Rct, Pt) then
{ Está no botão }
else
{ NÃO está no botão }
end;
{ Solução 2: }
var
Pt: TPoint;
begin
GetCursorPos(Pt);
if WindowFromPoint(Pt) = Button1.Handle then
{ Está no botão }
else
{ Não está no botão }
end;
A API GetWindowRect obtém o retângulo (TRect) ocupado por uma janela. Podemos usar GetClientRect para obter o somente da parte cliente da janela. Podemos também usar a propriedade BoundsRect que existe na maioria dos componentes visuais, ou mesmo informar qualquer outro retângulo da tela. Se usarmos a propriedade BoundsRect, precisaremos converter as coordenadas clientes para coordenadas de tela (com a função ClientToScreen). Um lembrete: a solução 2 só poderá ser aplicada a controles ajanelados.
Inclua na seção uses: Windows
if IsIconic(Application.Handle) then
{ Minimizado }
else
{ Não minimizado }
Pode-se verificar qualquer janela (form). Só um lembrete: quando clicamos no botão de minimizar do form principal, na verdade ele é oculto e o Application é que é minizado.
Inclua na seção uses: Windows
procedure TForm1.Button1Click(Sender: TObject); begin FatalAppExit(0, 'Erro fatal na aplicação.'); end;
A função FatalAppExit é uma API do Windows. Esta mostra uma caixa de diálogo (normalmente branca) com a mensagem passada no segundo parâmetro. Quando a caixa de diálogo é fechada a aplicação é finalizada. O evento OnCloseQuery dos forms não são chamados quando usamos esta função.
procedure TForm1.Table1TipoGetText(Sender: TField; var Text: String;
DisplayText: Boolean);
begin
if DisplayText then begin
case Table1Tipo.AsInteger of
1: Text := 'Promissória';
2: Text := 'Duplicata';
3: Text := 'Boleto';
else
Text := 'Desconhecido';
end;
end else
Text := Table1Tipo.AsString;
end;
Ao exibir será exibido os nomes. Mas ao digitar continue com os 1, 2, 3, etc. Para usar este recurso em relatórios, acesse a propriedade DisplayText em vez de AsString para obter o valor do campo.
{ É um "maximizar" com jeitinho brasileiro... mas funciona.
No evento OnShow do form coloque o código abaixo: }
Top := 0;
Left := 0;
Width := Screen.Width;
Height := Screen.Height;
Nos testes que fiz, mesmo com a barra de tarefas marcada como "Sempre Visível", funcionou perfeitamente. Fiz os testes usando o Win95. Talvez em novas versões, possa apresentar problemas.
Inclua na seção uses: Registry, SysUtils, Windows
{ Esta função retorna true se Local Share estiver "TRUE".
Caso contrário, retorna false. }
function tbBDELocalShare: boolean;
const
BdeKey = 'SOFTWARE\Borland\Database Engine\Settings\SYSTEM\INIT';
Ident = 'LOCAL SHARE';
var
Reg: TRegistry;
begin
Result := false;
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey(BdeKey, False) then
if Reg.ValueExists(Ident) then
Result := UpperCase(Reg.ReadString(Ident)) = 'TRUE';
finally
Reg.Free;
end;
end;
{ Use-a como abaixo: }
if tbBDELocalShare then
{ Local Share está TRUE }
else
{ Local Share está FALSE }
A função acima faz a verificação no registro do Windows. Por isto está sujeita a falha caso o BDE coloque as configurações em outro local (é o caso do BDE salvar as configurações no formato do Windows 3.x). O ideal seria usar uma API do BDE, mas até o momento não conheço uma que retorne esta informação. Caso alguém saiba, queira por gentileza nos informar.
Inclua na seção uses: Windows
{ 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;
Aqui o parâmetro passado foi 'MinhaSenha'. Você deverá trocar 'MinhaSenha' por algo que apenas você saiba (uma senha). Caso uma pessoa conheça esta senha, será possível chamar este programa passando-a como parâmetro. Neste caso sua "trava" estará violada.
var contador: Integer;
Início da página
Inclua na seção uses: Windows
{ Para inverter: }
SwapMouseButton(true);
{ Para voltar ao normal: }
SwapMouseButton(false);
Inclua na seção uses: Windows
{ - Coloque um botão no form e escreva seu OnClick como
abaixo: }
procedure TForm1.Button6Click(Sender: TObject);
var
Tempo: Cardinal;
begin
{ Obtém }
Tempo := GetDoubleClickTime;
ShowMessage(IntToStr(Tempo) + ' milisegundos');
{ Define }
SetDoubleClickTime(300);
end;
Um duplo-click nada mais é que dois cliques consecutivos (óbvio). Porém estes dois cliques podem ser interpretados de duas formas: dois cliques isolados ou um duplo-click. Para o Windows resolver esta situação, ele usa o que chamo de "tempo máximo do duplo-click". Se o intervalo entre o primeiro e o segundo click for menor ou igual a esse tempo, então houve duplo-click. E você pode alterar este tempo. O padrão do Windows é 500 milisegundos. Um tempo muito curto (ex: 100), faz com que o duplo-click tenha que ser muito rápido (quase impossível), enquanto muito longo (ex: 2000) faz com que o Windows interprete dois clicks isolados como duplo-click.
Inclua na seção uses: Windows
{ No form:
- Coloque um memo;
- Coloque um edit;
- Coloque um botão e escreva seu OnClick como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Attr: DWord;
begin
Memo1.Clear;
Attr := GetFileAttributes(PChar(Edit1.Text));
if Attr > 0 then
with Memo1.Lines do begin
if (Attr and FILE_ATTRIBUTE_ARCHIVE) > 0 then
Add('Archive');
if (Attr and FILE_ATTRIBUTE_COMPRESSED) > 0 then
Add('Compressed');
if (Attr and FILE_ATTRIBUTE_DIRECTORY) > 0 then
Add('Directory');
if (Attr and FILE_ATTRIBUTE_HIDDEN) > 0 then
Add('Hidden');
if (Attr and FILE_ATTRIBUTE_NORMAL) > 0 then
Add('Normal');
if (Attr and FILE_ATTRIBUTE_OFFLINE) > 0 then
Add('OffLine');
if (Attr and FILE_ATTRIBUTE_READONLY) > 0 then
Add('ReadOnly');
if (Attr and FILE_ATTRIBUTE_SYSTEM) > 0 then
Add('System');
if (Attr and FILE_ATTRIBUTE_TEMPORARY) > 0 then
Add('Temporary');
end;
end;
Inclua na seção uses: Windows
{ - Coloque um memo (TMemo) no form;
- Coloque um botão e altere seu OnClick como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
SetoresPorAgrup, BytesPorSetor, AgrupLivres,
TotalAgrup: DWord;
begin
Memo1.Clear;
if GetDiskFreeSpace('C:\', SetoresPorAgrup,
BytesPorSetor, AgrupLivres, TotalAgrup) then
with Memo1.Lines do begin
Add('Setores por agrupamento: ' + IntToStr(SetoresPorAgrup));
Add('Bytes por setor: ' + IntToStr(BytesPorSetor));
Add('Agrupamentos livres: ' + IntToStr(AgrupLivres));
Add('Total de agrupamentos: ' + IntToStr(TotalAgrup));
Add('----- Resumo -----');
Add('Total de bytes: ' +
IntToStr(TotalAgrup * SetoresPorAgrup * BytesPorSetor));
Add('Bytes livres: ' +
IntToStr(AgrupLivres * SetoresPorAgrup * BytesPorSetor));
end;
end;
{ O exemplo acima retorna as medidas em Bytes, Setores e
Agrupamentos. Se preferir algo mais simples,
use funções do Delphi. Veja: }
Memo1.Lines.Add('Total de bytes: ' + IntToStr(DiskSize(3)));
Memo1.Lines.Add('Bytes livres: ' + IntToStr(DiskFree(3)));
{ Onde o parâmetro (3) é o número da unidade, sendo
1=A, 2=B, 3=C, ... }
Para usar as funções DiskSize e DiskFree coloque SysUtils em uses.
Inclua na seção uses: Windows, Dialogs
{ - Coloque um edit (Edit1) e um botão no form;
- Altere o OnClick do botão conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
Tipo: byte;
begin
Tipo := GetDriveType(PChar(Edit1.Text[1] + ':\'));
case Tipo of
0: S := 'Tipo indeterminado';
1: S := 'Drive não existe';
DRIVE_REMOVABLE: S := 'Disco removível';
DRIVE_FIXED: S := 'Disco Fixo';
DRIVE_REMOTE: S := 'Unidade de rede';
DRIVE_CDROM: S := 'CD-ROM';
DRIVE_RAMDISK: S := 'RAM Disk';
else
S := 'Erro';
end;
ShowMessage(S);
end;
{ Para pegar o tipo da unidade atual troque...}
Tipo := GetDriveType(PChar(Edit1.Text[1] + ':\'));
{ por }
Tipo := GetDriveType(nil);
Para testar digite a letra do drive no Edit1 e clique no botão. A unit Dialogs foi colocada no uses apenas por causa da procedure ShowMessage. Para exibir todas as unidades existentes e seus respectivos tipos, use a função tbGetDrives (da pergunta 64) em conjunto com este exemplo.
Inclua na seção uses: Windows, System
{ - Coloque um memo (TMemo) no form;
- Coloque um botão e escreve seu evento
OnClick como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
SLabel, SSysName: PChar;
Serial, FileNameLen, X: DWord;
begin
Memo1.Clear;
GetMem(SLabel, 255);
GetMem(SSysName, 255);
try
GetVolumeInformation('C:\', SLabel, 255,
@Serial, FileNameLen, X, SSysName, 255);
with Memo1.Lines do begin
Add('Nome do volume (Label): ' + string(SLabel));
Add('Número Serial: ' + IntToHex(Serial, 8));
Add('Tamanho máximo p/ nome arquivo: ' +
IntToStr(FileNameLen));
Add('Sistema de Arquivos: ' + string(SSysName));
end;
finally
FreeMem(SLAbel, 255);
FreeMem(SSysName, 255);
end;
end;
Inclua na seção uses: Windows
{ Da unidade C: }
SetVolumeLabel('c:\', 'NovoLabel');
{ Da unidade atual: }
SetVolumeLabel(nil, 'NovoLabel');
Veja a pergunta nº 66.
Inclua na seção uses: Windows
{ A função abaixo retorna uma string contendo
as letras de unidades de discos presentes. }
function tbGetDrives: string;
var
Drives: DWord;
I: byte;
begin
Result := '';
Drives := GetLogicalDrives;
if Drives <> 0 then
for I := 65 to 90 do
if ((Drives shl (31 - (I - 65))) shr 31) = 1 then
Result := Result + Char(I);
end;
{ Para saber se uma determinada unidade está presente,
basta fazer algo como: }
if Pos('A', tbGetDrives) > 0 then
ShowMessage('Unidade A: presente.')
else
ShowMessage('Unidade A: ausente.');
A string retornada pela função tbGetDrives está sempre em letras maiúsculas.
{ À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
Isto pode não funcionar se ValorReal for muito alto. Isto por causa da multiplicação que poderá estourar a capacidade do tipo em uso. Lembre-se: os tipos reais aceitam valores muuuiiiito altos.
procedure tbDBDeleteAll(const DataSet: TDataSet);
begin
with DataSet do
while RecordCount > 0 do
Delete;
end;
{ Chame-a como nos exemplos abaixo: }
tbDBDeleteAll(Table1);
ou
tbDBDeleteAll(Query1);
Se houver um filtro ou range ativo, somente os registros filtrados serão excluídos. Portanto é diferente de Table1.EmptyTable. Esta função poderá ser chamada no evento BeforeDelete do Table (ou Query) principal em um formulário mestre-detalhe para excluir os itens (da parte detalhe).
{ 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;
{ Usando comandos da impressora podemos fazer isto de uma
forma bastante simples. Quando enviamos o caractere ASCII
número 8 (oito) para a impressora, a cabeça de impressão
retrocede uma posição, pois este caractere é o BackSpace.
Então podemos imprimir a letra sem acento e, sem seguida,
voltar e imprimir o acento desejado. Vejamos um exemplo:
- Coloque um botão no form;
- Altere o evento OnClick deste botão conforme abaixo:
}
procedure TForm1.Button2Click(Sender: TObject);
var
F: TextFile;
begin
AssignFile(F, 'LPT1');
Rewrite(F);
try
{ Regra: caractere sem acento + chr(8) + acento }
WriteLn(F, 'Este e' + #8 + '''' + ' um teste.');
WriteLn(F, 'Acentuac' + #8 + ',a' + #8 + '~o.');
WriteLn(F, 'Vovo' + #8 + '^');
WriteLn(F, 'U' + #8 + '''' + 'ltimo.');
WriteLn(F, #12); // Eject
finally
CloseFile(F);
end;
end;
Usando este recurso, a acentuação não fica excelente, mas melhora bastante.
{ A impressora Epson LX-300 dispõe de um comando que justifica
o texto. Este recurso é interessante, pois com ele podemos
continuar a enviar os comandos de formatação de caracteres
como condensado, negrito, italico, expandido, etc.
Para o exemplo abaixo:
- Coloque um botão no form;
- Altere o evento OnClick deste botão como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
const
cJustif = #27#97#51;
cEject = #12;
{ Tamanho da fonte }
c10cpi = #18;
c12cpi = #27#77;
c17cpi = #15;
cIExpandido = #14;
cFExpandido = #20;
{ Formatação da fonte }
cINegrito = #27#71;
cFNegrito = #27#72;
cIItalico = #27#52;
cFItalico = #27#53;
var
Texto: string;
F: TextFile;
begin
Texto := c10cpi +
'Este e um teste para impressora Epson LX 300. ' +
'O objetivo e imprimir texto justificado sem deixar ' +
'de usar formatacao, tais como: ' +
cINegrito + 'Negrito, ' + cFNegrito +
cIItalico + 'Italico, ' + cFItalico +
c17cpi + 'Condensado (17cpi), ' + c10cpi +
c12cpi + '12 cpi, ' + c10cpi +
cIExpandido + 'Expandido.' + cFExpandido +
' Este e apenas um exemplo, mas voce podera adapta-lo ' +
'a sua realidade conforme a necessidade.';
AssignFile(F, 'LPT1');
Rewrite(F);
try
WriteLn(F, cJustif, Texto);
WriteLn(F, cEject);
finally
CloseFile(F);
end;
end;
Este recurso de justificação da Epson LX-300 pode ser usado em qualquer linguagem de programação.
{ Coloque o código abaixo imediatamente abaixo da palavra
implementation: }
const
SHFMT_ID_DEFAULT = $FFFF;
{ Opções de formatação }
SHFMT_OPT_QUICKFORMAT = $0000; { Formatação rápida }
SHFMT_OPT_FULL = $0001; { Formatação completa }
SHFMT_OPT_SYSONLY = $0002; { Copia sistema }
{ Códigos de errros }
SHFMT_ERROR = $FFFFFFFF; { Ocorreu erro }
SHFMT_CANCEL = $FFFFFFFE; { Foi cancelado }
SHFMT_NOFORMAT = $FFFFFFFD; { Não formatou }
function SHFormatDrive(Handle: HWND; Drive, ID, Options: Word):
LongInt; stdcall; external 'shell32.dll' name 'SHFormatDrive'
{ Coloque um botão no form e altere o evento OnClick dele
conforme abaixo: }
procedure TForm1.Button3Click(Sender: TObject);
var
Erro: DWord;
Msg: string;
begin
Erro := SHFormatDrive(Handle, 0, SHFMT_ID_DEFAULT, SHFMT_OPT_QUICKFORMAT);
case Erro of
SHFMT_ERROR: Msg := 'Ocorreu um erro.';
SHFMT_CANCEL: Msg := 'A formatação foi cancelada.';
SHFMT_NOFORMAT: Msg := 'Não foi possível formatar.';
else
Msg := 'Disco formatado com sucesso.';
end;
ShowMessage(Msg);
end;
Para formatação completa troque SHFMT_OPT_QUICKFORMAT por SHFMT_OPT_FULL. O segundo parâmetro (zero no exemplo) indica a unidade, sendo que A é 0 (zero), B é 1, etc.
uses ShellApi;
procedure TForm1.Button1Click(Sender:
TObject);
begin
ShellExecute(0,nil,'C:\WINDOWS\START MENU\DELPHI\Delphi3.lnk' ,nil, nil, SW_SHOWNORMAL);
end;
Inclua na seção uses: MMSystem
{ Síncrona: aguarda terminar a reprodução para continuar: }
SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_SYNC);
{ Assíncrona: a execução continua normalmente enquanto
ocorre a reprodução: }
SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_ASYNC);
{ Contínua: a reprodução é repetida num efeito de loop.
Este tipo de reprodução precisa ser assíncrona: }
SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav',
SND_ASYNC or SND_LOOP);
{ Interrompe uma reprodução contínua: }
SndPlaySound(nil, 0);
A reprodução contínua pode ser usada, por exemplo, para altertar o usuário em uma situação extremamente crítica. Se o equipamento não possuir placa de som, o arquivo não será reproduzido.
Inclua na seção uses: Registry
{ Coloque um botão no form e altere seu evento OnCkick
como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegIniFile;
S: string;
begin
Reg := TRegIniFile.Create('SOFTWARE\MICROSOFT\MS SETUP (ACME)\');
try
S := Reg.ReadString('USER INFO','DefName','');
S := S + #13;
S := S + Reg.ReadString('USER INFO','DefCompany','');
ShowMessage(S);
finally
Reg.free;
end;
end;
Veja a pergunta nº 53.
Inclua na seção uses: ShellApi
{ - Coloque um botão no form e altere o evento OnClick
deste botão conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Dados: TSHFileOpStruct;
begin
FillChar(Dados,SizeOf(Dados), 0);
with Dados do
begin
wFunc := FO_COPY;
pFrom := PChar('c:\teste\*.txt');
pTo := PChar('a:\');
fFlags:= FOF_ALLOWUNDO;
end;
SHFileOperation(Dados);
end;
Esta forma de copiar arquivos oferecem várias vantagens. O Shell avisa para pôr um próximo disco quando o atual estiver cheio. Mostra a barra de progresso. Pode copiar arquivos usando máscara de uma forma extremamente simples.
{ - Coloque um Label no form (Label1);
- Mude a propriedade KeyPreview do form para true;
- Altere o evento OnKeyDown do form como abaixo: }
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Label1.Caption :=
Format('O código da tecla pressionada é: %d', [Key]);
end;
Para testar execute e observe o Label enquanto pressiona as teclas desejadas.
Inclua na seção uses: Windows
{ Você já observou a caixa "Propriedades", aquela que mostra
as propriedades de um arquivo no Windows Explorer, não
aparece na lista do Alt+Tab e tampouco na barra de tarefas?
Isto ocorre porque ela funciona como uma ToolWindow, enquanto
os demais aplicativos funcionam como AppWindow. Porém podemos
mudar o comportamento de nossos programas feito em Delphi
para que se comportem como uma ToolWindow também.
Para experimentar, crie um novo projeto e altere o
Project1.dpr como abaixo (não esqueça do uses):
}
program Project1;
uses
Forms, Windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}
var
ExtendedStyle : Integer;
begin
Application.Initialize;
ExtendedStyle := GetWindowLong(Application.Handle, gwl_ExStyle);
SetWindowLong(Application.Handle, gwl_ExStyle, ExtendedStyle or
ws_Ex_ToolWindow and not ws_Ex_AppWindow);
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Ao executar observe a barra de tarefas e teste o Alt+Tab (seu programa não estará lá!).
{ Evento Som Padrão }
MessageBeep(0); { ou Beep; }
{ Evento Parada Crítica }
MessageBeep(16);
{ Evento Pergunta }
MessageBeep(32);
{ Evento Exclamação }
MessageBeep(48);
{ Evento Asterisco }
MessageBeep(64);
{ Usando número da coluna (zero é a primeira coluna): }
DBGrid1.SelectedIndex := 0;
{ Usando o nome do campo }
DBGrid1.SelectedField := Table1.FieldByName(Edit2.Text);
Aconselho usar o nome do campo quando o que importa é o campo e não a posição. Use o número da coluna somente quando o que importa é a posição, e não o campo.
{ 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);
{ 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;
Para este exemplo é necessário ter o arquivo de cursor conforme apontado e também ter, no form, um Button1. Para usar este cursor em outros componentes basta atribuir à propriedade Cursor do componente em questão o valor 1 (um). Exemplo: Edit1.Cursor := 1; Form1.Cursor := 1;, etc.
Inclua na seção uses: ShellApi
{ Coloque a procedure abaixo na seção implementation }
procedure ArqParaLixeira(const NomeArq: string; var MsgErro: string);
var
Op: TSHFileOpStruct;
begin
MsgErro := '';
if not FileExists(NomeArq) then begin
MsgErro := 'Arquivo não encontrado.';
Exit;
end;
FillChar(Op, SizeOf(Op), 0);
with Op do begin
wFunc := FO_DELETE;
pFrom := PChar(NomeArq);
fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT;
end;
if ShFileOperation(Op) <> 0 then
MsgErro := 'Não foi possível enviar o arquivo para a lixeira.';
end;
{ - Coloque um botão no Form;
- Altere o evento OnClick do botão conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
S: string;
begin
ArqParaLixeira('c:\Diretorio\Teste.doc', S);
if S = '' then
ShowMessage('O arquivo foi enviado para a lixeira.')
else
ShowMessage(S);
end;
Table1.RecNo()
Se você está habituado a usar este código no filter... Table1.Filter := 'Nome = '''+ Edit1.Text + ''''; ou Table1.Filter := 'Data = ''' + DateToStr(Date) + ''''; Tente usar este: Table1.Filter := 'Nome = ' + QuotedStr(Edit1.Text); ou Table1.Filter := 'Data = ' + QuotedStr(DateToStr(Date));
A função QuitedStr() coloca apóstrofos envolvendo a string. Se houver um apóstrofo como parte da string, ela o subtitui por dois apóstrofos, para que seja corretamente interpretado.
Inclua na seção uses: MMSystem
PlaySound('C:\ArqSom.wav', 1, SND_ASYNC);
Troque o nome do arquivo (C:\ArqSom.wav) pelo arquivo desejado.
{ 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);
Se quizer que a janela do programa não apareça, troque sw_ShowNormal por sw_Hide.
{ - 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;
Este exemplo fecha o MS Word 97 se estiver aberto. A mensagem WM_QUIT fecha o programa da forma "ignorante". Isto significa que se houver dados não salvos, o programa a ser fechado não oportunidade para salvá-los. Uma alternativa mais suave é trocar a mensagem WM_QUIT por WM_CLOSE. Veja as perguntas 18 e 36.
{ - 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;
{ - Crie um novo projeto. Este já deverá ter o Form1;
- Adicione um novo Form (Form2);
- Coloque, no Form1, um TMediaPlayer (paleta System)
e um botão;
- Altere o evento OnClick do botão como abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
begin
with MediaPlayer1 do begin
FileName := 'c:\speedis.avi';
Open;
{ Ajusta tamanho do Form }
with MediaPlayer1.DisplayRect do begin
Form2.ClientHeight := Bottom - Top;
Form2.ClientWidth := Right - Left;
end;
Display := Form2;
Form2.Show;
Play;
end;
end;
Em vez de ajustar o Form ao vídeo, podemos ajustar o vídeo ao Form. Para isto troque o trecho with..end; por MediaPlayer1.DisplayRect := Form2.ClientRect;
{ 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;
Se quizer usar este função em outras unit's, coloque a declaração do tipo TChars na seção interface. Coloque aí também uma declaração da função FilterChars. E não se esqueça da cláusula uses.
{ Isto coloca zeros à esquerda do número até completar 6 casas }
S := FormatFloat('000000', 5);
"S" precisa ser uma variável string.
{ - Coloque um Button no Form;
- Altere o evento OnClick deste Button conforme abaixo: }
procedure TForm1.Button2Click(Sender: TObject);
var
SR: TSearchRec;
I: integer;
Origem, Destino: string;
begin
I := FindFirst('c:\Origem\*.*', faAnyFile, SR);
while I = 0 do begin
if (SR.Attr and faDirectory) <> faDirectory then begin
Origem := 'c:\Origem\' + SR.Name;
Destino := 'c:\Destino\' + SR.Name;
if not CopyFile(PChar(Origem), PChar(Destino), true) then
ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino);
end;
I := FindNext(SR);
end;
end;
No exemplo acima, se o arquivo já existir no destino, a função falha (não copia). Para que a função possa sobreescrever o arquivo destino (caso exista), altere o último parâmetro de CopyFile para false. CUIDADO! Se um arquivo for sobreescrito, estará perdido para sempre! Veja as perguntas nº 35 e 53.
{ - Coloque um Button no Form;
- Altere o evento OnClick deste Button conforme abaixo: }
procedure TForm1.Button2Click(Sender: TObject);
var
Origem, Destino: string;
begin
Origem := 'c:\Origem\NomeArq.txt';
Destino := 'c:\Destino\NomeArq.txt';
if not CopyFile(PChar(Origem), PChar(Destino), true) then
ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino);
end;
No exemplo acima, se o arquivo já existir no destino, a função falha (não copia). Para que a função possa sobreescrever o arquivo destino (caso exista), altere o último parâmetro de CopyFile para false. CUIDADO! Se um arquivo for sobreescrito, estará perdido para sempre! Veja as perguntas nº 36 e 53.
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;
{ 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;
Há uma margem de erro nesta verificação: pode haver outros programas que possuam uma janela com os mesmos nomes. Você mesmo pode criar aplicativos em Delphi e, propositadamente, criar uma janela com um destes nomes. Veja a pergunta nº 18.
{ - Coloque um Button no Form;
- Altere o evento OnClick do Button conforme abaixo: }
procedure TForm1.Button2Click(Sender: TObject);
var
SR: TSearchRec;
I: integer;
begin
I := FindFirst('c:\Teste\*.*', faAnyFile, SR);
while I = 0 do begin
if (SR.Attr and faDirectory) <> faDirectory then
if not DeleteFile('c:\Teste\' + SR.Name) then
ShowMessage('Não consegui excluir c:\Teste\' + SR.Name);
I := FindNext(SR);
end;
end;
No exemplo acima todos os arquivos do diretório c:\Teste serão excluídos. CUIDADO! Arquivos excluídos desta forma não vão para a lixeira. Veja a pergunta nº 46.
Inclua na seção uses: ComObj
{ - Coloque um botão no Form;
- Altere o evento OnClick do botão conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
Word: Variant;
begin
{ Abre o Word }
Word := CreateOleObject('Word.Application');
try
{ Novo documento }
Word.Documents.Add;
try
{ Adiciona tabela de 2 linhas e 3 colunas }
Word.ActiveDocument.Tables.Add(
Range := Word.Selection.Range,
NumRows := 2,
NumColumns := 3);
{ Escreve na primeira célula }
Word.Selection.TypeText(Text := 'Linha 1, Coluna 1');
{ Próxima célula }
Word.Selection.MoveRight(12);
{ Escreve }
Word.Selection.TypeText(Text := 'Linha 1, Coluna 2');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 1, Coluna 3');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 1');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 2');
Word.Selection.MoveRight(12);
Word.Selection.TypeText(Text := 'Linha 2, Coluna 3');
{ Auto-Formata }
Word.Selection.Tables.Item(1).Select; { Seleciona a 1º tabela }
Word.Selection.Cells.AutoFit; { auto-formata }
{ Imprime 1 cópia }
Word.ActiveDocument.PrintOut(Copies := 1);
ShowMessage('Aguarde o término da impressão...');
{ Para salvar... }
Word.ActiveDocument.SaveAs(FileName := 'c:\Tabela.doc');
finally
{ Fecha documento }
Word.ActiveDocument.Close(SaveChanges := 0);
end;
finally
{ Fecha o Word }
Word.Quit;
end;
end;
Foram usados neste exemplo o Delphi4 e MS-Word97.
Inclua na seção uses: DbiProcs
Os componentes TTable e TQuery possuem a propriedade
RecordCount que indicam a quantidade de registros da tabela.
No entanto esta propriedade é dependente de filtros, ou
seja, se tivermos uma tabela com dez registros com campo
"Codigo" de 1 a 10 e aplicarmos o filtro mostrado a seguir,
a propriedade RecordCount retornará 5 e não 10.
Table1.Filter := 'Codigo <= 5';
Table1.Filtered := true;
Se quizermos obter a quantidade total de registros,
independentemente de filtros, devemos usar uma API do BDE
conforme abaixo:
var
Total: integer;
begin
Check(DbiGetRecordCount(Table1.Handle, Total));
ShowMessage('Total de registros: ' + IntToStr(Total));
end;
Para testar o exemplo acima, o Table1 precisa estar aberto.
{ 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.
Para testar este programa você deverá compilar o projeto e fechar o Delphi. Depois, procure o Project1.exe (projeto compilado) usando o Windows Explorer e tente executá-lo mais de uma vez e veja o que acontece. Mas porque alterar o name do form principal para "DPGFormPrinc"? Este poderia ser qualquer outro nome, mas preferi usar as iniciais do meu nome (DPG). Procurei deixar um nome bem pessoal para não correr o risco de colocar um nome que possa ser encontrado em outro aplicativo do Windows. Por exemplo: se deixar Form1, será bem fácil encontrar outro aplicativo feito em Delphi que possua uma janela com este nome, o que causaria problema.
Inclua na seção uses: DbiProcs
{ Se estiver usando TTable, coloque nos eventos
AfterPost e AfterDelete a seguinte linha: }
dbiSaveChanges(Table1.Handle);
{ Para TQuery, a instrução é semelhante: }
dbiSaveChanges(Query1.Handle);
{ Quando usamos a propridade Position de um Form para
centralizá-lo estamos sujeitos a um inconveniente:
dependendo da posição/tamanho da barra de tarefas do
Windows, o nosso Form poderá ficar parcialmente coberto
por ela. Uma forma eficaz de resolver este problema é
posicionar o form considerando apenas a área livre do
Desktop. Vejamos este exemplo:
- Crie um novo projeto;
- Na seção implementation digite a procedure abaixo:
}
procedure FormPos(Form: TForm; const Horz, Vert: byte);
{ Horz: 1=esquerda, 2=centro, 3=direita
Vert: 1=topo, 2=centro, 3=em baixo }
var
R: TRect;
begin
if not SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0) then
R := Rect(0, 0, Screen.Width, Screen.Height);
with Form do
case Horz of
1: Form.Left := 0;
2: Form.Left := (R.Right - R.Left - Width) div 2;
3: Form.Left := R.Right - Width;
end;
with Form do
case Vert of
1: Form.Top := 0;
2: Form.Top := (R.Bottom - R.Top - Height) div 2;
3: Form.Top := R.Bottom - Height;
end;
end;
{ - Coloque dois TEdit's: Edit1 e Edit2;
- Coloque um TButton e altere o evento OnClick deste
conforme abaixo:
}
procedure TForm1.Button1Click(Sender: TObject);
begin
FormPos(Form1, StrToInt(Edit1.Text), StrToInt(Edit2.Text));
end;
Para testar, execute este exemplo e experimente digitar números de 1 a 3 em ambos os Edit's e clique no Button para ver o resultado. O Edit1 indica a posição horizontal (esquerda, centro e direita) e o Edit2 indica a posição vertical (topo, centro e em baixo).
{ 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;
O objeto Screen contém várias informações importantes: largura e altura da tela, fontes instaladas no Windows, etc.
Inclua na seção uses: System, SysUtils
{ - Crie um novo projeto;
- Na seção implementation da Unit1 digite a função abaixo: }
function DriveOk(Drive: Char): boolean;
var
I: byte;
begin
Drive := UpCase(Drive);
if not (Drive in ['A'..'Z']) then
raise Exception.Create('Unidade incorreta');
I := Ord(Drive) - 64;
Result := DiskSize(I) >= 0;
end;
{ - Coloque no Form1 um TEdit (Edit1)
- Coloque no Form1 um TButton
- Altere o evento OnClick do Button1 conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
begin
if DriveOk(Edit1.Text[1]) then
ShowMessage('Drive não preparado')
else
ShowMessage('Drive OK');
end;
Para testar você deverá executar o exemplo e digitar no Edit a letra do drive a ser testado (não precisa os dois-pontos). Após digitar, clique no Button1.
{ Crie uma nova Unit conforme abaixo: }
unit uFormFunc;
interface
uses Forms, IniFiles, SysUtils, Messages, Windows;
procedure tbLoadFormStatus(Form: TForm; const Section: string);
procedure tbSaveFormStatus(Form: TForm; const Section: string);
implementation
procedure tbSaveFormStatus(Form: TForm; const Section: string);
var
Ini: TIniFile;
Maximized: boolean;
begin
Ini := TIniFile.Create(ChangeFileExt(
ExtractFileName(ParamStr(0)),'.INI'));
try
Maximized := Form.WindowState = wsMaximized;
Ini.WriteBool(Section, 'Maximized', Maximized);
if not Maximized then begin
Ini.WriteInteger(Section, 'Left', Form.Left);
Ini.WriteInteger(Section, 'Top', Form.Top);
Ini.WriteInteger(Section, 'Width', Form.Width);
Ini.WriteInteger(Section, 'Height', Form.Height);
end;
finally
Ini.Free;
end;
end;
procedure tbLoadFormStatus(Form: TForm; const Section: string);
var
Ini: TIniFile;
Maximized: boolean;
begin
Maximized := false; { Evita msg do compilador }
Ini := TIniFile.Create(ChangeFileExt(
ExtractFileName(ParamStr(0)),'.INI'));
try
Maximized := Ini.ReadBool(Section, 'Maximized', Maximized);
Form.Left := Ini.ReadInteger(Section, 'Left', Form.Left);
Form.Top := Ini.ReadInteger(Section, 'Top', Form.Top);
Form.Width := Ini.ReadInteger(Section, 'Width', Form.Width);
Form.Height := Ini.ReadInteger(Section, 'Height', Form.Height);
if Maximized then
Form.Perform(WM_SIZE, SIZE_MAXIMIZED, 0);
{ A propriedade WindowState apresenta Bug.
Por isto usei a mensagem WM_SIZE }
finally
Ini.Free;
end;
end;
end.
{
Em cada formulário que deseja salvar/restaurar:
- Inclua na seção uses: uFormFunc
- No evento OnShow digite:
tbLoadFormStatus(Self, Self.Name);
- No evento OnClose digite:
tbSaveFormStatus(Self, Self.Name);
}
O arquivo INI terá o nome do executável e extensão INI e será salvo no diretório do Windows. A palavra Self indica o Form relacionado com a unit em questão. Poderia ser, por exemplo, Form1, Form2, etc. Onde aparece Self.Name poderá ser colocado um nome a sua escolha. Este nome será usado como SectionName no arquivo INI e deve ser idêntico no evento OnShow e OnClose de um mesmo Form, porém para cada Form deverá ser usado um nome diferente.
1. A forma mais simples consiste em alterar a altura (Height)
da banda Detail do nosso relatório de modo que a altura
total da página seja inferior a duas vezes a altura da banda.
Desta forma, cada registro será impresso em uma nova página,
teoricamente por falta de espaço na página atual.
2. Uma outra forma mais sofisticada é usar o evento AfterPrint
da banda Detail. Nele testamos se ainda não chegou no fim
da tabela e, caso positivo, pedimos uma nova página:
if not Table1.EOF then
QuickRep1.NewPage;
Deve existir outras alternativas, mas as duas anteriores
funcionaram bem nos testes realizados.
TForm1 = class(TForm)
procedure FormCreate(Sender:Tobject);
procedure FormPaint(Sender:TObject);
private
{ Private declarations }
grafico: TBitmap;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1. FormCreate(Sender:Tobject);
begin
grafico:= TBitmap.Create;
grafico.LoadFromFile ('diretório e nome da figura.bmp');
end;
procedure TForm1. FormPaint(Sender:TObject);
begin
Form1.Canvas.Draw(0,0,grafico);
end;
end.
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;
Para testar o exemplo anterior crie um novo projeto e coloque no Form1 um TStringGrid. Mude os três eventos mencionados conforme os exemplos. Execute e experimente digitar nas céluas 1 e 2 da primeira linha (na parte não fixada, é claro!).
{
* Crie um novo Projeto. Este certamente terá o Form1.
* Adicione um novo Form (Form2).
* Coloque no Form2 dois botões TBitBtn.
* Mude a propriedade Kind do BitBtn1 para bkOK.
* Mude a propriedade Kind do BitBtn2 para bkCancel.
* Vá no menu "Project/Options" na aba "Forms" e passe o
Form2 de "Auto-create Forms" para "Available Forms".
* Abra o arquivo Project.dpr (menu Project/View Source).
* Altere o conteúdo deste arquivo conforme abaixo:
}
program Project1;
uses
Forms, Controls,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.RES}
var
F: TForm2;
begin
F := TForm2.Create(Application);
try
if F.ShowModal = mrOK then begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
finally
F.Free;
end;
end.
O Form2 do exemplo é o Form de LogOn. Este deverá ser preparado para que se possa escolher o usuário, digitar a senha, etc.
Inclua na seção uses: Windows
{ Coloque um botão no form e altera o evento OnClick dele
conforme abaixo: }
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRect;
begin
{ Pega o retângulo da área cliente do form }
R := GetClientRect;
{ Converte as coordenadas do form em coordenadas da tela }
R.TopLeft := ClientToScreen(R.TopLeft);
R.BottomRight := ClientToScreen(R.BottomRight);
{ Limita a região de movimentação do mouse }
ClipCursor(@R);
ShowMessage('Tente mover o mouse para fora da área cliente do Form');
{ Libera a movimentação }
ClipCursor(nil);
end;
Cuidado! Isto pode irritar o usuário do seu programa.
Muitas vezes precisamos saber qual o nome de classe de uma determinada janela. Quando são janelas desenvolvidas por nós, você olha no código-fonte. Mas e se não for, como é o caso do Delphi? Por exemplo: Para verificar se o Delphi está sendo executado, procuramos no Windows pela janela cujo nome de classe seja TAppBuilder. Mas como verificar então se o Internet Explorer está sendo executado? Precisaremos saber o nome de classe da janela deste programa. Então o que fazer? Use o TBWinName. Pegue-o no download de www.ulbrajp.com.br/usuario/tecnobyte
Inclua na seção uses: Windows
{ Coloque no Form dois Botões: BotaoOcultar e BotaoExibir.
No evento OnClick do BotaoOcultar escreva: }
procedure TForm1.BotaoOcultarClick(Sender: TObject);
var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_HIDE);
end;
{ No evento OnClick do BotaoExibir escreva: }
procedure TForm1.BotaoExibirClick(Sender: TObject);
var
Janela: HWND;
begin
Janela := FindWindow('Shell_TrayWnd', nil);
if Janela > 0 then
ShowWindow(Janela, SW_SHOW);
end;
{ Execute e teste, clicando em ambos os botões }
A tarefa mais difícil é descobrir o nome de classe da janela da barra de tarefa do Windows, mas isto é fácil se você usar o TBWinName. Pegue-o no link download de www.ulbrajp.com.br/usuario/tecnobyte O resto é usar as APIs do Windows para manipulação de Janelas. Veja a pergunta nº 18.
Inclua na seção uses: Windows
{ Na seção "private" do Form principal acrescente: }
procedure AppMsg(var Msg: TMsg; var Handled: Boolean);
{ Na seção "implementation" acrescente (troque TForm1 para
o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.Message = wm_SysCommand) and
(Msg.wParam = sc_ScreenSave) then
Handled := true;
end;
{ No evento "OnCreate" do form principal, coloque: }
Application.OnMessage := AppMsg;
Inclua na seção uses: Windows
{ Coloque um TTimer no Form desejado. Define a propriedade
Interval do Timer para 1000 (1 segundo). Modifique
o evento OnTimer do Timer conforme abaixo: }
procedure TForm1.Timer1Timer(Sender: TObject);
begin
FlashWindow(Handle, true);
FlashWindow(Application.Handle, true);
end;
Inclua na seção uses: Windows
{ Digite a procedure abaixo imediatamente após a palavra
implementation no código do seu formulário. }
procedure MouseParaControle(Controle: TControl);
var
IrPara: TPoint;
begin
IrPara.X := Controle.Left + (Controle.Width div 2);
IrPara.Y := Controle.Top + (Controle.Height div 2);
if Controle.Parent <> nil then
IrPara := Controle.Parent.ClientToScreen(IrPara);
SetCursorPos(IrPara.X, IrPara.Y);
end;
{ Para testar, coloque no Form um botão e troque o name dele
para btnOK e modifique o evento OnShow do Form
conforme abaixo: }
procedure TForm1.FormShow(Sender: TObject);
begin
MouseParaControle(btnOk);
end;
A função "MouseParaControle" recebe um parâmetro do tipo TControl. Isto significa que você poderá passar para ela qualquer controle do Delphi, tais como: TEdit, TButton, TSpeedButton, TPanel, etc. Pode ser até mesmo o próprio Form.
{ 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;
A quantidade de cada cor primária é um número de 0 a 255. Observe que a cor retornada pela função RGB() está no formato do Windows (ColorRef); é por isto que fiz a conversão TColor(RGB(...)).
{ Coloque o código abaixo no OnClick de um botão }
AddFontResource(PChar('c:\MyFonts\Monospac.ttf'));
Troque o nome do arquivo do exemplo anterior pelo nome desejado. Arquivos de fonte possuem uma das seguintes extensões: FON, FNT, TTF, FOT. Veja também a pergunta nº 10.
Inclua na seção uses: Printers
{ Coloque este código no OnClick de um botão }
with Printer.Fonts do
if IndexOf('Draft 10cpi') >= 0 then
ShowMessage('A impressora possui a fonte.')
else
ShowMessage('A impressora NÃO possui a fonte.');
Isto pode ser útil quando queremos usar fonte da impressora quando for uma matricial ou fonte do Windows quando for uma Jato de Tinta ou Laser. Veja também a pergunta nº 10.
{ 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.');
Veja também a pergunta nº 11.
{ 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;
No Edit1 digite a nova data e no Edit2 digite a nova hora.
{ Mude a propriedade "KeyPreview" do Form para true. }
{ No evento "OnKeyPress" do Form acrescente o código abaixo: }
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then begin
Key := #0;
Perform(WM_NEXTDLGCTL, 1, 0);
end;
end;
{ Em StringGrid, escreva o evento OnKeyPress como abaixo: }
procedure TForm1.StringGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
StringGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;
{ Em DBGrid, escreva o evento OnKeyPress como abaixo: }
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if Key = #13 then
DBGrid1.Perform(WM_KEYDOWN, VK_TAB, 0);
end;
É bom lembrar que a tecla ENTER no Windows tem seu papel já bem definido quando se trata de caixa de diálogo: executar a ação padrão, normalmente o botão OK. Se não tomar cuidado poderá confundir o usuário, em vez de ajudá-lo.
{ Na seção "private" do Form principal acrescente: }
procedure AppMsg(var Msg: TMsg; var Handled: Boolean);
{ Na seção "implementation" acrescente (troque TForm1 para
o nome do seu form principal): }
procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean);
begin
if Msg.Message = WM_KEYDOWN then
if Msg.wParam = 110 then
Msg.wParam := 188;
end;
{ No evento "OnCreate" do form principal, coloque: }
Application.OnMessage := AppMsg;
Uma segunda alternativa:
Coloque o código abaixo no evento OnKeyPress do componente onde se quer a conversão (Edit, DBEdit, etc). Neste caso a conversão funcionará apenas neste componente (óbvio). } if Key = '.' then Key = DecimalSeparator;
Na primeira alternativa, sempre que for pressionado o ponto do teclado numérico (da direita do teclado), este será convertido para vírgula, independentemente do controle que estiver em foco. Já na segunda, o ponto pode ser de qualquer lugar do teclado.
Inclua na seção uses: Windows
{ Pausa por 1 segundo }
Sleep(1000);
{ Pausa por 10 segundos }
Sleep(10000);
Esta pausa não é interrompida pelo pressionamento de alguma tecla, como acontecia com InKey() do Clipper.
Inclua na seção uses: dbTables, DB
procedure CriaTabelaClientes;
var
Tabela: TTable;
begin
Tabela := TTable.Create(Application);
try
Tabela.DatabaseName := 'C:\';
{ ou Tabela.DatabaseName := 'NomeAlias'; }
Tabela.TableName := 'Clientes.DB';
Tabela.TableType := ttParadox; { ou ttDBase }
{ Somente Delphi4 }
if Tabela.Exists then { Se a tabela já existe... }
Exit;
{***}
{ Cria a tabela }
Tabela.FieldDefs.Add('Codigo', ftInteger, 0, true);
Tabela.FieldDefs.Add('Nome', ftString, 30, true);
Tabela.FieldDefs.Add('DataNasc', ftDate, 0, false);
Tabela.FieldDefs.Add('RendaMes', ftCurrency, 0, false);
Tabela.FieldDefs.Add('Ativo', ftBoolean, 0, true);
{ etc, etc, etc }
Tabela.CreateTable;
{ Cria os Índices }
Tabela.AddIndex('ICodigo', 'Codigo', [ixPrimary, ixUnique]);
Tabela.AddIndex('INome', 'Nome', [ixCaseInsensitive]);
{ etc, etc, etc }
finally
Tabela.Free;
end;
end;
Para verificar se o arquivo já existe na versão 3 ou anterior do Delphi, você deverá usar a função "FileExists" do Delphi.
Inclua na seção uses: FileCtrl, Dialogs
if DirectoryExists('C:\MEUSDOCS') then
ShowMessage('O diretório existe')
else
ShowMessage('O diretório não existe');
Inclua na seção uses: SysUtils, Dialogs
if FileExists('c:\carta.doc') then
ShowMessage('O arquivo existe')
else
ShowMessage('O arquivo não existe');
Inclua na seção uses: DB
{ Enxergar somente configurações da sessão atual }
Session.ConfigMode := cmSession;
{ Adicionar o Alias }
Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');
Veja a pergunta nº 1.
Inclua na seção uses: DB
{ se o alias não existir... }
if not Session.IsAlias('MeuAlias') then
begin
{ Adiciona o alias }
Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');
{ Salva o arquivo de configuração do BDE }
Session.SaveConfigFile;
end;
Para criar um alias do dBase troque a string 'PARADOX' por 'DBASE'. No caso acima usei como path o caminho "C:\DirProg", mas se você quiser poderá trocar este caminho por ExtractFilePath(ParamStr(0)) para que o alias seja direcionado para o local onde está seu .EXE. Neste último caso será necessário incluir na seção uses: SysUtils, System.