Вы находитесь на странице: 1из 97

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Dicas de Delphi
Como?
159 158 157 156 155 154 153 152 151 150 149 148 147 146 145 144 143 142 141 140 139 138 137 136 135 134 133 132 131 130 129 128 127 126 125 124 123 122 121 120 119 118 117 116 115 Pintar um Bitmap diretamente no Canvas do Form Verificar se a impressora est ligada Obter a letra do drive onde est o Windows Mostrar o nome do EXE no caption do form Fazer pesquisa incremental apenas com DBGrid Obter tipo de uma propriedade Consulta SQL que usa a data do sistema Abrir uma coneco Dial-Up Pintar uma imagem JPG no form Executar comando do MS-DOS Formatar CEP Permitir cancelar processo demorado Descobrir se uma data fim do ms Programar teclas de atalho do Windows Obter o tipo de dado de um valor no Registro do Windows Obter a clula de um StringGrid que est sob o cursor do mouse Limpar todas as clulas de um StringGrid Programar meu aplicativo para abrir arquivos a partir do Windows Explorer Consultar por ms de um campo data Criando tabelas via SQL Obter nomes dos campos de uma tabela Nomeando um relatrio no spool de impresso do Windows Obter tamanho de um arquivo Ocultar aplicao da lista de tarefas - CTRL+ALT+DEL Obter path de um Alias do BDE Ativar a proteo de tela do Windows Desligar/Ligar monitor Abrir e fechar o drive de CD-ROM Impedir que o form seja arrastado para fora das margens da tela Mostrar mensagem mesmo que esteja no Prompt do DOS Copiar todos os registros de uma tabela para o Clipboard Copiar um registro de uma tabela para o Clipboard Criar sub-diretrio no diretrio do EXE Ocultar o aplicativo do CTRL+ALT+DEL Personalizar a caixa de mensagem de excees (erro) do Delphi Implementar procedure Delay do Pascal no Delphi Enviar comandos de rolagem vertical para um TMemo Criar uma DLL de Bitmaps e us-la Construir a barra de ttulo do form com um Panel Criar form sem ttulo que possa ser arrastado Obter status da memria do sistema Definir data/hora de um arquivo Mostrar o dilogo About (Sobre) do Windows Ocultar/exibir o cursor do mouse Converter de Hexadecimal para Inteiro

1 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

114 - Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condio 113 - Colocar uma ProgressBar da StatusBar 112 - Executar um programa e aguardar sua finalizao antes de continuar 111 - Simular o pressionamento de uma combinao de teclas (ex: Ctrl+F2) 110 - Simular o pressionamento de uma tecla 109 - Ligar/desligar a tecla Caps Lock 108 - Verificar se uma determinada tecla est pressionada 107 - Verificar o estado de NumLock e CapsLock 106 - Configurar linhas de diferentes alturas em StringGrid 105 - Adicionar o evento OnClick do DBGrid 104 - Criar caixas de dilogo em tempo de execuo 103 - Converter a primeira letra de um Edit para maisculo 102 - Verificar se uma string contm uma hora vlida 101 - Verificar se uma string contm um valor numrico vlido 100 - Mostrar uma mensagem durante um processamento 99 - Mostrar um cursor de ampulheta durante um processamento 98 - Ler e escrever dados binrios no Registro do Windows 97 - Mudar a resoluo do vdeo via programao 96 - Ler e escrever dados no Registro do Windows 95 - Adicionar barra de rolagem horizontal no ListBox 94 - Simular um CharCase no DBGrid 93 - Verificar se uma string uma data vlida 92 - Fazer pesquisa incremental com DBGrid e Edit 91 - Adicionar zeros esquerda de um nmero 90 - Limpar um campo tipo data via programao 89 - Implementar um campo auto-incremental via programao 88 - Obter o endereo IP do Dial-Up 87 - Exibir a caixa de dilogo padro de solicitao de senha do banco de dados 86 - Obter a verso da biblioteca ComCtl32.DLL (usada na unit ComCtrls do Delphi) 85 - Implementar rotinas assembly em Pascal 84 - Exibir o dilogo About do Windows 83 - Obter a linha e coluna atual em um TMemo 82 - Exibir um arquivo de ajuda do Windows 81 - Obter o valor de uma varivel de ambiente 80 - Determinar se uma janela (form) est maximizada 79 - Determinar se o cursor do mouse est em determinado controle 78 - Determinar se o aplicativo est minimizado 77 - Fechar um aplicativo com uma mensagem de erro fatal 76 - Usar o evento OnGetText de um TField 75 - Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas 74 - Verificar, via programao, se Local Share do BDE est TRUE 73 - Criar um EXE que seja executado apenas atravs de outro EXE criado por mim 72 - Resolver "Internal error near: IBCheck" do Interbase 5.1.1 Server no NT 71 - Inverter os botes do mouse 70 - Obter/definir o tempo mximo do duplo-click do mouse 69 - Obter os atributos de um arquivo/diretrio 68 - Obter o espao total e livre de um disco 67 - Obter o tipo de um drive (removvel, fixo, CD-ROM, unidade de rede, etc) 66 - Obter informaes de um volume/disco (label, serial, sistema de arquivos, etc) 65 - Alterar o nome de volume (Label) de um disco 64 - Saber quais as unidades de disco (drives) esto presentes 63 - "truncar" valores reais para apenas n casas decimais 62 - Excluir todos os registros de uma tabela (como DELETE ALL do Clipper)
2 de 97 13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

61 - Saber se o sistema est usando 4 dgitos para o ano 60 - Imprimir caracteres acentuados diretamente para a impressora 59 - Imprimir texto justificado com formatao na impressora Epson LX-300 58 - Formatar um disquete atravs de um programa Delphi 57 - Alterar (e restaurar) o tamanho da pgina na impressora 56 - Reproduzir um arquivo de som WAV sem o TMediaPlayer 55 - Obter o nome do usurio e da empresa informado durante a instalao do Windows 54 - Mostrar uma barra de progresso enquanto copia arquivos 53 - Copiar arquivos usando o Shell do Windows 52 - Descobrir o cdigo ASCII de uma tecla 51 - Evitar que seu programa aparea na barra de tarefas 50 - Usar eventos de som do Windows 49 - Mudar a coluna ativa em um DBGrid via programao 48 - Fechar o Windows a partir do seu programa 47 - Carregar um cursor animado (.ani) 46 - Enviar um arquivo para a lixeira 45 - Obter o nmero do registro atual 44 - Trabalhar com Filter de forma mais prtica 43 - Reproduzir um arquivo WAV 42 - Executar um programa DOS e fech-lo em seguida 41 - Fechar um programa a partir de um programa Delphi 40 - Colocar Hint's de vrias linhas 39 - Reproduzir um vdeo AVI em um Form 38 - Separar (filtrar) caracteres de uma string 37 - Colocar zeros esquerda de nmeros 36 - Copiar arquivos usando curingas (*.*) 35 - Copiar arquivos 34 - Trabalhar com cores no formato string 33 - Verificar se determinado programa est em execuo (Word, Delphi, etc) 32 - Excluir arquivos usando curingas (*.*) 31 - Gerar uma tabela no Word atravs do Delphi 30 - Obter a quantidade de registros total e visvel de uma tabela 29 - Evitar que um programa seja executado mais de uma vez 28 - Executar um "COMMIT" no Delphi 27 - Posicionar Form's em relao ao Desktop do Windows 26 - Saber a resoluo de tela atual 25 - Verificar se uma unidade de disco (disk-drive) est preparada 24 - Salvar/restaurar o tamanho e posio de Form's 23 - Definir a quantidade de registros a ser impressa em uma pgina do QuickReport 22 - Onde encontrar tutoriais sobre construo de componentes em Delphi 21 - Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do TStringGrid 20 - Mostrar um Form de LogOn antes do Form principal 19 - Limitar a regio de movimentao do mouse 18 - Descobrir o nome de classe de uma janela do Windows 17 - Ocultar/exibir a barra de tarefas do Windows 16 - Evitar a proteo de tela durante seu programa 15 - Fazer a barra de ttulo ficar intermitente (piscante) 14 - Posicionar o cursor do mouse em um controle 13 - Criar cores personalizadas (sistema RGB) 12 - Adicionar uma nova fonte no Windows 11 - Saber se a impressora atual possui determinada fonte 10 - Saber se determinada Font est instalada no Windows 9 - Acertar a data e hora do sistema atravs do programa
3 de 97 13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

8 7 6 5 4 3 2 1

ENTER em vez de TAB no formulrio, no DBGrid e no StringGrid Simular a vrgula atravs do ponto do teclado numrico Paralizar um programa durante n segundos Criar uma tabela (DB, DBF) atravs do seu programa Verificar se um diretrio existe Verificar se um arquivo existe Criar um Alias temporrio atravs do seu programa Criar um Alias atravs do seu programa

159 - Pintar um Bitmap diretamente no Canvas do Form


- Declare a variavel Bmp na seo private: private Bmp: TBitmap; - Coloque um boto no Form e no evento OnClick digite: Bmp:= TBitMap.Create; try Bmp.LoadFromFile('c:\teste\arquivo.bmp'); Canvas.Draw(0,0, Bmp); finally Bmp.Free; end; Pronto! Ir aparecer a imagem no Canvas. til para fazer animaes. Dica enviada por: Alisson Viana Jardim Revisada por: Daniel Pereira Guimares

Incio da pgina

158 - Verificar se a impressora est ligada


Problema: Fao impresso direta para a porta da impressora e gostaria testar se a impressora est pronta antes de enviar o relatrio. Isto possvel em Delphi? Soluo: Usando instrues Assembly podemos fazer isto. A funo abaixo retorna true se a porta informada est pronta. Os possveis parmetros para esta funo so: 1 - para LPT1 2 - para LPT2 3 - para LPT3 4 - para LPT4 function tbTestLPT(Port: byte): boolean; var Pto : Word; Rdo : byte;

4 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

begin Pto := Port -1; asm MOV DX,Pto MOV AX,$0200 {AH := $02 : Leer el estado de la impresora} INT $17 MOV Rdo,AH {Guarda el estado en AL} end; Result := Rdo = 144; end;

Observaes Provavelmente esta funo no funcionar em Windows NT devido ao acesso em baixo nvel. Incio da pgina

157 - Obter a letra do drive onde est o Windows


Inclua na seo uses: Windows
Problema: Como saber em qual unidade de disco (drive) o Windows est instalado? Soluo: Esta funo retorna a letra do drive onde est instalado o Windows: function GetWindowsDrive: Char; var S: string; begin SetLength(S, MAX_PATH); if GetWindowsDirectory(PChar(S), MAX_PATH) > 0 then Result := string(S)[1] else Result := #0; end; { Exemplo de uso: } procedure TForm1.Button1Click(Sender: TObject); begin Caption := GetWindowsDrive; end;

Incio da pgina

156 - Mostrar o nome do EXE no caption do form


{ Esta funo extrai apenas o nome do arquivo passado, sem path e extenso }

5 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

function Titulo(Nome: String): String; var N, D: String; begin N := ExtractFileName(Nome); { Retira o path } D := ChangeFileExt(N,''); { Retira a extenso } { Coloca a primeira letra em maiscula e o resto em minscula } Titulo := UpperCase(Copy(D,1,1)) + LowerCase(Copy(D,2,Length(D)-1)); end; { No OnCreate do form, coloque: } procedure TForm1.FormCreate(Sender: TObject); begin Caption := Titulo(ParamStr(0)); end; - Dica enviada por: Luiz Eduardo.

Incio da pgina

155 - Fazer pesquisa incremental apenas com DBGrid


Problema: Gostaria de fazer um formulrio de pesquisa que, ao digitar algo sobre o DBGrid, o registro correspondendo fosse localizado. Soluo: - Coloque no form: TTable, TDataSource, TDBGrid e TLabel. - Ajuste as propriedades do Table1: DatabaseName = TableName = Active = true - Ajuste as propriedades do DataSource1: DataSet = Table1 - Ajuste as propriedades do DBGrid1: DataSource = DataSource1 Options -> dgEditing = false ReadOnly = true * Pode tambm ajustar a propriedades Columns para escolher as colunas que sero exibidas. - Na seo private da unit declare: private FTexto: string; - No evento OnCreate do form coloque: FTexto := ''; Label1.Caption := ''; - No evento OnKeyPress do DBGrid1:

