Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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) 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 8 - ENTER em vez de TAB no formulrio, no DBGrid e no StringGrid 7 - Simular a vrgula atravs do ponto do teclado numrico 6 - Paralizar um programa durante n segundos 5 - Criar uma tabela (DB, DBF) atravs do seu programa 4 - Verificar se um diretrio existe 3 - Verificar se um arquivo existe 2 - Criar um Alias temporrio atravs do seu programa 1 - Criar um Alias atravs do seu programa
function tbTestLPT(Port: byte): boolean; var Pto : Word; Rdo : byte; 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.
{ 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.
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.
Observaes
Verdadeiramente no sei exatamente onde poderamos aplicar esta dica, mas divulguei-a porque achei interessante. Acredito que o Object Inspector use algo parecido.
Observaes
Este exemplo foi testado com tabelas Paradox, mas deve funcionar na maioria dos bancos de dados com pouca ou nenhuma alterao.
Observaes
No se esquea de trocar o nome do arquivo JPG conforme sua necessidade. Este exemplo foi elaborado usando Delphi4.
Observaes
Para que a janela do DOS no seja exibida, use SW_HIDE no lugar de SW_SHOW.
Observaes
Para formatar outros cdigos como CPF, CGC, etc., pode-se usar a mesma idia.
- Vamos considerar em nosso exemplo que o processamento ocorre 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.
fim de ms. Retorna false caso contrrio. } function tbFimDoMes(const Data: TDateTime): boolean; var Ano, Mes, Dia: Word; begin DecodeDate(Data +1, Ano, Mes, Dia); Result := Dia = 1; end;
Observaes
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.
Observaes
A unit Dialogs foi acrescentada no uses somente para podermos usar a procedure ShowMessage.
Observaes
Note que a procedure MouseCell usa um valor negativo (-1) para coluna e linha se o mouse no estiver sobre o StringGrid.
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.
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: 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; - 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.
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.
Observaes
Este exemplo foi testado com banco de dados Paradox, porm dever funcionar em vrios outros bancos de dados com pouca ou nenhuma alterao.
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; === 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;
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.
Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa aparecer na lista. Dica enviada por: Luiz Carlos Manzolli
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.
Observaes
Este recurso pode no funcionar dependendo da configurao do sistema.
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.
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');
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.
end;
Observaes
Segundo o autor desta resposta, esta soluo foi testada em Win95, mas tambm deve funcionar em Win98. No sabe se funciona em NT.
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.
=== 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).
Observaes
Alm desta tcnica existem API's do Windows que fazem um trabalho equivalente.
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'); 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.
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.
[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;
Observaes
Dica enviada por: Marcelo Senger
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 $.
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: 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).
Observaes
Com um pouco de criatividade podemos fazer outras coisas interessantes usando o evento OnDrawPanel da StatusBar.
Observaes
No se esquea de informar o caminho (path) do arquivo completo. Esta funo foi desenvolvida para Delphi 32 bits (2, 3, 4,...).
Observaes
Neste exemplo pressionamos Ctrl+F2. No se esquea das teclas que precisam manter pressionadas: Ctrl, Alt, Shift.
Observaes
Consulte as constantes para os cdigos das teclas (ex: VK_RETURN, VK_DOWN, etc).
{ 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.
Observaes
Qualquer tecla pode ser verificada. Para isto basta saber o cdigo virtual (Virtual Key Code) da tecla.
Observaes
Qualquer tecla que possua os estados On/Off pode ser verificada. Basta, para isto, saber seu cdigo. O cdigo de CapsLock VK_CAPITAL.
Observaes
Cuidado para no especificar uma linha inexistente.
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.
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 } 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).
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.
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.
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); 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.
Observaes
Nos testes que fiz, nem tudo funcionou adequadamente. Mas vale a pena experimentar.
Observaes
User o aplicativo RegEdit.exe do windows para ver o registro. Cuidado para no alterar as configuraes do Windows!
evento OnKeyPress do DBGrid: Key := AnsiUpperCase(Key)[1]; Para converter para minsculo, troque por: Key := AnsiLowerCase(Key)[1];
DataSource1.DataSet = Table1 Table1.DatabaseName = 'NomeDoAlias' Table1.TableName = 'NomeDaTabela' Table1.IndexFieldNames = 'NomeDoCampo' Table1.Active = true DBGrid1.DataSource = DataSource1
Observaes
Este exemplo considera que o campo seja tipo string. Para outros tipos de campos pode ocorrer erro dependendo dos valores digitados no Edit1.
Observaes
Se o comprimento desejado (Casas) no for suficiente para conter o nmero, sero colocados asteriscos.
Observaes
Podemos usar este recurso para limpar tambm campos numricos, string, etc.
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.
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.
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.
Observaes
Normalmente, a verso 4.72 est presente quando o Internet Explorer 4 est instalado.
{ Soma dois inteiros de 8 bits } function Soma8(X, Y: byte): byte; asm mov al, &X add al, &Y end; { Soma dois inteiros de 16 bits } function Soma16(X, Y: Word): Word; asm mov ax, &X add ax, &Y end; { Soma dois inteiros de 32 bits } function Soma32(X, Y: DWord): DWord; asm mov eax, &X add eax, &Y end; { A chamada a estas funes so feitas da mesma forma que chamamos uma funo Pascal. Exemplo: } var A: byte; begin A := Soma8(30, 25); { A = 55 } 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; {...} end; - A segunda soluo foi apresentada por: Vanderley Pereira Rocha
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.
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; { Para us-la, faa como neste exemplo: } Edit1.Text := tbGetEnvVar('PATH');
Observaes
Veja a pergunta n. 78.
{ 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 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.
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.
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.
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.
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 perfeitamente. Fiz os testes usando o Win95. Talvez em novas verses, possa apresentar problemas.
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.
73 - Criar um EXE que seja executado apenas atravs de outro EXE criado por mim
Inclua na seo uses: Windows { Problema: Gostaria que um determinado programa (Prog1.EXE) fosse executado apenas atravs de outro programa (Prog2.EXE). Soluo: Antes da linha "Application.Initialize;" de Prog1.dpr (programa a ser chamado), coloque o cdigo abaixo: } if ParamStr(1) <> 'MinhaSenha' then begin { Para usar ShowMessage, coloque Dialogs no uses } ShowMessage('Execute este programa atravs de Prog2.EXE'); Halt; { Finaliza } end; { No Form1 de Prog2 (programa chamador) coloque um boto e escreva o OnClick deste boto como abaixo: } procedure TForm1.Button1Click(Sender: TObject); var Erro: Word; begin Erro := WinExec('Pro2.exe MinhaSenha', SW_SHOW); if Erro <= 31 then { Se ocorreu erro... } ShowMessage('Erro ao executar o programa.'); end;
Observaes
Aqui o parmetro passado foi 'MinhaSenha'. Voc dever trocar 'MinhaSenha' por algo que apenas voc saiba (uma senha). Caso uma pessoa conhea esta senha, ser possvel chamar este programa passando-a como parmetro. Neste caso sua "trava" estar violada.
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 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:
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.
- 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'); 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;
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
Para usar as funes DiskSize e DiskFree coloque SysUtils em uses.
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.
Observaes
Veja a pergunta n 66.
Observaes
A string retornada pela funo tbGetDrives est sempre em letras maisculas.
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.
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).
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.'); 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.
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'); 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.
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
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.
{ 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.
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.
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;
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.
Observaes
Para testar execute e observe o Label enquanto pressiona as teclas desejadas.
Observaes
Ao executar observe a barra de tarefas e teste o Alt+Tab (seu programa no estar l!).
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.
{ 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.
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.
Observaes
Troque o nome do arquivo (C:\ArqSom.wav) pelo arquivo desejado.
Observaes
Se quizer que a janela do programa no aparea, troque sw_ShowNormal por sw_Hide.
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.
with MediaPlayer1.DisplayRect do begin Form2.ClientHeight := Bottom - Top; Form2.ClientWidth := Right - Left; end; Display := Form2; Form2.Show; Play; end; end;
Observaes
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;
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.
Observaes
"S" precisa ser uma varivel string.
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.
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
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 36 e 53.
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.
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.
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'); 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.
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.
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.
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;
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).
Observaes
O objeto Screen contm vrias informaes importantes: largura e altura da tela, fontes instaladas no Windows, etc.
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;
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.
end; end; procedure tbLoadFormStatus(Form: TForm; const Section: string); var Ini: TIniFile; Maximized: boolean; begin Maximized := false; { Evita msg do compilador } Ini := TIniFile.Create(ChangeFileExt( ExtractFileName(ParamStr(0)),'.INI')); try Maximized := Ini.ReadBool(Section, 'Maximized', Maximized); Form.Left := Ini.ReadInteger(Section, 'Left', Form.Left); Form.Top := Ini.ReadInteger(Section, 'Top', Form.Top); Form.Width := Ini.ReadInteger(Section, 'Width', Form.Width); Form.Height := Ini.ReadInteger(Section, 'Height', Form.Height); if Maximized then Form.Perform(WM_SIZE, SIZE_MAXIMIZED, 0); { A propriedade WindowState apresenta Bug. Por isto usei a mensagem WM_SIZE } finally Ini.Free; end; end; end. { Em cada 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.
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.
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 os trs eventos mencionados conforme os exemplos. Execute e experimente digitar nas cluas 1 e 2 da primeira linha (na parte no fixada, claro!).
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.
Observaes
Cuidado! Isto pode irritar o usurio do seu programa.
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
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.
{ 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;
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.
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(...)).
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.
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.
Observaes
Veja tambm a pergunta n 11.
Observaes
No Edit1 digite a nova data e no Edit2 digite a nova hora.
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.
{ 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.
Observaes
Esta pausa no interrompida pelo pressionamento de alguma tecla, como acontecia com InKey() do Clipper.
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 funo "FileExists" do Delphi.
Observaes
Veja a pergunta n 1.
{ se o alias no existir... } if not Session.IsAlias('MeuAlias') then begin { Adiciona o alias } Session.AddStandardAlias('MeuAlias', 'C:\DirProg', 'PARADOX'); { 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.
CopyRect(R, CellRect(Col, Row)); with ComboBox1 do begin Visible := False; R.TopLeft := frmMain.ScreenToClient( StringGrid1.ClientToScreen(R.TopLeft)); R.BottomRight := frmMain.ScreenToClient( StringGrid1.ClientToScreen(R.BottomRight)); SetBounds(R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top); end; with StringGrid1 do if (TopRow <= Row) and (TopRow + VisibleRowCount > Row) then ComboBox1.Show; end; procedure TfrmMain.ComboBox1Change(Sender: TObject); begin with StringGrid1 do Cells[Col, Row] := ComboBox1.Text; end; In essence, the main routine here is the stringgrid's OnDrawCell event handler. Of course, I also set the stringgrid's DefaultRowHeight property to be the same height as the combobox. In addition, the stringgrid's OnTopLeftChanged event handler is used to hide the combobox when the user scrolls out of view. Also, when the user selects an item from the combobox, simply place the text in the current Col/Row. You can also do a couple other little tricks such as setting the stringgrid's Objects[] property to point to the combobox, as well as possibly setting the combobox's Parent property to point to the stringgrid. However, I've had problems with the Parent approach -- namely, that of dropping down the listbox associated with the combobox.
StrPCopy(TempPString,StringGrid1.Cells[Col,Row]); {DrawText--see other options in Windows API help; Change the DT_LEFT to DT_RIGHT for right justified txt!} DrawText(StringGrid1.Canvas.Handle,TempPString,-1,Rect,DT_LEFT); end;
end; procedure TForm1.Button1Click(Sender: TObject); begin { Sort rows based on the contents of two or more columns. Sorts first by column 1. If there are duplicate values in column 1, the next sort column is column 2 and so on...} SortGridByCols(StringGrid1, [1, 2, 0, 3, 4]); end;
// Hier evtl Word Doc speichern, beenden... // ... // Cleanup... WordApp := Unassigned; NewDoc := Unassigned; WordTable := Unassigned; end;
SStyle1 := SStyle1 + '<u>'; SStyle2 := SStyle2 + '</u>'; end; Text := sg.Cells[p, i]; if Text = '' then Text := ' '; Dest.Lines.Add(' <td width="' + IntToStr(sg.ColWidths[p]) + '" height="' + IntToStr(sg.RowHeights[p]) + '"><font color="#' + IntToHex(sg.Font.Color, 6) + '" face="' + SG.Font.Name + '">' + SStyle1 + Text + SStyle2 + '</font></td>'); end; Dest.Lines.Add(' </tr>'); end; Dest.Lines.Add(' </table>'); Dest.Lines.Add('</body>');; Dest.Lines.Add('</html>'); end; // Example, Beispiel procedure TFormCSVInport.Button6Click(Sender: TObject); begin SGridToHtml(StringGrid1, Memo1, 1); Memo1.Lines.SaveToFile('c:\test.html'); end;
// Hide Excel XLApp.Visible := False; // Add new Workbook XLApp.Workbooks.Add(xlWBatWorkSheet); Sheet := XLApp.Workbooks[1].WorkSheets[1]; Sheet.Name := ASheetName; // Fill up the sheet Sheet.Range[RefToCell(1, 1), RefToCell(AGrid.RowCount, AGrid.ColCount)].Value := Data; // Save Excel Worksheet try XLApp.Workbooks[1].SaveAs(AFileName); Result := True; except // Error ? end; finally // Quit Excel if not VarIsEmpty(XLApp) then begin XLApp.DisplayAlerts := False; XLApp.Quit; XLAPP := Unassigned; Sheet := Unassigned; end; end; end; // Example: procedure TForm1.Button1Click(Sender: TObject); begin if SaveAsExcelFile(stringGrid1, 'My Stringgrid Data', 'c:\MyExcelFile.xls') then ShowMessage('StringGrid saved!'); end; {**************************************************************} {2. Without OLE } procedure XlsWriteCellLabel(XlsStream: TStream; const ACol, ARow: Word; const AValue: string); var L: Word; const {$J+} CXlsLabel: array[0..5] of Word = ($204, 0, 0, 0, 0, 0); {$J-} begin L := Length(AValue); CXlsLabel[1] := 8 + L; CXlsLabel[2] := ARow; CXlsLabel[3] := ACol; CXlsLabel[5] := L; XlsStream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel)); XlsStream.WriteBuffer(Pointer(AValue)^, L);
end; function SaveAsExcelFile(AGrid: TStringGrid; AFileName: string): Boolean; const {$J+} CXlsBof: array[0..5] of Word = ($809, 8, 00, $10, 0, 0); {$J-} CXlsEof: array[0..1] of Word = ($0A, 00); var FStream: TFileStream; I, J: Integer; begin Result := False; FStream := TFileStream.Create(PChar(AFileName), fmCreate or fmOpenWrite); try CXlsBof[4] := 0; FStream.WriteBuffer(CXlsBof, SizeOf(CXlsBof)); for i := 0 to AGrid.ColCount - 1 do for j := 0 to AGrid.RowCount - 1 do XlsWriteCellLabel(FStream, I, J, AGrid.cells[i, j]); FStream.WriteBuffer(CXlsEof, SizeOf(CXlsEof)); Result := True; finally FStream.Free; end; end; // Example: procedure TForm1.Button2Click(Sender: TObject); begin if SaveAsExcelFile(StringGrid1, 'c:\MyExcelFile.xls') then ShowMessage('StringGrid saved!'); end; {**************************************************************} {3. Code by Reinhard Schatzl } uses ComObj; // Hilfsfunktion fr StringGridToExcelSheet // Helper function for StringGridToExcelSheet function RefToCell(RowID, ColID: Integer): string; var ACount, APos: Integer; begin ACount := ColID div 26; APos := ColID mod 26; if APos = 0 then begin ACount := ACount - 1; APos := 26; end; if ACount = 0 then Result := Chr(Ord('A') + ColID - 1) + IntToStr(RowID);
if ACount = 1 then Result := 'A' + Chr(Ord('A') + APos - 1) + IntToStr(RowID); if ACount > 1 then Result := Chr(Ord('A') + ACount - 1) + Chr(Ord('A') + APos - 1) + IntToSt r(RowID); end; // StringGrid Inhalt in Excel exportieren // Export StringGrid contents to Excel function StringGridToExcelSheet(Grid: TStringGrid; SheetName, FileName: string ; ShowExcel: Boolean): Boolean; const xlWBATWorksheet = -4167; var SheetCount, SheetColCount, SheetRowCount, BookCount: Integer; XLApp, Sheet, Data: OLEVariant; I, J, N, M: Integer; SaveFileName: string; begin //notwendige Sheetanzahl feststellen SheetCount := (Grid.ColCount div 256) + 1; if Grid.ColCount mod 256 = 0 then SheetCount := SheetCount - 1; //notwendige Bookanzahl feststellen BookCount := (Grid.RowCount div 65536) + 1; if Grid.RowCount mod 65536 = 0 then BookCount := BookCount - 1; //Create Excel-OLE Object Result := False; XLApp := CreateOleObject('Excel.Application'); try //Excelsheet anzeigen if ShowExcel = False then XLApp.Visible := False else XLApp.Visible := True; //Workbook hinzufgen for M := 1 to BookCount do begin XLApp.Workbooks.Add(xlWBATWorksheet); //Sheets anlegen for N := 1 to SheetCount - 1 do begin XLApp.Worksheets.Add; end; end; //Sheet ColAnzahl feststellen if Grid.ColCount <= 256 then SheetColCount := Grid.ColCount else SheetColCount := 256; //Sheet RowAnzahl feststellen if Grid.RowCount <= 65536 then SheetRowCount := Grid.RowCount
else SheetRowCount := 65536; //Sheets befllen for M := 1 to BookCount do begin for N := 1 to SheetCount do begin //Daten aus Grid holen Data := VarArrayCreate([1, Grid.RowCount, 1, SheetColCount], varVaria nt); for I := 0 to SheetColCount - 1 do for J := 0 to SheetRowCount - 1 do if ((I + 256 * (N - 1)) <= Grid.ColCount) and ((J + 65536 * (M - 1)) <= Grid.RowCount) then Data[J + 1, I + 1] := Grid.Cells[I + 256 * (N - 1), J + 65536 * (M - 1)]; //------------------------XLApp.Worksheets[N].Select; XLApp.Workbooks[M].Worksheets[N].Name := SheetName + IntToStr(N); //Zellen als String Formatieren XLApp.Workbooks[M].Worksheets[N].Range[RefToCell(1, 1), RefToCell(SheetRowCount, SheetColCount)].Select; XLApp.Selection.NumberFormat := '@'; XLApp.Workbooks[M].Worksheets[N].Range['A1'].Select; //Daten dem Excelsheet bergeben Sheet := XLApp.Workbooks[M].WorkSheets[N]; Sheet.Range[RefToCell(1, 1), RefToCell(SheetRowCount, SheetColCount)] .Value := Data; end; end; //Save Excel Worksheet try for M := 1 to BookCount do begin SaveFileName := Copy(FileName, 1,Pos('.', FileName) - 1) + IntToStr(M) + Copy(FileName, Pos('.', FileName), Length(FileName) - Pos('.', FileName) + 1); XLApp.Workbooks[M].SaveAs(SaveFileName); end; Result := True; except // Error ? end; finally //Excel Beenden if (not VarIsEmpty(XLApp)) and (ShowExcel = False) then begin XLApp.DisplayAlerts := False; XLApp.Quit; XLAPP := Unassigned; Sheet := Unassigned; end; end; end;
//Example procedure TForm1.Button1Click(Sender: TObject); begin //StringGrid inhalt in Excel exportieren //Grid : stringGrid, SheetName : stringgrid Print, Pfad : c:\Test\ExcelFile .xls, Excelsheet anzeigen StringGridToExcelSheet(StringGrid, 'Stringgrid Print', 'c:\Test\ExcelFile.x ls', True); end;
GERAL Strings copy - Copia uma substring, dentro de uma string Var vtexto, Copia: String; begin vtexto := Edit1.Text ; // descobriu o valor de texto Copia := copy(vtexto,2,2); // copia de vtexto, apartir da segunda letra dois caracteres Label1.Caption := Copia; // o label exibira as duas letras end; // delete - Deleta uma substring dentro de uma string. ex: Delete (Mystring, 2,1) // delete da varivel mysring, na segunda posio, 1 caractere insert - Insereuma substring em uma string . ex: Insert ("z", mystring, 1 ) //insere a letra z no comeo da string Inttostr - Converte um valor inteiro para string. ex: MyString := Inttostr(Shape1.top) //A variavel mystring recebe o valor top do componente Shape1 length - Retorna o nmero de caracteres de uma string ex: canvas.textout ( 10, 10, ' Nmero de caracteres =' + InttoStr (length MmyString ))); //exibe o nmero de caracteres contido em uma string. Lowercase - Converte para mensculos os caracteres alfabtiocs de uma string; Lowercase( 'SORTE' ); // tranformar para 'sorte' Pos - Esta funo retorna um valor integer correspondente a posio de uma string dentro de uma outra string. Var VPalavra : string; VNumero : Integer; Begin VPalavra := ' Pernambuco ' ; VNumero := Pos ( ' a ' , VPalavra ) ; // Numero retorna o valor 5 end; STR-Esta procedure converte um valor inteiro ou real para uma string. // a varivel Vs recebe o valor da varivel Vn Var Vn : real; Vs : string Begin Vn := 100 ; Str (Vn, Vs) ; end; StrtoInt - Esta funo converte um valor string para um valor inteiro. // A varivel Vlocal recebe o valor ( inteiro ) top do componente Shape1 Var vLocal : String; Begin Vlocal : InttoStr ( Shape1. Top) ; End Uppercase - Esta rotina substitui todas as letras minsculas de uma string por letras maisculas. Uppercase ('casa');// Retorna 'CASA' VAL - Esta rotina extrai o valor numrico ( tipo real ou integer ) de uma String; Sua sintaxe : Val ( S ; var v ; var Code : integer ); Observe o exemplo abaixo : Var N, C : integer ; Begin Val ( Edit1. Text, N, C ) ;
Button1. Top := N ; End ; // Se a varivel C tiver valor diferente de 0 significa que ouve erra na converso. ( ex : O texto do Edit no um nmero intiro vlido ) Declarando uma strings: var terra: string //declarao simples marte: string [5] //delimitado 5 caracteres para a string venus: shortstring //string de menos de 256 caracteres Format //Para coloca zeros a esquerda dos nmeros encontrados. %5 mostra o valor da varivel inteira "VNum" // .5d por que so 5 caracteres Edit1.text:= Format('%5.5d',[VNum]); //Colocar zeros a esquerda de um valor Real digitado no Edit Edit1.Text := FormatFloat(000000,StrToFloat(Edit1.Text)); //Colocar zeros a esquerda de um valor inteiro digitado no Edit Edit1.Text := FormatFloat(000000,StrToInt(Edit1.Text)); Formatando com estilo de moeda //Formatando um valor Real Edit1.Text := FormatFloat(#,##0.00,vSalario); //Formatando uma String Edit1.Text := FormatFloat(#,##0.00,StrToFloat(Edit1.Text)); Obs- (#) Cerquilha, para nmeros obcionais. (,) Ponto para separar milhar. (.) Virgula para separar casas decimais. //A linha abaixo exibe em um label, seu top. Misturando String do Inteiro Label1.Caption := Format('O top deste label %d',[Label1.top]); //Lendo uma varivel inteira Label.Caption := Format ('O nmero guardado : %d, [i]); // Para exibir o valor Hexadecimal de uma varivel integer(i) Label1.Caption := Format('$%x',[i]); //Formatando uma Data: dbedit1.text:=formatDateTime('dd/mm/yyyy hh:mm',now); Delete - Ex: Delete(MyString) // deleta da varivel MyString, na segunda posio, um caractere Insert - Ex: Insert ('z',MyString,1) // Insere a letra z no comeo da String InttoStr - Ex: MyString := InttoStr(Shape1.top)//A varivel MyString recebe o valor top do componente Shape1 Mensagens Menssagem simples ShowMessage( ' texto da menssagem ' ); Caixa de messagem MessageDlg( ' aviso ' , mtInformation, [mbOk], 0 ); if MessageDlg('Quer sair do programa',mtInformation,[mbYes,mbNo],0) = mrYes then Form1.close; if Application.MessageBox('Confirmar Excluso','Ateno',mb_YesNo + mb_iconQuestion) = idYes then {comandos...} If Application.MessageBox('Confirma Excluso?','ATENO',MB_ICONEXCLAMATION + MB_YESNO) = IDYES Then
DataModule1.Tb_Alunos.Delete; INPUTBOX e INPUTQUERY INPUTBOX //A linha abaixo exibe uma caixa de dilogo onde digitamos um valor que ser exibido em um label Label1.Caption := InputBox('digite','integer',''); <B.INPUTQUERY< b> //Sensvel maisculas e minsculas. Veja abaixo dois exemplos. Exemplo1 procedure TForm1.Button3Click(Sender: TObject); var NS: string; clickOK: Boolean; // clickok foi inventado begin NS := 'Nome fixo'; Label1.Caption := NS; clickOK := InputQuery('Input Box', 'digite', NS); if clickOK then Label1.Caption := 'The new string is ''' + NS + ''''; end; Exemplo2 var r : string ; begin inputQuery( ' ver ' , ' senha ' , r ); if r = ' s ' then shape1.Visible := true else showmessage( ' senha errada ' ); end; Tratando Erros Deletando um registro try DMAgenda.tbAgenda.Delete; except On E:EDBEngineError do ShowMessage('Registro em uso por outro USURIO. Excluso Cancelada'; end; Datas Invlidas Try StrtoDate(Edit1.text); except on EconvertError do ShowMessage('Data Invlida'); end; Centralizar um componeteNo evento OnResize digite No evento abaixo, toda vez que o form sor redimencionado, o Button ficara no centro Button1.Top := Form1.ClientHeight div 2 - Button1.Height div 2; Button1.Left := Form1.ClientWidth div 2 - Button1.Width div 2; Senhas Colocar senha numa tabela Paradox //...e retirar em tempo de execuo: Session.AddPassword('Senha-Da-Tabela');
... Session.RemovePassword; outra opo... Session.AddPassword('Senha'); Table1.Active := True; // vincule o Table1 ao Session> Encryptar uma string function Encrypt( Senha:String ): String; Const Chave : String = 'Jesus'; Var x,y : Integer; NovaSenha : String; begin for x := 1 to Length( Chave ) do begin NovaSenha := ''; for y := 1 to Length( Senha ) do NovaSenha := NovaSenha + chr( (Ord(Chave[x]) xor Ord(Senha[y]))); Senha := NovaSenha; end; result := Senha; end; Rotina para um janela de Login ... var contador : Integer ; begin if not DataModule1.Table1.findkey([edit1.text]) then // a coluna senha, na tabela, tem que ser a primeira begin ShowMessage( ' senha errada ' ) ; inc ( contador ) ; if contador = 3 then ShowMessage ( ' vc teve 3 chances ' ) ; exit ; end ; formSenha.Close ; formPrincipal.Enabled := true ; end ; findfield Contador : Integer;//colocar em na rea var ou uses var // no evento onClick do boto OK s : TstringField; //unit db begin s:= DataModlule1.Table1.findfield('senha')as TstringField; // procura na coluna senha if s.value <> Edit1.text then begin ShowMessage('senha invalida'); inc(contador); if Contador = 3 then begin ShowMessage('vc teve 3 chances'); formPrincipal.Close; end;
exit; formSenha.Close; formPrincipal.Enabled := true; end; Trabalhando com o teclado #0=Null #8=Backspace #13=Enter #27=Escape #32=Espao #127=Delete //fazer o Enter, substituir o Tab... if key = #13 then Edit1.SetFocus; // o Edit recebe o foco //fazer o Enter, substituir o Tab...(II) SelectNext(ActiveControl,true,true);// joga o foco no proximo componente ///Cancelando uma tecla if (Key = A) or (Key = 'a') then Key := #0; Levar o foco para o componente anterior // No evento OnKeyDown digite: if Key = (Vk_Up) then Perform(Wm_NextDlgCtl,1,0); Caracteres especiais // declare uma constante com os caracteres especiais... Const chrEspecial : Set of Char =['@','#','$','%']; //no evento OnKeyPress, digite: If key in ChrEspecial then ShowMessage('esta letra especial'); // Para digitar s maisculas... Key := Upcase(Key); //colocar no evento OnKeyPress de um Edit Emular o pressionamento de um boto If (key = VK_F1) then btnAjuda.Onclick(Self);//no evento OnKeyPress Para desabilitar o CTRL+ALT+DEL e ALT+TAB Var numero: integer; begin SystemParametersInfo(97,Word(true),@numero,0); end; { Para habilitar s chamar a mesma funo com Word(false) } Trabalhando com a Guia Dialogs SaveDialog if SaveDialog1.Execute then begin Memo1.Lines.SaveToFile (SaveDialog1.FileName); // pode ser um RichEdit end; OpenDialog if OpenDialog1.Execute then begin Memo1.Lines.LoadFromFile(OpenDialog1.FileName) ; // poderia ser um RichEdit end ; OpenPictureDialog
if OpenPictureDialog1.Execute then image1.Picture.LoadFromFile (OpenPictureDialog1.fileName) ; // carrega uma imagem no componente FontDialog if FontDialog1.Execute then begin Memo1.Font := Font;// poderia ser um RichEdit end; ou... with FontDialog1 dobr> begin Font := Label1.Font; if Execute then Label1.Font := Font; end; colordialog if colordialog1.Execute then begin with ColorDialog1 do begin Color := Label1.Color; ou... if Execute then Label1.Color := Color; end; RichEdit.Color := Color; end; PrintDialog PrintDialog1.Execute; Trabalhando com Data e Hora DateToStr(Date) ==> 21/09/01 TimeToStr(Time) ==> 11:50:00 FormatDateTime('d',Date); ==>21 FormatDateTime('d/m/y',Date);==> 21/9/01 FormatDateTime('dd/mm/yy',Date); ==>21/09/01 FormatDateTime('ddd/dd/mm/yy',Date); ==> Sex/05/09/01 FormatDateTime('dddd/dd/mmmm/yyyy',Date); ==> Sexta-feira/Setembro/1999 FormatDateTime('ddddd',Date); ==> 05/09/99 FormatDateTime('dddddd',Date); ==> Sexta=Feria, 21 de Setembro de 2001 Label1.caption := timetostr(time); Label1.caption := datetostr(date); // Somar uma data var Ts1, ts2 : TTimeStamp; Data1, Data2 : TDateTime; Dias : Integer; begin Date1 := StrtoDate(edit1.text); Date2 := StrtoDate(edit2.text); Ts1 := DateTimetoTimeStamp(Data1); Ts2 := DateTimetoTimeStamp(Data2); Dias := Ts2.Date - Ts1.Date; Edit3.Text := InttoStr(Dias); if Dias > 10 then ShowMessage('Passaram-se 10 dias'); end;
O Dia da Semana function DayOfWeek(Data:TDataTime):Integer; Ex.:Label1.Caption:= 'Data e Hora Atual' + DateTimeToStr(Now); - Retorna o dia da semana em um inteiro de 1 a 7. Mtodos e Propriedades do Form Show // exibe um form Hide // esconde um form mas no o descarrega Print // imprime um form SetFocus // establece o foco para um form ou componente BringtoFront // envia o frente Form1.formstyle := fsOntop; // para um formulrio aparcer sobre outros sempre Texto em um form canvas.textout(0,0,'Este texto aparece no form. Top e Left zerados'); Form Elptico No evento OnCreate do form, digite: var hR : THandle; begin {cria uma form de formato elptico} hR := CreateEllipticRgn (0,0,Width,Height); SetWindowRgn (Handle,hR,True); end; Obs. Tambm bom alterar a propriedade BorderStyle para bsNone. O tamanho da elpse definido pelo tamanho do form. Para criar um form em tempo de execuo NovoForm:= TfmFilho.Create (self); NovoForm.Parent := self; Form em tempo de execuo II Application.CreateForm(TForm2, Form2); //Cria o form Form2.ShowModal ; Form2.free; // Libera o form da memria Form em tempo de execuo III Application.CreateForm(TFormTal, FormTal); FormTal.ShowModal; FormTal.Free; Criando um QuickReport em tempo de execuo qrMovCaixa := TqrMovCaixa.Create(self); DMNL.qrMovCaixa.Open; qrMovCaixa.Preview; qrMovCaixa.Free; evitar que se tente abrir o mesmo Form, duas vezes if form1 = nil then // se o form1 ainda no foi criado... ... comandos para criar um form... //colocar no evento OnClose: form1 := nil; Para executar um outro aplicativo apartir do Delphi
If Winexec('c:\windows\calc.exe',sw_shownormal)= 2 then showmessage('Arquivo no encontrado'); Diretrio do aplicativo // No evento OnCreate, digite: var PathName: string; begin PathName := ExtractFilePath (ParamStr (0)); Label1.Caption := 'Estamos em: '+ PathName; end; O Componente TComboBox Para abrir um TComboBox sem clica-lo, digite: ComboBox1.DroppedDown := True;
Usando o Repeat var N : String; begin Repeat; N := Inputbox('GetNumber', 'Insira um nmero',''); Until N:= '7'; end; Atribuir Mesmo Valor para Vrios Edits em um Form for i := 0 to ComponentCount - 1 do if Components[i] is TEdit then TEdit(Components[i]).Text := Valor; Testa se h disco no Drive A: function TForm1.TemDiscoNoDrive(const drive : char): boolean; var DriveNumero : byte; EMode : word; begin result := false; DriveNumero := ord(Drive); if DriveNumero >= ord('a') then dec(DriveNumero,$20); EMode := SetErrorMode(SEM_FAILCRITICALERRORS); try if DiskSize(DriveNumero-$40) <> -1 then Result := true else messagebeep(0); finally SetErrorMode(EMode); end; end; procedure TForm1.Button1Click(Sender: TObject); begin if TemDiscoNoDrive('a') then ShowMessage('Tem disco no drive A:') else ShowMessage('No tem disco no drive A:'); end; Usando Enter no lugar de TAB // Coloque no form: keypreview = true. No ONKEYDOWN, digite: if (Key= VK_RETURN) or (Key= VK_DOWN) then begin Key := 0; Perform(WM_NEXTDLGCTL, 0, 0); end else if (Key= VK_UP) then begin Key := 0; Perform(WM_NEXTDLGCTL, 1, 0); end; Close em um Form OnCloseQuery //No evento OnCloseQuery. A segunda opo ("No") recebe o foco. CanClose := Application.MessageBox( 'Confirme Operao','Terminar Aplicao ?',
MB_ICONQUESTION + MB_YESNO + MB_DEFBUTTON2 ) = ID_YES; Salvar dados antes de fechar: //no evento OnClose: if Table1.Modified then if Application.MessageBox('Gravar alteraes?','Dados Alterado',MB_ICONQUESTION + MB_YESNO) = IDYES then Table1.Post else Table1.Cancel Obtendo o nmero serial do HD Function SerialNum(FDrive:String) :String; Var Serial:DWord; DirLen,Flags: DWord; DLabel : Array[0..11] of Char; begin Try GetVolumeInformation(PChar(FDrive+':\'),dLabel,12,@Serial,DirLen,Flags,nil,0); Result := IntToHex(Serial,8); Except Result :=''; end; end; BANCO DE DADOS SENHAS // Senha usadas na maioria dos programas No Campo Var, Digite : Contador : integer; Vs : string Em Usues, Digite : DB; No boto Ok, digite if not Table1.FindKey([edit1.Text]) then // o campo chave Nome begin ShowMessage('UsurioDesconhecido'); inc (contador); if contador = 4 then begin ShowMessage( Sua chance acabou'); FmPrincipal.Close; end; Exit; (* para encerrar *) end; vs:=Table1.findField(Login).asString; if vs<>Edit2.text then begin ShowMessage('Senha Errada'); inc(contador); if contador=4 then fmPrincipal.close; Edit2.setFocus; exit; end;
fmPrincipal.Enabled:=True; fmSenha.close; Criando Tabelas Atravs da funo FieldDefs.ADD. Parmetros: nome do campo, tipo, Tamanho, Chave_Primria. Procedure Cria_Tabela(Alias,Nome_Tabela:String); Begin With TTable.Create(Application) do begin Active := False; DatabaseName :=Alias; TableName := Nome_Tabela;; TableType := ttDefault; FieldDefs.Add('CODCLI', ftString, 5, False); FieldDefs.Add('NOMCLI', ftString, 40, False); FieldDefs.Add('DATCAD', ftDate, 0, False); CreateTable; Free; end; end; Como Usar: procedure TForm1.Button1Click(Sender: TObject); begin Cria_Tabela('C:\Temp','Alunos.db'); end; LOCALIZAR //nesta caixa de dilogo, o campo nome tem que ser o primeiro var // uma varirvel tem que ser criada. nome : string; Nome : = inputbox( ' Localizar ' , ' digite o nome ' , ' ' ) ; if nome <> ' ' then begin if not table1.findkey ( [ nome ] ) then showmessage ( ' nome no encontrado ' ) ; end; Simplificando: Table1.findkey([edit1.text]) ou table1.setkey; table1.fields[0].AsString := Edit1.text; Table1.GotoKey; Apenas a linha abaixo : Table1.FindKey([Edit1.Text]); Apenas a linha abaixo : Table1.FindNearest([Edit1.Text]); Table1.SetKey; // Primeiro campo a chave Table1.FieldName('Cidade') := Edit1.Text; Table1.GotoKey; Table1.IndexName := 'NomeCliente'; // procurar em um ndice secundrio Table1.Open; Table1.SetKey;
table1NomeCliente.AsString := Edit1.Text; Table1.GotoNearest; . // Procurar em um ndice primrio ou secundrio Table1.IndexName := 'Nome' Table1.Open; Table1.SetKey; Table1Nome_Cliente.AsString := Edit1.Text; Table1.GotoNearest; Locate// procura em um ndice primrio ou secundrio Table1.Locate('Nome',Trim(Edit1.text),[LoPartialKey,loCaseInsensitive]); if not DM.Table1.Locate('Vendedor;Data',VarArrayOf([EditVendedor.text, EditData.text]),[loCaseInsensitive]) then ShowMessage('O vendedor no realizou venda nesa data'); FindKey //Procura um nome em um campo. ( no primeiro campo ). // No evento OnClick do Boto Ok, digite begin if not DataModule.tsenha.FindKey ( [ editNome.text ] ) then beguin ShowMessage ( ' senha desconhecida ' ); Exit; end ; Excees Access violation Decrare a constante: const ChaveViolada = 9729; No evento OnPostError da tabela, digite: if (E is EDBEngineError) then if (E as EDBEngineError).Error[0].Errorcode = ChaveViolada then begin Table1.Cancel; ShowMessage('este cdigo j existe'); end; abort Outras excees if(E is EDBEngineError) then with EDBEngineError(E) do case Errors[0].ErrorCode of DBIERR_KEYVIOL: ShowMessage('Cliente j cadastrado.'); DBIERR_REQDERR: ShowMessage('Campo obrigatrio no preenchido.'); end else ShowMessage('Erro no banco de dados:' + #13#13 + E.Message); Action := daAbort; 0 SQL //Seleciona todos os campos da tabela cliente Select * from cliente //Selecione todos os campos da tabela cliente e produto
Select * from cliente, produto //Selecione o campo nproduto da tabela produto Select Nproduto form produto //Selecione os campos nproduto e descrio da tabela produto Select nprodutos, descrio from produto //Selecione todos os campos da tabela produto onde nproduto seja igual a 004 Select * from produto where nproduto = 004 //Selecione os campos descrio e preo produto onde nproduto seja igual a 004 Select descrio, preo from produto Where nproduto = 004 //Selecione todos os campos da tabela cliente onde ncliente seja maior que 01 e menor que 04 Select * from cliente where ncliente > 01 and ncliente < 04 //Exibir seus dados em ordem ascendente (A a Z, 0 a 9). SELECT Sobrenome, Nome FROM Funcionrios ORDER BY Sobrenome; SELECT Sobrenome, Nome FROM Funcionrios ORDER BY Sobrenome ASC; //Selecione todos os campos da tabela cliente organizadopor nome Select * form cliente order by nome //Selecione os campos nprodutos e descrio da tabela produto organizado por descrio Select nProdutos, descrio from produto order by descrio //Selecione todos os campos da tabela produto organizado por nproduto em ordem descendente Select * from produto order by nproduto desc //Classificar em ordem descendente (Z a A, 9 a 0), adicione a palavra reservada DESC ao final de cada campo SELECT Sobrenome, Salrio FROM Funcionrios ORDER BY Salrio DESC, Sobrenome; //Esse exemplo ordena os registros pelo sobrenome, em ordem descendente (Z-A). SELECT Sobrenome, Nome FROM Funcionrios ORDER BY Sobrenome DESC; //Esse exemplo ordena, primeiro, por categoria ID e depois por nome do produto. SELECT CategoriaID, ProdutoNome, PreoUnit FROM Produtos ORDER BY CategoriaID, NomeProduto; //Selecione os campos descrio, preo e o valor de preo + 20 de tabela produto onde nproduto = 004 Select descrio, preo, preo + 20 from produto where nproduto = 004 //Selecione todos os campos da tabela Leitores onde o campo nome seja iguas a 'Joo' Select * from Leitores where Nome = 'Joo Cabral' //Selecione todos os campos da tabela cliente onde o campo nome inicie com Vis* desprezando os outros caracteres Select * from cliente where nome LIKE 'Vis%' //Selecione todos os campo da tabela leitor onde o campo CPF nulo Select * from Leitor where CPF is Null Select nproduto + '', '' + descrio AS Itens, preo from produto Selecione nproduto + '', '' + descrio AS Itens, preo (junte os campos como Itens) da tabela produto
//Qual seria o salrio se cada funcionrio recebesse um aumento de 10 porcento. No altera o valor original dos salrios. SELECT Sobrenome, Salrio AS Atual, Salrio * 1.1 AS Proposto FROM Funcionrios; //Coloca o ttulo Nome no topo da coluna "Sobrenome". O ttulo Salrio, no topo da coluna "Salrio". SELECT Sobrenome AS Nome, Salrio FROM Funcionrios; Select nproduto from pedido/ produto where nPedido = 1 Select nproduto from pedido / produto where nProduto = 2 Select nproduto from pedido / produto where npedido = 1 UNION ALL Select nproduto From pedido/ produto where nProduto = 2 Select * from pedido where nproduto beteeen 2 and 5 Selecione todos os campos da tabela pedido onde o campo nproduto esteja entre 2 e 5 Selecione todos os campos da tabela pedido onde o campo npedido esteja entre 2 e 5 Select * from pedido where nproduto IN ( 2,5 ) Select DISTINCT * from pedido/produto Selecione retirando as duplicatas do campo nproduto da tabela pedido/produto Select TOP 3 from produto Selecione os primeiros 3 registros da tabela produto Select Ucase ( descrio) from produto Selecione ( descrio ) o campo descrio em maisculo da tabela produto Select COUNT ( * ) as quantidade from produto where preo > 50,00 //Conta o nmero de registros que tm uma entrada no campo "CdigoPostal" e nomeia o campo retornado como "Tcp". SELECT Count(CdigoPostal) AS Tcp FROM Clientes; Selecione o campo descrio em maiusculo da tabela produto Select SUM ( quantidade) from pedido/produto where nproduto = 1 Selecione a soma do campo soma da tabela pedido/produto onde nproduto= 1 Select min ( quantidade ) from pedido/ produto Selecione a menor quantidade do campo quantidade da tabela pedido / produto: pedido/produto Select MAX ( quantidade ) from pedido / produto //Seleciona Departamento da tabela Funcionrios e NomeSupv da tabela Supervisores: SELECT Funcionrios.Departamento, Supervisores.NomeSupv FROM Funcionrios INNER JOIN Supervisores WHERE Funcionrios.Departamento = Supervisores.Departamento; //O exemplo abaixo usa o ttulo Nasc para nomear o objeto Field retornado no objeto Recordset resultante: SELECT DataNasc AS Nasc FROM Funcionrios; //O exemplo abaixo usa o ttulo Contagem para nomear o objeto Field retornado no objeto Recordset resultante: SELECT COUNT(FuncionrioID) AS Contagem FROM Funcionrios; SELECT CategoriaID, Sum(UnidadesNoEstoque) FROM Produtos GROUP BY CategoriaID HAVING Sum(UnidadesNoEstoque) > 100 AND LIKE "BOS*"; // O exemplo abaixo habilita o usurio a ver as informaes de salrio (mesmo que no tenha outra permisso para ver a tabela Folha de Pagamentos) desde que o proprietrio da consulta tenha tal permisso: SELECT Sobrenome, Nome, Salrio FROM Funcionrios ORDER BY Sobrenome WITH OWNERACCESS OPTION;
//O nmero de funcionrios e os salrios mdio e mximo. SELECT Count(*) AS [Total de Funcionrios], Avg(Salrio) AS [Salrio Mdio], Max(Salrio) AS [Salrio Mximo] FROM Funcionrios; //Para cada registro, mostra Sobrenome e Salrio no primeiro e ltimo campos. A seqncia de caracteres "tem um salrio de" retornada como o campo do meio de cada registro. SELECT Sobrenome, 'tem um salrio de', Salrio FROM Funcionrios; //Cria uma lista de nomes de departamentos nicos e o nmero de funcionrios em cada um destes departamentos. SELECT Departamento, Count([Departamento]) AS Tbc FROM Funcionrios GROUP BY Departamento; //Para cada ttulo de funo nico, calcula o nmero de funcionrios do departamento de Vendas que tm este ttulo. SELECT Ttulo, Count(Ttulo) AS Tbc FROM Funcionrios WHERE Departamento = 'Vendas' GROUP BY Ttulo; //Calcula o nmero de itens em estoque para cada combinao de nmero e cor do item. SELECT Item, Sum(Unidades) AS Tbc FROM ItensEmEstoque GROUP BY Item, Cor; //Seleciona os ttulos de cargos do departamento de Produo atribudos a mais de 50 funcionrios. SELECT Ttulo, Count(Ttulo) FROM Funcionrios WHERE Departamento = 'Produo' GROUP BY Ttulo HAVING Count(Ttulo) > 50; //Esse exemplo seleciona os departamentos que tenham mais de 100 funcionrios. SELECT Departamento, Count([Departamento]) FROM Funcionrios GROUP BY Departamento HAVING Count(Departamento) > 100; //Seleciona todos os registros de "Novos Clientes" e os adiciona tabela "Clientes" (quando no so designadas colunas individuais, os nomes das colunas das tabelas SELECT devem corresponder exatamente aos da tabela INSERT INTO). INSERT INTO Clientes SELECT [Novos Clientes].* FROM [Novos Clientes]; //Esse exemplo cria um novo registro na tabela "Funcionrios" INSERT INTO Funcionrios (Nome,Sobrenome, Ttulo) VALUES ("Andr", "Pereira", "Estagirio"); Seleciona todos os estagirios de "Estagirios" que foram contratados h mais de 30 dias e adiciona seus registros tabela "Funcionrios". INSERT INTO Funcionrios SELECT Estagirios.* FROM Estagirios WHERE DataContrato < Now() - 30; //Aumenta o Valor do Pedido em 10 % e o valor do Frete em 3 % para embarques do Reino Unido: UPDATE Pedidos SET ValorPedido = ValorPedido * 1.1, Frete = Frete * 1.03 WHERE PasEmbarque = 'RU'; //Muda os valores no campo "RelatrioPara" para 5 para todos os registros de funcionrios que atualmente tm valores de RelatrioPara de 2. UPDATE Funcionrios SET RelatrioPara = 5 WHERE RelatrioPara = 2; //Aumenta o "PreoUnit" de todos os produtos no suspensos do fornecedor 8 em 10 porcento. UPDATE Produtos SET PreoUnit = PreoUnit * 1.1 WHERE FornecedorID = 8 AND Suspenso = No; //Reduz o PreoUnit de todos os produtos no suspensos fornecidos pela Tokyo Traders em 5 porcento. As tabelas "Produtos" e "Fornecedores" tm uma relao um para vrios. UPDATE Fornecedores INNER JOIN Produtos ON Fornecedores.FornecedorID = Produtos.FornecedorID SET PreoUnit = PreoUnit * .95 WHERE NomeEmpresa = 'Tokyo Traders' AND Suspenso = No; //Exclui todos os registros de funcionrios cujo ttulo seja Estagirio. Quando a clusula FROM inclui apenas uma tabela, no necessrio indicar o nome da tabela na instruo DELETE.
DELETE *FROM Funcionrios WHERE Ttulo = 'Estagirio'; //Exclui todos os registros de funcionrios cujo ttulo seja Estagirio e que tambm tenham um registro na tabela "FolhadePagamento". As tabelas "Funcionrios" e "FolhadePagamento" tm uma relao um por um. DELETE Funcionrios.* FROM Funcionrios INNER JOIN FolhaDePagamento ON Funcionrios.FuncionrioID = FolhadePagamento.FuncionrioID WHERE Funcionrios.Ttulo = 'Estagirio'; //Retorna todos os produtos cujo preo unitrio maior que o preo de qualquer produto vendido com um desconto de 25 % ou mais: SELECT * FROM Produtos WHERE PreoUnit > ANY (SELECT PreoUnit FROM PedidoDetalhes WHERE Desconto >= .25); //Retorna todos os produtos com um desconto de 25 % ou mais: SELECT * FROM Produtos WHERE ProdutoID IN (SELECT ProdutoID FROM PedidoDetalhes WHERE Desconto >= .25); //Retorna os nomes dos funcionrios cujos salrios sejam iguais ou superiores mdia de salrios de todos os funcionrios na mesma funo. Para a tabela Funcionrios dada o alias "T1": SELECT Sobrenome, Nome, Ttulo, Salrio FROM Funcionrios AS T1 WHERE Salrio >= (SELECT Avg(Salrio) FROM Funcionrios WHERE T1. T1.Ttulo = Funcionrios.Ttulo) Order by Title; //Lista o nome, ttulo e salrio de todos os representantes de vendas cujos salrios sejam superiores aos de todos os gerentes e diretores. SELECT Sobrenome, Nome, Ttulo, Salrio FROM Funcionrios WHERE Ttulo LIKE "*Repr Vendas*" AND Salrio > ALL (SELECT Salrio FROM Funcionrios WHERE (Ttulo LIKE "*Gerente*") OR (Ttulo LIKE "*Diretor*")); //Lista o nome e preo unitrio de todos os produtos cujo preo unitrio seja igual ao do Licor de Cacau. SELECT NomeProduto, PreoUnit FROM, Produtos WHERE PreoUnit = (SELECT PreoUnit FROM [Produtos] WHERE NomeProduto = "Licor de Cacau"); //Lista a empresa e o contato de cada empresa de todos os clientes que fizeram pedidos no segundo trimestre de 1995. SELECT NomeContato, NomeEmpresa, ContatoTtulo, Fone FROM Clientes WHERE ClienteID IN (SELECT ClienteID FROM Pedidos WHERE DataPedido BETWEEN #1/04/95# AND #1/07/95#); //Lista os funcionrios cujo salrio seja maior que a mdia dos salrios de todos os funcionrios. SELECT Sobrenome, Nome, Ttulo, Salrio FROM Funcionrios T1 WHERE Salrio >= (SELECT AVG(Salrio) FROM Funcionrios WHERE Funcionrios.Ttulo = T1.Ttulo) ORDER BY Ttulo; //Seleciona o nome de todos os funcionrios que tenham registrado pelo menos um pedido. Isto tambm poderia ser feito com INNER JOIN. SELECT Nome, Sobrenome FROM Funcionrios AS E WHERE EXISTS (SELECT * FROM Pedidos AS O WHERE O.FuncionrioID = E.FuncionrioID); //Altera o campo Efetuado do arquivo de servios para 2 caso o mesmo tenha parecer tcnico da entidade encaminhanhamento diferente de nulo. UPDATE servico SET efetuado = 2 WHERE numero_servico = ANY (SELECT servico.numero_servico FROM servico INNER JOIN encaminhamento ON (servico.numero_servico = encaminhamento. numero_servico) AND (servico. ano_servico = encaminhamento.ano_servico) WHERE (((servico.efetuado) Is Null) AND
((encaminhamento.parecer_tecnico) Is Not Null)) GROUP BY servico.numero_servico ORDER BY servico.numero_servico); Query - Parametros // digitar no SQL do query { Select * from geral where Nome like :ord Na properties Params colocar : Name := Ord, Value := %} Fields var s : string; begin s := Table1.Fields [0].FieldName; //retorna o nome do primeiro campo da tabela s := Table1.Fields [1] .asString; // retorna o contedo 2 campo da tabela s := Table1.FieldByName( ' nome ' ).AsString; //retorna o valor na coluna 'nome' s := Table1['Nome'] ; //retorna o valor do compo selecionado Label1.Caption := s ; // retorna o valor da string Indexar uma Tabela Table1.IndexFieldNames := 'Nomecli'; Table2.IndexFieldNames := 'Data, Vendedor'; ListBox // esta rotina exibe em um listbox os campos de uma tabela var i: Integer; begin ListBox1.Clear; for i := 0 to table1.fieldcount - 1 do Listbox1.items.add(table1.fields[i].fieldname); end; //Faz um ListBox exibir o contedo de uma tabela var i: Integer; begin ListBox1.Clear; for i := 0 to Table1.FieldCount - 1 do ListBox2.Items.Add(Table1.Fields[i].AsString); end; BOOKMARKS //guardar uma posio no registro var BM :tBookMark; {...} // Grava um Registro if bm = nil then // se bm est vazio ento... bm := table1.GetBookMark; // marque um ou if BookMark = nil then BookMark := Table1.GetBookMark; {++} // ir para o registro guardado if BookMark <> nil then // se o BookMark no est vazio...
begin table1.GotoBookMark(BookMark) // v para o marcado end; ou.. if BM <> nil then begin BM := table1.GetBookMark(BM); {++} //limpa da memria o registro guardado if BookMark <> nil then // se o BookMark no est vazio ento faa.. begin Table1.FreeBookMark (BookMark); // libere o marcado.. BookMark := nil; // deixe-o vazio end; ou if bm <> nil then begin Table1.FreeBookMark (bm); bm := nil; end; // conjunto de comandos if BookMark < > nil then begin table1.GotoBookMark(BookMark); Table1.FreeBookmark(BookMark); BookMark := nil; end; Gravar em um banco de dados tabel1.edit;// abre o dataset tabel1['senha'] := 'Marvel'; // edita 'Marvel' no campo senha tabel1.post; // grava a informao Filter Table1.Filtered := false; Table1.Filter := 'idade > 30 ' ; (ex: Table1.Filter := 'Nota1>=' + '''' + Edit1.text + ''''';) Table1.Filtered := true; Filter II Table1.SetRangeStart; Table1.FieldbyName('cdigo') := 100;//Table1Codigo.AsInteger := 100 Table1.KeyExclusive := False; Table1.SetRageEnd; Table1.FieldbyName('Codigo') := 200; //Table1Codigo.AsInteger := 200 Table1.KeyExclusive := true; Table1.ApplyRange // Aplicar um filtro usando um CHECKBOX Table1.Filtered := checkbox1.Checked; // No componente TABLE, no evento OnFilterRecord Accept := Table1['Nome']= Edit1.Text // Um boto pode seguir para o prximo tem procurado Table1.FindNext Soma
// RecordCount, conta quantos registros ha na Tabela Label1.Caption := InttoStr(Table1.Recordcount); Os estados de um Data Base if Table1.State = dsEdit then begin... Para saber o Estado de um DataBase. Digite no Evento OnStateChange do DataSourse: Var S : String; begin Case Table1.State of dsInactive : S := 'Inativo'; dsBrownse : S := 'Browse'; dsEdit : S := 'Edio'; dsInsert : S := 'Insero'; dsSetKey : S := 'SetKey'; dsCalcFields : S := 'CalkFields'; end; Label1.Caption := S; //Para digitar s nmeros em um edit No evento KeyPress, digite: if not (Key in['0'..'9',Chr(8)]) then Key:= #0; // Obs: Chr(8), para BackSpace e DecimalSeparator, para a vrgula dentro dos colchetes. Alias Criando um alias.. Check(DBiAddAlias(Nil, Pchar('AliasName'),Nil, Pchar('AliasPath), true)); AliasName = nome do alias; AliasPath = caminho do alias; Inclua em Uses = BDE e BD; Criando um alias temporrio // Utilizando o componente TSession // No evento OnShow, digite: session1.ConfigMode:=cmSession; Session1.AddStandardAlias('NomedoAlias','C:\Arquivos de Programas\Arquivos comuns\Borland Shared\Data','PARADOX'); Table1.OPen; // No componete TTable, digite o nome do Alias e o nome da tabela Atualizando as informaes em ambiente de rede Acessando a mesma tabela concorrente com outra estao ou outro objeto Query, Table a) Crie procedure para uso no evento OnActive: Procedue TTorm1.FormRefresh(Sender: TObject); begin Table1.Refresh; ... TableN.Refresh; end; b)No evento OnActive do formulrio acrescente a linha: Application.OnActive := FormRefresh; c) No evento OnShow do formulrio acreste a linha FormRefresh(Sender); d) No evento OnAfterPost de cada objeto TTable acrescente as linhas; Table.FlushBuffer; FormRefres(Self);
Salvando os Dados Fisicamente em uma Tabela USES DBIProcs; Nos eventos OnAfterPost e OnAfterDelete, digite: DBISaveChanges(Table1.handle); Salvando Os dados Visicamente II USES BDE: DbiSaveChandges((Dataset as TTable).Handle); O DBNavigator //Para pegar o nome do boto que foi pressionado DBNavigator1.BtnClick(nbNext); // pegando o boto clicado if Button in [nbFirst,nbLast,nbPrior,nbNext] then DBNavigator.DataSource.DataSet.Refresh; MULTIMIDIA Imagem no Form Colocar uma figura bmp, no form sem o Picture var BitMap : TBitMap; Begin BitMap : = TBitMap.Creat ; With BitMap do Biguin LoadFromFile( ' c : \ figura . bmp' ) ; Transparent := true ; Form1. Canvas . Draw (50,50, bitMap); end: end; //Desktop, imagem no form //Procedure TForm E. FormResize(Sender: tobject); Var R : TRect ; DC : HDc ; Canv : TCanvas ; Begin R : = Rect (0,0, Screen.Width, Screen.Height); DC : = GetWindowDC (GetDeskTopWindow); Canv := TCanvas.Create; Canv . Handle := DC; Canvas . CopyRect(R,Canv,R); ReleaseDC (GetDeskTopWindow, DC); end; CopyFile, para copiar arquivos CopyFile(pchar('c:\conto.txt'),('a:\conto.txt'),false); // no final: true=no regrava o arquivo, se false, ele regrava. A Tecla Pressionada //No evento OnKeyDown, digite: Label1.Caption := Format('O cdigo da tecla : %d', [Key]); O componente TMediaPlayer Para ouvir um som With MediaPlayer1 do
begin FileName := 'c:\bettoven.wav'; // pode ser um Mid Open; Play; end; Para ver um *.avi no form... with MediaPlayer1 do begin FileName := 'c:\super.avi'; Open; Display := Form2; Form2.Show; Play; end; Arquivos Texto Carregando o texto em um RichEdit RichEdit1.Lines.LoadFromFile('c:\aviso.txt'); //colocando cores ReachEdit1.Font.Color := clGreen; Estilos de Texto //testo em negrito if CheckNegrito.Checked then //Para o boto Negrito Memo1.Font.Style := Memo1.Font.Style + [fsBold] // coloca em estilo negrito else Memo1.Font.Style := Memo1.Font.Style - [fsBold]; // retira o estilo negrito //Memo1.Font.Style := Memo1.Font.Style + [fsItalic] // Para o boto Itlico //Memo1.Font.Style := Memo1.Font.Style + [fsUnderline] // Para o boto Sublinhado //testo em negrito II if BoldButton.Down then CurrText.Style := CurrText.Style + [fsBold] else CurrText.Style := CurrText.Style - [fsBold]; end; function TMainForm.CurrText: TTextAttributes; begin if Editor.SelLength > 0 then Result := Editor.SelAttributes else Result := Editor.DefAttributes; end; Alinhamento do texto {taLeftJustify, taCenter, taRightJustify} Label1.Alignment := taLeftJustify; Trabalhando com Arquivos .INI Acrescente a unit inifiles na guia uses //declare uma varivel inifile: ArqIni: TIniFile; //no evento OnCreate, do form, digite: ArqIni := TIniFile.Create('c:\windows\ArqIni.ini'); lendo um arquivo ini // lendo um valor string: EditString.Text := ArqIni.ReadString('String', 'texto', ''); //lendo um valor inteiro: EditString.Top := ArqIni.ReadInteger('Integer', 'altura', 0);
//lendo um valor boolean EditString.Visible := ArqIni.ReadBool('Boolean', 'visivel',False); //lendo um arquivo ini em um meno: Memo1.Lines.LoadFromFile('c:\inicial.ini'); gravando em um arquivo .ini //gravando um valor string ArqIni.WriteString('String', 'texto', EditString.Text); //gravando um valor inteiro ArqIni.WriteInteger('Integer', 'altura', SpinEdit1.value); // gravando um valor boolean ArqIni.WriteBool('Boolean', 'visivel', CheckBox1.Checked); //no evento OnDestroy, do form, libere o nosso arquivo ArqIni.Free; Movimento fazer um panel ter seu texto em movimento var texto : string; begin texto : = panel1.caption; panel1.caption := copy(texto,2,length (texto)) + texto[1]; end; ColorGrid Form1.Color := ColorGrid1.ForegroundColor ; //boto esquerdo do mouse Form1.Color := ColorGrid1.BackgroundColor ;// boto direito do mouse Movendo Arquivos var origem, destino : string; begin origem := 'c:\delete\faq.txt'; destino:= 'c:\games\faq.txt'; if not copyfile(pchar(origem),pchar(destino),true) then showMessage ( 'problemas com' + origem + 'para' + destino) MOVENDO UM OBJETO // Coleque em um objeto ( ex: um Button) // Na guia VAR, digite MouseDownSpot : TPoint; Capturing : bool; // No evento OnMouseDown SetCapture(Button1.Handle); Capturing := true; MouseDownSpot.X := x; MouseDownSpot.Y := Y; // No evento OnMouseMove if Capturing then begin Button1.Left:= Button1.Left-(MouseDownSpot.x -x); Button1.Top:= Button1.Top - (MouseDownSpot.y -y); end; // No evento OnMouseUp if Capturing then begin
ReleaseCapture; Capturing := false; Button1.Left := Button1.Left - (MouseDownSpot.x -x); Button1.Top := Button1.Top - (MouseDownSpot.y - y); end; Arquivos Help // digite a linha abaixo para chamar um arquivo help WinHelp(Form1.handle, 'c:\Ajuda.hlp', HELP_CONTENTES,0); Randomize //A linha de comando abaixo faz o label exibir aleatriamente um nmero de 1 a 100 Label1.Caption := InttoStr(Random(100)); Hint //colocar no evento OnCreate do form principal.. Application.HintColor := clYellow; // define a cor de todos os hints Application.HintPause := 200; // define o tempo de espera de um hint btnOk.ShowHint := true; // habilita a exibio de um hint btnOk.Hint := 'Clique aqui';// define o texto Edit1.hint := 'Primeira linha' + #13 + 'segunda linha';//Hint com quebra de linha Criar um componente em tempo de execuo var PictImg1 : TImage;//declarando um TImage begin PictImg1 := tImage.Create(self); PictImg1.Height := 200; pictImg1.Width := 200; PictImg1.Picture.LoadFromFile('C:\1.bmp'); PictImg1.parent := Self; end; Cores com RGB //o form abaixo recebe a cor composta por:" red, green e blue" Form1.Color := Rgb(100, 100, 100); Progess Bar Criando um ProgressBar em tempo de execuo //Declare a procedure abaixo procedure TestProgress(Form: TForm; Count: SmallInt); var ProgressBar1: TProgressBar; i: SmallInt; begin ProgressBar1 := TProgressBar.Create(Form); try ProgressBar1.Parent := Form; ProgressBar1.Align := alBottom; ProgressBar1.Min := 0; ProgressBar1.Max := Count; ProgressBar1.Step := 1; for i := 1 to Count do ProgressBar1.Stepit; ShowMessage('Now the ProgressBar control will be freed'); finally
ProgressBar1.Free; end; end; Finalmente, facha a chamada para o ProgessBar... TestProgress(Self, 1000); form2.show; O Componente TCalendar Calendar1.PrevYear;//para exibir o ano anterior Calendar1.NextYear;//para exibir o proximo ano Calendar1.PrevMonth;//para exibir o ms anterior Calendar1.NextMonth;//para exibir o prximo ms Calendar1.CalendarDate := CalendarDate - 1;// vai para um dia anterior Calendar1.CalendarDate := CalendarDate + 1;// vai para o proximo dia Arquivos .ini Acresentar em Uses: IniFiles; Declare: Tini : TInifile; Criando do arquivo. No evento OnCreate: Tini := TInifile.Create('c:\super.ini'); Lendo em um arquivo... Label1.Caption := Tini.ReadString('Label','titulo',''); Label1.top := Tini.ReadInteger('Label','top',0); Label1.visible := Tini.ReadBool('Label','ver',true); Gravando em um arquivo... Tini.WriteString('label','titulo','Ol Mundo'); Tini.WriteInteger('label','top',10); Tini.WriteBool('label','ver',true); Ao findar tudo... IniFile.Destroy; Dias da semana var WeekDay : array[1..7] of string; DayNo : integer; QDay : string; begin weekday[1] := 'domingo weekday[2] := 'segunda'; weekday[3] := 'tera'; weekday[4] := 'quarta'; weekday[5] := 'quinta'; weekday[6] := 'sexta'; weekday[7] := 'sabado'; DayNo := DayofWeek(Date); // pega numero do dia da semana.. // a mensagem exibe o valor do array na posio n. da semana ShowMessage('O dia : ' + WeekDay[DayNo]); Verificando os dgitoso do ano Function AnoQuatroDigitos: Boolean; begin Result := (Pos('yyyy',SHortDateFormat)>0); if Result = True then ShowMessage('O ano esta configurado para quatro dgitos.')
else ShowMessage('O ano no esta configurado para quatro dgitos.'); end; Trabalhando com Frames // No menu File>New, insira um TFrame. Declare em { Private declarations } FFrame: TFrame; // Dois botes usando a mesma varivel do frame... // boto um.. if FFrame <> nil then FFrame.Free; FFrame := TFrame1.Create(pnlParent); FFrame.Align := alClient; FFrame.Parent := pnlParent; // boto dois.. if FFrame <> nil then FFrame.Free; FFrame := TFrame2.Create(pnlParent); FFrame.Align := alClient; FFrame.Parent := pnlParent; Jogar uma imagem direto para um campo na tabela var BMP : TBitMap; begin BMP := TBitmap.Create; if OpenPicutrueDialog1.Execute then begin BMP.LoadFromFile(OpenPictureDialog1.FileName); Table1Graphic.Assign(BMP); end; TPrinter //Uses Printers BiginDoc = inicia uma impresso EndDoc = finaliza uma impresso Abrot = interrompe a impresso Priting = para saber se esta havendo uma impresso printers = lista as impressoras instaladas PrinterIndex = indica a impessora selecionada Fonts = lista as fontes da impressora Orientation ( em Portrait ou LandScape) = orientao do papel PageHeight = Altura da pgina PageWidth = Largura da pgina PageNumber = Nmero da pgina atual
INTERNET Para executar um pgina da Web I Winexec ( 'start c:\windows\index.html',sw_ShowMinimized ) Para executar um pgina da Web II ShellExecute(Handle, 'open', HTMLFile, nil, nil, SW_SHOWNORMAL);
Chamando um site utilizando o seu browse padro. Coloque em USES:UrlMon; HlinkNavigateString(nil, 'http://www.geocities.com/escolarte'); //Verificando se voc est conectado a Internet //Inclua um componente TCP no Form, e digite o cdigo: if (TCP1.LocalIP = '0.0.0.0' or TCP1.LocalIP = '127.0.0.1') then ShowMessage('No existe conexo') else ShowMessage('Existe Conexo')
Original : http://www.drbob42.com/delphi4/actions.htm A new and handy feature of Delphi 4 - also present in C++Builder 4 by the way - is the TActionList component, found in the "Standard" tab of the component palette. With an ActionList, we can group and manage "actions" (event handling code) between different components and even re-use them among different applications! This article shows how to use Actions and ActionLists - without writing a single line of Delphi or C++ code - and contains some nice gotchas too...
Using TActionList
Start a new application, and drop a TActionList component on the Form. Right-click with the mouse on the ActionList1 component to get the Action List Editor. The Action List Editor shows the action categories, and for each action category the individual actions that are available for the current application. We can define new actions, or select a number of existing (standard) actions. The latter can be done by right-clicking with the mouse in the Action List Editor, and selecting the New Standard Action menu:
This will give us a new dialog with the (current) list of standard actions. Note that we can select more than one action at the same time by holding down the Ctrl key and clicking on each individual item (see left figure below).
After we click on OK, we return to the Action List Editor which now shows two categories (Edit and Window) and four actions in total (Copy, Cut and Paste for the Edit categories, and MinimizeAll for Windows) - see right figure above. It's now time to add some controls to the Form and connect them to these actions.
Control Action
Go to the Win32 tab of the component palette, and drop a ToolBar component on the form. Right-click on it and select "New Button" to add a new button. Repeat this until you have four buttons next to each other on the toolbar (tip: you may want to insert a separator between the third and fourth button). Now, click the left button, and set its Action property to EditCopy1. Set the Action property of the second button to EditCut1, and the third button to EditPaste1. Finally, set the Action property of the last button to WindowMinimizeAll1. Before we compile and run this application, let me remind you that we now have four fully functional toolbar buttons without having written a single line of code. That's because we're using standard behavior that's already been provided to us as "standard" re-usable Actions. But it gets even better, because we can share these actions with multiple components. Go back to the Standard tab of the component palette, and drop a TMainMenu component on the Form. Double-click on it (to get into the Menu Designer). Right-click on the Menu Designer select "Insert from Template" and pick the Edit menu template. This gives us a list of 10 menu items, while we only need three (Cut, Copy and Paste), but at least it saves us some typing. You can easily remove the menu items that you don't need, by the way. Go to the Cut1 menu item, and set its Action property to EditCut1. Set the Action property of the Copy1 menu item to EditCopy1, and let Paste1 point to EditPaste1. We're now almost ready to compile and run our application, but we need one more thing. Let's drop three normal buttons on the form (again from the Standard tab), and connect them to EditCut1, EditCopy1 and EditPaste1 like we've done twice before already. Note that the "regular" buttons automatically get captions with "Cut", "Copy" and "Paste", where the speedbuttons
on the ToolBar remain empty (their Hint property it set, but not their caption). A solution to this potential (confusing) problem can be implemented by assigning an ImageList to the ActionList, so each action can get associated with a specific image. To do this, drop a TImageList (from the Win32 tab) on the Form, and right-click on it to fill it with some images. Set the Images property of the ActionList a component to ImageList1, and double-click again on the ActionList to get the Action List Editor where we can now specify which image should be used by which individual Action item by setting the ImageIndex for each individual action:
Note that the speedbuttons on the toolbar and the images next to the menu texts still don't show the images from the ImageList1 at design-time. In order to let them "share" the same images, we must set the Images property of the ToolBar1 component to ImageList1, and do the same with the Images property of the MainMenu1 component. The ImageIndex properties will now be copied from the index belonging to the Action components, so each action will look the same on a speedbutton or as a menu-item. The really final thing we need to do is drop a TEdit component on the Form (after all, we would need some Edit control to test the Cut, Copy and Paste actions with, right?). After that, your application should resemble the following screenshot (at least a little bit, I hope):
Action!
Now, save your work, compile and run the application. Initially, all buttons and menu-items will be disabled, meaning that we cannot Cut or Copy text, nor can we Paste any text at this time. If your clipboard is filled with some text, and you select the editbox, then the Paste buttons and menu-item get enabled automatically (at the same time). We can then select the Paste menu, for example, and the text from the clipboard will be pasted inside the editbox. As soon as we select some text from the editbox, the Cut and Copy buttons and menu-items will get enabled as well (we can only Cut and Copy selected text, of course). We can now click on the Cut or Copy speedbutton in the toolbar to get the effect we want. Note that each Action items somehow "knows" when it can be executed (in our case: when the current control is an editbox or memo, and - in case of Cut and Copy - whether or not any text is currently selected). The Action items can enable and disable all controls that are associated with them as soon as something changes that influences them (like selecting text, or moving the focus from the editbox to another control, for example).
Problems?
This all seems to work fine. However, if you try to Cut, Copy or Paste text inside the editbox using any of the "normal" buttons, then you will find that they do not appear to work. For some reason, the big Cut button doesn't cut the text, nor does the bit Paste button paste it. In fact, they only seem to result in de-selecting the text in the editbox (if any text was selected), and moving the focus away... Strange! Well, that last piece of information, regarding the focus, should have been a subtle hint: the buttons take away the focus before the Action can be executed. In other words: the Action expects an editbox to have the focus, but by the time the Action it executed, it's the button that has the focus (if not for the Button's Click method that fires the action, the action wouldn't even have been fired, since giving the button the focus means disabling the action and all controls associated with the action). Of course, the workaround is never to use any controls that can get the focus (like a TButton which has a Windows handle), so the focus will never be list when we click on any Action-bound control again. This is not something that's documented too well, however, and I must admit that even I fell into this trap (while performing my Delphi 4 Workout in London, by the way), so be aware.