Escolar Documentos
Profissional Documentos
Cultura Documentos
Dicas Delphi Book2
Dicas Delphi Book2
www.ramosdainformatica.com.br
ndice
1 ndice ............................................................................................................................ 2 Descobrindo o cdigo ASCII de uma tecla .................................................................. 6 Funo - Retornando o prximo dia til....................................................................... 6 DBGrid - Colocando em Letras maisculas uma coluna selecionada.......................... 7 DBGrid - Mostrando todo contedo de um campo Memo........................................... 7 Crtica de datas no objeto Edit sem mensagem de erro do Delphi ............................. 10 Preenchimento de zeros para completar a data........................................................... 14 Multimdia - Fazendo suas aplicaes Delphi falar ................................................... 14 Multimdia - Toque um som quando o mouse passar por cima de um boto............. 15 Hints com multiplas linhas ......................................................................................... 15 Multimdia - Usando cursores animados .................................................................... 16 Detectando a verso do Internet Explorer .................................................................. 16 QuickReport - Filtrando registros............................................................................... 17 Evitando efeito de maximizao................................................................................. 17 Calcula a quantidade de dias no ms .......................................................................... 18 Calculando abono salrial de modo progressivo ........................................................ 18 Checa se um processo est rodando ........................................................................... 19 Checa se um diretrio est vazio ................................................................................ 20 dbExpress - Passando parmetros com CommandText via programao.................. 20 Corrigindo problemas de instalao do Borland Data Provider For Firebird............. 21 Lendo texto de um arquivo PDF ................................................................................ 21 Deixando seu EXE mais enxuto e rpido e, mais seguro contra decompilao......... 24 Copiando (Upload) um diretrio para um servidor FTP ............................................ 26 Trabalhando com arquivos texto no Delphi ............................................................... 29 Criando uma conexo ao DBExpress em tempo de execuo.................................... 31 ActiveX - Pegar um texto selecionado no Internet Explorer...................................... 32 Cria um efeito na apresentao de um formulrio...................................................... 33 Criando um Menu transparente .................................................................................. 34 Checa se um diretrio est vazio ................................................................................ 36 Mostra multiplas linhas de texto em um ComboBox ................................................. 37 Criando atalhos no Windows pelo Delphi.................................................................. 38 Faa suas aplicaes Falar.......................................................................................... 39 Imprimindo arquivos PDF sem abrir-los .................................................................... 39 Ler arquivos PDF ....................................................................................................... 39 Inno Setup - Script para criao de conexo OBDC DSN ......................................... 40 Colocar cursor no final do Edit ao receber o foco...................................................... 42 Mudar a cor de fundo de um Hint............................................................................... 42 Fazer um executvel ser executado somente se chamado por um determinado executvel ................................................................................................................... 42 DBGrid - Focando a clula selecionada mudando sua cor......................................... 43 Verificando a verso do Windows ............................................................................. 43 Rave Report - Alterar a impressora padro ................................................................ 44 Atribundo efeitos para abertura de formulrios......................................................... 44 API do Windows - Funo para excluir uma pasta e todos arquivos desta pasta....... 45 Inno Setup - Verificando se existe determinada Chave no Registro do Windows..... 46 Controlando o PowerPoint no Delphi......................................................................... 46 Rave Report - Indicar pgina inicial........................................................................... 48 2
InnoSetup - Adicionar um programa no iniciar do Windows .................................... 48 Validando endereo de e-mail no Delphi em aplicaes Win32, .Net e Asp.Net ...... 49 Memo redondo............................................................................................................ 50 Colocar Banners em Menus........................................................................................ 50 Usando a WebCam no Delphi .................................................................................... 51 Colocando imagens em um ComboBox ..................................................................... 52 Importando e Exportando Registro ............................................................................ 53 DBGrid - Colocar um ComboBox num DBGrid........................................................ 54 Enviando mensagens HTML com imagens anexadas ................................................ 54 Mostrando dicas balo para caixas de edio wm WindowsXP ................................ 56 CheckLisBox - Trocar a cor das linhas ...................................................................... 57 Windows - Verificar a impressora padro.................................................................. 58 RichEdit - Pesquisar um texto, posicionar sobre ele e mostrar ao usurio................. 58 ActiveControl - Envia um valor para Edit que estiver em foco ................................. 59 Registro do Windows - Retorna portas seriais ........................................................... 59 Verifica se um programa est aberto, caso contrrio, abre......................................... 60 Funo que verifica a velocidade do processador ...................................................... 60 DBGrid - Ao clicar no campo no DBGrid ordenar os registros ................................. 61 Criando um lista Push and Pop em Delphi ................................................................. 61 Rave Report - Imprimindo cdigo de barras em modo de programao.................... 64 Gerar planilhas no Excel atravs de uma Query......................................................... 64 Rave Report - Somar valores...................................................................................... 65 Colorir componente focado - Preservando sua cor original ....................................... 66 ActiveControl - Envia valor para Edit que tiver em foco........................................... 67 TFields - Adiciona Fields no Fields Editors em tempo de execuo ......................... 67 ListBox - Colorir ........................................................................................................ 69 Associando um extenso de arquivo a um executvel ............................................... 69 Retornar as contas de E-Mail...................................................................................... 70 HKEY, Registry ......................................................................................................... 71 Criar e ler chave.......................................................................................................... 72 Retornar lista de hardware via registry....................................................................... 73 Verificar se um valor existe dentro de uma Chave..................................................... 73 Quick Report - Selecionando itens do ComboBox para PapeSize ............................. 74 ListBox - Pesquisa incremental .................................................................................. 74 Acertar data e hora com o servidor............................................................................. 75 QuickReport - Access Violation no Windows 2000 e XP ......................................... 75 DBGrid - Alterar as cores do ttulo em tempo de execuo....................................... 75 Testa se a impressora est funcionando...................................................................... 76 Como implementar um AutoComplete num Edit comum.......................................... 76 Como adicionar um CheckBox em um StringGrig .................................................... 78 Abreviao automtica de nomes ............................................................................... 80 Compilando a aplicao pelo MS-DOS ..................................................................... 81 Colorao gradiente no Form ..................................................................................... 82 Usar perfeitamente o LookupComboBox................................................................... 83 Como colocar um codigo para que a aplicacao feche apos XX segundos sem atividades no teclado ou sem cliques do mouse. ........................................................ 83 Escondendo a barra de tarefas do Windows............................................................... 85 Pega todos os erros do Sistema, captura tela do erro, grava em arquivo e envia por email ............................................................................................................................. 85 Detectando o tipo de Conexo com a internet............................................................ 86
Funo de potenciao - Juros.................................................................................... 87 Para trocar as cores dos botoes do radiogroup ........................................................... 87 Como criar uma figura do tipo marca d' gua ............................................................ 88 Criptografando Imagens ............................................................................................. 88 Alterar a fonte de determinado registro num DBGrid................................................ 89 Alinhar ttulo da barra de titulos do Form a esquerda ou direita................................ 89 Alterar fonte do Hint................................................................................................... 90 Criando arquivo Texto................................................................................................ 91 Como selecionar tudo (Ctrl+A) em um TMemo/TDBMemo..................................... 92 Mudando o IP da mquina via API do Windows ....................................................... 93 Texto na diagonal e girando ....................................................................................... 93 Criar um alias dinamicamente na memria ................................................................ 94 Rodar videos em um panel ......................................................................................... 94 Como colocar uma coluna do DBGrid em maiuscula ................................................ 95 DBGrid - Alinhando texto conforme condio .......................................................... 95 DBGrid - Colocando CheckBox no grid .................................................................... 96 RichEdit - Como fazer uma pesquisa e substituio em um RichEdit ....................... 97 TForm - Criando formulrios transparentes ............................................................... 98 TList - Ordenando os itens ......................................................................................... 99 3 formas de dar um shutdown................................................................................... 100 QuickReport e FastReport - Gerando um PDF......................................................... 103 SetVolumeLabel - Mudando o Label do HD............................................................ 104 Memo - Rolagem vertical ......................................................................................... 105 Como adicionar o evento OnClick no DBGrid ........................................................ 106 Alterando a cor dos TabSheet de um PageControl................................................... 107 Como chamar uma home page utilizando o seu browse padro............................... 107 Como alterar o caption da janela de preview do quickreport ................................... 107 Como passar parmetros entre 2 forms .................................................................... 108 Como reduzir o tempo e carga de um programa ...................................................... 109 Escondendo o Programa de Ctrl+Alt+Del................................................................ 110 Verifica se o BDE est instalado .............................................................................. 112 Verificando se um alias est instalado...................................................................... 114 Como prevenir a movimentao do mouse para fora do form? ............................... 114 Como criar hints customizados?............................................................................... 114 Como capturar a tela? ............................................................................................... 116 Como mostrar um TMenuItem alinhado direita? .................................................. 121 Como mover o form clicando em qualquer lugar? ................................................... 121 Como mostrar um texto de vrias linhas em um TCombobox? ............................... 122 Como criar tooltips com bales? .............................................................................. 124 Mostra o total de pginas.......................................................................................... 144 InnoSetup Verificando a verso do software, se inferior, ento, no instalar ....... 144 InnoSetup Manipulao de arquivos texto ............................................................ 145 Finalizando processos do Windows via programao.............................................. 146 Gravando CDs .......................................................................................................... 147 Quick Report - Obtendo a lista de papeis disponveis.............................................. 147 DBGrid - Como fazer quebra de linhas .................................................................... 148 Arquivo: Verificar se est ReadOnly........................................................................ 150 Treeview Foco ....................................................................................................... 151 Rave Report Indicar pgina inicial ........................................................................ 151 Desktop do Windows auto-arranjar icones............................................................ 152
Clculo de Parcelas................................................................................................... 153 Porta Serial Como verificar se uma porta est em uso .......................................... 154 GIF Como converter uma imagem GIF para BMP ............................................... 155 Veja como criar atalhos no menu iniciar do Windows............................................. 155 Como mover um componente em Run-time............................................................. 158 Como apresentar o nmero da linha e coluna em um DBGrid?............................... 159 Como implementar um log de todos os erros gerados na aplicao?....................... 160 Printers - Como retornar informaes das impressoras instaladas na mquina ....... 161 IP Como retornar o hostname a partir de um endereo IP..................................... 163 Windows Como criar grupos e subgrupos de programas no menu iniciar............ 164 Windows Como desabilitar uma combinao de teclas genericamente ................ 165
Mem.DataSource := Dts; Mem.DataField := Fld.FieldName; Mem.ReadOnly := True; Mem.ScrollBars := ssVertical; Frm.ShowModal; finally Mem.Free; end; finally Frm.Free; end; end; Result := Ret; end;
Uma vez desenvolvida nossa funo, preciso colocar em prtica, no evento OnCellClick do DBGrid, insira o cdigo a seguir:
procedure TForm1.DBGrid1CellClick(Column: TColumn); begin MostraMemo(DBGrid1.DataSource, DBGrid1, DBGrid1.SelectedField); end; Confira como ficou todo exemplo: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, DBGrids, DB, DBTables, StdCtrls, DBCtrls; type TForm1 = class(TForm) Table1: TTable; DataSource1: TDataSource; DBGrid1: TDBGrid; procedure DBGrid1CellClick(Column: TColumn); private function MostraMemo(Dts: TDataSource; Dbg: TDBGrid; Fld: TField): Boolean; { Private declarations } public { Public declarations } end;
var Form1: TForm1; implementation {$R *.dfm} function TForm1.MostraMemo(Dts: TDataSource; Dbg: TDBGrid; Fld: TField): Boolean; var Frm: TForm; Ret: Boolean; Mem: TDBMemo; begin Ret := False; if Dts.DataSet.RecordCount > 0 then if Dbg.SelectedField = Fld then begin Ret := True; Frm := TForm.Create(nil); try Frm.Width := 240; Frm.Height := 120; Frm.Top := Mouse.CursorPos.Y; Frm.Left := Mouse.CursorPos.X; Frm.BorderStyle := bsToolWindow; Frm.Caption := Fld.DisplayLabel; Mem := TDBMemo.Create(nil); try Mem.Parent := Frm; Mem.Align := alClient; Mem.DataSource := Dts; Mem.DataField := Fld.FieldName; Mem.ReadOnly := True; Mem.ScrollBars := ssVertical; Frm.ShowModal; finally Mem.Free; end; finally Frm.Free; end; end; Result := Ret; end;
10
// A matriz M preenchida com o ltimo dia de cada ms // A matriz K preenchida com 1. A posio relativa de cada caracter do campo // data, dentro da matriz K, ser prenchida com zero se o caracter for vlido. // Caso contrrio ser setado Erro igual a s for I := 1 to 12 do begin K[I] := 1; M[I] := 31; end; M[4] := 30; M[2] := 28; M[6] := 30; M[9] := 30; M[11] := 30; //Num contm os nmeros e / para controle do campo data. SetLength (Num, 11); for I := 0 to 9 do Num[I] := IntToStr(I); Num[10] := '/'; // Barra controla a posio das duas // do campo data Barras := 0; // Verifica a quantidade de barras digitadas Barra1 := 0; // Posio da 1 barra (pode ser 2 ou 3) Barra2 := 0; // Posio da 2 barra (pode ser 4, 5 ou 6) for I := 1 to length(Data) do begin Caracter := copy(Data,I,1); if Caracter = '/' then begin Barras := Barras + 1; if Barra1 = 0 then Barra1 := I else Barra2 := I; end; for J := 0 to 10 do if Num[J] = Caracter then K[I] := 0; end; //Se Algum elemento da varivel Data no for vlido // seta o erro com s for J := 1 to length(Data) do if K[J] = 1 then Erro := 's'; if (length(data) < 6) or (length(data) > 10) then Erro := 's';//or // (length(data) = 9) then Erro := 's'; if Barras > 2 then Erro := 's'; if (Barra1 > 3) or (Barra1 < 2) then Erro := 's'; if (Barra2 > 6) or (Barra2 < 4) then Erro := 's'; // At aqui j sabemos que a data est em formato vlido com barras if Erro = 'n' then begin Caracter := Copy(Data,(Barra2 + 1),4); if length(Caracter) < 4 then begin Caracter := '20' + Caracter; // Se a data entrar no formato dd/mm/aa // fazemos a data ficar dd/mm/20aa Data := Copy(Data,1,Barra2)+Caracter; end;
11
// Podemos converter as posies da string em inteiros sem receio de recebermos // aquela mensagem de erro do delphi. Dia := StrToInt(Copy(Data,1,(Barra1 - 1))); Mes := StrToInt(Copy(Data,(Barra1+1),(Barra2 - Barra1 - 1))); Ano := StrToInt(Copy(Data,(Barra2 + 1),4)); // Verifica se o ano bissexto para a crtica do dia se o ms for fevereiro. J := Ano mod 4; if J = 0 then M[2] := 29 else M[2] := 28; // Critica o mes if (mes < 1) or (mes >12) then Erro := 's'; // Critica o dia if Erro = 'n' then if (dia < 1) or (dia > M[Mes]) then Erro := 's'; // critica o ano (Se quiser) if ano < 2003 then Erro := 's'; end; if Erro = 's' then begin Data := ''; messageDlg('Data inconsistente!!!',mtError, // Esta ser a nica mensagem mostrada. [mbOk],0); end; end;
A mesma procedure CriticaData, mais enxuta, porm, com o controle dos caracteres feito no evento OnKeyPress: procedure TForm1.CriticaData(var Data: string); //Com controle dos caracteres //digitados no objeto Edit1 atravs do evento OnKeyPress var I, J, Dia, Mes, Ano : Integer; Barras, Barra1, Barra2 : Integer; // Verifica a posio das barras; M : Array Of Integer; Caracter, Erro : String; begin Erro:='n'; //Em princpio o campo considerado como correto(vlido). // Cria-se o Array M com 13 campos dos quais usaremos do 1 ao 12 SetLength (M, 13); // A matriz M preenchida com o ltimo dia de cada ms for I := 1 to 12 do begin M[I] := 31; end; M[4] := 30; M[2] := 28; M[6] := 30; M[9] := 30; M[11] := 30; // Barra controla a posio das duas // do campo data Barras := 0; // Verifica a quantidade de barras digitadas
12
Barra1 := 0; // Posio da 1 barra (pode ser 2 ou 3) Barra2 := 0; // Posio da 2 barra (pode ser 4, 5 ou 6) for I := 1 to length(Data) do begin Caracter := copy(Data,I,1); if Caracter = '/' then begin Barras := Barras + 1; if Barra1 = 0 then Barra1 := I else Barra2 := I; end; end; if (length(data) < 6) or (length(data) > 10) then Erro := 's'; if Barras > 2 then Erro := 's'; if (Barra1 > 3) or (Barra1 < 2) then Erro := 's'; if (Barra2 > 6) or (Barra2 < 4) then Erro := 's'; // Aqui j sabemos se a data numrica e se est em formato vlido com barras if Erro = 'n' then begin Caracter := Copy(Data,(Barra2 + 1),4); if length(Caracter) < 4 then begin Caracter := '20' + Caracter; // Se a data entrar no formato dd/mm/aa // fazemos a data ficar dd/mm/20aa Data := Copy(Data,1,Barra2)+Caracter; end; // Podemos converter as posies da string em inteiros sem receio de recebermos // aquela mensagem de erro do delphi. Dia := StrToInt(Copy(Data,1,(Barra1 - 1))); Mes := StrToInt(Copy(Data,(Barra1+1),(Barra2 - Barra1 - 1))); Ano := StrToInt(Copy(Data,(Barra2 + 1),4)); // Verifica se o ano bissexto J := Ano mod 4; if J = 0 then M[2] := 29 else M[2] := 28; // Critica o mes if (mes < 1) or (mes >12) then Erro := 's'; // Critica o dia if Erro = 'n' then if (dia < 1) or (dia > M[Mes]) then Erro := 's'; // critica o ano (Se quiser) if ano < 2003 then Erro := 's'; end; if Erro = 's' then begin Data := ''; messageDlg('Data inconsistente!!!',mtError, [mbOk],0); end;
No evento onKeyPress do Edit1 inserido cdigos para que possa controlar os caracteres digitados:
13
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin if not (Key = Chr(vk_Back)) then // Este if habilita a tecla Backspace para correo do objeto if not (Key in ['0'..'9','/']) then // Este if permite a digitao somente de nmeros e da barra / abort; end;
14
var voice: OLEVariant; begin voice := CreateOLEObject('SAPI.SpVoice'); voice.Rate := 0; voice.Volume := 100; voice.Speak('Ramos da Informtica',0); voice := unassigned; end;
uses MMSystem; TYourObject = class(TAnyControl) ... private procedure CMMouseEnter(var AMsg: TMessage); message CM_MOUSEENTER; procedure CMMouseLeave(var AMsg: TMessage); message CM_MOUSELEAVE; ... end; implementation procedure TYourObject.CMMouseEnter(var AMsg: TMessage); begin sndPlaySound('c:\win\media\ding.wav',snd_Async or snd_NoDefault); end; procedure TYourObject.CMMouseLeave(var AMsg: TMessage); begin sndPlaySound(nil,snd_Async or snd_NoDefault); end;
begin Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey('Software\\Microsoft\\Internet Explorer', False); try Result := Reg.ReadString('Version'); if (Result='') then Result := Reg.ReadString('IVer'); except Result := ''; end; Reg.CloseKey; finally Reg.Free; end; end; Atravs da verso do IE determina-se qual ActiveX poder ser carregado para fazer OLE com o IE. At a verso 3.0 o componente o TWebBrowser_V1 e a partir do IE 4.0, o componente o TWebBrowser.
17
Onde S = Salrio (No nosso exemplo R$ 290,00 ou R$ 300,00). F= Faixa do Abono (No nosso exemplo R$ 300,00). A1= 1 Abono (Valor mais alto, no nosso exemplo R$ 50,00). A2= 2 Abono (Valor mais baixo, no nosso exemplo R$ 30,00). Result= Retorno da funo com o calculo do novo salrio.
Para executar basta declarar as variveis ou campos do banco de dados exatamente na ordem acima em modo Double.
18
Esta uma funo para calcular de modo progressivo um abono (por exemplo, folha de pagamento) sem cometer injustia. Expl: Digamos que queremos que todos os funcionrios que ganham at R$ 299,99 recebam um abono de R$ 50,00 e acima deste valor um abono de R$ 30,00. Se no aplicarmos a formula o que vai acontecer quem ganha, por exemplo, R$ 290,00 recebera R$ 340,00 (o correto seria ganhar R$ 324,00) passando a ganhar mais de quem ganhava R$ 300,00, pois este ter apenas um abono de R$ 30,00 percebendo R$ 330,00. A funo acima corrige estas distores, e pode ser aplicada num banco de dados para diversas faixas salariais.
function processExists(exeFileName: string): Boolean; var ContinueLoop: BOOL; FSnapshotHandle: THandle; FProcessEntry32: TProcessEntry32; begin FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); FProcessEntry32.dwSize := SizeOf(FProcessEntry32); ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32); Result := False; while Integer(ContinueLoop) <> 0 do begin if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then begin Result := True; end; ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); end; CloseHandle(FSnapshotHandle); end;
// Exemplo: procedure TForm1.Button1Click(Sender: TObject); begin if processExists('calc.exe') then ShowMessage('Processo em execuo') else 19
// Exemplo: procedure TForm1.Button1Click(Sender: TObject); begin if DirectoryIsEmpty('C:\test') then Label1.Caption := 'empty' else Label1.Caption := 'not empty'; end;
20
Memo1: TMemo; OpenDialog1: TOpenDialog; GroupBox1: TGroupBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end;
var Form1: TForm1; implementation uses ComObj; {$R *.dfm} {$TYPEDADDRESS OFF} // preciso dazer esta chamada var PDDoc: Acrobat_TLB.CAcroPDDoc; PDPage: Variant; PDHili: Variant; PDTextS: Variant; acrobat: Variant; Result: Boolean; NTL, i, j, Pagecount: Integer; zeilen: string; stichwortcounter: Integer; Size: Integer; gesamtstring: AnsiString; zwreal: Real; procedure TForm1.Button1Click(Sender: TObject); function removecrlf(workstring: string): string; var i: Integer; begin removecrlf := ''; for i := 0 to Length(workstring) do begin if workstring[i] = #13 then workstring[i] := ' '; if workstring[i] = #10 then
22
workstring[i] := ' '; end; removecrlf := workstring; end; begin if not opendialog1.Execute then Exit; memo1.Clear; gesamtstring := ''; stichwortcounter := 0; Size := 0; try acrobat := CreateOleObject('AcroExch.pdDoc'); //Identifica arquivos PDF atravs do OLE Result := acrobat.Open(opendialog1.FileName);
if Result = False then begin messagedlg('O arquivo no pode ser aberto', mtWarning, [mbOK], 0); Exit; end; for j := 0 to acrobat.GetNumPages - 1 do begin memo1.Lines.Add('----------------------------------------------'); //Primeira pgina do documento ativa PDPage := acrobat.acquirePage(j); PDHili := CreateOleObject('AcroExch.HiliteList'); Result := PDHili.Add(0, 4096); //Marca sobre o texto PDTextS := PDPage.CreatePageHilite(PDHili); ntl := PDTextS.GetNumText; for i := 0 to ntl - 1 do begin zeilen := PDTextS.GetText(i); if (Length(zeilen) > 0) and (zeilen <> '') then memo1.Lines.Add(removecrlf(zeilen)); gesamtstring := gesamtstring + removecrlf(zeilen); //Apenas para estatstica Size := Size + SizeOf(zeilen); Inc(stichwortcounter);
23
Application.ProcessMessages; end; //Depois libera pdhili := Unassigned; pdtextS := Unassigned; pdpage := Unassigned; label2.Caption := IntToStr(stichwortcounter); label4.Caption := IntToStr(Size); label2.Refresh; label4.Refresh; end;
except on e: Exception do begin messagedlg('Erro: ' + e.Message, mtError, [mbOK], 0); Exit; end; end; if Size > 1024 then begin zwreal := Size / 1024; str(zwreal: 2: 1,zeilen); label4.Caption := zeilen; label5.Caption := 'KB'; end; memo1.Lines.SaveToFile(Extractfilepath(Application.exename) + '\debug.txt'); end; end.
Deixando seu EXE mais enxuto e rpido e, mais seguro contra decompilao
Geralmente, arquivos EXE criados com Delphi so maiores que os criados com outras linguagens de programao. O motivo disso so as VCL (Claro que VCL tem muitas vantagens e devem ser usadas). Porm, possvel deixar os executveis menores e, consequentemente, mais rpidos de serem abertos, fcil de distribuio pela Web (mesmo na era da banda larga), fica mais difcil de piratas de cdigos abrir seus softwares, etc. Ento apresento aqui, 10 passos (ou dicas) para deixar seu executvel mais enxuto: 01) Use um EXE-Packer (UPX, ASPack,...) 02) Use o KOL.
24
03) O que puder ser desenvolvido sem o uso de VCL deve ser feito, pois quanto maior a quantidade de VCLs, maior ser o executvel, mas as VCL devem ser usadas, ok. 04) Use a ACL (API Controls Library) 05) Use StripReloc. 06) Desative a opo remote debugging information e TD32 do Delphi. 07) You might want to put code in a dll. 08) No coloque imagens em Formulrios. De preferncia, leia em tempo de execuo. 09) Use imagens compactas, como por exemplo JPG ao invs de BMP. ****************************************************** 01) UPX um software freeware, Compactao de alto desempenho em linha de comando (sem interface grfica). Em testes, alguns arquivos chegaram a ficar com apenas 22% de seu tamanho original. A descompresso tambm muito veloz: mais de 10 MB por segundo em um pentium 133. http://upx.sourceforge.net/ ASPack um Compressor de arquivos executveis Win32, capaz de reduzir o tamanho de programas Windows 32-bit em mais de 70% (bem melhor que o padro industrial ZIP, que fica em torno de 10 a 20%). Torna menores os programas e suas bibliotecas, diminuindo o tempo de transferncia atravs de rede e o tempo de download a partir da Internet. Tambm protege os programas contra engenharia reversa por hackers no profissionais. Os programas comprimidos pelo ASPack rodam da mesma maneira que rodavam antes, sem perda de performance do tempo de execuo.
http://www.aspack.com/aspack.htm {****************************************************************} 02) KOL - Key Objects Library um conjunto de objetos para desenvolvimento de poderosas aplicaes Windows 32 bit GUI usando Delphi sem o uso de VCL. distribudo livremente e com o cdigo fonte http://bonanzas.rinet.ru/ {****************************************************************} 03) nonVCL Delphi possibilita muitos caminhos. Se voc quer um executvel pequeno, ento no uso a VCL. Isso possvel usando 100% chamadas APIs, standards resources, etc. Alguns sites que podem ajudar: http://nonvcl.luckie-online.de http://www.erm.tu-cottbus.de/delphi/stuff/Tutorials/nonVCL/index.html http://www.angelfire.com/hi5/delphizeus/ http://www.tutorials.delphi-source.de/nonvcl/
25
{****************************************************************} 04) ACL (API Controls Library) Voc tambm pode usar a ACL, o que facilita o uso de APIs, para mais informaes visite este site: http://www.apress.ru/pages/bokovikov/delphi/index.html/ {****************************************************************} 05) StripReloc Este programa remove a seo de recolocao (".reloc") dos executvies Win32 PE, reduzindo o tamanho deles. A maioria do compiladores/linkeditores (inclusive o do Delphi) insere esta seo no executvel e uma seo que nunca ser usada e no tem outra finalidade seno desperdiar espao na memria e em disco. http://www.jrsoftware.org/striprlc.php {****************************************************************} 06) Desativando o Debug Information Exclusa qualquer informao de debug no final indo ao menu do Delphi Project / Pptions Compiler - Debugging e Project / Options: Linker EXE e DLL options. {****************************************************************} 08 e 09) Sobre imagens Formulrios com muitas imagens anexadas so criadas junto ao executvel, deixando ele muito grande e sempre que executado o tamanho original multiplicado, o que torna invivel. O melhor anexar as imagens e enviar junto ao executvel pois assim no h esta multiplicao. Use arquivos JPEG ao invs de BMP. Isso ajuda a reduzir o tamanho do EXE. {****************************************************************} Essas so apenas algums dicas, no preciso fazer todas elas, mas caso precise...
var SearchRec: TSearchRec; details, nodetails: TStringList; k: Integer; begin //Pega direito o diretrio if FindFirst(dir + '*.*', faAnyFile, SearchRec) = 0 then begin repeat if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then begin //Se acharmos a pasta if (SearchRec.Attr and faDirectory) = faDirectory then begin //Pega a pasta que contm do FTP. um com detalhes e outro sem details := TStringList.Create; nodetails := TStringList.Create; FTPClient.List(details, '', True); FTPClient.List(nodetails, '', False); for k := details.Count - 1 downto 0 do begin if details.Strings[k] <> '' then begin if (details.Strings[k][1] <> 'd') or (nodetails.Strings[k] = '.') or (nodetails.Strings[k] = '..') then begin details.Delete(k); nodetails.Delete(k); end; end; end; //Se o diretrio no existe no servidor, ento cria if nodetails.IndexOf(SearchRec.Name) = -1 then begin FTPClient.MakeDir(SearchRec.Name); end; //Muda o diretrio no servidor FTPClient.ChangeDir(SearchRec.Name); details.Free; nodetails.Free; //Se achou, vai para o prximo sub-siretrio GetDir(dir + SearchRec.Name + '\'); //Temos que ir a um diretrio a cima
27
FTPClient.ChangeDirUp; end else begin //Se apenas um arquivo, upload o diretrio atual FTPClient.Put(dir + SearchRec.Name, SearchRec.Name); end; end; until FindNext(SearchRec) <> 0; FindClose(SearchRec); end; end; var dir: string; details, nodetails: TStringList; k: Integer; begin //Seta as configuraes para acesso ao servidor de FTP(TIdFTPClient) with FTPClient do begin Host := 'your_server.com'; // Coloque host Username := 'your_username'; // Colque senha Password := 'your_password'; // Adjust your data here Passive := True; end; FTPClient.Connect; //Se for de um computador remoto, ou na rede, faa isso dir := StringReplace('your/remote_directory', '\', '/', [rfReplaceAll]); if dir <> '' then begin if dir[1] = '/' then Delete(dir, 1, 1); if dir[Length(dir)] <> '/' then dir := dir + '/'; while Pos('/', dir) > 0 do begin details := TStringList.Create; nodetails := TStringList.Create; FTPClient.List(details, '', True); FTPClient.List(nodetails, '', False); for k := details.Count - 1 downto 0 do begin if details.Strings[k] <> '' then begin if (details.Strings[k][1] <> 'd') or
28
(nodetails.Strings[k] = '.') or (nodetails.Strings[k] = '..') then begin details.Delete(k); nodetails.Delete(k); end; end; end; if nodetails.IndexOf(Copy(dir, 1, Pos('/', dir) - 1)) = -1 then begin FTPClient.MakeDir(Copy(dir, 1, Pos('/', dir) - 1)); end; FTPClient.ChangeDir(Copy(dir, 1, Pos('/', dir) - 1)); Delete(dir, 1, Pos('/', dir)); details.Free; nodetails.Free; end; end; dir := 'C:\your\local\directory\'; if dir[Length(dir)] <> '\' then dir := dir + '\'; GetDir(dir); FTPClient.Disconnect; end;
29
Antes de se iniciar a leitura do arquivo, precisamos associar a variavel TextFile com um arquivo fisicamente armazenado no disco: AssignFile ( arq, 'C:\AUTOEXEC.BAT' ); Reset ( arq ); A rotina AssignFile faz a associao enquanto Reset abre efetivamente o arquivo para leitura. AssignFile corresponde Assign do Turbo Pascal. Em seguida necessrio fazer uma leitura ao arquivo, para isto utilizaremos a procedure ReadLn: ReadLn ( arq, linha ); O comando acima l apenas uma linha de cada vez, assim precisamos de um loop para efetuar vrias leituras at que o arquivo acabe. Para verificar o fim do arquivo, utilizaremos a funo Eof: while not Eof ( arq ) do Agora uma rotina quase completa para fazer a leitura de um arquivo texto. Esta rotina recebe como parmetro o nome do arquivo que ser lido: procedure percorreArquivoTexto ( nomeDoArquivo: String ); var arq: TextFile; linha: String; begin AssignFile ( arq, nomeDoArquivo ); Reset ( arq ); ReadLn ( arq, linha ); while not Eof ( arq ) do begin { Processe a linha lida aqui. } { Para particionar a linha lida em pedaos, use a funo Copy. } ReadLn ( arq, linha ); end; CloseFile ( arq ); end; E tambm uma rotina quase completa para gravao de um arquivo texto. Esta rotina recebe como parmetro o nome do arquivo que ser gravado e uma tabela (TTable) de onde os dados sero lidos: procedure gravaArquivoTexto ( nomeDoArquivo: String; tabela: TTable ); var arq: TextFile; linha: String; begin AssignFile ( arq, nomeDoArquivo ); Rewrite ( arq ); tabela.First; while not tabela.Eof do begin Write ( arq, AjustaStr ( tabela.FieldByName ( 'Nome' ).AsString, 30 ) ); Write ( arq, FormatFloat ( '00000000.00', tabela.FieldByName ( 'Salario' ).AsFloat ) );
30
WriteLn ( arq ); tabela.Next; end; CloseFile ( arq ); end; Note nesta segunda rotina, a substituio de Reset por Rewrite logo aps o AssignFile. Rewrite abre o arquivo para escrita, destruindo tudo que houver l anteriormente . Note tambm o uso de Write e WriteLn para gravar dados no arquivo texto. Finalmente note o uso de AjustaStr e FormatFloat para garantir que campos string e numericos sejam gravados com um nmero fixo de caracteres. FormatFloat uma rotina do prprio Delphi enquanto AjustaStr est definida abaixo: function AjustaStr ( str: String; tam: Integer ): String; begin while Length ( str ) < tam do str := str + ' '; if Length ( str ) > tam then str := Copy ( str, 1, tam ); Result := str; end; O uso da funo AjustaStr fundamental quando voc estiver gravando arquivos texto com registros de tamanho fixo a partir de bases de dados Paradox que usualmente no preenchem campos string com espaos no final.
31
ConnectionName := 'VCLScanner'; DriverName := 'INTERBASE'; LibraryName := 'dbexpint.dll'; VendorLib := 'GDS32.DLL'; GetDriverFunc := 'getSQLDriverINTERBASE'; Params.Add('User_Name=SYSDBA'); Params.Add('Password=masterkey'); Params.Add('Database=milo2:D:\ramosinfo\webservices\umlbank.gdb'); LoginPrompt := False; Open; end; DataSet := TSQLDataSet.Create(nil); with DataSet do begin SQLConnection := Connection; CommandText := Format('INSERT INTO kings VALUES("%s","%s","%s")', [Email, FirstN, LastN]); try ExecSQL; except end; end; Connection.Close; DataSet.Free; Connection.Free; end;
32
function GetSelectedIEtext: string; var x: Integer; Sw: IShellWindows; IE: HWND; begin IE := FindWindow('IEFrame', nil); sw := CoShellWindows.Create; for x := SW.Count - 1 downto 0 do if (Sw.Item(x) as IWebbrowser2).hwnd = IE then begin Result := variant(Sw.Item(x)).Document.Selection.createRange.Text; break; end; end;
33
repeat if hat + (maxy div 24) >= maxy then begin hat := maxy end else begin hat := hat + (maxy div 24); end; if hal + (maxx div 24) >= maxx then begin hal := maxx end else begin hal := hal + (maxx div 24); end; hak := (Sender as TForm).Left + ((Sender as TForm).Width div 2) - (hal div 2); haa := (Sender as TForm).Top + ((Sender as TForm).Height div 2) - (hat div 2); MyCanvas.Rectangle(hak, haa, hak + hal, haa + hat); delay(10); until (hal = maxx) and (hat = maxy); (Sender as TForm).Show; end;
procedure TForm1.Button1Click(Sender: TObject); begin animin(form2); end; procedure TForm1.Button2Click(Sender: TObject); begin animin(form3); end;
34
TSetLayeredWindowAttributes = function(hwnd: HWND; crKey: COLORREF; bAlp ha: Byte; dwFlags: Longint): Longint; stdcall; const // Use crKey para definir a cor como transparente LWA_COLORKEY = 1; // Use bAlpha para determinar a opacidade do layer do windows LWA_ALPHA = 2; WS_EX_LAYERED = $80000; var hUser32: HMODULE; SetLayeredWindowAttributes: TSetLayeredWindowAttributes; i : Integer; begin Result := False; // imnportante usarmos a DLL USER32.DLL e distribuir na aplicao. hUser32 := GetModuleHandle('USER32.DLL'); if hUser32 <> 0 then begin @SetLayeredWindowAttributes := GetProcAddress(hUser32,'SetLayeredWindowAtt ributes'); if @SetLayeredWindowAttributes <> nil then begin SetWindowLong(Wnd, GWL_EXSTYLE, GetWindowLong(Wnd, GWL_EXST YLE) or WS_EX_LAYERED); SetLayeredWindowAttributes(Wnd, 0, Trunc((255 / 100) * (100 nAlpha)), LWA_ALPHA); Result := True; end; end; end; // hook procedure function HookCallWndProc(nCode: Integer; wParam, lParam: Longint): Longint; stdca ll; const MENU_CLASS = '#32768'; N_ALPHA = 60; var cwps: TCWPStruct; lRet: THandle; szClass: array[0..8] of char; begin if (nCode = HC_ACTION) then begin CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT)); case cwps.message of WM_CREATE: begin GetClassName(cwps.hwnd, szClass, Length(szClass)-1);
35
// Window name for menu is #32768 if (lstrcmpi(szClass, MENU_CLASS) = 0) then begin MakeWndTrans(cwps.hwnd, N_ALPHA {Alphablending}); end; end; end; end; Result := CallNextHookEx(WH_CALLWNDPROC, nCode, wParam, lParam); end; // Coloque no evento OnCreate do form procedure TForm1.FormCreate(Sender: TObject); var tpid: DWORD; begin tpid := GetWindowThreadProcessId(Handle, nil); hHookID := SetWindowsHookEx(WH_CALLWNDPROC, HookCallWndProc, 0, tpi d); end; // Pare o processo no evento OnDestroy procedure TForm1.FormDestroy(Sender: TObject); begin if (hHookID <> 0) then // Remove o menu transparente UnhookWindowsHookEx(hHookID); end;
36
begin if DirectoryIsEmpty('C:\test') then Label1.Caption := 'empty' else Label1.Caption := 'not empty'; end;
37
38
2.) V em Project + Import Type Library. 3.) Selecione Acrobat Control para ActveX..... + install ........... 4.) Aparcer uma tela, clique em compilar...... 5.) V depois na palheta ActiveX e escolha o componente PDF 6.) Faa as devidos ajuste e digite no button: if opendialog1.execute then pdf1.src:=opendialog1.filename;
40
strDriver, strAttributes, NewLine : String; begin // if it is not auto configuration, setting HWND of wizard let show // DSN setup dialog with attributes specified if not showdlg then hwnd := 0 else hwnd := StrToInt(ExpandConstant('{wizardhwnd}')); // MYSQL Sample { strDriver := 'MySQL'; NewLine := Chr(0); strAttributes := 'SERVER=localhost' + NewLine + 'DESCRIPTION=MySQL Driver DSN' + NewLine + 'DSN=SAMPLE_DSN' + NewLine + 'DATABASE=test' + NewLine + 'UID=username' + NewLine + 'PASSWORD=password' + NewLine + 'PORT=3306' + NewLine + 'OPTION=3' + NewLine; } Result := SQLConfigDataSource( hwnd, ODBC_ADD_SYS_DSN, strDriver, strAttributes); end;
function NextButtonClick(CurPage: Integer): Boolean; var showdlg : Boolean; begin // by default go to next page Result := true; // if curpage is wpSelectTasks check config DSN if CurPage = wpSelectTasks then begin showdlg := ShouldProcessEntry( '','cfgdsndlg') = srYes ; if CreateDSN( showdlg ) = 0 then MsgBox( 'DSN not done.', mbError, MB_OK ) else MsgBox( 'DSN Created !', mbInformation, MB_OK ); end; end;
41
esta senha, ser possvel chamar este programa passando-a como parmetro. Neste caso sua "trava" estar violada.
43
5: // Win2K, XP case Win32MinorVersion of 0: Result := Windows 2000; 1: Result := Windows XP or .NET server; else Result := SO desconhecido; end; else Result := SO desconhecido; end; end; // Chamada: { mostrar em um label } OSVersion.Caption := GetWinVersion;
AW_CENTER : Makes the window appear to collapse inward AW_HOR_POSITIVE : Animates the window from left to right. AW_HOR_NEGATIVE : Animates the window from right to left AW_VER_POSITIVE : Animates the window from top to bottom AW_VER_NEGATIVE : Animates the window from bottom to top } end;
API do Windows - Funo para excluir uma pasta e todos arquivos desta pasta
implementation uses ShellApi; {$R *.dfm} procedure DeleteDir(hHandle: THandle; Const sPath : String; Confirm: boolean); var OpStruc: TSHFileOpStruct; FromBuffer, ToBuffer: Array[0..128] of Char; begin FillChar( OpStruc, Sizeof(OpStruc), 0 ); FillChar( FromBuffer, Sizeof (FromBuffer), 0 ); FillChar( ToBuffer, Sizeof(ToBuffer), 0 ); StrPCopy( FromBuffer, sPath); With OpStruc Do Begin Wnd:= hHandle; wFunc:=FO_DELETE; pFrom:= @FromBuffer; pTo:= @ToBuffer; if not confirm then begin fFlags:= FOF_NOCONFIRMATION; end; fAnyOperationsAborted:=False; hNameMappings:=nil; End; ShFileOperation(OpStruc); end; Usando a Funo: procedure TForm1.Button1Click(Sender: TObject); begin DeleteDir(Self.Handle,C:\TESTE,True) 45
end; end.
var PowerPointApp: OLEVariant; begin try PowerPointApp := CreateOleObject('PowerPoint.Application'); except ShowMessage('Error...'); Exit; end; // Torna o Powerpoint visivel PowerPointApp.Visible := True; // Mostra verso do PowerPoint ShowMessage(Format('Powerpoint version: %s',[PowerPointApp.Version])); // Abre uma apresentao PowerPointApp.Presentations.Open('c:\\windows\\desktop\\teste.ppt', False, False, True); // SMostra o nmero de slides ShowMessage(Format('%s slides.',[PowerPointApp.ActivePresentation.Slides.Count])); // Roda a apresentao PowerPointApp.ActivePresentation.SlideShowSettings.Run; // Vai para o prximo slide PowerPointApp.ActivePresentation.SlideShowWindow.View.Next; // Vai para slide 2 PowerPointApp.ActivePresentation.SlideShowWindow.View.GoToSlide(2); // Vai para o slide anterior PowerPointApp.ActivePresentation.SlideShowWindow.View.Previous; // Vai para o ltimo slide PowerPointApp.ActivePresentation.SlideShowWindow.View.Last; // Mostra o nome do Slide corrente ShowMessage(Format('Current slidename: %s',[PowerPointApp.ActivePresentation.SlideShowWindow.View.Slide.Name])); // Fecha o Powerpoint PowerPointApp.Quit; PowerPointApp := UnAssigned; end;
47
[Files] Source: C:\teste.exe; DestDir: {userstartup}; DestName: teste.exe Veja que o segredo est no diretrio de destino da aplicao ou atalho da mesma, o qual dever ser destinado para {userstartup} que representa um path especial que o Windows ir buscar no momento que estiver iniciando.
49
A_POS:=Pos('@', EMail); If (A_POS = 0) or (A_POS < 3) then OK:=False; If Pos('.', Copy(EMail, A_POS, Length(EMail)-A_POS)) = 0 then OK:=False; If OcorrenciasEm('@', EMail) > 1 then OK:=False; If Pos('..', EMail) > 0 then OK:=False; If Pos('@.', EMail) > 0 then OK:=False; If Email[1] = '.' then OK:=False; If Email[Length(EMail)] = '.' then OK:=False; If Length(Email) > 250 then OK:=False; Result:=OK; End;
Memo redondo
Pensando no carnaval, que tal montar o Rei Memo? Veja a rotina: procedure TForm1.Button1Click(Sender: TObject); procedure MemoRedondo(QueMemo: TMemo); var rect : TRect; rgn : HRGN; begin rect := QueMemo.ClientRect; rgn := CreateRoundRectRgn( rect.Left, rect.top, rect.right, rect.bottom, 20, 20); QueMemo.BorderStyle := bsNone; QueMemo.Perform(EM_GETRECT, 0, lparam(@rect)); InflateRect(rect, -5, -5); QueMemo.Perform(EM_SETRECTNP, 0, lparam(@rect)); SetWindowRgn(QueMemo.Handle, rgn, true); end; Como usar: begin MemoRedondo(Memo1); end;
50
procedure TForm1.Exit1DrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; Selected: Boolean); begin ACanvas.FillRect(ARect); ACanvas.TextOut(ARect.Left+48, ARect.Top, StripHotkey((Sender as TMenuItem).Caption)); ACanvas.Draw(0, 0, Image1.Picture.Graphic); ImageList1.Draw(ACanvas, ARect.Left+30, ARect.Top, (Sender as TMenuItem).ImageIndex); end;
51
end; end;
52
begin Cmb := (Control as TComboBox); with Cmb.Canvas do begin FillRect(Rect); Off := 0; Bmp := TBitmap(ComboBox1.Items.Objects[Index]); if Bmp <> nil then begin BrushCopy(Bounds(Rect.Left+2, Rect.Top+2, Bmp.Width, Bmp.Height), Bmp, Bounds(0, 0, Bmp.Width, Bmp.Height), clOlive); Off := Bmp.Width+8; end; TextOut(Rect.Left + Off, Rect.Top, ComboBox1.Items[Index]); end; end; E, finalmente, no evento "OnMeasureItem" do ComboBox: procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer); begin Height := 20; end; Alguma explicao: O evento "OnDrawItem" o responsvel por "desenhar" cada tem do ComboBox quando clicamos no cone para abr-lo. Simplesmente aproveitamos isto para desenhar a nossa imagem antes do texto. Neste mesmo evento fizemos uma chamada a funo "BrushCopy", onde o ltimo parmetro a cor que deseja que fique transparente. Como eu utilizei imagens que vem com o Delphi, a cor de fundo destas imagens o amarelo escuro (clOlive). Da pra frente testar com imagens diferentes, porm, uma sugesto que todas tenham o mesmo tamanho para que se mantenha um padro dentro do seu ComboBox.
53
Result := FileExists(FileName); End; Function ImportRegistry(FileName:String; ExportKey:String):Boolean; Begin Result := FileExists(FileName); If Result Then Begin ShellExecute(0,nil,'REGEDIT.EXE',PChar('/SC /C '+FileName),nil,sw_hide); End; End; Exemplo: procedure TForm1.Button1Click(Sender: TObject); begin ExportRegistry('c:\\windows\\desktop\\teste.reg','HKEY_CURRENT_USER\\Software\\ Borland'); end;
54
Imagem := TIdAttachment.Create(MessageParts, 'c:\windows\cafezinho.bmp'); // Aqui estou preenchendo o Content-ID Imagem.ExtraHeaders.Values['Content-ID'] := '<minhaimagem>'; Imagem.ContentType := 'image/jpeg'; Desta maneira, a imagem vai na mensagem e aberta sem problemas. Ao executar o programa da postagem, notamos um problema: a mensagem enviada corretamente, com a imagem em anexo, porm o html no gerado corretamente, aparecendo como texto normal. Analisando o cabealho da mensagem, vemos que o content-type da mensagem est como text/plain, mesmo tendo especificado text/html. O que ocorre que a mensagem, quando tem um anexo, transformada em multipart e isso faz que o contedo seja enviado como texto. Uma soluo para isto enviar o texto da mensagem como uma parte de texto, com contedo html. Isto feito criando-se uma varivel do tipo TIdText, que ser preenchida com o texto que queremos. Na realidade, iremos criar duas partes de texto na mensagem: uma normal, no html, que ser mostrada em leitores de e-mail no html, e outra html. Isto feito da seguinte maneira:
// configura para multipart ContentType := 'Multipart/Alternative'; // parte de texto normal idText := TIdText.Create(MessageParts,nil); idText.ContentType := 'text/plain'; idText.Body.Add('Esta parte texto puro e no mostra a imagem'); // parte de texto html idText := TIdText.Create(MessageParts,nil); idText.ContentType := 'text/html'; idText.Body.Text := '<html><body>Esta mensagem html tem '+ 'imagens<br />'+ 'A imagem est como anexo, e no est fora da mensagem:<br />'+ '<img src="cid:MinhaImagem"></body></html>'; // Configura anexos Imagem := TIdAttachment.Create(MessageParts, 'c:\windows\cafezinho.bmp'); Imagem.ExtraHeaders.Values['Content-ID'] := '<minhaimagem>'; Imagem.ContentType := 'image/jpeg'; Desta maneira, temos a mensagem com anexos formatada corretamente, podendo ser vista tanto em leitores texto como html.
55
{$R *.dfm}
procedure ShowBalloonTip(Window : HWnd; Texto, Titulo : PWideChar;Tipo : Integer); var EditBalloonTip : TEditBalloonTip; begin EditBalloonTip.cbStruct := SizeOf(TEditBalloonTip); EditBalloonTip.pszText := Texto; EditBalloonTip.pszTitle := Titulo; EditBalloonTip.ttiIcon := Tipo; SendMessageW(Window, EM_SHOWBALLOONTIP, 0, Integer(@EditBalloonTip)); end; procedure HideBalloonTip(Window : HWnd); begin SendMessageW(Window, EM_HIDEBALLOONTIP, 0, 0) end; procedure TForm1.Button1Click(Sender: TObject); begin ShowBalloonTip(Edit1.Handle,'Texto a ser mostrado', 'Ttulo da janela',TTI_INFO); end; procedure TForm1.Button2Click(Sender: TObject); begin HideBalloonTip(Edit1.Handle); end; Nota: Esta dica s funciona com os estilos do XP ativados. Assim, voc precisa colocar um componente TXpManifest na sua Form.
57
else begin CheckListBox1.Canvas.Font.Color := clBlack; CheckListBox1.Canvas.Brush.Color := clWhite; end; end; CheckListBox1.Canvas.TextOut(Rect.Left+2,Rect.Top,CheckListBox1.Items.Strings[In dex]);
SelStart := nPos; SelLength := Length(Edit1.Text); { Pega a quantidade de linhas que separa a ltima linha para essa nova linha posicionada } Linha := Perform(EM_LINEFROMCHAR, SelStart, 0)-Linha; { Visualiza a nova linha } Perform(EM_LINESCROLL, Linha, Linha); end; end;
59
sw_shownormal);
Result := TimerLo / (1000.0 * DelayTime); end; procedure TForm1.Timer1Timer(Sender: TObject); var CPUSpeed: Double; begin CPUSpeed := GetCPUSpeed; Label1.Caption := FormatFloat('0.00 MHz', CPUSpeed); end;
61
Type TInfo = Record Nome : String; End; PInfo = ^TInfo; //============================================================= ================= // Coloca itens na lista //============================================================= ================= Procedure PushItem(List:TList; Nome:String); Var Info : PInfo; Begin New(Info); Info.Nome := Nome; List.Add(Info); End; //============================================================= ================= // Retira o ultimo item da lista //============================================================= ================= Procedure PopItem(List:TList; Var Nome:String); Begin If List.Count>0 then Begin Nome := PInfo(List[List.Count-1]).Nome; Dispose(PInfo(List[List.Count-1])); List.Delete(List.Count-1); End Else Begin Nome := ''; End; End; //============================================================= ================= // Retorna um item a partir de sua posicao //============================================================= ================= Procedure GetItem(List:TList; Var Info:PInfo; RecordNumber:Integer); Begin Info := PInfo(List[RecordNumber]); End; //============================================================= ================= // Cria o objeto de lista //============================================================= =================
62
Procedure CreateList(Var List:TList); Begin If not Assigned(List) then List := TList.Create Else List.Clear; End; //============================================================= ================= // Destroi a lista e remove os ponteiros //============================================================= ================= Procedure DestroyList(List:TList); Var I : Integer; Begin for i := 0 to List.Count-1 do Dispose(PInfo(List[i])); List.Free; End; //============================================================= ================= // Exemplo de Uso da lista //============================================================= ================= procedure TForm1.Button1Click(Sender: TObject); Var List : TList; i : Integer; Info : PInfo; Nome : String; begin CreateList(List); // Empilha itens PushItem(List,'Adenilton'); PushItem(List,'Ana'); PushItem(List,'Roberto'); PushItem(List,'Marta'); PushItem(List,'Silvia'); PushItem(List,'Pedro'); // Remove itens comecando pelo ultimo inserido PopItem(List,Nome); ShowMessage('Retirando '+Nome+' da lista '); PopItem(List,Nome); ShowMessage('Retirando '+Nome+' da lista '); PopItem(List,Nome); ShowMessage('Retirando '+Nome+' da lista ');
63
PushItem(List,'Carlos'); // Mostra os demais Itens de baixo para cima for i := List.Count-1 downto 0 do Begin GetItem(List,Info,i); ShowMessage(Info.Nome); End; // Destroi a lista DestroyList(List); end;
64
'Incompatvel','Erro',MB_OK+MB_ICONEXCLAMATION); end; Consulta.First; try for linha:=0 to Consulta.RecordCount-1 do begin for coluna:=1 to Consulta.FieldCount do // eliminei a coluna 0 da relao do Excel begin valor:= Consulta.Fields[coluna-1].AsString; excel.cells [linha+2,coluna]:=valor; end; Consulta.Next; end; for coluna:=1 to Consulta.FieldCount do // eliminei a coluna 0 da relao do Excel begin valor:= Consulta.Fields[coluna-1].DisplayLabel; excel.cells[1,coluna]:=valor; end; excel.columns.AutoFit; // esta linha para fazer com que o Excel dimencione as clulas adequadamente. excel.visible:=true; except Application.MessageBox ('Aconteceu um erro desconhecido durante a converso'+ 'da tabela para o Ms-Excel','Erro',MB_OK+MB_ICONEXCLAMATION); end; end;
65
{Procedure que altera a cor} procedure TForm1.ColorControl(Sender: TObject); begin if Screen.ActiveControl is TForm then Exit; if (ControlaCor.Objeto = Nil) or (not TComboBox(ControlaCor.Objeto).Showing) then begin ControlaCor.Objeto := Screen.ActiveControl; ControlaCor.Cor := TComboBox(Screen.ActiveControl).Color; end; With Screen.ActiveForm do begin TComboBox(ControlaCor.Objeto).Color := ControlaCor.Cor; ControlaCor.Objeto := Screen.ActiveControl; ControlaCor.Cor := TComboBox(Screen.ActiveControl).Color; TComboBox(Screen.ActiveControl).Color := clInfoBk end; end; 66
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Screen.OnActiveControlChange := Nil; end;
Table1Name := TStringField.Create(Table1); Table1Name.FieldName := 'Name'; Table1Name.DataSet := Table1; Table1Name.FieldKind := fkData; Table1Name.Size := 24; Table1Capital := TStringField.Create(Table1); Table1Capital.FieldName := 'Capital'; Table1Capital.DataSet := Table1; Table1Capital.FieldKind := fkData; Table1Capital.Size := 24; Table1Continent := TStringField.Create(Table1); Table1Continent.FieldName := 'Continent'; Table1Continent.DataSet := Table1; Table1Continent.FieldKind := fkData; Table1Continent.Size := 24; Table1Area := TFloatField.Create(Table1); Table1Area.FieldName := 'Area'; Table1Area.DataSet := Table1; Table1Population := TFloatField.Create(Table1); Table1Population.FieldName:= 'Population'; Table1Population.DataSet := Table1; Table1.Open; end; { Aqui destruimos todos os objetos Fields criados } procedure TForm1.Button2Click(Sender: TObject); begin Table1.Close; Button1.Enabled := True; Button2.Enabled := False; Table1Name.Free; Table1Capital.Free; Table1Continent.Free; Table1Area.Free; Table1Population.Free; Table1.Open; end; { Um simples exemplo de como configurar a mscara via programao } procedure TForm1.Button3Click(Sender: TObject); begin try Table1.Close; Table1Area.DisplayFormat := '###,###,##0'; Table1Population.DisplayFormat := '###,###,##0';
68
ListBox - Colorir
procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); begin if StrToInt(ListBox1.Items[Index]) > 5 then begin ListBox1.Canvas.Font.Color := clBlue; ListBox1.Canvas.Font.Style := [fsBold]; ListBox1.Canvas.Brush.Color := clYellow; end; ListBox1.Canvas.FillRect(Rect); ListBox1.Canvas.TextOut(Rect.Left, Rect.Top, Listbox1.Items[Index]); end; *** Alterar a propriedade Style para onDrawVariable
procedure CriaAssociacao(const NomeDoc, NomeApp, NomeEXE, NomeIcone, Ext: string); begin CriaChave(NomeDoc, , NomeApp); 69
procedure TForm1.Button1Click(Sender: TObject); begin Button1.Enabled := false; Try // EdDoc.Text = Nome do arquivo Exemplo: Doc01 // EdNome.Text = Nome do programa Exemplo:NotePad // EdExe.Text = Executvel Exemplo: // c:\windows\notepad.exe %1 // EdIcone.Text = cone Exemplo: // c:\windows\notepad.exe // EdExt.Text = Extenso Exemplo: .xxx // CriaAssociacao(EdDoc.Text, EdNome.Text, // EdEXE.Text, EdIcone.Text, EdExt.Text); finally Button1.Enabled := true; end; end;
70
Reg.CloseKey; Reg.Free; end; end; { evento OnClick do TButton } procedure TForm1.Button1Click(Sender: TObject); var Reg: TRegistry; sKey : String; begin if ListBox1.ItemIndex = -1 then Exit; Reg := TRegistry.Create; try Reg.RootKey := HKEY_CURRENT_USER; sKey := \Software\Microsoft\Internet Account Manager\Accounts\; sKey := sKey + ListBox1.Items[ListBox1.ItemIndex]; Reg.OpenKey(sKey, False); if Reg.ValueExists(SMTP Server) then ShowMessage( O SMTP da conta selecionada :+#13+ Reg.ReadString(SMTP Server) ) else ShowMessage(SMTP no existe para esta conta); finally Reg.CloseKey; Reg.Free; end; end;
HKEY, Registry
implementation uses registry;
{ Atribui um informacao para o Registry } procedure TForm1.BitBtn2Click(Sender: TObject); Var Reg : TRegistry; begin Reg := Tregistry.Create; With TRegistry.Create do begin RootKey:= HKEY_USERS; OpenKey(RamosInformatica\curso\teste', True); WriteString('Teste_Reg1','Teste Teste'); Free; end;
71
end; { Recupera um valor do Registry } procedure TForm1.BitBtn7Click(Sender: TObject); Var Reg : TRegistry; Value : string; begin Reg := Tregistry.Create; With TRegistry.Create do begin RootKey:= HKEY_USERS; OpenKey('Ramosinformatica\curso\teste', True); Caption := ReadString('Teste_Reg1'); Free; end; end;
//L informaes da Empresa cadastrado na mquina procedure TForm1.Button1Click(Sender: TObject); var Info: TRegDataInfo; Reg: TRegistry; begin Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE;
72
if not Reg.OpenKey('\SOFTWARE\Microsoft\Windows\CurrentVersion', FALSE) then Reg.GetDataInfo('RegisteredOrganization', Info); Label1.Caption := 'Empresa...: ' + Reg.ReadString('RegisteredOrganization'); Label2.Caption := 'Usuario...: ' + Reg.ReadString('RegisteredOwner'); end;
procedure TForm1.Button1Click(Sender: TObject); var Reg: TRegistry; begin Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey('\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\', False); if Reg.ValueExists('DSQUERY') then Showmessage('Existe!'); end;
procedure TForm1.FormCreate(Sender: TObject); begin // Atribui os nomes ao ComboBox ComboBox1.Items.ADD('Letter'); ComboBox1.Items.ADD('Custom'); ComboBox1.Items.ADD('A4'); end;
procedure TForm1.Edit1Change(Sender: TObject); var S: Array[0 ..255] of char; begin StrPCopy(S, Edit1.Text); with ListBox1 do ItemIndex := Perform(LB_SELECTSTRING, 0, LongInt(@S)); if (ListBox1.ItemIndex < 0) or (ListBox1.Items[ListBox1.ItemIndex] <> Edit1.Text) then ListBox1.ItemIndex := -1; end;
75
DBGrid1.Columns[i].Title.Font.Color := clBlack; DBGrid1.Columns[i].Title.Font.Style := []; end; Column.Title.color := ClYellow; Column.Title.Font.Style := [ fsBold, fsItalic]; Column.Title.Font.Color := clRed; end;
76
// To add auto-complete capability to a TEdit component // 1) Declare a global TStringlist object // 2) Create it on the form create event // 3) Free it on the form destroy event // 4) Add new entry to it on the TEdit exit event // 5) Do the auto-complete on the TEdit keyUp event // 6) Add a TCheckbox control for enable/disable // If desired, initialize the list from a database, ini file etc. procedure TForm1.FormCreate(Sender: TObject); begin listValues := TStringList.create; listValues.sorted := true; listValues.Duplicates := dupIgnore; end; procedure TForm1.FormDestroy(Sender: TObject); begin listValues.free; end; procedure TForm1.edtListExit(Sender: TObject); begin listValues.add(edtList.text); end; procedure TForm1.edtListKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); var theText: string; i, p: integer; begin if not ckbxList.checked then exit; // User can enable/disable with edtList do case key of 8, 13, 46, 37..40: ; // No backspace, enter, delete, or arrows else begin // Search for unselected portion at start of text p := selStart; // cursor position theText := copy(text, 0, p); // Excludes searched portion // Match entered text portion for i := 0 to listValues.count-1 do begin // Keep case of listed item if pos(upperCase(theText), upperCase(listValues[i]))=1 then if compareText(theText, listValues[i]) < 0 then begin text := listValues[i]; selStart := p;
77
SelLength := length(text) - selStart; break; // Match found, so quit search end; end; // for end; // case end; // with end;
procedure TForm1.CheckBox1Click(Sender: TObject); begin ShowMessage('Aqui'); end; procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.Cells[0,0] := 'Uma Maneira'; StringGrid1.Cells[1,0] := 'Simples'; StringGrid1.Cells[2,0] := 'Para'; StringGrid1.Cells[3,0] := 'Fazer'; StringGrid1.Cells[4,0] := 'Marcar'; AdicionarCheckBoxes; //rotina que adiciona os Check end; procedure TForm1.AdicionarCheckBoxes; var i: Integer; NovoCheckBox: TCheckBox; begin limpaBuffer; // bom no esquecer de limpar controles no utilizados for i := 1 to 4 do begin StringGrid1.Cells[0,i] := 'a'; StringGrid1.Cells[1,i] := 'b'; StringGrid1.Cells[2,i] := 'c'; StringGrid1.Cells[3,i] := 'd'; NovoCheckBox := TCheckBox.Create(Application); NovoCheckBox.Width := 0; NovoCheckBox.Visible := false; NovoCheckBox.Caption := 'OK'; NovoCheckBox.Color := clWindow;
78
NovoCheckBox.Tag := i; NovoCheckBox.OnClick := CheckBox1.OnClick; //Associar um evento OnClick j existente para o Novo CheckBox NovoCheckBox.Parent := Panel1; StringGrid1.Objects[4,i] := NovoCheckBox; StringGrid1.RowCount := i; end; AlinhaCheck; // agora vamos alinhar o check na celular end; Procedure TForm1.Limpabuffer; var NovoCheckBox: TCheckBox; i: Integer; begin for i := 1 to StringGrid1.RowCount do begin NovoCheckBox := (StringGrid1.Objects[4,i] as TCheckBox); if NovoCheckBox <> nil then // o objeto deve existir para poder ser destrudo begin NovoCheckBox.Visible := false; StringGrid1.Objects[4,i] := nil; end; end; end; Procedure TForm1.AlinhaCheck; var NovoCheckBox: TCheckBox; Rect: TRect; i: Integer; begin for i := 1 to StringGrid1.RowCount do begin NovoCheckBox := (StringGrid1.Objects[4,i] as TCheckBox); if NovoCheckBox <> nil then begin Rect := StringGrid1.CellRect(4,i); // aqui descobrimos a posio da celula para utilizarmos no check NovoCheckBox.Left := StringGrid1.Left + Rect.Left+2; NovoCheckBox.Top := StringGrid1.Top + Rect.Top+2; NovoCheckBox.Width := Rect.Right - Rect.Left; NovoCheckBox.Height := Rect.Bottom - Rect.Top; NovoCheckBox.Visible := True; end; end; end; procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);
79
80
end; end;
81
ARQUIVO: teste.dfm ------------------------------------------------------object frm: tfrm width = 350 height = 290 caption = 'programa teste' object button1: tbutton caption = 'Clique' left = 20 top = 20 width = 100 height = 30 onclick = button1click end end ------------------------------------------------------Pense no arquivo .dfm como se fosse a janela de propriedades do objeto. Caso voc queira alterar cor, alinhamento, etc, etc e etc, s colocar no .dfm. Para compilar, simplesmente digite na linha do prompt : dcc32 teste Pronto. Voc ter, no mesmo diretrio, um arquivo chamado teste.exe, que nada mais que o seu projeto compilado.
82
Como colocar um codigo para que a aplicacao feche apos XX segundos sem atividades no teclado ou sem cliques do mouse.
Ol Ramos, enviei uma duvida no forum do Ramos e nao esperava ter tido tanta discussao, mas depois que consegui a resposta ninguem mais comentou sobre o assunto. De qualquer forma apesar de ter postado no forum a resposta que recebi de outro camarada, abaixo segue de novo um exemplo de como colocar um codigo para que a aplicacao feche apos XX segundos sem atividades no teclado ou sem cliques do mouse. Este codigo deve ser colocado no Form principal e fazer os devidos ajustes. Nao esquecer de colocar o timer. Esta dica foi enviada por Cristiano Menusi- Oeste - SC e ele tambem havia encontrado na Net
83
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); private procedure AppIdle(Sender: TObject; var Done: Boolean); procedure AppMessage(var Msg: TMsg; var Handled: Boolean); public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} { TForm1 } procedure TForm1.AppIdle(Sender: TObject; var Done: Boolean); begin Timer1.Enabled := True; end; procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean); begin Case Msg.message of WM_LBUTTONDOWN,WM_RBUTTONDOWN,WM_KEYDOWN :Timer1.Enabled := False; end; end; procedure TForm1.FormCreate(Sender: TObject); begin Application.OnMessage := AppMessage; Application.OnIdle := AppIdle; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Application.Terminate; end;
84
Pega todos os erros do Sistema, captura tela do erro, grava em arquivo e envia por e-mail
Como montar uma rotina para pegar todos os erros do sistema e capturar tela do erro e gravar em arquivo para futura inspecao ou envio por e-mail. Coloque esta rotina no menu principal de seu sistema. unit Form_Menu; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, DB, ComCtrls, ExtCtrls, StdCtrls,Buttons, Mask, DBTables, DBIPROCS, DBITypes, DBIErrs, Gauges, ImgList, ToolWin, jpeg, ExtDlgs; type TFrm_Menu = class(TForm) MainMenu1: TMainMenu; PRIVATE { Private declarations } Procedure ManipulaExcecoes(Sender: TObject; E: Exception); public { Public declarations } end; var Frm_Menu: TFrm_Menu; implementation //------------------------------------// //...Rotina de manipulaco de erros // //------------------------------------//
85
Procedure TFrm_Menu.ManipulaExcecoes(Sender: TObject; E: Exception); Var BitMap : TBitmap; Begin //...Captura e salva a tela atual do erro. BitMap := TBitmap.Create; BitMap := CaptureScreenRect(Bounds(0,0,Screen.Width,Screen.Height)); BitMap.SaveToFile(ExtractFilePath(Application.ExeName)+'erro.bmp') ; BitMap.Free; //...Messagem de erro do sistema MessageDlg(E.Message + #13#13 +'Suporte tcnico:'#13 +'aceinfo@starknet.com.br',mtError, [mbOK], 0); end; {$R *.DFM} procedure TFrm_Menu.FormCreate(Sender: TObject); Begin Application.OnException := ManipulaExcecoes; end; End.
86
ShowMessage('Modem Busy'); end; end; procedure TForm1.Button1Click(Sender: TObject); begin ConnectionKind; end;
87
begin // Para trocar as cores dos botoes do RadioGroup for i := 0 to RADIOGROUP1.Items.Count-1 do begin TRadioButton(RADIOGROUP1.Controls[i]).Font.Color := clGreen; TRadioButton(RADIOGROUP1.Controls[i]).Font.Style := [fsBold]; end; TRadioButton(RADIOGROUP1.Controls[RADIOGROUP1.ItemIndex]).Font.Color := clRed; TRadioButton(RADIOGROUP1.Controls[RADIOGROUP1.ItemIndex]).Font.Style := [fsBold]; end;
Criptografando Imagens
procedure cripto(const BMP: TBitmap; Key: Integer); var BytesPorScan: Integer; w, h: integer; p: pByteArray; begin try BytesPorScan := Abs(Integer(BMP.ScanLine[1]) Integer(BMP.ScanLine[0])); except raise Exception.Create('Erro !'); end; RandSeed := Key; for h := 0 to BMP.Height - 1 do begin P := BMP.ScanLine[h]; for w := 0 to BytesPorScan - 1 do 88
P^[w] := P^[w] xor Random(256); end; end; Agora vamos ao evento onclick do Button chamar a nossa procedure cripto, basta digitar o seguinte cdigo: procedure TForm1.Button1Click(Sender: TObject); begin cripto(Image1.Picture.Bitmap, 1); Image1.Refresh; end; Ao chamar a rotina passamos como parmetro o caminho da imagem que no exemplo foi utilizado o componente image e 1 como um valor inteiro para retornamos a imagem normal, logo aps a execuo da nossa procedure atualizamos o image para que ele possa exibir nossa imagem criptografada.
try SetWindowText(Handle, nil); GetWindowRect(Handle, R2); R1.Left := GetSystemMetrics(SM_CXSIZE) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFRAME); R1.Top := GetSystemMetrics(SM_CYFRAME); R1.Right := R2.Right - R2.Left - R1.Left - 2 * GetSystemMetrics(SM_CXSIZE); R1.Bottom := R1.Top + GetSystemMetrics(SM_CYSIZE); if wParam = 1 then begin SetBkColor(DC, GetSysColor(COLOR_ACTIVECAPTION)); end else begin SetBkColor(DC, GetSysColor(COLOR_INACTIVECAPTION)); end; SetTextColor(DC, GetSysColor(COLOR_CAPTIONTEXT)); if pos = 1 then begin DrawText(DC, Titulo, -1, R1, DT_LEFT or DT_VCENTER); end else begin DrawText(DC, Titulo, -1, R1, DT_RIGHT or DT_VCENTER); end; finally ReleaseDC(Handle, DC); end; end;
90
Edit2: TEdit; Edit3: TEdit; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } procedure MyShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: THintInfo); end; var Form1: TForm1; implementation {$R *.DFM} // Funo que ir alterar a fonte do Hint procedure TForm1.MyShowHint(var HintStr: string; var CanShow: Boolean; var HintInfo: HintInfo); var i : integer; begin for i := 0 to Application.ComponentCount - 1 do if Application.Components[i] is THintWindow then with THintWindow(Application.Components[i]).Canvas do begin Font.Name := 'Arial'; Font.Size := 18; Font.Style := [fsBold]; HintInfo.HintColor := clWhite; end; end; // Evento OnCreate do Form procedure TForm1.FormCreate(Sender: TObject); begin // Ativa a funo que ir alterar o formato do Hint Application.OnShowHint := MyShowHint; end;
91
F:TextFile; Begin AssignFile(f,'c:\qq_arquivo.txt'); Rewrite(f); //abre o arquivo para escrita Writeln(f,'Testando'); escreve no arquivo e desce uma linha Write(f,'Linha de Cdigo - www.linhadecodigo.com.br'); //escreve no arquivo sem descer a linha Closefile(f); //fecha o handle de arquivo End; ///Rotina para ler de um arquivo texto: var f:TextFile; linha:String; begin AssignFile(f,'c:\qq_arquivo.txt'); Reset(f); //abre o arquivo para leitura; While not eof(f) do begin Readln(f,linha); //le do arquivo e desce uma linha. O contedo lido transferido para a varivel linha Memo1.lines.add(linha); End; Closefile(f); end;
92
if Win32Plataform = VER_PLATAFORM_WIN32_NT then WinExec('cmd /c netsh interface ip set address "Conexo local" DHCP', SW_SHOWNORMAL) else MessageBox(Handle, 'esse Comando no pode ser rodado fora da plataforma NT', 'NETSH', MB_ICONWARNING); {onde verifico se a plataforma do Programa uma plataforma NT, caso contrrio informo ao usurio que esse comando no pode ser rodado fora de uma plataforma NT. Mudando as Configuraes dos IPs da mquina, menos os DNS: Na mesma aplicao do exemplo acima Ponha outro TButton e no Evento OnClick dele escreva:} if Win32Plataform = VER_PLATAFORM_WIN32_NT then WinExec('cmd /c netsh interface ip set address "Conexo local" static 192.168.10.104 255.255.255.0 192.168.10.1 1', SW_SHOWNORMAL) else MessageBox(Handle, 'esse {Comando no pode ser rodado fora da plataforma NT', 'NETSH', MB_ICONWARNING);
Pronto seu IP, SubnetMask e Gateway foram mudados. Para maiores informaes sobre o NETSH visite o site da Microsoft: Suporte Microsoft.
var lf : TLogFont; tf : TFont; i : integer; begin with Form1.Canvas do begin Font.Name := 'Verdana'; Font.Size := 16; tf := TFont.Create; tf.Assign(Font); GetObject(tf.Handle, sizeof(lf), @lf); lf.lfOrientation := 1000; end; For i:= 50000 Downto 1 do Begin lf.lfEscapement := i; tf.Handle := CreateFontIndirect(lf); Form1.Canvas.Font.Assign(tf); Form1.Canvas.TextOut(200, Height div 2, 'Ramos da Informtica'); //Sleep(10); Este pode cria um Delay na execuo end; tf.Free; end;
94
gridCountry.Canvas.Font.Color := clRed; R := Rect; Format := FmtCentered; { poder utilizar: FmtCentered, FmtLeft, FmtRight } gridCountry.Canvas.FillRect(Rect); DrawText(gridCountry.Canvas.Handle, PChar(Column.Field.AsString), Length Column.Field.AsString), R, Format); end; end;
96
if cdsExemplo.State = dsBrowse then cdsExemplo.Edit; cdsExemploSituacao.AsBoolean := not cdsExemploSituacao.AsBoolean; end; end; procedure TForm1.grdExemploEnter(Sender: TObject); begin { No permite edio na clula do CheckBox } with grdExemplo do begin if SelectedField = cdsExemploSituacao then Options := Options - [dgEditing] else Options := Options + [dgEditing]; end; end; procedure TForm1.cdsExemploNewRecord(DataSet: TDataSet); begin cdsExemploSituacao.AsBoolean := True; end;
X + length(InReplace), ToEnd, []) ; end; end; Screen.Cursor := oldCursor; end; procedure TForm1.Button1Click (Sender: TObject) ; var SearchText, ReplaceText: string; begin SearchText := Pascal; ReplaceText := Delphi; RearchAndReplace(SearchText, ReplaceText) ; end;
98
CtlX := X + Left; CtlY := Y + Top; CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + Width, CtlY + Height); CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR); end; end; end; SetWindowRgn(Handle, FullRgn, True); end; procedure TForm1.UndoTransparent; begin FullRgn := CreateRectRgn(0, 0, Width, Height); CombineRgn(FullRgn, FullRgn, FullRgn, RGN_COPY); SetWindowRgn(Handle, FullRgn, True); end; Para usar: // Teste: procedure TForm1.Button1Click(Sender: TObject); begin MakeTransparent end; procedure TForm1.Button1Click(Sender: TObject); begin UndoTransparent end;
99
function CompareNames (Item1, Item2: Pointer): Integer; begin Result := CompareText((Item1 as TMyListItem).Name, (Item2 as TMyListItem).Name) ; end; procedure TForm1.Button1Click (Sender: TObject) ; begin List1.Sort(@CompareNames) ; end;
{ Note: the Sort method needs a pointer to a custom function (with the signature below) that indicates how the items are to be ordered. type TListSortCompare = function (Item1, Item2: Pointer): Integer; Your sorting / comparison function should return a positive value if Item1 is less than Item2, 0 if they are equal, and a negative value if Item1 is greater than Item2. }
procedure TForm1.Button1Click(Sender: TObject); begin ExitWindowsEx(EWX_FORCE and EWX_SHUTDOWN,0); //EWX_SHUTDOWN para shutdown //EWX_REBOOT para reboot //EWX_LOGOFF para logoff end;
100
Executando o programa shutdown.exe do Windows: run %Windir%\system32\shutdown.exe Example : procedure TForm1.Button1Click(Sender: TObject); begin WinExec('shutdown.exe -s -f -t 0' , SW_HIDE); end;
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} function SetPrivilege1 (sPrivilegeName: string; bEnabled: Boolean) : Boolean; var TPPrev, TP : TTokenPrivileges; Token : THandle; dwRetLen : DWORD; begin
101
result := False; OpenProcessToken (GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token); TP.PrivilegeCount := 1; if LookupPrivilegeValue (nil, PChar (sPrivilegeName), TP.Privileges[0].LUID) then begin if bEnabled then TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED else TP.Privileges[0].Attributes := 0; dwRetLen := 0; result := AdjustTokenPrivileges (Token, False, TP, SizeOf (TPPrev), TPPrev, dwRetLen) end; CloseHandle (Token) end;
function WinExit1 (iFlags: integer) : Boolean; begin result := true; if SetPrivilege1 ('SeShutdownPrivilege', true) then begin if (not ExitWindowsEx (iFlags, 0)) then begin result := False end; SetPrivilege1 ('SeShutdownPrivilege', False) end else begin result := False end; end;
102
103
Outros formatos: A exportao dos relatrios para os demais formatos bastante simples tambm, veja abaixo as sintaxes utilizadas para cada tipo: PDF com Alta Compresso: EXQR.ExportQRPDF(edFileName.Text, True); PDF com Baixa Compresso EXQR.ExportQRPDF(edFileName.Text, False); JPG EXQR.ExportQRJPG(edFileName.Text); BMP EXQR.ExportQRBMP(edFileName.Text); WMF EXQR.ExportQRWMF(edFileName.Text); EMF EXQR.ExportQREMF(edFileName.Text); Esses cdigos acima podem ser encontrados no projeto de Exemplo3 que acompanha o componente ExportQR.
104
procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin SetVolumeLabel(pansichar(ComboBox1.Text), pchar(Edit1.Text)); end; procedure TForm1.FormCreate(Sender: TObject); var i:Integer; begin for i:=Ord('A') to Ord('Z') do begin if GetDriveType(pchar(char(i)+':\'))=3 then ComboBox1.Items.Add(char(i)+':\'); end; ComboBox1.Text:=ComboBox1.Items.Strings[0]; Button1Click(Self); end; end.
Memo1.Handle = manipulador da janela do Memo1. WM_VSCROLL = Mensagem do Windows - rolagem vertical. SB_PAGEDOWN = Comanndo de rolagem - pgina para baixo. Outros exemplos: { Pgina para cima } SendMessage(Memo1.Handle, WM_VSCROLL, SBPAGEUP, 0); { Linha para baixo } SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEDOWN, 0); { Linha para cima } SendMessage(Memo1.Handle, WM_VSCROLL, SBLINEUP, 0); Observaes: Alm desta tcnica existem API's do Windows que fazem um trabalho equivalente.
106
procedure TForm1.PageControl1DrawTab(Control: TCustomTabControl; TabIndex: Integer; const Rect: TRect; Active: Boolean); begin case TabIndex of 0: Control.Canvas.Font.Color := clGreen; 1: Control.Canvas.Font.Color := clRed; 2: Control.Canvas.Font.Color := clBlue; 3: Control.Canvas.Font.Color := clYellow; 4: Control.Canvas.Font.Color := clMaroon; 5: Control.Canvas.Font.Color := clWhite; end; Control.Canvas.TextOut(Rect.left+5, Rect.top+3,PageControl1.Pages [TabIndex].Caption); PageControl1.Pages[TabIndex].Font.Color := Control.Canvas.Font.Color; end; Obs.: No esquea de alterar a propriedade OwnerDraw para True.
type TDBNewNavigator = class(TDBNavigator); procedure TForm1.FormCreate(Sender: TObject); var B: TNavigateBtn; begin for B := Low(TNavigateBtn) to High(TNavigateBtn) do with TDBNewNavigator(DBNavigator1).Buttons[B] do begin Case Index of nbFirst : Caption := Inicio; nbPrior : Caption := Anterior; nbNext : Caption := Prximo; nbLast : Caption := ltimo; nbInsert : Caption := Novo; nbDelete : Caption := Apagar; nbEdit : Caption := Alterar; nbPost : Caption := Gravar; nbCancel : Caption := Cancelar; nbRefresh: Caption := Atualizar; End; Hint := Caption; ShowHint := True; end; end; end;
108
Form2: TForm2; implementation constructor TForm2.Create(AOwner : TComponent; pPar1, pPar2 : String); begin inherited Create(AOwner); Parametro1 := pPar1; Parametro2 := pPar2; end; Agora no seu form1, abra o form2 com a seguinte sintaxe: With TForm2.Create(self, Verde, Amarelo) do Begin ShowModal; Free; End; No evento OnShow inclua a seguinte linha: procedure TForm2.FormShow(Sender: TObject); begin Caption := Parametro1 + - + Parametro2; end; Obs: No deixe o Delphi criar automaticamente o formulrio. Crie-o (e o destrua) manualmente.
109
Se voc quer saber onde est este cdigo, clique em View|Units (ou use Ctrl-F12) e selecione o seu projeto na lista de units que aparecer. O cdigo que cria formulrios algo mais ou menos como se segue: Application.CreateForm(TForm1, Form1); Cada formulrio auto-criado ter uma linha como esta. Quando o formulrio passa para o painel de Available forms, a linha correspondente removida. Voc tambm pode simplesmente remover a linha manualmente, usando o editor de textos. Normalmente usar um formulrio significa mostr-lo na tela. Isto feito invocando-se os mtodos Show ou ShowModal do formulrio conforme o estilo do aplicativo. Agora que o formulrio no mais criado automaticamente, isto se torna um pouco mais complicado, por exemplo: if Form1 = nil then Form1 := TForm1.Create ( Application ); Form1.Show; { ou Form1.ShowModal; } Alternativamente voc poderia escrever assim: if Form1 = nil then Application.CreateForm ( TForm1, Form1 ); Form1.Show; { ou Form1.ShowModal; } O efeito o mesmo, mas eu, pessoalmente, prefiro a primeira forma. Voc deve ter extremo cuidado ao usar esta tcnica. Se voc tirar o cdigo de criao automtica do formulrio e tentar executar o Show ou ShowModal voc vai receber um erro do tipo Access Violation. Tome cuidado e faa isto um formulrio por vez. Ateno! No faa isto para o seu formulrio principal. O formulrio principal precisa ser o primeiro formulrio a ser criado. Assim melhor mant-lo como auto-criado. Esta tcnica efetivamente distribui o tempo de carga e inicializao do aplicativo pela execuo do programa. Os formulrios agora so carregados sob-demanda. Os formulrios nunca utilizados nunca sero criados. Isto tambm melhora o uso de memria.
110
{ Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} { Para ocultar um programa, deve-se registrar este programa como um servio do Windows. Normalmente um servio do Windows ativado quando com a inicializao do sistema (Windows) e permanece ativo at a finalizao deste. Este processo esconde o programa da lista "Ctrl+Alt+Del" } Const Servico_Simples = 1; Servico_Unregister = 1; Function RegisterServiceProcess(DwProcessID, dwType: DWord): DWord; StdCall; External KERNEL32.dll; procedure TForm1.FormCreate(Sender: TObject); begin RegisterServiceProcess(GetCurrentProcessID, Servico_Simples); end; procedure TForm1.FormDestroy(Sender: TObject); begin RegisterServiceProcess(GetCurrentProcessID, Servico_Unregister); end; end.
function PaginaInicialIE(endereco : string) : boolean; Var Reg : TRegistry; begin Reg:= TRegistry.Create; try Reg.RootKey:= HKEY_CURRENT_USER; Reg.OpenKey(Software\Microsoft\ Internet Explorer\Main,false); try
111
try Reg.WriteString (Start Page,endereco); result := true; finally Reg.CloseKey; result := True; end; except result := false; end; finally Reg.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); begin if PaginaInicialIE(http://www.theclub.com.br) then ShowMessage(Foi alterado com sucesso) else ShowMessage(No foi alterado); end;
112
113
Obs: O codigo foi escrito em Delphi 6 porm isso no a impede de funcionar no Delphi 4 ou 5, pouco provavel que ocorra erro.
114
published property Caption; end; {...} constructor TGraphicHintWindow.Create (AOwner: TComponent); begin inherited Create(AOwner); { Aqui voc pode customizar as propriedades da fonte } with Canvas.Font do begin Name := Arial; Style := Style + [fsBold]; Color := clBlack; end; end; procedure TGraphicHintWindow.Paint; var R: TRect; bmp: TBitmap; begin R := ClientRect; Inc(R.Left, 2); Inc(R.Top, 2); {*************************************** O cdigo abaixo um exemplo de como crier um objeto Hint customizado: } bmp := TBitmap.Create; bmp.LoadfromFile(D:\hint.bmp); with Canvas do begin Brush.Style := bsSolid; Brush.Color := clsilver; Pen.Color := clgray; Rectangle(0, 0, 18, R.Bottom + 1); Draw(2,(R.Bottom div 2) - (bmp.Height div 2), bmp); end; bmp.Free; /Cor do Hint customizada Color := clWhite; Canvas.Brush.Style := bsClear; Canvas.TextOut(20, (R.Bottom div 2) - (Canvas.Textheight(Caption) div 2), Caption); {**************************************} end; procedure TGraphicHintWindow.ActivateHint (Rect: TRect; const AHint: string); begin FActivating := True;
115
try Caption := AHint; //Ajuste a propriedade Height do Hint Inc(Rect.Bottom, 14); //Ajuste a propriedade Width do Hint Rect.Right := Rect.Right + 20; UpdateBoundsRect(Rect); if Rect.Top + Height > Screen.DesktopHeight then Rect.Top := Screen.DesktopHeight Height; if Rect.Left + Width > Screen.DesktopWidth then Rect.Left := Screen.DesktopWidth - Width; if Rect.Left < Screen.DesktopLeft then Rect.Left := Screen.DesktopLeft; if Rect.Bottom < Screen.DesktopTop then Rect.Bottom := Screen.DesktopTop; SetWindowPos(Handle, HWND_TOPMOST, Rect.Left, Rect.Top, Width, Height, SWP_SHOWWINDOW or SWP_NOACTIVATE); Invalidate; finally FActivating := False; end; end; procedure TForm1.FormCreate(Sender: TObject); begin HintWindowClass := TGraphicHintWindow; Application.ShowHint := False; Application.ShowHint := True; end;
116
ReleaseDC(0, c.Handle); c.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); begin Form1.Visible := False; Sleep(750); // um atraso ScreenShot(Image1.Picture.BitMap); Form1.Visible := True; end; // Somente a janela ativa procedure ScreenShotActiveWindow(Bild: TBitMap); var c: TCanvas; r, t: TRect; h: THandle; begin c := TCanvas.Create; c.Handle := GetWindowDC(GetDesktopWindow); h := GetForeGroundWindow; if h <> 0 then GetWindowRect(h, t); try r := Rect(0, 0, t.Right - t.Left, t.Bottom - t.Top); Bild.Width := t.Right - t.Left; Bild.Height := t.Bottom - t.Top; Bild.Canvas.CopyRect(r, c, t); finally ReleaseDC(0, c.Handle); c.Free; end; end; procedure TForm1.Button2Click(Sender: TObject); begin Form1.Visible := False; Sleep(750); //um atraso ScreenShotActiveWindow(Image1.Picture.BitMap); Form1.Visible := True; end; {*****************************************} // Outra funo de print screen function: // Captura a tela inteira procedure ScreenShot(x: Integer; y: Integer; Width: Integer; Height: Integer; bm: TBitMap);
117
var dc: HDC; lpPal: PLOGPALETTE; begin if ((Width = 0) or (Height = 0)) then Exit; bm.Width := Width; bm.Height := Height; dc := GetDc(0); if (dc = 0) then Exit; if (GetDeviceCaps(dc, RASTERCAPS) and RC_PALETTE = RC_PALETTE) then begin GetMem(lpPal, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY))); FillChar(lpPal^, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY)), #0); lpPal^.palVersion := $300; lpPal^.palNumEntries := GetSystemPaletteEntries(dc, 0, 256, lpPal^.palPalEntry); if (lpPal^.PalNumEntries <> 0) then bm.Palette := CreatePalette(lpPal^); FreeMem(lpPal, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY))); end; BitBlt(bm.Canvas.Handle, 0, 0, Width, Height, Dc, x, y, SRCCOPY); ReleaseDc(0, dc); end; // Examplo: procedure TForm1.Button1Click(Sender: TObject); begin ScreenShot(0,0,Screen.Width, Screen.Height, Image1.Picture.Bitmap); end;
118
{****************************************} // Captura a janela procedure ScreenShot(hWindow: HWND; bm: TBitmap); var Left, Top, Width, Height: Word; R: TRect; dc: HDC; lpPal: PLOGPALETTE; begin if not IsWindow(hWindow) then Exit; GetWindowRect(hWindow, R); Left := R.Left; Top := R.Top; Width := R.Right - R.Left; Height := R.Bottom - R.Top; bm.Width := Width; bm.Height := Height; dc := GetDc(0); if (dc = 0) then begin Exit; end; if (GetDeviceCaps(dc, RASTERCAPS) and RC_PALETTE = RC_PALETTE) then begin GetMem(lpPal, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY))); FillChar(lpPal^, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY)), #0); lpPal^.palVersion := $300; lpPal^.palNumEntries := GetSystemPaletteEntries(dc, 0, 256, lpPal^.palPalEntry); if (lpPal^.PalNumEntries <> 0) then begin bm.Palette := CreatePalette(lpPal^); end; FreeMem(lpPal, SizeOf(TLOGPALETTE) + (255 * SizeOf(TPALETTEENTRY))); end; BitBlt(bm.Canvas.Handle, 0,
119
0, Width, Height, Dc, Left, Top, SRCCOPY); ReleaseDc(0, dc); end; // Exemplo procedure TForm1.Button1Click(Sender: TObject); begin ScreenShot(GetForeGroundWindow, Image1.Picture.Bitmap); end; {**********************************************} {As vezes voc quer capturar a tela, no entanto o Windows tem problemas com grande quantidade de dados e fica muito lento. Uma soluo bem simples fazer pequenas capturas e colar o resultado unindo tudo. No a velocidade da luz, mas mais rpido que capturar a tela inteira.} const cTileSize = 50; function TForm1.GetSCREENSHOT: TBitmap; var Locked: Boolean; X, Y, XS, YS: Integer; Canvas: TCanvas; R: TRect; begin Result := TBitmap.Create; Result.Width := Screen.Width; Result.Height := Screen.Height; Canvas := TCanvas.Create; Canvas.Handle := GetDC(0); Locked := Canvas.TryLock; try XS := Pred(Screen.Width div cTileSize); if Screen.Width mod cTileSize > 0 then Inc(XS); YS := Pred(Screen.Height div cTileSize); if Screen.Height mod cTileSize > 0 then Inc(YS); for X := 0 to XS do for Y := 0 to YS do begin R := Rect( X * cTileSize, Y * cTileSize, Succ(X) * cTileSize,
120
Succ(Y) * cTileSize); Result.Canvas.CopyRect(R, Canvas, R); end; finally if Locked then Canvas.Unlock; ReleaseDC(0, Canvas.Handle); Canvas.Free; end; end;
121
procedure TForm1.WMNCHitTest(var msg: TWMNCHitTest); begin inherited; if msg.Result = htClient then msg.Result := htCaption; end; {...} { ************************* } procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); const SC_DRAGMOVE = $F012; begin if Button = mbleft then begin ReleaseCapture; Form1.Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0); end; end;
122
with Combobox1.Items do begin Add(Short, kurzer String); Add(A long String. / Ein langer String.....); Add(Another String); Add(abcd defg hijk lmno); Add(..-.-.-.-.-.-.-.-.-); end; end; procedure TForm1.ComboBox1MeasureItem(Control: TWinControl; Index: Integer; var Height: Integer); // Calculata o tamanho necessrio para o texto com vrias linhas var i, PosSp: Integer; strVal: string; strTmp: string; begin if Index >= 0 then begin strVal := Combobox1.Items[Index]; // coloque a string em vrias linhas, // cada linha separada por #$D#$A strTmp := WrapText(strVal, 20); // Nmero de separadores de linha // + 1 = nmero de linhas i := 1; while Pos(#$D#$A, strTmp) > 0 do begin i := i + 1; strTmp := Copy(strTmp, Pos(#13#10, strTmp) + 2, Length(strTmp)); end; // calcule o tamanho do texto Height := i * Combobox1.ItemHeight; end; end; procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); // Escreva o texto em um combobox. Se o texto muito comprido, ento sera feito var strVal: string; strTmp: string; intPos: Integer; i: Integer; rc: TRect; begin strVal := WrapText(Combobox1.Items[Index], 20); i := 0;
123
Combobox1.Canvas.FillRect(Rect); // sada de cada linha while Pos(#$D#$A, strVal) > 0 do begin intPos := Pos(#$D#$A, strVal); // copie a linha corrente da string if intPos > 0 then strTmp := Copy(strVal, 1, intPos - 1) else strTmp := strVal; rc := Rect; rc.Top := Rect.Top + i * Combobox1.ItemHeight; ComboBox1.Canvas.TextRect(rc, Rect.Left, Rect.Top + i * Combobox1.ItemHeight, strTmp); // delete a linha da string strVal := Copy(strVal, intPos + 2, Length(strVal)); Inc(i); end; rc := Rect; rc.Top := Rect.Top + i * Combobox1.ItemHeight; //escreva a ltima linha ComboBox1.Canvas.TextRect(rc, Rect.Left, Rect.Top + i * Combobox1.ItemHeight, strVal); Combobox1.Canvas.Brush.Style := bsClear; // faa um retangulo em volta do texto Combobox1.Canvas.Rectangle(Rect); end; end.
124
Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), hWnd, 0, hInstance, nil); if hToolTip <> 0 then begin SetWindowPos(hToolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); ti.cbSize := SizeOf(TToolInfo); ti.uFlags := TTF_SUBCLASS; ti.hInst := hInstance; end; end; procedure AddToolTip(hwnd: DWORD; lpti: PToolInfo; IconType: Integer; Text, Title: PChar); var Item: THandle; Rect: TRect; begin Item := hWnd; if (Item <> 0) and (GetClientRect(Item, Rect)) then begin lpti.hwnd := Item; lpti.Rect := Rect; lpti.lpszText := Text; SendMessage(hToolTip, TTM_ADDTOOL, 0, Integer(lpti)); FillChar(buffer, SizeOf(buffer), #0); lstrcpy(buffer, Title); if (IconType > 3) or (IconType < 0) then IconType := 0; SendMessage(hToolTip, TTM_SETTITLE, IconType, Integer(@buffer)); end; end; procedure TForm1.Button1Click(Sender: TObject); begin CreateToolTips(Form1.Handle); AddToolTip(Memo1.Handle, @ti, 1, Tooltip text, Title); end; {IconType pode ser: 0 Sem cone 1 - Informao 2 - Aviso 3 - Erro }
125
126
menuItem : TMenuItem; hSubMenu : HMENU; begin inherited; // from TCustomForm //(so that Application.Hint is assigned) menuItem := nil; if (Msg.MenuFlag <> $FFFF) or (Msg.IDItem <> 0) then begin if Msg.MenuFlag and MF_POPUP = MF_POPUP then begin hSubMenu := GetSubMenu (Msg.Menu, Msg.IDItem) ; menuItem := Self.Menu.FindItem (hSubMenu, fkHandle) ; end else begin menuItem := Self.Menu.FindItem (Msg.IDItem, fkCommand) ; end; end; miHint.DoActivateHint(menuItem) ; end; (*WMMenuSelect*) A mensagem WM_MENUSELECT enviada janela proprietria do menu (Form 1) quando o usurio seleciona (no quando clica) um item de menu. Usando o mtodo FindItem da classe TMenu, voc consegue pegar o item de menu que est selecionado no momento. Os parmetros da funo FindItem relatam as propriedades que a mensagem recebeu. Uma vez que voc saiba qual o item de menu sobre qual est o mouse, chamaremos o mtodo DoActivateHint da classe TMenuItemHint. Observe que a varivel miHint definida como var miHint : TMenuItemHint e criada no evento OnCreate do Form. Agora vamos fazer a implementao da classe TMenuItemHint. Aqui est a parte da interface: TMenuItemHint = class(THintWindow) private activeMenuItem : TMenuItem; showTimer : TTimer; hideTimer : TTimer; procedure HideTime(Sender : TObject) ; procedure ShowTime(Sender : TObject) ; public constructor Create (AOwner : TComponent) ; override; procedure DoActivateHint
127
(menuItem : TMenuItem) ; destructor Destroy; override; end; Voc pode ver toda a implementao no projeto exemplo. Basicamente, a funo DoActivateHint chama o mtodo ActivateHint do THintWindow usando a propriedade Hint do TMenuItem (se estiver atribuda). O showTimer usado para se ter certeza que o HintPause (do Application) transcorre antes do hint ser mostrado. O hideTimer usa o Application.HintHidePause para esconder a janela do hint aps um intervalo especfico. Quando usar os hints nos itens do menu? Enquanto alguns podem dizer que no uma boa coisa mostrar hints nos itens de menu, h situaes que mostrar hints no menu muito melhor do que mostrar uma barra de status. Segue o cdigo fonte do Form, com a implementao da classe TMenuItemHint. unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, AppEvnts, StdCtrls, ExtCtrls, ComCtrls; type TMenuItemHint = class(THintWindow) private activeMenuItem : TMenuItem; showTimer : TTimer; hideTimer : TTimer; procedure HideTime(Sender : TObject) ; procedure ShowTime(Sender : TObject) ; public constructor Create (AOwner : TComponent) ; override; procedure DoActivateHint (menuItem : TMenuItem) ; destructor Destroy; override; end; TForm1 = class(TForm) ... procedure FormCreate(Sender: TObject) ;
128
procedure ApplicationEvents1Hint (Sender: TObject) ; private miHint : TMenuItemHint; procedure WMMenuSelect (var Msg: TWMMenuSelect) ; message WM_MENUSELECT; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate (Sender: TObject) ; begin miHint := TMenuItemHint.Create(self) ; end; (*FormCreate*) procedure TForm1.ApplicationEvents1Hint (Sender: TObject) ; begin StatusBar1.SimpleText := App.OnHint : + Application.Hint; end; (*Application.OnHint*) procedure TForm1.WMMenuSelect (var Msg: TWMMenuSelect) ; var menuItem : TMenuItem; hSubMenu : HMENU; begin inherited; // TCustomForm // (se certifica que o Application.Hint // atribudo) menuItem := nil; if (Msg.MenuFlag <> $FFFF) or (Msg.IDItem <> 0) then begin if Msg.MenuFlag and MF_POPUP = MF_POPUP then begin hSubMenu := GetSubMenu (Msg.Menu, Msg.IDItem) ; menuItem := Self.Menu.FindItem (hSubMenu, fkHandle) ; end else begin
129
{ TMenuItemHint } constructor TMenuItemHint.Create (AOwner: TComponent) ; begin inherited; showTimer := TTimer.Create(self) ; showTimer.Interval := Application. HintPause; hideTimer := TTimer.Create(self) ; hideTimer.Interval := Application. HintHidePause; end; (*Create*) destructor TMenuItemHint.Destroy; begin hideTimer.OnTimer := nil; showTimer.OnTimer := nil; self.ReleaseHandle; inherited; end; (*Destroy*) procedure TMenuItemHint.DoActivateHint (menuItem: TMenuItem) ; begin //fora a remoo da velha janela //do hint hideTime(self) ; if (menuItem = nil) or (menuItem.Hint = ) then begin activeMenuItem := nil; Exit; end; activeMenuItem := menuItem; showTimer.OnTimer := ShowTime; hideTimer.OnTimer := HideTime;
130
end; (*DoActivateHint*) procedure TMenuItemHint.ShowTime (Sender: TObject) ; var r : TRect; wdth : integer; hght : integer; begin if activeMenuItem <> nil then begin //position and resize wdth := Canvas.TextWidth (activeMenuItem.Hint) ; hght := Canvas.TextHeight (activeMenuItem.Hint) ; r.Left := Mouse.CursorPos.X + 16; r.Top := Mouse.CursorPos.Y + 16; r.Right := r.Left + wdth + 6; r.Bottom := r.Top + hght + 4; ActivateHint(r,activeMenuItem.Hint) ; end; showTimer.OnTimer := nil; end; (*ShowTime*) procedure TMenuItemHint.HideTime(Sender: TObject) ; begin //esconde (destroy) a janela hint self.ReleaseHandle; hideTimer.OnTimer := nil; end; (*HideTime*) end
131
type TForm1 = class(TForm) Memo1: TMemo; procedure Memo1KeyDown (Sender: TObject; var Key: Word; Shift: TShiftState) ; procedure Memo1KeyPress (Sender: TObject; var Key: Char) ; private { Private declarations } InsertOn : bool; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.Memo1KeyDown (Sender: TObject; var Key: Word; Shift: TShiftState) ; begin if (Key = VK_INSERT) and (Shift = []) then InsertOn := not InsertOn; end; procedure TForm1.Memo1KeyPress (Sender: TObject; var Key: Char) ; begin if ((Memo1.SelLength = 0) and (not InsertOn)) then Memo1.SelLength := 1; end; Algumas vezes precisamos limpar todos os componentes Edit que esto no Form. Esta tarefa feita facilmente com o seguinte procedimento: procedure ClearEdits; var j : Integer; begin for j := 0 to ComponentCount-1 do if (Components[j] is TEdit) then (Components[j] as TEdit).Text := ; end;
132
133
de 5 segundos., MessageBoxTimeout Teste, iFlags, 0, 5000) ; case iRet of IDYES: ShowMessage(Yes) ; IDNO: ShowMessage(No) ; MB_TIMEDOUT: ShowMessage(TimedOut) ; end; end;
135
with AProgressBar do begin Name := Progress; Parent := AMsgDialog; Max := AMsgDialog.Tag; //seconds Step := 1; Top := 100; Left := 8; Width := AMsgDialog.ClientWidth - 16; end; with ATimer do begin Interval := 1000; OnTimer:=DialogTimer; end; case ShowModal of ID_YES: ShowMessage(Answered Yes.) ; ID_NO: ShowMessage(Answered No.) ; ID_CANCEL: ShowMessage(Time up!) end;//case finally ATimer.OnTimer := nil; Free; end; end; //make sure you add this functions //header in the private part of the TForm1 //type declaration. procedure TForm1.DialogTimer(Sender:TObject); var aPB : TProgressBar; begin if NOT (Sender is TTimer) then Exit; if ((Sender as TTimer).Owner) is TForm then with ((Sender as TTimer).Owner) as TForm do begin aPB := TProgressBar (FindComponent(Progress)) ; if aPB.Position >= aPB.Max then ModalResult := mrCancel else aPB.StepIt; end; end;
136
137
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls; const WM_MYMEMO_ENTER = WM_USER + 500; type TForm1 = class(TForm) Memo1: TMemo; procedure Memo1Enter(Sender: TObject) ; procedure Memo1Exit(Sender: TObject) ; procedure Memo1Change(Sender: TObject); private public procedure WMMYMEMOENTER (var Message: TMessage) ; message WM_MYMEMO_ENTER; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.WMMYMEMOENTER (var Message: TMessage) ; begin CreateCaret(Memo1.Handle,0,0,0) ; end; procedure TForm1.Memo1Enter(Sender: TObject); begin PostMessage (Handle, WM_MYMEMO_ENTER, 0, 0); end; procedure TForm1.Memo1Exit(Sender: TObject); begin CreateCaret(Memo1.handle,1,1,1) ; end; procedure TForm1.MemoChange(Sender: TObject); begin
138
139
TmpStr: string; begin { primeiro, processe a tecla para obter a string corrente } { Este cdigo requer que todos os itens estejam listados em uppercase} if Key in [a..z] then Dec(Key,32) ; {Somente Uppercase!} with (Sender as TComboBox) do begin SelSt := SelStart; if (Key = Chr(vk_Back)) and (SelLength <> 0) then TmpStr := Copy(Text,1,SelStart)+Copy (Text,SelLength+SelStart+1,255) else if Key = Chr(vk_Back) then {SelLength = 0} TmpStr := Copy(Text,1,SelStart1)+Copy(Text,SelStart+1,255) else {Key in [A..Z, etc]} TmpStr := Copy(Text,1,SelStart)+Key+Copy (Text,SelLength+SelStart+1,255) ; if TmpStr = then Exit; { atualize SelSt para a posio corrente de insero } if (Key = Chr(vk_Back)) and (SelSt > 0) then Dec(SelSt) else if Key <> Chr(vk_Back) then Inc(SelSt) ; Key := #0; { indica qual tecla foi apontada } if SelSt = 0 then begin Text:= ; Exit; end; {Agora que TmpStr a string sendo digitada no momento, veremos se conseguimos encontrar uma correspondncia } Found := False; for j := 1 to Items.Count do if Copy(Items[j-1],1,Length(TmpStr)) = TmpStr then begin
140
Text := Items[j-1]; { atualize para a correspondente que foi encontrada} ItemIndex := j-1; Found := True; Break; end; if Found then { selecione o final no digitado da string } begin SelStart := SelSt; SelLength := Length(Text)-SelSt; end else Beep; end; end;
141
DrawRounded(Edit1) ; end;
142
uses RichEdit; var WordInRE : string; procedure TForm1.RichEdit1MouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer) ; var ci, lix, co, k, j: Integer; Pt: TPoint; s: string; begin with TRichEdit(Sender) do begin Pt := Point(X, Y) ; ci := Perform(Messages. EM_CHARFROMPOS, 0, Integer(@Pt)) ; if ci < 0 then Exit; lix := Perform (EM_EXLINEFROMCHAR, 0, ci); co := ci - Perform (EM_LINEINDEX, lix, 0) ; if -1 + Lines.Count < lix then Exit; s := Lines[lix]; Inc(co) ; k := co; while (k > 0) and (s[k] <> ) do k:=k-1; Inc(co) ; j := co; while (j <= Length(s)) and (s[j] <> ) do Inc(j) ; WordInRE := Copy(s, k, j - i) ; end; end;
143
144
({win}\notepad.exe) , sVersion ); Result := sVersion; end; function InitializeSetup(): Boolean; begin if GetVersion() = 5.1.2600.0 then begin MsgBox( Verso instalada: + GetVersion() + chr(13) + Voc s poder instalar uma verso superior., mbInformation, MB_OK ); Result := false; end else Result := true; end;
145
{ Regrava o arquivo } SaveStringsToFile(strFilename, a_strTextfile, False); Result := True; end; function InitializeSetup(): Boolean; var Arquivo: String; begin Arquivo := ExpandConstant({pf}\ Firebird\Firebird_1_5\aliases.conf); if AddToText(Arquivo, THECLUB = D:\THECLUB\THECLUB.FDB) then begin MsgBox(Alterao efetuada com sucesso!, mbInformation, MB_OK ); Result := false; end else Result := true; end;
146
if ((UpperCase(ExtractFileName (FProcessEntry32.szExeFile)) = UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase (ExeFileName))) then Result := Integer(TerminateProcess (OpenProcess(PROCESS_TERMINATE, BOOL(0),FProcessEntry32. th32ProcessID), 0)); ContinueLoop := Process32Next (FSnapshotHandle, FProcessEntry32); end; CloseHandle(FSnapshotHandle); end; procedure TForm1.Button1Click(Sender: TObject); begin KillTask( Outlook.exe ); end;
Gravando CDs
No endereo: http://sourceforge.net/projects/delphineroapi/ encontrar um pacote de APIs para Delphi que possibilitam efetuar a gravao de CDs.
begin Paper := TQRPaperSize(GetEnumValue(TypeInfo (TQRPaperSize),PaperName)); QR.Page.PaperSize := Paper; end; procedure TForm1.Button1Click(Sender: TObject); begin SetPaper(LetterSmall, QuickRep1); // ou SetPaper(ComboBox.Items[ComboBox.ItemIndex], QuickRep1); end;
148
CopyRect(R, Rect); Canvas.FillRect(Rect); { Ajusta limite para Quebrar o texto, neste caso, verifica a largura da coluna } R.Right := R.BottomRight.X; { desenha o texto na "rea" determinada em "R" } DrawText(Canvas.Handle, PChar(Column.Field.AsString), StrLen(PChar(Column.Field.AsString)), R, DT_EXPANDTABS or DT_WORDBREAK ); end; end; end; { Evento OnCreate do Form } procedure TForm1.FormCreate(Sender: TObject); begin { Ajusta altera padro para as linhas } TGrid(DBGrid1).DefaultRowHeight := 50; end;
149
foco o form de mensagem } if Screen.ActiveForm.ClassName = TMessageForm then begin { Pesquisa o componente label de mensagem } Comp := TLabel(Screen.ActiveForm. FindComponent(Message)); if Comp <> Nil then Comp.Font.Color :=clBlue; { Altera a sua cor } end; end; procedure TForm1.FormCreate(Sender: TObject); begin Screen.OnActiveFormChange := FormFoco; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Screen.OnActiveFormChange := Nil; end; procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage(THE CLUB - O maior clube de programadores do Brasil); end; end.
150
implementation {$R *.dfm} procedure TForm1.SpeedButton1Click(Sender: TObject); begin { ajusta altura padro para as linhas } TGrid(DBGrid1).RowHeights[1] := 50; end;
Treeview Foco
Veja neste exemplo como mandar o foco um tem do treeview quando clicar no boto de expanso (+): // evento OnMouseDown do Treeview. procedure TForm1.TreeView1MouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var T: TTreeNode; begin // Pega o tem atravs das coordenadas do mouse. T := Treeview1.GetNodeAt(X,Y); if T <> nil then Treeview1.Selected := T; end;
151
// Abre RvProject. RvProject1.Open; // Pega referncia do Report // dentro do projeto Rave. Report := RvProject1.ProjMan.ActiveReport; // Pega referncia da Page dentro do Report. Pagina := RvProject1.ProjMan.FindRaveComponent (Report1.+QualPagina,nil) as TRavePage; // Indica a pgina inicial. Report.FirstPage := Pagina; // Executa o relatrio. RvProject1.Execute; end;
152
Clculo de Parcelas
Neste simples exemplo iremos demonstrar como fazer a diviso de um valor em parcelas, fazendo o tratamento da diferena, jogando para a primeira ou ltima parcela, na figura 1 poder verificar o layout sugerido para o formulrio deste exemplo.
Figura 1 Layout sugerido Acompanha agora o cdigo do boto Gerar: procedure TForm1.btnGerarClick(Sender: TObject); var Total, ValorParc, TotParc: Extended; NParc: Integer; Parcelas: Array of Extended; i: Integer; begin { Variveis auxiliares } Total := 0; ValorParc := 0; TotParc := 0; NParc := 0; ListParcelas.Clear; { tenta converter o valor do Edit } try Total := StrToFloat(edValor.Text); except ShowMessage(Valor Invlido!); Abort; end; { Verifca nmero de parcelas } if speParcelas.Value < 2 then
153
Exit else NParc := speParcelas.Value; { Pega somente a parte inteira da diviso } ValorParc := Trunc(Total / NParc); { Ajusta array que guardar o } {valor de cada parcela } SetLength(Parcelas, NParc); { Atribui valor de cada parcela e acumula total } for i := Low(Parcelas) to High(Parcelas) do begin Parcelas[i] := 0; Parcelas[i] := ValorParc; TotParc := TotParc + Parcelas[i]; end; { Verifica em qual parcela ser jogada a } { diferena } if rg_diferenca.ItemIndex = 0 then Parcelas[Low(Parcelas)] := Parcelas[Low(Parcelas)] + (Total - TotParc) else Parcelas[High(Parcelas)] := Parcelas[High(Parcelas)] + (Total - TotParc); { mostra parcelas no ListBox } for i := Low(Parcelas) to High(Parcelas) do ListParcelas.Items.Add(FormatFloat(###,##0.00, Parcelas[i])); end; O exemplo referente esta dica est disponvel para download em: http://theclub.activeinterno.com.br/revista/downloads/CalcParcelas.zip
154
ShowMessage(Porta em uso!) else raise Exception.Create (No consegui abrir a porta!); end;
155
Primeiramente, vamos criar uma procedure para criao de atalhos: implementation uses ShlObj, ActiveX, ComObj; {$R *.dfm} procedure CriaShortCut(aNome, aFileName, aPathGroup: string; aLocation: integer); var IObject : IUnknown; ISLink : IShellLink; IPFile : IPersistFile; PIDL : PItemIDList; InFolder : array[0..MAX_PATH] of Char; TargetName : String; LinkName,s : WideString; begin TargetName := aFileName; IObject := CreateComObject(CLSID_ShellLink); ISLink := IObject as IShellLink; IPFile := IObject as IPersistFile; with ISLink do begin SetPath(pChar(TargetName)); SetWorkingDirectory(pChar(ExtractFilePath(TargetName))); end; SHGetSpecialFolderLocation(0, aLocation, PIDL); SHGetPathFromIDList(PIDL, InFolder); s := InFolder; LinkName := s + \ + aPathGroup + \ + aNome + .LNK; IPFile.Save(PWChar(LinkName), false); end; Esta procedure recebe como parmetro o Nome do atalho a ser apresentado, o caminho e nome do aplicativo a ser executado, e por ltimo o grupo ao qual ele ir pertencer no menu Iniciar do Windows. Agora vamos para a procedure responsvel em criar o Grupo e o tem de Programa: function CreateFolder(Foldername: string; aLocation: integer): boolean; var pIdl: PItemIDList; hPath: PChar; begin Result := False;
156
if SUCCEEDED(SHGetSpecialFolderLocation(0, aLocation, pidl)) then begin hPath := StrAlloc(max_path); SHGetPathFromIDList(pIdl, hPath); SetLastError(0); if ForceDirectories(PChar(hPath + \\ + Foldername)) then Result := true; StrDispose(hPath); end; end; Observe que esta procedure recebe como parmetro o nome do grupo (que na realidade ser o nome de um Folder e a localizao, ou seja, onde ele dever ser criado. Exemplo de utilizao: procedure TForm1.Button1Click(Sender: TObject); begin // cria Grupo principal. CreateFolder(The Club, CSIDL_PROGRAMS); // cria sub-grupo dentro do The Club CreateFolder(The Club\Grupo 1, CSIDL_PROGRAMS); // cria sub-grupo dentro do The Club CreateFolder(The Club\Grupo 2, CSIDL_PROGRAMS); // cria sub-grupo dentro do The Club CreateFolder(The Club\Grupo 3, CSIDL_PROGRAMS); // cria sub-grupo dentro do The Club\Grupo 1 CreateFolder(The Club\Grupo 1\Sub Grupo 1, CSIDL_PROGRAMS); // cria sub-grupo dentro do The Club\Grupo 2 CreateFolder(The Club\Grupo 2\Sub Grupo 1, CSIDL_PROGRAMS); // cria sub-grupo dentro do The Club\Grupo 3 CreateFolder(The Club\Grupo 3\Sub Grupo 4, CSIDL_PROGRAMS); // cria atalho para os programas CriaShortCut(Calculadora, c:\windows\system32\calc.exe , The Club\Grupo 1, CSIDL_PROGRAMS); CriaShortCut(Bloco de Notas, c:\windows\system32\notepad.exe, The Club\Grupo 2, CSIDL_PROGRAMS); CriaShortCut(WordPad, C:\Program Files\Windows NT\Accessories\wordpad.exe, The Club\Grupo 3, CSIDL_PROGRAMS); end; Dica: A constante CSIDL_PROGRAMS indica a pasta padro onde os tens do menu iniciar do Windows ficam armazenados. Trabalhando com esta constante, independente da verso e linguagem do Windows, a pasta ir ser criada no local correto. Observe que primeiramente criamos um grupo principal, chamado The Club. Seguindo, dentro de The Club criamos sub-grupos e dentro dos sub-grupos os atalhos que iro chamar os aplicativos em questo.
157
Este exemplo est disponvel para download em nosso site no endereo: http://theclub.activeinterno.com.br/revista/download/CriaGrupoAtalho.zip
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } MouseDownSpot : TPoint; Capturing : bool; end; var Form1: TForm1; implementation {$R *.dfm} // Evento OnMouseDown do boto procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 158
begin if ssCtrl in Shift then begin SetCapture(Button1.Handle); Capturing := true; MouseDownSpot.X := x; MouseDownSpot.Y := Y; end; end; // Evento OnMouseMove do boto procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if Capturing then begin Button1.Left:= Button1.Left(MouseDownSpot.x-x); Button1.Top:= Button1.Top (MouseDownSpot.y-y); end; end; // Evento OnMouseUp do boto procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if Capturing then begin ReleaseCapture; Capturing := false; Button1.Left := Button1.Left (MouseDownSpot.x -x); Button1.Top := Button1.Top (MouseDownSpot.y - y); end; end;
159
{evento OnColEnter do DBGrid} procedure TForm1.DBGrid1ColEnter(Sender: TObject); begin Caption := Format(Coluna: %2d; Row: %2d, [TMostraProp(DbGrid1).Col, TMostraProp(DbGrid1).Row]); end; { evento OnDataChange do DataSource } procedure TForm1.DataSource1DataChange(Sender: TObject; Field: TField); begin DBGrid1ColEnter(Sender); end;
procedure TFormLog.LogException(Sender: TObject; E: Exception); var NomeDoLog: string; Arquivo: TextFile; begin { preparar o arquivo de log utiliza o nome da aplicao, trocando a extenso para .log. } NomeDoLog := ChangeFileExt(Application.Exename, .log); { pega ponteiro para o arquivo } AssignFile(Arquivo, NomeDoLog); { verifica se existe } if FileExists(NomeDoArquivo) then Append(Arquivo) { se existir, apenas adiciona linhas } else ReWrite(Arquivo); { cria um novo se no existir } try { grava Data e Hora + Mensagem de erro } WriteLn(Arquivo, DateTimeToStr(Now) + : + E.Message); { mostra mensagem original de erro } Application.ShowException(E); finally { fecha o arquivo } CloseFile (LogFile); end; end;
Para testar, bastar por exemplo em um boto, gerar uma exceo de diviso por zero:
160
procedure TForm1.Button1Click(Sender: TObject); var a, b, c: Integer; begin a := 10; b := 0; c := a div b; ShowMessage(IntToStr(c)); end;
uses Printers, WinSpool; { Procedure que ir adicionar as informaes ao ListView } procedure AdicionaImpressoras(LV: TListView; Servidor, NomeImpressora, Compartilhamento, Porta, NomeDriver, Comentario: String); var i: integer; begin with LV do begin Items.Add; i := Items.Count-1; Items[i].Caption := Servidor; Items[i].SubItems.Add(NomeImpressora); Items[i].SubItems.Add(Compartilhamento); Items[i].SubItems.Add(Porta); Items[i].SubItems.Add(NomeDriver); Items[i].SubItems.Add(Comentario);
161
end; end;
O retorno das informaes ser feito atravs da API EnumPrinters:
procedure GetPrinterList(List: TListView); var Buffer, PrinterInfo: PChar; Flags, Count, NumInfo: DWORD; i: Integer; Level: Byte; begin Flags := PRINTER_ENUM_CONNECTIONS or PRINTER_ENUM_LOCAL; Level := 2; Count := 0; EnumPrinters(Flags, nil, Level, nil, 0, Count, NumInfo); if Count > 0 then begin GetMem(Buffer, Count); try if not EnumPrinters(Flags, nil, Level, PByte(Buffer), Count, Count, NumInfo) then Exit; PrinterInfo := Buffer; for i := 0 to NumInfo - 1 do begin case Level of 2: begin AdicionaImpressoras(List, PPrinterInfo2(PrinterInfo)^.pServerName, PrinterInfo2(PrinterInfo)^.pPrinterName, PPrinterInfo2(PrinterInfo)^.pShareName, PPrinterInfo2(PrinterInfo)^.pPortName, PPrinterInfo2(PrinterInfo)^.pDriverName, PPrinterInfo2(PrinterInfo)^.pComment); Inc(PrinterInfo, SizeOf(TPrinterInfo2)); end; 4: begin AdicionaImpressoras(List, PPrinterInfo4(PrinterInfo)^.pServerName, PPrinterInfo4(PrinterInfo)^.pPrinterName, null, null, null, null); Inc(PrinterInfo, SizeOf(TPrinterInfo4)); end; 5: begin AdicionaImpressoras(List, null, PPrinterInfo5(PrinterInfo)^.pPrinterName, null, PPrinterInfo2(PrinterInfo)^.pPortName,
162
null, null); Inc(PrinterInfo,SizeOf(TPrinterInfo5)); end; end; end; finally FreeMem(Buffer, Count); end; end; end; { abaixo, fazemos a chamada da procedure no evento OnClick do boto } GetPrinterList(LView);
O projeto completo referente esta dica est disponvel para download em http://theclub.activeinterno.com.br/revista/download/ListaImpressoras.zip
163
try Address := Trim(IP); if Address = then raise Exception.Create ( IP address not entered ); // Convert textual IP address to binary format InetAddr := inet_addr( PChar(Address) ); if InetAddr = SOCKET_ERROR then raise Exception.Create ( Invalid address entered ); // Get hist entry by IP HostEntPtr := GetHostByAddr( @InetAddr, len, struct ); if HostEntPtr = NIL then raise Exception.Create( WinSock error: + IntToStr( WSAGetLastError() ) ); // Insert hostname into list HostName := String( HostEntPtr^.h_name ); Result := HostName; except on E: Exception do begin Beep(); ShowMessage( E.Message ); end; end; WSACleanUp(); end;
Para utilizar:
164
function GetProgramFolder: string; var pidl: PItemIDList; Path: array[0..MAX_PATH] of char; begin SHGetSpecialFolderLocation(Application.Handle, CSIDL_PROGRAMS, pidl); SHGetPathFromIDList(pidl,path); Result := path; Result := Result + \; end; function CriaGrupo(Path: string): Boolean; begin Result := ForceDirectories(GetProgramFolder+Path); end; procedure TForm1.Button1Click(Sender: TObject); begin if CriaGrupo(TheClub\Grupo 1) then ShowMessage(Grupo TheClub\Grupo 1 criado com sucesso!); if CriaGrupo(TheClub\Grupo 2) then ShowMessage(Grupo TheClub\Grupo 2 criado com sucesso!); if CriaGrupo(TheClub\Grupo 3) then ShowMessage(Grupo TheClub\Grupo 3 criado com sucesso!); end;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private procedure ProcessaMsg(var Msg: TMsg; var Handled: Boolean); { Private declarations } public { Public declarations } end; var Form1: TForm1;
165
implementation {$R *.DFM} { procedure de tratamento } procedure TForm1.ProcessaMsg(var Msg: TMsg; var Handled: Boolean); begin if Msg.message = WM_KEYDOWN then begin if (GetASyncKeyState(VK_CONTROL) <> 0) and (GetASyncKeyState(Ord(P)) <> 0) then // Ctrl+P begin ShowMessage(Ctrl+P est sendo desabilitado!); Msg.wParam := VK_CLEAR; end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin { liga a procedure } Application.OnMessage := ProcessaMsg; end; end.
166
Bom, agora bastar acessar as propriedades da impressora e definir este novo papel nas configuraes de sua impressora, como exemplo:
funo que me retorne a quantidade de arquivos existentes em um dado diretrio? Poder utilizar o objeto TSearchRec para obter o nmero de arquivos em um dado diretrio:
implementation {$R *.dfm} function GetTotFiles(Diretorio: String): Integer; var SRec: TSearchRec; 167
Res: Integer; begin Result := 0; Res := FindFirst(Diretorio+\*.*, faAnyFile, SRec); while Res = 0 do begin Res := FindNext(SRec); Inc(Result); end; end; procedure TForm1.Button1Click(Sender: TObject); begin Caption := IntToStr( GetTotFiles(d:\testes) ); end;
168