6 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); begin if Key in [#8, #32..#255] then begin if Key = #8 then { BackSpace } FTexto := Copy(FTexto, 1, Length(FTexto)-1) else FTexto := FTexto + Key; { Posiciona na coluna Nome } Table1.FieldByName('Nome').FocusControl; { Escolhe o ndice e procura } Table1.IndexFieldNames := 'Nome'; Table1.FindNearest([FTexto]); { Mostra o texto procurado } Label1.Caption := FTexto; end; end;

Observaes No nosso exemplo estamos pesquisando atravs do campo "Nome". Para esta pesquisa precisamos de um ndice com este campo. Incio da pgina

154 - Obter tipo de uma propriedade


Inclua na seo uses: TypInfo
{ Esta funo retorna uma string com o nome do tipo de dado de uma propriedade. Exemplos de retornos: PropType(Button1, 'Caption'); // Retorna 'TCaption' PropType(Edit1, 'Width'); // Retorna 'Integer'; PropType(Edit1, 'Color'); // Retorna 'TColor'; } function PropType(const Obj: TObject; const PropName: string): string; var Info: PPropInfo; begin Info := GetPropInfo(Obj.ClassInfo, PropName); if Assigned(Info) then Result := Info^.PropType^.Name else Result := ''; end; { Exemplo de uso: - Coloque um TButton e um TEdit; - No OnClick do Button1 coloque o cdigo abaixo; - Execute, digite 'Caption' no Edit1 e clique em Button1. } procedure TForm1.Button2Click(Sender: TObject);

7 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

begin ShowMessage(PropType(Button1, Edit1.Text)); end;

Observaes Verdadeiramente no sei exatamente onde poderamos aplicar esta dica, mas divulguei-a porque achei interessante. Acredito que o Object Inspector use algo parecido. Incio da pgina

153 - Consulta SQL que usa a data do sistema


Problema: Preciso fazer uma consulta com SQL que me retorne todos os registros em que o valor de um campo do tipo data seja igual ou anterior dada do sistema. Como fazer? Soluo: Query.Close; Query.SQL.Text := 'select * from Tabela where CampoData <= :Hoje'; Query.ParamByName('Hoje').AsDate := Date; Query.Open;

Observaes Este exemplo foi testado com tabelas Paradox, mas deve funcionar na maioria dos bancos de dados com pouca ou nenhuma alterao. Incio da pgina

152 - Abrir uma coneco Dial-Up


Inclua na seo uses: Windows
{ A funo abaixo abre a caixa de dilogo de coneco com a rede Dial-Up. O parmetro "name" o nome da coneco previamente configurada. } procedure DialUpConnect(const Name: string); begin WinExec(PChar('rundll32.exe rnaui.dll,RnaDial ' + Name), SW_SHOW); end; { Exemplo de uso: } procedure TForm1.Button1Click(Sender: TObject); begin DialUpConnect('NomeDaConeco'); end;

Incio da pgina
8 de 97 13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

151 - Pintar uma imagem JPG no form


Inclua na seo uses: Graphics, JPeg
Problema: Gostaria de pintar imagens de arquivos JPG (JPeg) nos forms de minha aplicao. Isto possvel? Como? Soluo: Para trabalhar com arquivos JPG voc precisa usar um objeto TPicture, assim como colocar no uses a unit JPeg. Siga os passos abaixo para pintar uma imagem JPG no form: - No evento OnPaint do form coloque o cdigo abaixo: procedure TForm1.FormPaint(Sender: TObject); var Imagem: TPicture; begin Imagem := TPicture.Create; try Imagem.LoadFromFile('c:\teste\foto.jpg'); Canvas.StretchDraw(ClientRect, Imagem.Graphic); finally Imagem.Free; end; end; - E no evento OnResize do form, coloque: procedure TForm1.FormResize(Sender: TObject); begin Repaint; end;

Observaes No se esquea de trocar o nome do arquivo JPG conforme sua necessidade. Este exemplo foi elaborado usando Delphi4. Incio da pgina

150 - Executar comando do MS-DOS


Usando WinExec voc pode executar qualquer comando do DOS. Para isto chame o COMMAND.COM passando como parmetro a linha de comando a ser executada. O parmetro /C opcional e faz com que a janela do DOS seja fechada assim que o comando terminar. No exemplo abaixo estou executando a seguinte linha de comando: DIR C:\*.* WinExec('COMMAND.COM /C DIR C:\*.*', SW_SHOW);

Observaes

9 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Para que a janela do DOS no seja exibida, use SW_HIDE no lugar de SW_SHOW. Incio da pgina

149 - Formatar CEP


{ Esta funo forma CEP como: 99.999-999 } function tbFormataCEP(const CEP: string): string; var I: integer; begin Result := ''; for I := 1 to Length(CEP) do if CEP[I] in ['0'..'9'] then Result := Result + CEP[I]; if Length(Result) <> 8 then raise Exception.Create('CEP invlido.') else Result := Copy(Result, 1, 2) + '.' + Copy(Result, 3, 3) + '-' + Copy(Result, 6, 3); end; === Para testar === - Coloque um Edit e um Button no form; - No evento OnClick do Button coloque a instruo abaixo: Edit1.Text := tbFormataCEP(Edit1.Text);

Observaes Para formatar outros cdigos como CPF, CGC, etc., pode-se usar a mesma idia. Incio da pgina

148 - Permitir cancelar processo demorado


Problema: Em determinadas partes no programa existem processos que podem demorar vrios minutos para serem concludos. Muitas vezes o usurio desiste e deseja cancelar o processamento. Como permitir este cancelamento? Soluo: Em aplicativos para Windows comum, em processamentos demorados, o programa mostrar uma janela de dilogo avisando que o processo pode levar um tempo extra. Nesta mesma janela normalmente coloca-se tambm um boto "Cancelar" que d ao usurio a opo aguardar ou desistir do processo. Para fazer isto em um aplicativo Delphi, siga os passos abaixo: - Vamos considerar em nosso exemplo que o processamento ocorre

10 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

na unit do Form1. - Declare, na seo public do Form1, uma varivel boolean. public; Cancelar: boolean; - Crie um novo form (vou cham-lo de Form2); - Coloque um boto neste novo form. Programe o OnClick deste boto conforme abaixo: Form1.Cancelar := true; - Na parte onde ocorre o loop do processamento demorado coloque algo como: try { Antes de comear o processamento } Form2.Caption := 'Processamento demorado...'; Form2.Show; { No incio do loop "Cancelar" precisa ser false } Cancelar := false; { Aqui inicia o loop do processamento demorado } while {...} do begin { ... Processa algo aqui... } { Permite que o programa processe mensagens do Windows } Application.ProcessMessages; { Se a varivel "Cancelar" foi alterada para true... } if Cancelar then begin ShowMessage('Operao cancelada pelo usurio.'); Break; { Sai do loop } end; end; finally Form2.Close; end;

Observaes No se esquea de que o Form1 precisa usar Form2 e vice-versa. Incio da pgina

147 - Descobrir se uma data fim do ms


Inclua na seo uses: SysUtils
{ Esta funo retorna true se a data passada como parmetro fim de ms. Retorna false caso contrrio. } function tbFimDoMes(const Data: TDateTime): boolean; var

11 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Ano, Mes, Dia: Word; begin DecodeDate(Data +1, Ano, Mes, Dia); Result := Dia = 1; end;

Incio da pgina

146 - Programar teclas de atalho do Windows


Inclua na seo uses: Windows, Dialogs
Problema: Gostaria de programar algumas teclas de atalho para chamar, por exemplo, uma calculadora, quando meu aplicativo estiver aberto. Como fazer? Soluo: - No evento OnCreate do form coloque o cdigo abaixo: procedure TForm1.FormCreate(Sender: TObject); begin if not RegisterHotkey(Handle, 1, MOD_CONTROL or MOD_ALT, VK_F11) then ShowMessage('Erro ao programar Ctrl+Alt+F11'); if not RegisterHotkey(Handle, 2, MOD_CONTROL or MOD_ALT, VK_F12) then ShowMessage('Erro ao programar Ctrl+Alt+F12'); end; - No evento OnDestroy do form coloque o cdigo abaixo: procedure TForm1.FormDestroy(Sender: TObject); begin UnRegisterHotkey(Handle, 1); UnRegisterHotkey(Handle, 2); end; - Declere a procedure abaixo na seo private: private procedure WMHotkey(var Msg: TWMHotkey); message WM_HOTKEY; - Abaixo da palavra implementation escreva a procedure: procedure TForm1.WMHotkey(var Msg: TWMHotkey); begin case Msg.HotKey of 1: WinExec('calc.exe', SW_SHOW); 2: ShowMessage('Ctrl+Alt+F12 foram pressionadas'); end; end; - Execute este programa e experimente pressionar Ctrl+Alt+F11 ou Ctrl+Alt+F12.

Observaes

12 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Se a combinao de teclas j estiver em uso (num atalho, por exemplo), no ser possvel us-la em nossa aplicao. Existem outras formas de implementar teclas de atalho em programas escritos em Delphi, mas a forma apresentada bastante funcional. Incio da pgina

145 - Obter o tipo de dado de um valor no Registro do Windows


Inclua na seo uses: Registry, Dialogs
{ - Coloque um boto no form; - Altere o evento OnClick do boto conforme abaixo: } procedure TForm1.Button1Click(Sender: TObject); const cRegPath = 'System\CurrentControlSet\control\FileSystem'; cRegValue = 'ACDriveSpinDown'; var Reg: TRegistry; S: string; begin Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey(cRegPath, false) then begin case Reg.GetDataType(cRegValue) of rdUnknown: S := 'Tipo Desconhecido'; rdString: S := 'String'; rdExpandString: S := 'ExpandString'; rdInteger: S := 'Inteiro'; rdBinary: S := 'Binrio'; end; ShowMessage(S); end else ShowMessage('Erro ao abrir chave do Registro'); finally Reg.Free; end; end;

Observaes A unit Dialogs foi acrescentada no uses somente para podermos usar a procedure ShowMessage. Incio da pgina

144 - Obter a clula de um StringGrid que est sob o cursor do mouse


Inclua na seo uses: Windows

13 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Esta procedure pega a linha e coluna da clula onde estiver o mouse. Valores negativos para Linha ou Coluna indicam que o mouse est fora da rea cliente do StringGrid } procedure MouseCell(Grid: TStringGrid; var Coluna, Linha: integer); var Pt: TPoint; begin GetCursorPos(Pt); Pt := Grid.ScreenToClient(Pt); if PtInRect(Grid.ClientRect, Pt) then Grid.MouseToCell(Pt.X, Pt.Y, Coluna, Linha) else begin Coluna := -1; Linha := -1; end; end; { Exemplo de uso: - Coloque um boto no form; - Altere o evento OnClick deste boto como abaixo: } procedure TForm1.Button1Click(Sender: TObject); var Coluna, Linha: integer; begin MouseCell(StringGrid1, Coluna, Linha); if (Coluna >= 0) and (Linha >= 0) then Caption := 'Coluna: ' + IntToStr(Coluna) + ' - ' + 'Linha: ' + IntToStr(Linha); else Caption := 'O mouse no est no StringGrid'; end; { Para testar: - Execute o programa; - Posicione o cursor do mouse sobre alguma clula do StringGrid; - Pressione TAB at chegar ao boto e pressione ENTER; - O resultado ser mostrado no Caption do form; }

Observaes Note que a procedure MouseCell usa um valor negativo (-1) para coluna e linha se o mouse no estiver sobre o StringGrid. Incio da pgina

143 - Limpar todas as clulas de um StringGrid


Existem trs mtodos que podemos aplicar para limpar um StringGrid. { Limpando uma clula de cada vez: } procedure TForm1.Button1Click(Sender: TObject);

14 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

var I, J: integer; begin with StringGrid1 do for I := 0 to ColCount -1 do for J := 0 to RowCount -1 do Cells[I,J] := ''; end; { Limpando uma linha de cada vez: } procedure TForm1.Button2Click(Sender: TObject); var I: integer; begin with StringGrid1 do for I := 0 to RowCount -1 do Rows[I].Clear; end; { Limpando uma coluna de cada vez: } procedure TForm1.Button3Click(Sender: TObject); var I: integer; begin with StringGrid1 do for I := 0 to ColCount -1 do Cols[I].Clear; end;

Observaes Em todos os exemplos estamos limpando o StringGrid completamente, inclusive linhas e colunas fixas. Para preservar linhas ou colunas fixas troque os valores iniciais de I ou J conforme a necessidade. Incio da pgina

142 - Programar meu aplicativo para abrir arquivos a partir do Windows Explorer
Inclua na seo uses: Registry
Problema: Criei um editor de textos no Delphi. Agora gostaria que o Windows Explorer usasse este editor para abrir arquivos com a extenso .dpg e .dan. Como fazer? Soluo: Para fazer isto ser necessria a criao de algumas chaves no Registro do Windows. O exemplo abaixo cria todas as chaves necessrias. - Coloque um TButton e no evento OnClick dele coloque o cdigo abaixo:

15 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

procedure TForm1.Button1Click(Sender: TObject); var Reg: TRegistry; begin Reg := TRegistry.Create; try Reg.RootKey := HKEY_CLASSES_ROOT; Reg.LazyWrite := false; { Define o nome interno (ArquivoDaniel) e uma legenda que aparecer no Windows Explorer (Arquivo do Daniel) } Reg.OpenKey('ArquivoDaniel', true); Reg.WriteString('', 'Arquivo do Daniel'); Reg.CloseKey; { Define o comando a ser executado quando abrir um arquivo pelo Windows Explorer (NomeDoExe %1). O smbolo %1 indica que o arquivo a ser aberto ser passado como primeiro parmetro para o aplicativo - ParamStr(1). } Reg.OpenKey('ArquivoDaniel\shell\open\command', true); Reg.WriteString('', ParamStr(0) + ' %1'); { NomeDoExe %1 } Reg.CloseKey; { Define o cone a ser usado no Windows Explorer: 0 - primeiro cone do EXE 1 - segundo cone do EXE, etc } Reg.OpenKey('ArquivoDaniel\DefaultIcon', true); Reg.WriteString('', ParamStr(0) + ',0'); { 0 = primeiro cone } Reg.CloseKey; { Define as extenses de arquivos que sero abertos pelo meu aplicativo } { *.dpg } Reg.OpenKey('.dpg', true); Reg.WriteString('', 'ArquivoDaniel'); Reg.CloseKey; { *.dan } Reg.OpenKey('.dan', true); Reg.WriteString('', 'ArquivoDaniel'); Reg.CloseKey; finally Reg.Free; end; end; - Coloque um TMemo; - No evento OnShow do Form coloque o cdigo abaixo: procedure TForm1.FormShow(Sender: TObject); begin { Se o primeiro parmetro for um nome de arquivo existente... } if FileExists(ParamStr(1)) then { Carrega o contedo do arquivo no memo } Memo1.Lines.LoadFromFile(ParamStr(1)); end; *** Para testar *** - Execute este programa; - Clique no boto para criar as chaves no Registro do Windows; - Feche o programa; - Crie alguns arquivos com as extenses .dpg e .dan; - V ao Windows Explorer e procure pelos arquivos criados;

16 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

- Experimente dar um duplo-clique sobre qualquer dos arquivos com uma das extenses acima.

Observaes Existem outros recursos que podero ser configurados. Porm, para comear, este j um bom exemplo. Incio da pgina

141 - Consultar por ms de um campo data


Problema: Tenho um cadastro de clientes com Codigo, Nome, DataNasc, etc. Preciso fazer uma consulta onde apareceo apenas os clientes que fazem aniversrio em determinado ms. Como fazer? Soluo: Use uma Query como abaixo: - Coloque no form os seguintes componentes: * TQuery * TDataSource * TDBGrid * TEdit * TButton - Altere as propriedades dos componentes como abaixo: * Query1.DatabaseName = (alias do BDE) * DataSource1.DataSet = Query1 * DBGrid1.DataSource = DataSource1 - Coloque o cdigo abaixo no evento OnClick de Button1: Query1.Close; Query1.SQL.Clear; Query1.SQL.Add('select * from dCli'); Query1.SQL.Add('where extract(month from DataNasc) = :Mes'); Query1.ParamByName('Mes').AsInteger := StrToInt(Edit1.Text); Query1.Open; - Execute. Digite um nmero de 1 a 12 no Edit e clique no boto.

Observaes Os nmeros de 1 a 12 representam, respectivamente, os meses de Janeiro a Dezembro. Este exemplo foi testado com Delphi4, BDE5 e tabela Paradox7. Incio da pgina

140 - Criando tabelas via SQL


Inclua na seo uses: dbTables

17 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

- Coloque um TButton no form; - Escreve no OnClick do Button como abaixo: procedure TForm1.Button1Click(Sender: TObject); var Q: TQuery; begin Q := TQuery.Create(Application); try Q.DatabaseName := 'SF'; with Q.SQL do begin Add('Create Table Funcionarios'); Add('( Codigo AutoInc,'); Add(' Nome Char(30),'); Add(' Salario Money,'); Add(' Depto SmallInt,'); Add(' Primary Key (Codigo) )'); end; Q.ExecSQL; finally Q.Free; end; end;

Observaes Este exemplo foi testado com banco de dados Paradox, porm dever funcionar em vrios outros bancos de dados com pouca ou nenhuma alterao. Incio da pgina

139 - Obter nomes dos campos de uma tabela


Inclua na seo uses: dbTables, Classes, Forms
A funo abaixo obtm os nomes de todos os campos de uma tabela do banco de dados. procedure tbGetFieldNames(const DBName, TblName: string; List: TStringList); var I: integer; begin List.Clear; with TTable.Create(Application) do try DatabaseName := DBName; TableName := TblName; with FieldDefs do begin Update; for I := 0 to Count -1 do List.Add(Items[I].Name); end; finally Free; end; end;

18 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

=== Exemplo de uso === - Coloque um TMemo e um TButton no Form; - Coloque o cdigo abaixo no evento OnClick do Button: procedure TForm1.Button1Click(Sender: TObject); var List: TStringList; begin List := TStringList.Create; try tbGetFieldNames(Edit1.Text, Edit2.Text, List); Memo1.Lines.Assign(List); finally List.Free; end; end;

Incio da pgina

138 - Nomeando um relatrio no spool de impresso do Windows


Inclua na seo uses: Printers
Problema: Quando mandamos imprimir no Windows, normalmente o nome do documento aparece na fila de impresso (spool). Como fazer com que aplicativos feitos em Delphi se comporte desta forma? Ou seja, como nomear meus relatrios feitos em Delphi? Soluo: Antes de enviar seu relatrio, faa assim: Printer.Title := 'Nome do relatrio';

Observaes Esta soluo aplica-se perfeitamente aos relatrios feitos usando o objeto Printer. Nos casos de geradores de relatrios, estes provavelmente possuem uma propriedade equivalente. Incio da pgina

137 - Obter tamanho de um arquivo


Inclua na seo uses: SysUtils
{ A funo abaixo retorna o tamanho do arquivo, ou -1 se o arquivo no for encontrado } function tbFileSize(const FileName: string): integer; var SR: TSearchRec; I: integer; begin

19 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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

Incio da pgina

136 - Ocultar aplicao da lista de tarefas - CTRL+ALT+DEL


- Declare a funo abaixo antes da palavra implementation: function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL'; - Coloque dois botes no Form; - No evento OnClick do Button1 coloque: RegisterServiceProcess(GetCurrentProcessID, 1); - No evento OnClick do Button2 coloque: RegisterServiceProcess(GetCurrentProcessID, 0); === Para testar === Clique no Button1 e pressione CTRL+ALT+DEL. O seu programa no aparecer na lista. Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa aparecer na lista. Dica enviada por: Luiz Carlos Manzolli

Incio da pgina

135 - Obter path de um Alias do BDE


Inclua na seo uses: BDE
{ A funo abaixo retorna o path (caminho) de um Alias do BDE } function GetAliasPath(AliasName: String):String; var dbDes: DBDesc; begin Result:=''; DBiInit(Nil);// invoca o BDE , se no inicializado If DbiGetDatabaseDesc(PChar(AliasName), @dbDes)= DBIERR_NONE then with dbDes do Result:=StrPas(szPhyName);

20 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

DBiExit;// Libera o BDE end; Dica enviada por: Angelo Ricardo Miquelin Neto.

Observaes Se a unit em que essa rotina for colocada utilizar as units DB e DBTABLES, as chamadas a DbiInit() e DbiExit() podero ser omitidas. Incio da pgina

134 - Ativar a proteo de tela do Windows


Inclua na seo uses: Windows
{ Ativa a proteo de tela do Windows, se estiver configurada. } SendMessage(Application.Handle, WM_SYSCOMMAND, SC_SCREENSAVE, 0);

Incio da pgina

133 - Desligar/Ligar monitor


Inclua na seo uses: Windows
No Win95 podemos desligar o monitor afim de economizar energia eltrica. Normalmente este recurso controlado pelo prprio Windows. Porm sua aplicao Delphi tambm 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);

Observaes Este recurso pode no funcionar dependendo da configurao do sistema. Incio da pgina

132 - Abrir e fechar o drive de CD-ROM


Inclua na seo uses: MMSystem
{ Para abrir } mciSendString('Set cdaudio door open wait', nil, 0, handle);

21 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Para fechar } mciSendString('Set cdaudio door closed wait', nil, 0, handle);

Incio da pgina

131 - Impedir que o form seja arrastado para fora das margens da tela
- Na seo 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.

Incio da pgina

130 - Mostrar mensagem mesmo que esteja no Prompt do DOS


Inclua na seo uses: Windows
Problema: Fiz um programa que mostra mensagens de lembrete quando chegada determinada data/hora. Porm quando o usurio vai para o Prompt do MS-DOS em modo tela cheia, a mensagem no aparece. O que devo fazer? Soluo: Antes de mostrar a mensagem, coloque sua aplicao na frente das demais. SetForegroundWindow(Application.Handle); ShowMessage('Teste');

Incio da pgina

129 - Copiar todos os registros de uma tabela para o Clipboard


22 de 97 13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Inclua na seo uses: Clipbrd


Problema: Gostaria de colocar em minha aplicao o recurso de copiar todos os registros de uma tabela para a rea de transferncia, permitindo ao usurio colar estes dados em outro aplicativo (ex: MS-Word). Isto possvel? Soluo: Sim. Siga os passos abaixo: - Crie seu form normalmente, colocando DataSource, Table e demais componentes; - Coloque um boto e no evento OnClick deste boto coloque o cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); const SeparadorCampoValor = ': '; SeparadorCampo = #13#10; { Quebra de linha } SeparadorRegistro = '===========' + #13#10; var S: string; I: integer; begin S := ''; Table1.First; while not Table1.EOF do begin for I := 0 to Table1.FieldCount -1 do S := S + Table1.Fields[I].FieldName + SeparadorCampoValor + Table1.Fields[I].AsString + SeparadorCampo; S := S + SeparadorRegistro; Table1.Next; end; Clipboard.AsText := S; end; Para testar: - Execute este aplicativo; - Clique no boto; - V em outro aplicativo (ex: MS-Word) e mande colar (Ctrl+V).

Observaes CUIDADO! No use este recurso com tabelas grandes, pois poder usar memria demasiadamente. No teste que fiz, o tamanho da string S atingiu 20K e funcionou normalmente. Mas isto pode variar de uma mquina para outra. Incio da pgina

128 - Copiar um registro de uma tabela para o Clipboard


Inclua na seo uses: Clipbrd
Problema:

23 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Gostaria de colocar em minha aplicao o recurso de copiar um registro de uma tabela para a rea de transferncia, permitindo ao usurio colar estes dados em outro aplicativo (ex: MS-Word). Isto possvel? Soluo: Sim. Siga os passos abaixo: - Crie seu form normalmente, colocando DataSource, Table e demais componentes; - Coloque um boto e no evento OnClick deste boto coloque o cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); const SeparadorCampoValor = ': '; SeparadorCampo = #13#10; { Quebra de linha } var S: string; I: integer; begin S := ''; for I := 0 to Table1.FieldCount -1 do S := S + Table1.Fields[I].FieldName + SeparadorCampoValor + Table1.Fields[I].AsString + SeparadorCampo; Clipboard.AsText := S; end; Para testar: - Execute este aplicativo; - Clique no boto; - V em outro aplicativo (ex: MS-Word) e mande colar (Ctrl+V).

Incio da pgina

127 - Criar sub-diretrio no diretrio do EXE


Inclua na seo uses: FileCtrl, SysUtils
Problema: Gostaria de criar um sub-diretrio dentro do diretrio onde se encontra o EXE de minha aplicao. Como fazer? Soluo: Primeiramente vamos conhecer algumas funes do Delphi que precisaremos us-las: ParamStr(Indice) - Retorna valores passados na linha de comando quando executamos o programa. Se o valor de Indice for 0 (zero) ser retornado o caminho+nome do EXE. ExtractFilePath(NomeArq) - Retorna o caminho (path) do nome de arquivo informado. Exemplo: S := 'C:\NomeDir\Programa.exe'; ExtractFilePath(S); { retorna: 'C:\NomeDir\' }

24 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

DirectoryExists(CaminhoDir) - Retorna true se o diretrio informado existe. False em caso contrrio. CreateDir(CaminhoDir) - Tenta criar o diretrio informado. Se conseguir, retorna true. Caso contrrio retorna false. Agora que sabemos como trabalham estas funes, vamos escrever uma funo que precisamos para criar um sub-diretrio conforme proposto. function CriaSubDir(const NomeSubDir: string): boolean; var Caminho: string; begin Caminho := ExtractFilePath(ParamStr(0)) + NomeSubDir; if DirectoryExists(Caminho) then Result := true else Result := CreateDir(Caminho); end; Exemplo de uso: - Chame a funo no evento OnCreate do form: procedure TForm1.FormCreate(Sender: TObject); begin if not CriaSubDir('MeuSubDir') then ShowMessage('No foi possvel criar o sub-diretrio MeuSubDir.'); end;

Incio da pgina

126 - Ocultar o aplicativo do CTRL+ALT+DEL


Inclua no implementation de seu programa a seguinte linha: function RegisterServiceProcess(dwProcessID, dwType: Integer): Integer; stdcall; external 'KERNEL32.DLL'; e depois no OnCreate ponha a seguinte linha: RegisterServiceProcess(GetCurrentProcessID, 1); Isso vai fazer o programa nao aparecer no CTRL+ALT+DEL, mas seu form principal vai continuar aparecendo. Para ocultar tambm o form, basta por no OnCreate antes da linha acima a seguinte linha: Application.ShowMainForm:=False; Resposta enviada por: dexter07

Observaes Segundo o autor desta resposta, esta soluo foi testada em Win95, mas tambm deve funcionar em Win98. No sabe se funciona em NT.

25 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

125 - Personalizar a caixa de mensagem de excees (erro) do Delphi


Problema: Quando ocorre uma exceo no Delphi, ele automaticamente exibe uma mensagem de erro. Gostaria de poder personalizar estas mensagens, acrescentando, por exemplo, o e-mail do suporte tcnico. Isto possvel? Soluo: Sim. Siga os passos abaixo: - Declare um mtodo (procedure) na seo private do form principal conforme abaixo: private procedure ManipulaExcecoes(Sender: TObject; E: Exception); - V at a seo implementation e implemente este mtodo, conforme o exemplo: procedure TForm1.ManipulaExcecoes(Sender: TObject; E: Exception); begin MessageDlg(E.Message + #13#13 + 'Suporte tcnico:'#13 + 'tecnobyte@ulbrajp.com.br', mtError, [mbOK], 0); end; - No evento OnCreate do Form principal escreva o cdigo abaixo: procedure TForm1.FormCreate(Sender: TObject); begin Application.OnException := ManipulaExcecoes; end; === Para testar === - Coloque um Button no form; - No evento OnClick deste boto coloque o cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); begin StrToInt('ABCD'); { Isto provoca uma exception } end;

Observaes Cuidado! No coloque cdigo que possa gerar exceo na rotina que manipula as excees, pois se ocorrer uma exceo neste rotina, esta ser chamada recursivamente at estourar a pilha. Incio da pgina

26 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

124 - Implementar procedure Delay do Pascal no Delphi


Inclua na seo uses: Windows, Forms
Problema: O Pascal para DOS possui uma procedure chamada Delay que serve para pausar o processamento atual em "n" milsimos de segundo. Como implemento isto no Delphi? Soluo: Simles. Veja: procedure Delay(MSec: Cardinal); var Start: Cardinal; begin Start := GetTickCount; repeat Application.ProcessMessages; until (GetTickCount - Start) >= MSec; end; === Exemplos de uso: === Delay(1000); { Aguarda 1 segundo } Delay(5000); { Aguarda 5 segundos } Delay(60000); { Aguarda 60 segundos - 1 minuto }

Observaes Alm da procedure Delay criada acima, o programador Delphi pode usar tambm a API do Windows Sleep. H porm uma diferena: Delay permite que que o programa continue a processar as mensagens do Windows (mouse, teclado, etc). Incio da pgina

123 - Enviar comandos de rolagem vertical para um TMemo


Inclua na seo uses: Windows
Problema: Gostaria que o meu programa rolasse automaticamente o contedo de um TMemo, simulando o deslizamento da barra de rolagem vertical. Isto possvel no Delphi? Soluo: Sim. Utilizando mensagens do Windows isto fcil. Vejamos algums exemplos: SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEDOWN, 0); Onde: Memo1.Handle = manipulador da janela do Memo1.

27 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

WM_VSCROLL = Mensagem do Windows - rolagem vertical. SB_PAGEDOWN = Comanndo de rolagem - pgina para baixo. Outros exemplos: { Pgina para cima } SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEUP, 0); { Linha para baixo } SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEDOWN, 0); { Linha para cima } SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEUP, 0);

Observaes Alm desta tcnica existem API's do Windows que fazem um trabalho equivalente. Incio da pgina

122 - Criar uma DLL de Bitmaps e us-la


Problema: Gostaria de colocar algums bitmaps em uma DLL e us-los em tempo de execuo. possvel fazer isto em Delphi? Soluo: Sim. Siga os passos abaixo para criar a DLL de bitmaps: - Crie um arquivo de recursos (.RES) contendo os Bitmaps. Use o Image Editor do Delphi para criar este arquivo. Salve-o com o nome BMPS.RES na pasta onde ser salvo o projeto do Delphi; - Crie um novo projeto no Delphi; - Remova todos os forms do projeto; - Salve este projeto com o nome DLLBmp.dpr; - Abra o arquivo de projeto (DLLBmp.dpr) e altere para ficar somente com as linhas abaixo: {$R BMPS.RES} library DLLBmp; end. - Compile o projeto (Ctrl+F9). Ser criado o arquivo DLLBmp.DLL. - Feche o projeto atual e crie um novo projeto; - Salve-o na mesma pasta que salvou o anterior, mas com outro nome qualquer; - Coloque no form um Edit e um Button; - No evento OnClick do Button coloque o cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); var Bmp: TBitmap; HandleDLL: THandle; begin { Carrega a DLL } HandleDLL := LoadLibrary('DLLBmp.DLL');

28 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

if HandleDLL = 0 then ShowMessage('No foi possvel carregar DLLBmp.DLL') else try Bmp := TBitmap.Create; try Bmp.Handle := LoadBitmap(HandleDLL, PChar(Edit1.Text)); if Bmp.Handle = 0 then ShowMessage('No foi possvel 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 boto. O bitmap dever ser pintado no form.

Observaes O arquivo DLL poder ser colocado na pasta onde estiver o EXE, no diretrio do Windows ou ainda no sub-diretrio System do Windows. Alm de bitmaps podemos colocar qualquer outro tipo de recurso em DLL's. Incio da pgina

121 - Construir a barra de ttulo do form com um Panel


Pegue o arquivo tbtitle.zip na seo Download do IntereSite: www.ulbrajp.com.br/~tecnobyte

Incio da pgina

120 - Criar form sem ttulo que possa ser arrastado


Problema: Fazer um relgio num form fcil. Porm gostaria que esse form no possusse a barra de ttulo, mas que o usurio ainda pudesse arrast-lo com o mouse. Isto possvel no Delphi? Soluo: Sim, possvel e fcil. Siga os passos abaixo:

29 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

- 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 seo private do Form1 e declare a procedure abaixo: private procedure WMNCHitTest(var Msg: TMessage); message WM_NCHitTest; public { Public declarations } end; - V na seo 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.

Observaes Para fechar este aplicativo pressione Alt+F4. Uma alternativa mais elegante colocar um menu local (PopupMenu) com um comando para fechar. Incio da pgina

119 - Obter status da memria do sistema


Inclua na seo uses: Windows, SysUtils
- Coloque um TMemo no form

30 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

- 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('Memria em uso: %d%%', [M.dwMemoryLoad])); Add(Format('Total de memria fsica: %f MB', [M.dwTotalPhys / cBytesPorMb])); Add(Format('Memria fsica disponvel: %f MB', [M.dwAvailPhys / cBytesPorMb])); Add(Format('Tamanho mximo do arquivo de paginao: %f MB', [M.dwTotalPageFile / cBytesPorMb])); Add(Format('Disponvel no arquivo de paginao: %f MB', [M.dwAvailPageFile / cBytesPorMb])); Add(Format('Total de memria virtual: %f MB', [M.dwTotalVirtual / cBytesPorMb])); Add(Format('Memria virtual disponvel: %f MB', [M.dwAvailVirtual / cBytesPorMb])); end; end;

Incio da pgina

118 - Definir data/hora de um arquivo


Inclua na seo uses: SysUtils
{ Esta funo altera a data e hora de um arquivo. Se obter sucesso retorna true, caso contrrio 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('No foi possvel definir data/hora do arquivo.');

31 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ 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('No foi possvel definir data/hora do arquivo.'); end;

Incio da pgina

117 - Mostrar o dilogo About (Sobre) do Windows


Inclua na seo uses: ShellApi
procedure TForm1.Button1Click(Sender: TObject); begin ShellAbout(Handle, 'Sistema Financeiro', 'Marcelo Senger', Application.Icon.Handle); end;

Observaes Dica enviada por: Marcelo Senger Incio da pgina

116 - Ocultar/exibir o cursor do mouse


Inclua na seo uses: Windows
- Escreva a funo 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;

32 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

- Exemplos de uso: MouseShowCursor(false); { Oculta o cursor } MouseShowCursor(true); { Exibe o cursor }

Incio da pgina

115 - Converter de Hexadecimal para Inteiro


Inclua na seo uses: SysUtils
Problema: A funo IntToHex do Delphi converte inteiro para hexadecimal. O que preciso, no entanto, fazer o contrrio, ou seja, converter de hexadecimal para inteiro. Existe isto pronto no Delphi ou terei que escrever uma funo para isto? Soluo: A funo StrToInt pode receber uma string no formato de um nmero decimal ou hexadecimal. Ento podemos us-la assim: var I: integer; begin I := StrToInt('$' + Edit1.Text); {...} end;

Observaes No Delphi, um nmero na notao decimal deve iniciar com o smbolo $. Incio da pgina

114 - Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condio
Problema: Uso um DBCtrlGrid e gostaria que, quando o valor de um determinado campo for negativo, o DBEdit ligado a este campo seja exibido em vermelho e, caso contrrio, em azul. Isto possvel? Soluo: - 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:

33 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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;

Observaes Neste exemplo mudamos a cor da fonte do componente DBEdit, Porm, pode-se tambm mudar a cor do prprio componente (DBEdit1.Color). Incio da pgina

113 - Colocar uma ProgressBar da StatusBar


- Coloque uma StatusBar no form. - Adicione dois paineis na StatusBar (propriedade Panels). - Ajuste as propriedades do primeiro painel conforme abaixo: Style = psOwnerDraw Width = 150 - Coloque uma ProgressBar no form e mude sua propriedade Visible para false. - No evento OnDrawPanel da StatusBar digite o cdigo 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 cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); var I: integer; begin for I := ProgressBar1.Min to ProgressBar1.Max do begin { Atualiza a posio da ProgressBar } ProgressBar1.Position := I; { Repinta a StatusBar para forar a atualizao visual } StatusBar1.Repaint; { Aguarda 50 milisegundos }

34 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Sleep(50); end; { Aguarde 500 milisegundos } Sleep(500); { Reseta (zera) a ProgressBar } ProgressBar1.Position := ProgressBar1.Min; { Repinta a StatusBar para forar a atualizao visual } StatusBar1.Repaint; end; - Execute e clique no boto para ver o resultado.

Observaes Com um pouco de criatividade podemos fazer outras coisas interessantes usando o evento OnDrawPanel da StatusBar. Incio da pgina

112 - Executar um programa e aguardar sua finalizao antes de continuar


Inclua na seo uses: Windows
{ Esta funo 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 necessrio devido aos espaos 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:

35 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

ExecAndWait('c:\windows\notepad.exe', '', SW_SHOW);

Observaes No se esquea de informar o caminho (path) do arquivo completo. Esta funo foi desenvolvida para Delphi 32 bits (2, 3, 4,...). Incio da pgina

111 - Simular o pressionamento de uma combinao de teclas (ex: Ctrl+F2)


Inclua na seo uses: Windows
{ Mantm 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);

Observaes Neste exemplo pressionamos Ctrl+F2. No se esquea das teclas que precisam manter pressionadas: Ctrl, Alt, Shift. Incio da pgina

110 - Simular o pressionamento de uma tecla


Inclua na seo 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 faa 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 boto e escreva no OnClick (do boto) como abaixo: procedure TForm1.Button1Click(Sender: TObject);

36 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

begin keybd_event(VK_F2, 0, 0, 0); end;

Observaes Consulte as constantes para os cdigos das teclas (ex: VK_RETURN, VK_DOWN, etc). Incio da pgina

109 - Ligar/desligar a tecla Caps Lock


Inclua na seo uses: Windows
{ Esta funo liga/desliga Caps Lock, conforme o parmetro 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 }

Observaes Aparentemente, podemos usar esta mesma tcnica para ligar/desligar Num Lock. Neste caso trocaramos VK_CAPITAL por VK_NUMLOCK. Por incrvel que parea no funcionou (pelo menos no teste que fiz). E tem mais: isto est na documentao do (R)Windows. Incio da pgina

108 - Verificar se uma determinada tecla est pressionada


Inclua na seo uses: Windows
{ Esta funo retorna true se a tecla informada estiver pressionada. False em caso contrrio. } function tbKeyIsDown(const Key: integer): boolean; begin Result := GetKeyState(Key) and 128 > 0; end; { Exemplos de uso: }

37 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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 }

Observaes Qualquer tecla pode ser verificada. Para isto basta saber o cdigo virtual (Virtual Key Code) da tecla. Incio da pgina

107 - Verificar o estado de NumLock e CapsLock


Inclua na seo uses: Windows
{ Esta funo retorna true se a tecla informada estiver ligada. False em caso contrrio } 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 }

Observaes Qualquer tecla que possua os estados On/Off pode ser verificada. Basta, para isto, saber seu cdigo. O cdigo de CapsLock VK_CAPITAL. Incio da pgina

106 - Configurar linhas de diferentes alturas em StringGrid


- Coloque o StringGrid no form. - No evento OnCreate do form coloque o cdigo abaixo: procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.RowHeights[0] := 15; StringGrid1.RowHeights[1] := 20; StringGrid1.RowHeights[2] := 50;

38 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

StringGrid1.RowHeights[3] := 35; end;

Observaes Cuidado para no especificar uma linha inexistente. Incio da pgina

105 - Adicionar o evento OnClick do DBGrid


Problema: Meu programa precisa processar algo quando o usurio clicar no DBGrid em um determinado form. O problema que o DBGrid no possui o evento OnClick. possvel adicionar este evento no DBGrid? Soluo: possvel sim. Afinal muito simples. Siga os passos abaixo para resolver seu problema: - Monte seu form normalmente, colocando o DBGrid e demais componentes; - V na seo "private" da unit e declare a procedure abaixo: private procedure DBGridClick(Sender: TObject); - Logo aps a palavra "implementation", escreva a procedure: implementation {$R *.DFM} procedure TForm1.DBGridClick(Sender: TObject); begin ShowMessage('Clicou no DBGrid.'); end; - Coloque as instrues 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.

Observaes O segredo principal desta dica est OnCreate do Form. A primeira instruo ativa o evento OnClick. A segunda instruo 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.

39 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

104 - Criar caixas de dilogo em tempo de execuo


Inclua na seo uses: Forms, StdCtrls, Buttons
A funo abaixo demonstra a criao de uma caixa de dilogo que pode ser usada para permitir ao usurio digitar o seu nome: { Esta funo retorna true se for pressionado OK e false em caso contrrio. Se for OK, o texto digitado pelo usurio ser copiado para a varivel Nome } function ObterNome(var Nome: string): boolean; var Form: TForm; { Varivel para o Form } Edt: TEdit; { Varivel para o Edit } begin Result := false; { Por padro retorna false } { Cria o form } Form := TForm.Create(Application); try { Altera algumas propriedades do Form } Form.BorderStyle := bsDialog; Form.Caption := 'Ateno'; 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 boto 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; { Boto Ok } end; { Coloca o boto Cancel } with TBitBtn.Create(Form) do begin Parent := Form; Left := Form.ClientWidth - Width - 10; Top := 80; Kind := bkCancel; { Boto Cancel }

40 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

end; { Exibe o form e aguarda a ao do usurio. Se for OK... } if Form.ShowModal = mrOK then begin Nome := Edt.Text; Result := true; end; finally Form.Free; end; end; Para chamar esta funo siga o exemplo abaixo: procedure TForm1.Button1Click(Sender: TObject); var S: string; begin if ObterNome(S) then Edit1.Text := S; end;

Observaes Os componentes Label, Edit (var Edt) e BitBtn's (botes) no so destrudos explicitamente (Componente.Free). Isto no necessrio, pois ao cri-los informei como proprietrio o Form (ex: TLabel.Create(Form)). Neste caso, estes componentes so destrudos automaticamente ao destruir o Form (Form.Free). Incio da pgina

103 - Converter a primeira letra de um Edit para maisculo


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 tambm converter durante a digitao. Para isto coloque o cdigo abaixo no evento OnKeyPress do Edit: if Edit1.SelStart = 0 then Key := AnsiUpperCase(Key)[1] else Key := AnsiLowerCase(Key)[1];

Incio da pgina

102 - Verificar se uma string contm uma hora vlida


- Use a funo abaixo: function StrIsTime(const S: string): boolean; begin try StrToTime(S);

41 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Result := true; except Result := false; end; end;

Incio da pgina

101 - Verificar se uma string contm um valor numrico vlido


- Use uma das funes 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;

Incio da pgina

100 - Mostrar uma mensagem durante um processamento


Problema: Um processamento em meu sistema bastante demorado e por isto colocar apenas o cursor de ampulheta continua deixando o usurio confuso, pensando que o sistema travou. possvel exibir uma mensagem enquanto um processamento demorado ocorre? Sim. E fcil. Vejamos: - Crie um form com a mensagem. Um pequeno form com um Label j suficiente. Aqui vou cham-lo de FormMsg. - V em Project|Options e passe o FormMsg de "Auto-create forms" para "Available forms". - Abaixo vou simular um processamento demorado, usando a API Sleep: procedure TForm1.Button1Click(Sender: TObject); var Form: TFormMsg; I: integer; begin

42 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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;

Observaes A funo Sleep uma API do Windows e serve para paralisar a aplicao por um determinado dempo. Este tempo em milisegundos. Incio da pgina

99 - Mostrar um cursor de ampulheta durante um processamento


- Salve o cursor atual - Defina o novo cursor (crHourGlass ampulheta) - Faa o processamento - Restaure o cursor. Vejamos: var PrevCur: TCursor; begin PrevCur := Screen.Cursor; try Screen.Cursor := crHourGlass; { Coloque aqui as instrues do processamento } finally Screen.Cursor := PrevCur; end; end;

Observaes 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 tambm criar o seu prprio cursor. Incio da pgina

98 - Ler e escrever dados binrios no Registro do Windows


Inclua na seo uses: Registry
Coloque no Form: - trs edits;

43 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

- dois botes. 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 varivel 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 no 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);

44 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Edit2.Text := Ficha.Nome; Edit3.Text := DateToStr(Ficha.DataCadastro); end else ShowMessage('Valor no existe no registro.') end else ShowMessage('Chave (path) no existe no registro.'); finally Reg.Free; end; end;

Observaes Qualquer tipo de dado pode ser gravado e lido de forma binria no registro do Windows. Para isto voc precisa saber o tamanho do dado. Para dados de tamanho fixo, use SizeOf(). Lembrete: no grave dados muito extensos no Registro do Windows (ex: imagens), pois isto prejudicar o desempenho do sistema. Incio da pgina

97 - Mudar a resoluo do vdeo via programao


- 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 boto no form - Altere o evento OnClick do boto conforme abaixo: procedure TForm1.Button1Click(Sender: TObject); var DevMode : TDevMode; begin EnumDisplaySettings(nil,Listbox1.ItemIndex,Devmode); ChangeDisplaySettings(DevMode,0); end;

Observaes Nos testes que fiz, nem tudo funcionou adequadamente. Mas vale a pena experimentar. Incio da pgina

45 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

96 - Ler e escrever dados no Registro do Windows


Inclua na seo uses: Registry
- Coloque no form dois edits e dois botes. - No evento OnClick do Button1 escreva o cdigo 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 no existir, cria e abre. } Reg.OpenKey('MeuPrograma\Configurao', 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\Configurao') then begin Reg.OpenKey('MeuPrograma\Configurao', false); if Reg.ValueExists('Numero') then Edit1.Text := IntToStr(Reg.ReadInteger('Numero')) else ShowMessage('No existe valor com o nome "Numero"'); if Reg.ValueExists('Nome') then Edit2.Text := Reg.ReadString('Nome') else ShowMessage('No existe valor com o nome "Nome"'); end else ShowMessage('No existe a chave no registro'); finally Reg.Free; end; end;

Observaes User o aplicativo RegEdit.exe do windows para ver o registro. Cuidado para no alterar as configuraes do Windows!

46 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

95 - Adicionar barra de rolagem horizontal no ListBox


{ - Coloque um ListBox no form; - Altere o OnCreate do Form conforme abaixo: } procedure TForm1.FormCreate(Sender: TObject); var I, Temp, MaxTextWidth: integer; begin { Adiciona algumas linhas no ListBox } Listbox1.Items.Add('Linha 1'); Listbox1.Items.Add('Linha 2, longa para que seja necessria a barra de rolagem horizontal'); Listbox1.Items.Add('Linha 3'); if Listbox1.Items.Count > 1 then begin { Obtm 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 instruo abaixo: } SendMessage(ListBox1.Handle, LB_SETHORIZONTALEXTENT, 0, 0);

Incio da pgina

94 - Simular um CharCase no DBGrid


Para converter a digitao para maisculo, coloque isto no evento OnKeyPress do DBGrid: Key := AnsiUpperCase(Key)[1]; Para converter para minsculo, troque por: Key := AnsiLowerCase(Key)[1];

Incio da pgina

93 - Verificar se uma string uma data vlida

47 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Escreva a funo 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 boto coloque o cdigo abaixo: if tbStrIsDate(Edit1.Text) then ShowMessage(Edit1.Text + ' data vlida.') else ShowMessage(Edit1.Text + ' NO data vlida.');

Incio da pgina

92 - Fazer pesquisa incremental com DBGrid e Edit


Problema: Gostaria de montar um formulrio de pesquisa com um DBGrid e um Edit de modo que, enquanto o usurio digita um nome do Edit, o registro vai sendo localizado no DBGrid. Como fazer? - Crie um ndice na tabela com campo a ser usado na pesquisa. Coloque no Form: - Um - Um - Um - Um DataSource Table DBGrid 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 instruo abaixo no evento OnChange do Edit: Table1.FindNearest([Edit1.Text]);

Observaes Este exemplo considera que o campo seja tipo string. Para outros tipos de campos pode ocorrer erro dependendo dos valores digitados no Edit1.

48 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

91 - Adicionar zeros esquerda de um nmero


Existem vrias 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;

Observaes Se o comprimento desejado (Casas) no for suficiente para conter o nmero, sero colocados asteriscos. Incio da pgina

90 - Limpar um campo tipo data via programao


Table1.FieldByName('Data').Clear; { ou } Table1.FieldByName('Data').AsString := '';

Observaes Podemos usar este recurso para limpar tambm campos numricos, string, etc. Incio da pgina

49 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

89 - Implementar um campo auto-incremental via programao


Inclua na seo 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;

Observaes A funo acima incrementa o campo somente se estiver vazio. Assim podemos dar ao usurio a opo de digitar neste campo ou deix-lo vazio para que seja auto-incrementado. Existem vrias outras formas de implementar este recurso. Incio da pgina

88 - Obter o endereo IP do Dial-Up


Inclua na seo uses: WinSock
{ Esta funo retorna o endereo 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

50 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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;

Observaes Se o endereo IP for designado pelo servidor, a cada coneco teremos um endereo IP diferente e, obviamente, se no estivermos conectados, no conseguiremos obt-lo. Incio da pgina

87 - Exibir a caixa de dilogo padro de solicitao de senha do banco de dados


Inclua na seo uses: DbPwDlg
{ Coloque um boto 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;

Observaes As senhas adicionadas nesta caixa de dilogo so adicionadas na sesso (TSession) atual. Isto til quando colocamos senha em tabelas Paradox, ou mesmo quando trabalhamos com banco de dados Client Servidor, e queremos que o usurio digite a senha de acesso. Se no fizermos desta forma, nem adicionarmos via programao as senhas necessrias, esta caixa de dilogo ser mostrada quando o programa tentar abrir uma tabela com senha. A grande vantagem aqui que podemos traduzir os Caption's dos componentes.
51 de 97 13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

86 - Obter a verso da biblioteca ComCtl32.DLL (usada na unit ComCtrls do Delphi)


Inclua na seo uses: ComCtrls
{ A verso desta biblioteca determina a aparncia de alguns controles do Delphi, tais como ToolBar e CoolBar. O exemplo abaixo obtm a verso desta biblioteca. Para este exemplo, coloque um TEdit e um TButton no Form. O evento OnClick do boto escreva o cdigo 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;

Observaes Normalmente, a verso 4.72 est presente quando o Internet Explorer 4 est instalado. Incio da pgina

85 - Implementar rotinas assembly em Pascal


{ O Delphi permite a implementao de rotinas assembly mescladas ao cdigo Pascal. No entrarei em detalhes minuciosos, mas darei alguns exemplos bsicos de como implementar rotinas simples que retornam nmeros 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

52 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

mov eax, &X add eax, &Y end; { A chamada a estas funes so feitas da mesma forma que chamamos uma funo Pascal. Exemplo: } var A: byte; begin A := Soma8(30, 25); { A = 55 } end;

Incio da pgina

84 - Exibir o dilogo About do Windows


Inclua na seo uses: Windows
{ About padro do Windows } ShellAbout(Handle, 'Windows', '', 0); { Personalizada } ShellAbout(Handle, 'NomePrograma', 'Direitos autorais reservados a'#13'Fulano de Tal', Application.Icon.Handle);

Incio da pgina

83 - Obter a linha e coluna atual em um TMemo


{ === SOLUO 1 === } { Esta procedure obtm 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; { === SOLUO 2 === } var Lin, Col: integer; begin Lin := Memo1.CaretPos.y; Col := Memo1.CaretPos.x;

53 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{...} end; - A segunda soluo foi apresentada por: Vanderley Pereira Rocha

Incio da pgina

82 - Exibir um arquivo de ajuda do Windows


Inclua na seo 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 tpico n. 100 } procedure TForm1.Button1Click(Sender: TObject); begin WinHelp(0, 'c:\Win95\Help\Calc.hlp', HELP_CONTEXT, 100); end;

Observaes Para utilizar um arquivo de ajuda em seu programa desenvolvido em Delphi, basta usar os recursos do prprio Delphi. O exemplo acima somente para mostrar o uso de uma API para este fim. Incio da pgina

81 - Obter o valor de uma varivel de ambiente


Inclua na seo uses: Windows
{ Esta funo recebe o nome da varivel de ambiente que queremos acessar e retorna uma string com seu valor, ou uma string vazia se a varivel no existir. } function tbGetEnvVar(const VarName: string): string; var I: integer; begin Result := ''; { Obtm o comprimento da varivel } I := GetEnvironmentVariable('PATH', nil, 0); if I > 0 then begin SetLength(Result, I); GetEnvironmentVariable('PATH', PChar(Result), I); end; end;

54 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Para us-la, faa como neste exemplo: } Edit1.Text := tbGetEnvVar('PATH');

Incio da pgina

80 - Determinar se uma janela (form) est maximizada


Inclua na seo uses: Windows
if IsZoomed(Form1.Handle) then { Form1 est maximizado } else { Form2 NO est maximizado }

Observaes Veja a pergunta n. 78. Incio da pgina

79 - Determinar se o cursor do mouse est em determinado controle


Inclua na seo uses: Windows
{ Os exemplos abaixo verificam se o cursor do mouse est em Button1: } { Soluo 1: } var Pt: TPoint; Rct: TRect; begin GetCursorPos(Pt); GetWindowRect(Button1.Handle, Rct); if PtInRect(Rct, Pt) then { Est no boto } else { NO est no boto } end; { Soluo 2: } var Pt: TPoint; begin GetCursorPos(Pt); if WindowFromPoint(Pt) = Button1.Handle then { Est no boto } else { No est no boto } end;

Observaes A API GetWindowRect obtm o retngulo (TRect) ocupado por uma janela. Podemos usar GetClientRect para obter o somente da parte cliente da janela. Podemos tambm usar a

55 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

propriedade BoundsRect que existe na maioria dos componentes visuais, ou mesmo informar qualquer outro retngulo da tela. Se usarmos a propriedade BoundsRect, precisaremos converter as coordenadas clientes para coordenadas de tela (com a funo ClientToScreen). Um lembrete: a soluo 2 s poder ser aplicada a controles ajanelados. Incio da pgina

78 - Determinar se o aplicativo est minimizado


Inclua na seo uses: Windows
if IsIconic(Application.Handle) then { Minimizado } else { No minimizado }

Observaes Pode-se verificar qualquer janela (form). S um lembrete: quando clicamos no boto de minimizar do form principal, na verdade ele oculto e o Application que minizado. Incio da pgina

77 - Fechar um aplicativo com uma mensagem de erro fatal


Inclua na seo uses: Windows
procedure TForm1.Button1Click(Sender: TObject); begin FatalAppExit(0, 'Erro fatal na aplicao.'); end;

Observaes A funo FatalAppExit uma API do Windows. Esta mostra uma caixa de dilogo (normalmente branca) com a mensagem passada no segundo parmetro. Quando a caixa de dilogo fechada a aplicao finalizada. O evento OnCloseQuery dos forms no so chamados quando usamos esta funo. Incio da pgina

76 - Usar o evento OnGetText de um TField


{ Problema: Tenho um sistema de contas a receber, onde um campo chamado "Tipo" contm um nmero inteiro que indica o tipo do documento conforme abaixo:

56 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

1 - Promissria 2 - Duplicata 3 - Boleto Gostaria que, ao exibir os dados (num DBGrid por exemplo), fosse exibido o nome e no o nmero, ou seja, "Promissria" em vez de "1". Soluo: Isto pode ser feito de vrias formas, mas aqui vou mostrar como resolver usando o evento OnGetText do TField. Vejamos: - Adicione todos os campos no Field Editor; - Clique no campo "Tipo"; - V ao Object Inspector e d um duplo-click no evento OnGetText; - Neste evento, digite o cdigo abaixo: } procedure TForm1.Table1TipoGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin if DisplayText then begin case Table1Tipo.AsInteger of 1: Text := 'Promissria'; 2: Text := 'Duplicata'; 3: Text := 'Boleto'; else Text := 'Desconhecido'; end; end else Text := Table1Tipo.AsString; end;

Observaes Ao exibir ser exibido os nomes. Mas ao digitar continue com os 1, 2, 3, etc. Para usar este recurso em relatrios, acesse a propriedade DisplayText em vez de AsString para obter o valor do campo. Incio da pgina

75 - Maximizar um form de forma que cubra toda a tela, inclusive a barra de tarefas
{ um "maximizar" com jeitinho brasileiro... mas funciona. No evento OnShow do form coloque o cdigo abaixo: } Top := 0; Left := 0; Width := Screen.Width; Height := Screen.Height;

Observaes Nos testes que fiz, mesmo com a barra de tarefas marcada como "Sempre Visvel", funcionou

57 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

perfeitamente. Fiz os testes usando o Win95. Talvez em novas verses, possa apresentar problemas. Incio da pgina

74 - Verificar, via programao, se Local Share do BDE est TRUE


Inclua na seo uses: Registry, SysUtils, Windows
{ Esta funo retorna true se Local Share estiver "TRUE". Caso contrrio, 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 }

Observaes A funo acima faz a verificao no registro do Windows. Por isto est sujeita a falha caso o BDE coloque as configuraes em outro local ( o caso do BDE salvar as configuraes no formato do Windows 3.x). O ideal seria usar uma API do BDE, mas at o momento no conheo uma que retorne esta informao. Caso algum saiba, queira por gentileza nos informar. Incio da pgina

73 - Criar um EXE que seja executado apenas atravs de outro EXE criado por mim
Inclua na seo uses: Windows
{ Problema:

58 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Gostaria que um determinado programa (Prog1.EXE) fosse executado apenas atravs de outro programa (Prog2.EXE). Soluo: Antes da linha "Application.Initialize;" de Prog1.dpr (programa a ser chamado), coloque o cdigo abaixo: } if ParamStr(1) <> 'MinhaSenha' then begin { Para usar ShowMessage, coloque Dialogs no uses } ShowMessage('Execute este programa atravs de Prog2.EXE'); Halt; { Finaliza } end; { No Form1 de Prog2 (programa chamador) coloque um boto e escreva o OnClick deste boto como abaixo: } procedure TForm1.Button1Click(Sender: TObject); var Erro: Word; begin Erro := WinExec('Pro2.exe MinhaSenha', SW_SHOW); if Erro <= 31 then { Se ocorreu erro... } ShowMessage('Erro ao executar o programa.'); end;

Observaes Aqui o parmetro passado foi 'MinhaSenha'. Voc dever trocar 'MinhaSenha' por algo que apenas voc saiba (uma senha). Caso uma pessoa conhea esta senha, ser possvel chamar este programa passando-a como parmetro. Neste caso sua "trava" estar violada. Incio da pgina

72 - Resolver "Internal error near: IBCheck" do Interbase 5.1.1 Server no NT


Recebi esta mensagem do desenvolvedor Alexsando S. Pimenta. Como deve ser do interesse de outros desenvolvedores, coloquei-a aqui: ==== Mensagem original ==== Ol Daniel, Anote est soluo, muitos tem o mesmo problema mas no conseguem a soluo to facilmente como eu. Look: Problema: Estou com um problemo. Trabalho com o NT 4 workstation Service Pack 3, Delphi 3 e Interbase 4.2.xxx. E instalei o Interbase 5.1.1 Server nesta mquina. At a tudo bem. Quando fui rodar a aplicao deram alguns problemas de converso do tipo de Dado. Analisando o problema percebi que havia esquecido de instalar o Client do Interbase. Foi a que comearam os problemas. Tentei instalar o client, porm o instalador aps preparar os arquivos de instalao mostrava

59 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

a seguinte mensagem e parava : Titulo da janela = "Severe", mensagem = "Internal error near: IBCheck"; comecei a ler os manuais, em certo ponto aconselhava desinstalar qualquer verso posterior do Interbase da minha mquina. Foi ento que desinstalei o Interbase 4.2.xxx (atravs do "Control Panel", "Add/Remove Programs"). Nova tentativa de instalar o client, o erro persistia. Resolvi desinstalar (atravs do "Control Panel", "Add/Remove Programs") todo o Interbase da minha mquina e comear tudo de novo. Porm quando tentei instalar novamente o Interbase Server, surpresa, o erro apareceu novamente. Mas agora no havia interbase instalado. Fui desinstalando Delphi, BDE, ... e nada. Entrei no Regedit, pois o desinstalador, normalmente, faz o trabalho incompleto e necessrio excluir um monte de lixo do Registry. Deparei com a seguintes chaves: hkey_local_machine\system\controlset001\enum\root\legacy_interbase_guard hkey_local_machine\system\controlset001\enum\root\legacy_interbase Tentei exclu-las, porm so chaves protegidas, e o regedit no permitiu que eu exclusse-as. Poderiam me dar uma soluo para eu poder instalar o Interbase em minha mquina? Preciso disto com urgncia. Obrigado, Alexsandro Pimenta Xenon Software Comrcio e Servios Ltda apepper@uol.com.br

Soluo: Sr. Alexsandro, Esse erro: 'Internal error near: IBCheck' acontece apenas em algumas mquinas NT 4. Na hora da instalao, criada uma chave com valor errado. Entre no registry do Windows e altere a opo, PATH de binrio para string, da chave: HKEY_CURRENT_USER\Environment Renata Oliva Inprise Support Center

Incio da pgina

71 - Inverter os botes do mouse


Inclua na seo uses: Windows
{ Para inverter: } SwapMouseButton(true); { Para voltar ao normal: } SwapMouseButton(false);

60 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

70 - Obter/definir o tempo mximo do duplo-click do mouse


Inclua na seo uses: Windows
{ - Coloque um boto no form e escreva seu OnClick como abaixo: } procedure TForm1.Button6Click(Sender: TObject); var Tempo: Cardinal; begin { Obtm } Tempo := GetDoubleClickTime; ShowMessage(IntToStr(Tempo) + ' milisegundos'); { Define } SetDoubleClickTime(300); end;

Observaes Um duplo-click nada mais que dois cliques consecutivos (bvio). Porm estes dois cliques podem ser interpretados de duas formas: dois cliques isolados ou um duplo-click. Para o Windows resolver esta situao, ele usa o que chamo de "tempo mximo do duplo-click". Se o intervalo entre o primeiro e o segundo click for menor ou igual a esse tempo, ento houve duplo-click. E voc pode alterar este tempo. O padro do Windows 500 milisegundos. Um tempo muito curto (ex: 100), faz com que o duplo-click tenha que ser muito rpido (quase impossvel), enquanto muito longo (ex: 2000) faz com que o Windows interprete dois clicks isolados como duplo-click. Incio da pgina

69 - Obter os atributos de um arquivo/diretrio


Inclua na seo uses: Windows
{ No form: - Coloque um memo; - Coloque um edit; - Coloque um boto 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');

61 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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;

Incio da pgina

68 - Obter o espao total e livre de um disco


Inclua na seo uses: Windows
{ - Coloque um memo (TMemo) no form; - Coloque um boto 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 funes do Delphi. Veja: } Memo1.Lines.Add('Total de bytes: ' + IntToStr(DiskSize(3))); Memo1.Lines.Add('Bytes livres: ' + IntToStr(DiskFree(3))); { Onde o parmetro (3) o nmero da unidade, sendo 1=A, 2=B, 3=C, ... }

Observaes

62 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Para usar as funes DiskSize e DiskFree coloque SysUtils em uses. Incio da pgina

67 - Obter o tipo de um drive (removvel, fixo, CD-ROM, unidade de rede, etc)


Inclua na seo uses: Windows, Dialogs
{ - Coloque um edit (Edit1) e um boto no form; - Altere o OnClick do boto 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 no existe'; DRIVE_REMOVABLE: S := 'Disco removvel'; 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);

Observaes Para testar digite a letra do drive no Edit1 e clique no boto. 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 funo tbGetDrives (da pergunta 64) em conjunto com este exemplo. Incio da pgina

66 - Obter informaes de um volume/disco (label, serial, sistema de arquivos, etc)


Inclua na seo uses: Windows, System
{ - Coloque um memo (TMemo) no form; - Coloque um boto e escreve seu evento OnClick como abaixo: } procedure TForm1.Button1Click(Sender: TObject);

63 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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('Nmero Serial: ' + IntToHex(Serial, 8)); Add('Tamanho mximo p/ nome arquivo: ' + IntToStr(FileNameLen)); Add('Sistema de Arquivos: ' + string(SSysName)); end; finally FreeMem(SLAbel, 255); FreeMem(SSysName, 255); end; end;

Incio da pgina

65 - Alterar o nome de volume (Label) de um disco


Inclua na seo uses: Windows
{ Da unidade C: } SetVolumeLabel('c:\', 'NovoLabel'); { Da unidade atual: } SetVolumeLabel(nil, 'NovoLabel');

Observaes Veja a pergunta n 66. Incio da pgina

64 - Saber quais as unidades de disco (drives) esto presentes


Inclua na seo uses: Windows
{ A funo 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

64 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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

Observaes A string retornada pela funo tbGetDrives est sempre em letras maisculas. Incio da pgina

63 - "truncar" valores reais para apenas n casas decimais


{ s vezes voc precisa considerar apenas duas casas de valores reais, mas o Delphi no oferece algo pronto para isto. Se usarmos funes como Round que vem com o Delphi, o valor ser arredondado (e no truncado). Com Round() o valor abaixo ser 135.55 (e no 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 { Trs casas } X := Trunc(ValorReal * 1000) / 1000; // X ser 135.5465

Observaes Isto pode no funcionar se ValorReal for muito alto. Isto por causa da multiplicao que poder estourar a capacidade do tipo em uso. Lembre-se: os tipos reais aceitam valores muuuiiiito altos. Incio da pgina

62 - Excluir todos os registros de uma tabela (como DELETE ALL do Clipper)


procedure tbDBDeleteAll(const DataSet: TDataSet); begin with DataSet do while RecordCount > 0 do Delete; end;

65 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Chame-a como nos exemplos abaixo: } tbDBDeleteAll(Table1); ou tbDBDeleteAll(Query1);

Observaes Se houver um filtro ou range ativo, somente os registros filtrados sero excludos. Portanto diferente de Table1.EmptyTable. Esta funo poder ser chamada no evento BeforeDelete do Table (ou Query) principal em um formulrio mestre-detalhe para excluir os itens (da parte detalhe). Incio da pgina

61 - Saber se o sistema est usando 4 dgitos para o ano


{ Para no correr o risco de surpresas desagradveis, melhor que seu programa em Delphi verifique se o Windows est ajustado para trabalhar com 4 dgitos para o ano. Assim seu programa pode alertar o usurio quando o ano estiver sendo representado com apenas 2 dgitos. A funo abaixo retorna true se estiver ajustado para 4 dgitos. } function Is4DigitYear: Boolean; begin result:=(Pos('yyyy',ShortDateFormat)>0); end;

Incio da pgina

60 - Imprimir caracteres acentuados diretamente para a impressora


{ Usando comandos da impressora podemos fazer isto de uma forma bastante simples. Quando enviamos o caractere ASCII nmero 8 (oito) para a impressora, a cabea de impresso retrocede uma posio, pois este caractere o BackSpace. Ento podemos imprimir a letra sem acento e, sem seguida, voltar e imprimir o acento desejado. Vejamos um exemplo: - Coloque um boto no form; - Altere o evento OnClick deste boto 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.');

66 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

WriteLn(F, 'Vovo' + #8 + '^'); WriteLn(F, 'U' + #8 + '''' + 'ltimo.'); WriteLn(F, #12); // Eject finally CloseFile(F); end; end;

Observaes Usando este recurso, a acentuao no fica excelente, mas melhora bastante. Incio da pgina

59 - Imprimir texto justificado com formatao na impressora Epson LX-300


{ A impressora Epson LX-300 dispe de um comando que justifica o texto. Este recurso interessante, pois com ele podemos continuar a enviar os comandos de formatao de caracteres como condensado, negrito, italico, expandido, etc. Para o exemplo abaixo: - Coloque um boto no form; - Altere o evento OnClick deste boto 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; { Formatao 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');

67 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Rewrite(F); try WriteLn(F, cJustif, Texto); WriteLn(F, cEject); finally CloseFile(F); end; end;

Observaes Este recurso de justificao da Epson LX-300 pode ser usado em qualquer linguagem de programao. Incio da pgina

58 - Formatar um disquete atravs de um programa Delphi


{ Coloque o cdigo abaixo imediatamente abaixo da palavra implementation: } const SHFMT_ID_DEFAULT = $FFFF; { Opes de formatao } SHFMT_OPT_QUICKFORMAT = $0000; { Formatao rpida } SHFMT_OPT_FULL = $0001; { Formatao completa } SHFMT_OPT_SYSONLY = $0002; { Copia sistema } { Cdigos de errros } SHFMT_ERROR = $FFFFFFFF; { Ocorreu erro } SHFMT_CANCEL = $FFFFFFFE; { Foi cancelado } SHFMT_NOFORMAT = $FFFFFFFD; { No formatou } function SHFormatDrive(Handle: HWND; Drive, ID, Options: Word): LongInt; stdcall; external 'shell32.dll' name 'SHFormatDrive' { Coloque um boto 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 formatao foi cancelada.'; SHFMT_NOFORMAT: Msg := 'No foi possvel formatar.'; else Msg := 'Disco formatado com sucesso.'; end; ShowMessage(Msg); end;

Observaes

68 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Para formatao completa troque SHFMT_OPT_QUICKFORMAT por SHFMT_OPT_FULL. O segundo parmetro (zero no exemplo) indica a unidade, sendo que A 0 (zero), B 1, etc. Incio da pgina

57 - Alterar (e restaurar) o tamanho da pgina na impressora


Inclua na seo uses: tbPrn
{ - Peque em nosso Download o arquivo tbPrn.zip. Ele contm a unit tbPrn.pas, onde est a funo tbPrnSetPaperSize usada no exemplo abaixo; - Adicione a unit tbPrn.pas em seu projeto; - Siga o exemplo abaixo para criar seus relatrios usando o TPrinter. } procedure TForm1.Button1Click(Sender: TObject); var Papel: TtbPrnPaper; begin Papel.Size := 256; // 256 o tam. personalizado Papel.Width := 2100; // 21 cm Papel.Height := 1000; // 10 cm Papel := tbPrnSetPaperSize(Papel); try Printer.BeginDoc; try { coloque aqui os comandos para impresso } finally Printer.EndDoc; end; finally tbPrnSetPaperSize(Papel); // Restaura o tamanho end; end; { Papel.Size refere-se ao tamanho do papel. Veja alguns: 0 - Default 1 - Letter 5 - Legal 8 - A3 9 - A4 11 - A5 256 - Custom (personalizado) }

Observaes S ser necessrio informar Papel.Height e Papel.Width quando Papel.Size for 256. Incio da pgina

56 - Reproduzir um arquivo de som WAV sem o TMediaPlayer


Inclua na seo uses: MMSystem
69 de 97 13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Sncrona: aguarda terminar a reproduo para continuar: } SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_SYNC); { Assncrona: a execuo continua normalmente enquanto ocorre a reproduo: } SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_ASYNC); { Contnua: a reproduo repetida num efeito de loop. Este tipo de reproduo precisa ser assncrona: } SndPlaySound('C:\Win95\Media\Office97\Lembrete.wav', SND_ASYNC or SND_LOOP); { Interrompe uma reproduo contnua: } SndPlaySound(nil, 0);

Observaes A reproduo contnua pode ser usada, por exemplo, para altertar o usurio em uma situao extremamente crtica. Se o equipamento no possuir placa de som, o arquivo no ser reproduzido. Incio da pgina

55 - Obter o nome do usurio e da empresa informado durante a instalao do Windows


Inclua na seo uses: Registry
{ Coloque um boto 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;

Incio da pgina

54 - Mostrar uma barra de progresso enquanto copia arquivos


Veja a pergunta n 53.

Incio da pgina

70 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

53 - Copiar arquivos usando o Shell do Windows


Inclua na seo uses: ShellApi
{ - Coloque um boto no form e altere o evento OnClick deste boto 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;

Observaes Esta forma de copiar arquivos oferecem vrias vantagens. O Shell avisa para pr um prximo disco quando o atual estiver cheio. Mostra a barra de progresso. Pode copiar arquivos usando mscara de uma forma extremamente simples. Incio da pgina

52 - Descobrir o cdigo ASCII de uma tecla


{ - Coloque um Label no form (Label1); - Mude a propriedade KeyPreview do form para true; - Altere o evento OnKeyDown do form como abaixo: } procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin Label1.Caption := Format('O cdigo da tecla pressionada : %d', [Key]); end;

Observaes Para testar execute e observe o Label enquanto pressiona as teclas desejadas. Incio da pgina

51 - Evitar que seu programa aparea na barra de tarefas


Inclua na seo uses: Windows

71 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Voc j observou a caixa "Propriedades", aquela que mostra as propriedades de um arquivo no Windows Explorer, no 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. Porm podemos mudar o comportamento de nossos programas feito em Delphi para que se comportem como uma ToolWindow tambm. Para experimentar, crie um novo projeto e altere o Project1.dpr como abaixo (no esquea 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.

Observaes Ao executar observe a barra de tarefas e teste o Alt+Tab (seu programa no estar l!). Incio da pgina

50 - Usar eventos de som do Windows


{ Evento Som Padro } MessageBeep(0); { ou Beep; } { Evento Parada Crtica } MessageBeep(16); { Evento Pergunta } MessageBeep(32); { Evento Exclamao } MessageBeep(48); { Evento Asterisco } MessageBeep(64);

Incio da pgina

72 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

49 - Mudar a coluna ativa em um DBGrid via programao


{ Usando nmero da coluna (zero a primeira coluna): } DBGrid1.SelectedIndex := 0; { Usando o nome do campo } DBGrid1.SelectedField := Table1.FieldByName(Edit2.Text);

Observaes Aconselho usar o nome do campo quando o que importa o campo e no a posio. Use o nmero da coluna somente quando o que importa a posio, e no o campo. Incio da pgina

48 - Fechar o Windows a partir do seu programa


{ Reinicia o Windows } ExitWindowsEx(EWX_REBOOT, 0); { Desliga o Windows } ExitWindowsEx(EWX_SHUTDOWN, 0); { Fora todos os programa a desligarem-se } ExitWindowsEx(EWX_FORCE, 0);

Incio da pgina

47 - Carregar um cursor animado (.ani)


{ Altere o evento OnCreate do Form conforme abaixo: } procedure TForm1.FormCreate(Sender: TObject); begin Screen.Cursors[1] := LoadCursorFromFile('c:\win95\cursors\globe.ani'); Button1.Cursor := 1; end;

Observaes Para este exemplo necessrio ter o arquivo de cursor conforme apontado e tambm ter, no form, um Button1. Para usar este cursor em outros componentes basta atribuir propriedade Cursor do componente em questo o valor 1 (um). Exemplo: Edit1.Cursor := 1; Form1.Cursor := 1;, etc. Incio da pgina

46 - Enviar um arquivo para a lixeira

73 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Inclua na seo uses: ShellApi


{ Coloque a procedure abaixo na seo implementation } procedure ArqParaLixeira(const NomeArq: string; var MsgErro: string); var Op: TSHFileOpStruct; begin MsgErro := ''; if not FileExists(NomeArq) then begin MsgErro := 'Arquivo no 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 := 'No foi possvel enviar o arquivo para a lixeira.'; end; { - Coloque um boto no Form; - Altere o evento OnClick do boto 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;

Incio da pgina

45 - Obter o nmero do registro atual


Table1.RecNo()

Incio da pgina

44 - Trabalhar com Filter de forma mais prtica


Se voc est habituado a usar este cdigo no filter... Table1.Filter := 'Nome = '''+ Edit1.Text + ''''; ou Table1.Filter := 'Data = ''' + DateToStr(Date) + ''''; Tente usar este: Table1.Filter := 'Nome = ' + QuotedStr(Edit1.Text);

74 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

ou Table1.Filter := 'Data = ' + QuotedStr(DateToStr(Date));

Observaes A funo QuitedStr() coloca apstrofos envolvendo a string. Se houver um apstrofo como parte da string, ela o subtitui por dois apstrofos, para que seja corretamente interpretado. Incio da pgina

43 - Reproduzir um arquivo WAV


Inclua na seo uses: MMSystem
PlaySound('C:\ArqSom.wav', 1, SND_ASYNC);

Observaes Troque o nome do arquivo (C:\ArqSom.wav) pelo arquivo desejado. Incio da pgina

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


{ Coloque isto no evento OnClick de um boto: } WinExec('command.com /c programa.exe',sw_ShowNormal); { Se quizer passar parmetros pasta adicion-los aps o nome do programa. Exemplo: } WinExec('command.com /c programa.exe param1 param2',sw_ShowNormal);

Observaes Se quizer que a janela do programa no aparea, troque sw_ShowNormal por sw_Hide. Incio da pgina

41 - Fechar um programa a partir de um programa Delphi


{ - Coloque um boto 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 no encontrado')

75 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

else PostMessage(Janela, WM_QUIT, 0, 0); end;

Observaes 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 no salvos, o programa a ser fechado no oportunidade para salv-los. Uma alternativa mais suave trocar a mensagem WM_QUIT por WM_CLOSE. Veja as perguntas 18 e 36. Incio da pgina

40 - Colocar Hint's de vrias linhas


{ - Coloque um TButton no Form; - Altere o evento OnCreate do Form como abaixo: } procedure TForm1.FormCreate(Sender: TObject); begin Button1.Hint := 'Linha 1 da dica' + #13 + 'Linha 2 da dica' + #13 + 'Linha 3 da dica'; Button1.ShowHint := true; end;

Incio da pgina

39 - Reproduzir um vdeo AVI em um Form


{ - Crie um novo projeto. Este j dever ter o Form1; - Adicione um novo Form (Form2); - Coloque, no Form1, um TMediaPlayer (paleta System) e um boto; - Altere o evento OnClick do boto 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;

Observaes

76 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Em vez de ajustar o Form ao vdeo, podemos ajustar o vdeo ao Form. Para isto troque o trecho with..end; por MediaPlayer1.DisplayRect := Form2.ClientRect; Incio da pgina

38 - Separar (filtrar) caracteres de uma string


{ Abaixo da palavra implementation digite: } type TChars = set of Char; function FilterChars(const S: string; const ValidChars: TChars): string; var I: integer; begin Result := ''; for I := 1 to Length(S) do if S[I] in ValidChars then Result := Result + S[I]; end; { Para usar a funo: - Coloque um boto no Form; - Altere o evento OnClick deste boto conforme abaixo: } procedure TForm1.Button4Click(Sender: TObject); begin { Pega s letras } ShowMessage(FilterChars('D63an*%i+/e68l13', ['A'..'Z', 'a'..'z'])); { Pega s nmeros } ShowMessage(FilterChars('D63an*%i+/e68l13', ['0'..'9'])); end;

Observaes Se quizer usar este funo em outras unit's, coloque a declarao do tipo TChars na seo interface. Coloque a tambm uma declarao da funo FilterChars. E no se esquea da clusula uses. Incio da pgina

37 - Colocar zeros esquerda de nmeros


{ Isto coloca zeros esquerda do nmero at completar 6 casas } S := FormatFloat('000000', 5);

Observaes "S" precisa ser uma varivel string.

77 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

36 - Copiar arquivos usando curingas (*.*)


{ - Coloque um Button no Form; - Altere o evento OnClick deste Button conforme abaixo: } procedure TForm1.Button2Click(Sender: TObject); var SR: TSearchRec; I: integer; Origem, Destino: string; begin I := FindFirst('c:\Origem\*.*', faAnyFile, SR); while I = 0 do begin if (SR.Attr and faDirectory) <> faDirectory then begin Origem := 'c:\Origem\' + SR.Name; Destino := 'c:\Destino\' + SR.Name; if not CopyFile(PChar(Origem), PChar(Destino), true) then ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino); end; I := FindNext(SR); end; end;

Observaes No exemplo acima, se o arquivo j existir no destino, a funo falha (no copia). Para que a funo possa sobreescrever o arquivo destino (caso exista), altere o ltimo parmetro de CopyFile para false. CUIDADO! Se um arquivo for sobreescrito, estar perdido para sempre! Veja as perguntas n 35 e 53. Incio da pgina

35 - Copiar arquivos
{ - Coloque um Button no Form; - Altere o evento OnClick deste Button conforme abaixo: } procedure TForm1.Button2Click(Sender: TObject); var Origem, Destino: string; begin Origem := 'c:\Origem\NomeArq.txt'; Destino := 'c:\Destino\NomeArq.txt'; if not CopyFile(PChar(Origem), PChar(Destino), true) then ShowMessage('Erro ao copiar ' + Origem + ' para ' + Destino); end;

Observaes No exemplo acima, se o arquivo j existir no destino, a funo falha (no copia). Para que a funo possa sobreescrever o arquivo destino (caso exista), altere o ltimo parmetro de CopyFile para false. CUIDADO! Se um arquivo for sobreescrito, estar perdido para sempre!

78 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Veja as perguntas n 36 e 53. Incio da pgina

34 - Trabalhar com cores no formato string


procedure TForm1.Button3Click(Sender: TObject); begin { Exibe as cores atuais dos Edit's } ShowMessage(ColorToString(Edit1.Color)); ShowMessage(ColorToString(Edit2.Color)); { Altera as cores dos Edit's } Edit1.Color := StringToColor('clBlue'); Edit2.Color := StringToColor('$0080FF80'); end;

Incio da pgina

33 - Verificar se determinado programa est em execuo (Word, Delphi, etc)


{ Coloque um Button no Form e altere o evento OnClick deste como abaixo: } procedure TForm1.Button1Click(Sender: TObject); begin { Verifica o Delphi } if FindWindow('TAppBuilder', nil) > 0 then ShowMessage('O Delphi est aberto') else ShowMessage('O Delphi NO est aberto'); { Verifica o Word } if FindWindow('OpusApp', nil) > 0 then ShowMessage('O Word est aberto') else ShowMessage('O Word NO est aberto'); { Verifica o Excell } if FindWindow('XLMAIN', nil) > 0 then ShowMessage('O Excell est aberto') else ShowMessage('O Excell NO est aberto'); end;

Observaes H uma margem de erro nesta verificao: 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. Incio da pgina

79 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

32 - Excluir arquivos usando curingas (*.*)


{ - Coloque um Button no Form; - Altere o evento OnClick do Button conforme abaixo: } procedure TForm1.Button2Click(Sender: TObject); var SR: TSearchRec; I: integer; begin I := FindFirst('c:\Teste\*.*', faAnyFile, SR); while I = 0 do begin if (SR.Attr and faDirectory) <> faDirectory then if not DeleteFile('c:\Teste\' + SR.Name) then ShowMessage('No consegui excluir c:\Teste\' + SR.Name); I := FindNext(SR); end; end;

Observaes No exemplo acima todos os arquivos do diretrio c:\Teste sero excludos. CUIDADO! Arquivos excludos desta forma no vo para a lixeira. Veja a pergunta n 46. Incio da pgina

31 - Gerar uma tabela no Word atravs do Delphi


Inclua na seo uses: ComObj
{ - Coloque um boto no Form; - Altere o evento OnClick do boto 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 clula } Word.Selection.TypeText(Text := 'Linha 1, Coluna 1'); { Prxima clula } 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');

80 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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 cpia } Word.ActiveDocument.PrintOut(Copies := 1); ShowMessage('Aguarde o trmino da impresso...'); { 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;

Observaes Foram usados neste exemplo o Delphi4 e MS-Word97. Incio da pgina

30 - Obter a quantidade de registros total e visvel de uma tabela


Inclua na seo 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 no 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;

Observaes Para testar o exemplo acima, o Table1 precisa estar aberto.

81 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Incio da pgina

29 - Evitar que um programa seja executado mais de uma vez


{ Muitos programas Windows permitem apenas uma cpia em execuo de cada vez. Isto interessante principalmente quando um grande aplicativo, pois duas cpias ao mesmo tempo usuaria muito mais memria. Em aplicativos desenvolvidos em Delphi podemos ter esta caracterstica. Vejamos: - Crie um novo projeto; - Mude o "Name" do Form1 para DPGFormPrinc; - Altere o cdigo-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 cpia ' + '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.

Observaes 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 no correr o risco de colocar um nome que possa ser encontrado em outro aplicativo do Windows. Por exemplo: se deixar Form1, ser bem fcil encontrar outro aplicativo feito em Delphi que possua uma janela com este nome, o que causaria problema. Incio da pgina

28 - Executar um "COMMIT" no Delphi

82 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Inclua na seo uses: DbiProcs


{ Se estiver usando TTable, coloque nos eventos AfterPost e AfterDelete a seguinte linha: } dbiSaveChanges(Table1.Handle); { Para TQuery, a instruo semelhante: } dbiSaveChanges(Query1.Handle);

Incio da pgina

27 - Posicionar Form's em relao ao Desktop do Windows


{ Quando usamos a propridade Position de um Form para centraliz-lo estamos sujeitos a um inconveniente: dependendo da posio/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 seo 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;

83 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Observaes Para testar, execute este exemplo e experimente digitar nmeros de 1 a 3 em ambos os Edit's e clique no Button para ver o resultado. O Edit1 indica a posio horizontal (esquerda, centro e direita) e o Edit2 indica a posio vertical (topo, centro e em baixo). Incio da pgina

26 - Saber a resoluo de tela atual


{ Coloque um TButton no Form e altere o evento OnClick deste boto como abaixo: } procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage('Largura: ' + IntToStr(Screen.Width) + #13 + 'Altura: ' + IntToStr(Screen.Height)); end;

Observaes O objeto Screen contm vrias informaes importantes: largura e altura da tela, fontes instaladas no Windows, etc. Incio da pgina

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


Inclua na seo uses: System, SysUtils
{ - Crie um novo projeto; - Na seo implementation da Unit1 digite a funo abaixo: } function DriveOk(Drive: Char): boolean; var I: byte; begin Drive := UpCase(Drive); if not (Drive in ['A'..'Z']) then raise Exception.Create('Unidade incorreta'); I := Ord(Drive) - 64; Result := DiskSize(I) >= 0; end; { - Coloque no Form1 um TEdit (Edit1) - Coloque no Form1 um TButton - Altere o evento OnClick do Button1 conforme abaixo: } procedure TForm1.Button1Click(Sender: TObject); begin if DriveOk(Edit1.Text[1]) then ShowMessage('Drive OK') else ShowMessage('Drive no preparado'); end;

84 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Observaes Para testar voc dever executar o exemplo e digitar no Edit a letra do drive a ser testado (no precisa os dois-pontos). Aps digitar, clique no Button1. Incio da pgina

24 - Salvar/restaurar o tamanho e posio de Form's


{ Crie uma nova Unit conforme abaixo: } unit uFormFunc; interface uses Forms, IniFiles, SysUtils, Messages, Windows; procedure tbLoadFormStatus(Form: TForm; const Section: string); procedure tbSaveFormStatus(Form: TForm; const Section: string); implementation procedure tbSaveFormStatus(Form: TForm; const Section: string); var Ini: TIniFile; Maximized: boolean; begin Ini := TIniFile.Create(ChangeFileExt( ExtractFileName(ParamStr(0)),'.INI')); try Maximized := Form.WindowState = wsMaximized; Ini.WriteBool(Section, 'Maximized', Maximized); if not Maximized then begin Ini.WriteInteger(Section, 'Left', Form.Left); Ini.WriteInteger(Section, 'Top', Form.Top); Ini.WriteInteger(Section, 'Width', Form.Width); Ini.WriteInteger(Section, 'Height', Form.Height); end; finally Ini.Free; end; end; procedure tbLoadFormStatus(Form: TForm; const Section: string); var Ini: TIniFile; Maximized: boolean; begin Maximized := false; { Evita msg do compilador } Ini := TIniFile.Create(ChangeFileExt( ExtractFileName(ParamStr(0)),'.INI')); try Maximized := Ini.ReadBool(Section, 'Maximized', Maximized); Form.Left := Ini.ReadInteger(Section, 'Left', Form.Left); Form.Top := Ini.ReadInteger(Section, 'Top', Form.Top); Form.Width := Ini.ReadInteger(Section, 'Width', Form.Width); Form.Height := Ini.ReadInteger(Section, 'Height', Form.Height); if Maximized then Form.Perform(WM_SIZE, SIZE_MAXIMIZED, 0); { A propriedade WindowState apresenta Bug. Por isto usei a mensagem WM_SIZE } finally

85 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Ini.Free; end; end; end. { Em cada formulrio que deseja salvar/restaurar: - Inclua na seo uses: uFormFunc - No evento OnShow digite: tbLoadFormStatus(Self, Self.Name); - No evento OnClose digite: tbSaveFormStatus(Self, Self.Name); }

Observaes O arquivo INI ter o nome do executvel e extenso INI e ser salvo no diretrio do Windows. A palavra Self indica o Form relacionado com a unit em questo. 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 idntico no evento OnShow e OnClose de um mesmo Form, porm para cada Form dever ser usado um nome diferente. Incio da pgina

23 - Definir a quantidade de registros a ser impressa em uma pgina do QuickReport


Ou seja, gostaria que, ao visualizar ou imprimir um relatrio do Quick Report, saia em cada pgina apenas um registro, mesmo que o espao permita mais de um. Existem pelo menos duas formas de resolver este problema: 1. A forma mais simples consiste em alterar a altura (Height) da banda Detail do nosso relatrio de modo que a altura total da pgina seja inferior a duas vezes a altura da banda. Desta forma, cada registro ser impresso em uma nova pgina, teoricamente por falta de espao na pgina atual. 2. Uma outra forma mais sofisticada usar o evento AfterPrint da banda Detail. Nele testamos se ainda no chegou no fim da tabela e, caso positivo, pedimos uma nova pgina: if not Table1.EOF then QuickRep1.NewPage; Deve existir outras alternativas, mas as duas anteriores funcionaram bem nos testes realizados.

Incio da pgina

22 - Onde encontrar tutoriais sobre construo de componentes em Delphi

86 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Existem vrios sites especializados no assunto, basta fazer uma busca

Incio da pgina

21 - Para que servem OnGetEditMask, OnGetEditText e OnSetEditText do TStringGrid


O evento OnGetEditMask ocorre quando entramos no modo de edio. Neste momento podemos verificar em qual linha/coluna se encontra o cursor e ento, se quiser, poder especificar uma mscara de edio. 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 tambm quando entramos no modo de edio. Neste momento podemos manipularmos o texto da clula atual (linha/coluna) e ento podemos simular algo tal como uma tabela onde opes podem ser digitadas atravs de nmeros. 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 samos do modo de edio. 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;

Observaes Para testar o exemplo anterior crie um novo projeto e coloque no Form1 um TStringGrid. Mude

87 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

os trs eventos mencionados conforme os exemplos. Execute e experimente digitar nas cluas 1 e 2 da primeira linha (na parte no fixada, claro!). Incio da pgina

20 - Mostrar um Form de LogOn antes do Form principal


{ * * * * * * Crie um novo Projeto. Este certamente ter o Form1. Adicione um novo Form (Form2). Coloque no Form2 dois botes 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 contedo 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.

Observaes O Form2 do exemplo o Form de LogOn. Este dever ser preparado para que se possa escolher o usurio, digitar a senha, etc. Incio da pgina

19 - Limitar a regio de movimentao do mouse


Inclua na seo uses: Windows
{ Coloque um boto no form e altera o evento OnClick dele

88 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

conforme abaixo: } procedure TForm1.Button1Click(Sender: TObject); var R: TRect; begin { Pega o retngulo 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 regio de movimentao do mouse } ClipCursor(@R); ShowMessage('Tente mover o mouse para fora da rea cliente do Form'); { Libera a movimentao } ClipCursor(nil); end;

Observaes Cuidado! Isto pode irritar o usurio do seu programa. Incio da pgina

18 - Descobrir o nome de classe de uma janela do Windows


Muitas vezes precisamos saber qual o nome de classe de uma determinada janela. Quando so janelas desenvolvidas por ns, voc olha no cdigo-fonte. Mas e se no 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 ento se o Internet Explorer est sendo executado? Precisaremos saber o nome de classe da janela deste programa. Ento o que fazer? Use o TBWinName. Pegue-o no download de www.ulbrajp.com.br/usuario/tecnobyte

Incio da pgina

17 - Ocultar/exibir a barra de tarefas do Windows


Inclua na seo uses: Windows
{ Coloque no Form dois Botes: BotaoOcultar e BotaoExibir. No evento OnClick do BotaoOcultar escreva: } procedure TForm1.BotaoOcultarClick(Sender: TObject); var Janela: HWND; begin Janela := FindWindow('Shell_TrayWnd', nil);

89 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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

Observaes A tarefa mais difcil descobrir o nome de classe da janela da barra de tarefa do Windows, mas isto fcil 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 manipulao de Janelas. Veja a pergunta n 18. Incio da pgina

16 - Evitar a proteo de tela durante seu programa


Inclua na seo uses: Windows
{ Na seo "private" do Form principal acrescente: } procedure AppMsg(var Msg: TMsg; var Handled: Boolean); { Na seo "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;

Incio da pgina

15 - Fazer a barra de ttulo ficar intermitente (piscante)


Inclua na seo 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);

90 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

begin FlashWindow(Handle, true); FlashWindow(Application.Handle, true); end;

Incio da pgina

14 - Posicionar o cursor do mouse em um controle


Inclua na seo uses: Windows
{ Digite a procedure abaixo imediatamente aps a palavra implementation no cdigo do seu formulrio. } 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 boto 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;

Observaes A funo "MouseParaControle" recebe um parmetro 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 prprio Form. Incio da pgina

13 - Criar cores personalizadas (sistema RGB)


{ Coloque um TButton no form e escreva o evento OnClick deste como abaixo: } procedure TForm1.Button1Click(Sender: TObject); var Vermelho, Verde, Azul: byte; MinhaCor: TColor; begin Vermelho := 0; Verde := 200; Azul := 150; MinhaCor := TColor(RGB(Vermelho, Verde, Azul)); Form1.Color := MinhaCor;

91 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

end;

Observaes A quantidade de cada cor primria um nmero de 0 a 255. Observe que a cor retornada pela funo RGB() est no formato do Windows (ColorRef); por isto que fiz a converso TColor(RGB(...)). Incio da pgina

12 - Adicionar uma nova fonte no Windows


{ Coloque o cdigo abaixo no OnClick de um boto } AddFontResource(PChar('c:\MyFonts\Monospac.ttf'));

Observaes Troque o nome do arquivo do exemplo anterior pelo nome desejado. Arquivos de fonte possuem uma das seguintes extenses: FON, FNT, TTF, FOT. Veja tambm a pergunta n 10. Incio da pgina

11 - Saber se a impressora atual possui determinada fonte


Inclua na seo uses: Printers
{ Coloque este cdigo no OnClick de um boto } with Printer.Fonts do if IndexOf('Draft 10cpi') >= 0 then ShowMessage('A impressora possui a fonte.') else ShowMessage('A impressora NO possui a fonte.');

Observaes 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 tambm a pergunta n 10. Incio da pgina

10 - Saber se determinada Font est instalada no Windows


{ Coloque este cdigo no OnClick de um boto } with Screen.Fonts do if IndexOf('Courier New') >= 0 then ShowMessage('A fonte est instalada.') else ShowMessage('A fonte no est instalada.');

Observaes

92 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Veja tambm a pergunta n 11. Incio da pgina

9 - Acertar a data e hora do sistema atravs do programa


{ Coloque dois TEdit no form. Coloque um TButton no form e altere o evento OnClick deste boto 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;

Observaes No Edit1 digite a nova data e no Edit2 digite a nova hora. Incio da pgina

8 - ENTER em vez de TAB no formulrio, no DBGrid e no StringGrid


{ Mude a propriedade "KeyPreview" do Form para true. } { No evento "OnKeyPress" do Form acrescente o cdigo 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);

93 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

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;

Observaes bom lembrar que a tecla ENTER no Windows tem seu papel j bem definido quando se trata de caixa de dilogo: executar a ao padro, normalmente o boto OK. Se no tomar cuidado poder confundir o usurio, em vez de ajud-lo. Incio da pgina

7 - Simular a vrgula atravs do ponto do teclado numrico


{ Na seo "private" do Form principal acrescente: } procedure AppMsg(var Msg: TMsg; var Handled: Boolean); { Na seo "implementation" acrescente (troque TForm1 para o nome do seu form principal): } procedure TForm1.AppMsg(var Msg: TMsg; var Handled: Boolean); begin if Msg.Message = WM_KEYDOWN then if Msg.wParam = 110 then Msg.wParam := 188; end; { No evento "OnCreate" do form principal, coloque: } Application.OnMessage := AppMsg; { Uma segunda alternativa (Jos Geraldo - ES): Coloque o cdigo abaixo no evento OnKeyPress do componente onde se quer a converso (Edit, DBEdit, etc). Neste caso a converso funcionar apenas neste componente (bvio). } if Key = '.' then Key = DecimalSeparator;

Observaes Na primeira alternativa, sempre que for pressionado o ponto do teclado numrico (da direita do teclado), este ser convertido para vrgula, independentemente do controle que estiver em foco. J na segunda, o ponto pode ser de qualquer lugar do teclado. Incio da pgina

6 - Paralizar um programa durante n segundos

94 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

Inclua na seo uses: Windows


{ Pausa por 1 segundo } Sleep(1000); { Pausa por 10 segundos } Sleep(10000);

Observaes Esta pausa no interrompida pelo pressionamento de alguma tecla, como acontecia com InKey() do Clipper. Incio da pgina

5 - Criar uma tabela (DB, DBF) atravs do seu programa


Inclua na seo 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;

Observaes Para verificar se o arquivo j existe na verso 3 ou anterior do Delphi, voc dever usar a

95 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

funo "FileExists" do Delphi. Incio da pgina

4 - Verificar se um diretrio existe


Inclua na seo uses: FileCtrl, Dialogs
if DirectoryExists('C:\MEUSDOCS') then ShowMessage('O diretrio existe') else ShowMessage('O diretrio no existe');

Incio da pgina

3 - Verificar se um arquivo existe


Inclua na seo uses: SysUtils, Dialogs
if FileExists('c:\carta.doc') then ShowMessage('O arquivo existe') else ShowMessage('O arquivo no existe');

Incio da pgina

2 - Criar um Alias temporrio atravs do seu programa


Inclua na seo uses: DB
{ Enxergar somente configuraes da sesso atual } Session.ConfigMode := cmSession; { Adicionar o Alias } Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');

Observaes Veja a pergunta n 1. Incio da pgina

1 - Criar um Alias atravs do seu programa


Inclua na seo uses: DB
{ se o alias no existir... } if not Session.IsAlias('MeuAlias') then begin { Adiciona o alias } Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX');

96 de 97

13/12/2011 15:16

Delphi

http://microportal.vilabol.uol.com.br/dicasdelphi.htm

{ Salva o arquivo de configurao do BDE } Session.SaveConfigFile; end;

Observaes 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 necessrio incluir na seo uses: SysUtils, System. Incio da pgina

VOLTAR

97 de 97

13/12/2011 15:16

Вам также может понравиться