Escolar Documentos
Profissional Documentos
Cultura Documentos
A utilizao, reproduo, apropriao, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criaes intelectuais em cada publicao da revista The Club so terminantemente proibidos sem autorizao escrita dos titulares dos direitos autorais.
EDITORIAL
Editorial
THE CLUB
Rua Acre, 950 - Avar - SP - CEP 18.700-260 Informaes: (0xx14) 3732-3689 Suporte: (0xx14) 3733-1588 Fax: (0xx14) 3732-0987
Internet
http://www.theclub.com.br Cadastro: cadastro@theclub.com.br Suporte: suporte@theclub.com.br Informaes: info@theclub.com.br
Dvidas
Correspondncia ou fax com dvidas devem ser enviados ao - THE CLUB, indicando "Suporte".
Opinio
Se voc quer dar a sua opinio sobre o clube em geral, mande a sua correspondncia para a seo "Tire sua dvida".
Reproduo
A utilizao, reproduo, apropriao, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criaes intelectuais em cada publicao da Revista The Club so terminantemente proibidos sem autorizao escrita dos titulares dos direitos autorais.
O THE CLUB em conjunto com a VUE firmaram uma parceria para aplicao de testes especializados da Microsoft, Novell Cisco e outros. Eis alguns exemplos de certificao da Microsoft: MCP - Microsoft Certified Professional - Pessoa que passou em pelo menos um exame de certificao da Microsoft. MCSE - Microsoft Certified System Engineer - Pessoa que passou em 7 exames de certificao da Microsoft. Profissional totalmente habilitado para trabalhar com o ambiente do Windows 2000. Este profissional hoje to requisitado que, as pessoas que conquistam essa certificao tem emprego garantido na Brs e Figueiredo, o maior parceiro da Microsoft no mundo. MCDBA - Microsoft Certified DataBase Administrator - Pessoa que passou em 4 exames. Dois exames de Windows 2000 e dois de SQL Server. MCSD - Microsoft Certified Solution Developer - Pessoa que passou em 4 exames. Dois exames sobre Visual Basic ou C, um sobre SQL Server, um sobre anlise de sistemas. MCSA - Microsoft Certified System Administrator - Pessoa que passou em 4 exames sobre Windows 2000. Os exames podem ser feitos no THE CLUB. Para maiores informaes ligue para (14) 3732-3689. Informaes sobre a certificao Microsoft e os exames disponveis podem ser obtidos no endereo: http://www.microsoft.com/mcp. As inscries tambm podem ser feitas no site da VUE: http://www.vue.com.
Diretor - Presidente
Mauro SantAnna
Colaboradores
Mrio Camilo Bohm - Claudenir C. Andrade Anderson Haertel Rodrigues - Cludio Akerman
Delphi marca registrada da Borland International, as demais marcas citadas so registradas pelos seus respectivos proprietrios.
Editorial .................................................................... 03 News ........................................................................ 04 HOTSYNC com emulador ......................................... 05 Tratamento global de exceptions ............................. 08 Dicas de instrues e comandos Oracle ................... 11 Que fazer para.... Recuperar as formas de pagamento do ECF............. 15 Trabalhando com o campo BLOB no Interbase ......... 16 FireBird a continuidade do Interbase Open-Source .. 24 Eventos ..................................................................... 27 Dicas & Truques ........................................................ 30
MeGAZINE 3
NEWS
MeGAZINE
DELPHI
HOTSYNC
com Emulador
Por: Claudio Akerman
Ol amigos do The Club, estamos de volta com mais um artigo sobre a plataforma Palm. Em uma das edies anteriores, mostramos como voc pode desenvolver um sistema de Conduit usando o Delphi. Para testar seu Conduit, voc pode usar o Emulator do Palm para garantir que seu Conduit esteja funcionando perfeitamente antes de coloc-lo em produo em equipamentos Palm. isso que vamos mostrar hoje!
Configurando o ambiente
Configurando o PC
Clique com o boto direito do mouse no cone do Hotsync
Introduo
O emulador uma tima ferramenta para se testar aplicaes em desenvolvimento. Transferir uma aplicao para o Emulador muito mais rpido do que para um dispositivo Palm.
Vantagens
1) O Hotsync com o emulador mais rpido que o realizado com o prprio dispositivo; 2) Capacidade de testar vrios modelos diferentes de dispositivos; 3) Capacidade de configurar diferentes usurios; 4) No gasta bateria; 5) No necessita porta serial;
1. Marque a opo Network. As outras opes (Local e Modem) tambm podem estar marcadas.
Verso do Palm OS
O sincronismo em rede, que permite o Hotsync com o emulador, est disponvel nas verses do PalmOS superiores a 3.0, ou seja, a ROM utilizada no emulador dever ser de uma verso igual ou superior a esta. Entre na opo de Setup.
MeGAZINE
DELPHI
1 - Escolha a aba Network.
3 - Clique neste boto para ver e anotar os dados de TCP/IP da sua estao de trabalho.
Configurando o Emulador
1 - Clique com o boto direito do mouse sobre o emulador e escolha: Settings e em seguida Properties. Preencha a caixa HotSync User Name com o nome do usurio que ser utilizado para efetuar o sincronismo.
MeGAZINE
DELPHI
5 -Selecione no menu a opo Primary PC Setup. 2 - Selecione a aplicao HotSync
Escreva em Primary PC Name ou em Prymary PC Address os dados anotados do TCP/IP Settings de sua mquina.
6 - Selecione Modem na tela principal do HotSync Clique em seguida em Select Service. 7 - Voc pode deixar marcado o servio default. Service: Aimnet 4 -Selecione no menu a opo LANSync Prefs Em seguida entre com o telefone 00. 8 - Agora clique no cone do HotSync e ele ir acontecer.
MeGAZINE
.NET
MeGAZINE
.NET
Na classe do formulrio, crie um mtodo como o mostrado a seguir. O nome do mtodo e dos argumentos podem variar, mas os tipos dos argumentos devem ser mantidos: public void DeuPau(object sender, System.Threading.ThreadExceptionEventArgs t) { // Trata exception MessageBox.Show (this, t.Exception.Message, Deu Pau); } onde a exception foi gerada; Embora estejamos fazendo o tratamento no formulrio principal, ele funciona para todos os formulrios.
Testando
Para testar o nosso programa, devemos causar o disparo de algumas exceptions. Acrescente botes ao formulrio:
Coloque o cdigo seguinte para processar os eventos Click: // Diviso por zero private void button1_Click(object sender, System.EventArgs e) { decimal x = 0; decimal y = 10 / x; Text = y.ToString(); } // Arquivo no existe private void button2_Click(object sender, System.EventArgs e) { System.IO.StreamReader Arq = new System.IO.StreamReader(xxx.www); } // Acesso a referncia nula private void button3_Click(object sender, System.EventArgs e) { object O = null; Text = O.ToString(); } // Cast invlido
MeGAZINE
.NET
private void button4_Click(object sender, System.EventArgs e) { int i = 10; object O = i; double d = (double) O; } // Converso invlida private void button5_Click(object sender, System.EventArgs e) { Convert.ToInt32(Z); } Veja um exemplo do tratamento: public void DeuPau(object sender, System.Threading.ThreadExceptionEventArgs t) { // Trata exception string Msg; if (t.Exception is DivideByZeroException) Msg = No posso dividir por zero; else if (t.Exception is System.IO.IOException) Msg = Problema no acesso a arquivo; else if (t.Exception is NullReferenceException) Msg = Referncia nula acessada; else if (t.Exception is InvalidCastException) Msg = Problema na converso de tipos; else if (t.Exception is FormatException) Msg = No posso converter o texto suprido; else Msg = Exception desconhecida\r\n + t.Exception.Message; MessageBox.Show(this, Msg, Deu Pau); }
Concluso
O tratamento global de exceptions, embora esteja longe de resolver todas as questes relacionadas ao tema, uma tcnica til para fazer um tratamento simples.
10
MeGAZINE
ORACLE
Neste ms, vamos discutir algumas dicas bastante teis para programao SQL e para administrao de bases Oracle. Divirtam-se!
por exemplo, que equivale ao limite de crdito do cliente, podemos desejar ver apenas os registros mais significativos, que contm os maiores limites de crdito. Podemos para isso utilizar ento a clusula ROWNUM e definir para ela um parmetro, que corresponder ao nmero de linhas que iremos desejar no retorno do SELECT. Veja que simples:
MeGAZINE
11
ORACLE
evidente que iremos obter tantos registros quantos forem os clientes com negcios dentro da seleo que fizermos, o que nem sempre necessrio e importante para nossas anlises. Podemos desejar como resultado, por exemplo, apenas os clientes com mais de R$ 3.150.000,00 de pedidos acumulados. Para isso, podemos utilizar a clusula HAVING dentro de nosso GROUP BY. Veja que simples:
12
MeGAZINE
ORACLE
Agora temos apenas os clientes que tem vendas acumulada acima do parmetro que definimos na clusula HAVING. Simples no?
Vamos utilizar ento essa VIEW para listarmos, em ordem de TIPO DE OBJETO e depois de NOME DE OBJETO, todos os objetos do usurio em que estivermos conectados:
MeGAZINE
13
ORACLE
A partir da fica fcil, por exemplo, listarmos apenas os objetos TABLE do usurio, em ordem de nome do objeto:
Simples tambm no mesmo? Voc vai notar, contudo, que os objetos CONSTRAINT no aparecem nessa VIEW, porque na verdade so objetos que dependem da existncia de outros e esto relacionados na VIEW USER_CONSTRAINTS. No prximo ms continuaremos com novas e interessantes dicas. At l!
14
MeGAZINE
DELPHI
MeGAZINE
15
DELPHI
16
MeGAZINE
DELPHI
mostrar a caixa de dilogo. Se o usurio escolher um arquivo e clicar no boto OK, o cdigo verifica se o ClientDataSet, cdsBlob, est em modo Browse. Neste caso o mtodo Edit do ClientDataSet chamado. Depois o mtodo LoadFromFile chamado para carregar o contedo do arquivo selecionado para dentro do campo Binary_Data do registro corrente. procedure TfrmBmp.btnLoadFileClick(Sender: TObject); begin with OpenBmpDlg do begin InitialDir := ExtractFilePath( Application.ExeName + gFileDir); if not Execute then Exit; end; if dmMain.cdsBlob.State = dsBrowse then dmMain.cdsBlob.Edit; dmMain.cdsBlobBinary_Data.LoadFromFile( OpenBmpDlg.FileName); end; Figura2: Cdigo do boto Load File do form BitMap Este cdigo s trabalha porque o campo cdsBlob ClientDataSet foi instanciado em tempo de design usando o Fields Editor, assim que o objeto instanciado TBlobField chamado cdsBlobBinary_Data poderia se usado para chamar o mtodo LoadFromFile. Se voc tentar usar: dmMain.cdsBlob.FieldByName(Binary_Data). LoadFromFile(OpenBmpDlg.FileName; voc receber um erro Undeclared identifier:LoadFromFile . Isto acontece porque o mtodo FieldByName retorna uma referencia de objeto TField e TField no tem o mtodo LoadFromFile. Se voc quer usar o FieldByName ou o array de Fields para acessar os campos, voc ter que converter a referncia para TBlobField como mostrado na instruo abaixo: dmMain.cdsBlob.TBlobField(FieldByName(Binary_Data )).LoadFromFile(OpenBmpDlg.FileName; O boto Save File do form BitMap usa um cdigo quase igual. A nica diferena que ele usa um TSaveDialog e chama o mtodo SavetoFile O BitMap o tipo mais fcil para se trabalhar com o Delphi, porque ele pode ser mostrado atravs de um componente DBImage. O nico truque para mostrar bitmaps como voc quer controlar o tamanho da imagem em relao ao tamanho do componente DBImage. Existem duas escolhas. A primeira, mostrar o bitmap com o tamanho atual configurando a propriedade Strech do DBImage para False. Se o Bitmap for maior que o componente DBImage, voc s poder ver parte da imagem. Isto provavelmente insatisfatrio desde que no exista um caminho para adicionar um scroll bar para o DBImage para permitir que os usurios movam para outras reas da imagem. Resolver o problema em relao a largura e altura fcil se todas as imagens tiverem o mesmo tamanho. Tudo o que voc tem que fazer ter certeza de configurar as propriedades Width e Height do DBImage para estar compatvel em relao a largura e altura dos seus bitmaps em tempo de design. O exemplo tem bitmaps em ambas orientaes portrait e landscape. Para resolver o problema, o mtodo SetImageSize, mostrado na figura 4, foi chamado a partir do evento AfterScroll do ClientDataSet cdsBlob. O DBImage tem uma propriedade Picture do tipo TPicture que uma referncia ao objeto TPicture que guarda o bitmap. O SetImageSize usa as propriedades Picture.Width e Picture.Height do DBImage para determinar se a orientao da imagem portrait ou landscape. Se a orientao for portrait, o mtodo configura a altura do DBImage para a altura do painel que o contm menos dois pixels e calcula a largura do DBImage para preservar a relao entre a largura e a altura. Se a orientao for landscape, o mtodo configura a largura do DBImage para a largura do painel menos dois pixels, e calcula a altura para manter a relao entre a largura e a altura. procedure TfrmBmp.SetImageSize; begin if dbiBmp.Picture.Height > dbiBmp.Picture.Width then begin if dbiBmp.Picture.Height > 0 then begin dbiBmp.Height := pnlBmp.Height - 2; dbiBmp.Width := Trunc(dbiBmp.Height * (dbiBmp.Picture.Width / dbiBmp.Picture.Height)); dbiBmp.Left := (pnlBmp.Width-dbiBmp.Width) div 2; dbiBmp.Top := 1; end; end else if dbiBmp.Picture.Width > 0 then begin dbiBmp.Width := pnlBmp.Width - 2; dbiBmp.Height := Trunc(dbiBmp.Width * (dbiBmp.Picture.Height / dbiBmp.Picture.Width)); dbiBmp.Top := (pnlBmp.Height-dbiBmp.Height)
MeGAZINE
17
DELPHI
div 2; dbiBmp.Left := 1; end; end; Figura 4: O mtodo SetImageSize Para pegar uma imagem que est no DBImage e jog-la para a rea de transferncia, chame a propriedade CopyToClipboard do componente DBImage. Para colar um bitmap da rea de transferencia para um DBImage, chame o mtodo PasteFromClipBoard. Veja na figura 5 cdigo do boto Copy and Paste. procedure TfrmBmp.btnCopyClipboardClick (Sender: TObject); begin dbiBmp.CopyToClipboard; end; procedure TfrmBmp.btnPasteClick(Sender: TObject); begin dbiBmp.PasteFromClipboard; end; Figura 5: Evento OnClick do boto Copy and Paste. Uma das desvantagens do bitmap que neste formato no h compresso, ento os arquivos so muito grandes. Se voc precisar salvar um bitmap para um arquivo e quiser diminuir o seu tamanho, voc pode convert-lo para o formato JPEG. O formato JPEG diminui muito o tamanho do arquivo. Veja na figura 6 o cdigo para salvar a imagem bitmap para jpeg. Este mtodo inicia criando uma instncia da classe TJpegImage. O cdigo converte o bitmap que est sendo mostrado no DBImage chamando o mtodo Assign do objeto JpegImage, e passando a propriedade Bitmap do objeto Picture referenciado pela propriedade Picture do componente DBImage como parmetro. Isto converte o bitmap para jpeg. Depois o mtodo SaveToFile do objeto JPegImage chamado para salvar a imagem para o arquivo BitMap.jpg. Finalmente o objeto JPegImage liberado. Voc pode reduzir a compresso e aumentar a qualidade da imagem jpeg modificando a propriedade CompressionQuality do objeto JpegImage como descrito no help.
procedure TfrmBmp.btnSaveJpegClick(Sender: TObject); var JpegImage: TJpegImage; begin JpegImage := TJpegImage.Create; try JpegImage.Assign(dbiBmp.Picture.Bitmap); JpegImage.SaveToFile(ExtractFilePath( Application.ExeName) + gFileDir + Bitmap.jpg); finally JpegImage.Free; end; end; Figura 6: Salvando um bitmap para jpeg.
18
MeGAZINE
DELPHI
// carrega arquivo para o buffer BinFile.Read(Buff[1], BinFile.Size); // instrucao SQL para inserir a imagem. dmMain.ibsqlMisc.SQL.Add( INSERT INTO Blobs (Blob_Type, Binary_Data) + VALUES (:BlobType, :BlobData)); dmMain.ibtranMisc.StartTransaction; try // atribui parametros dmMain.ibsqlMisc.Params.ByName( BlobType).AsString := btBmp; dmMain.ibsqlMisc.Params.ByName( BlobData).AsString := Buff; // Executa query. dmMain.ibsqlMisc.ExecQuery; finally dmMain.ibtranMisc.Commit; end; finally BinFile.Free; end; end; dmMain.cdsBlob.Refresh; end; Figura 7: Cdigo do evento OnClick do boto Insert Query. O data module do exemplo contm um componente IBSQL, ibsqlMisc, que usado para inserir um novo registro. A instruo INSERT INTO Blobs (Blob_Type, Binary_Data) VALUES (:BlobType, :BlobData) incluida na propriedade SQL se o componente IBSQL e os valores forem informados para os dois parmetros na instruo SQL. Note que o parmetro BlobData informado usando a sua propriedade AsString da varivel string Buff que contm o bitmap. Finalmente o cdigo comea uma transao, executa a query, d um commit na transao e libera o FileStream. A atualizao de um campo Blob em um registro existente feito exatamente da mesma forma. Isto pode parecer estranho para usar uma varivel string para armazenar o Blob, mas esta nica opo disponvel para os componentes IBSQL e IBDataSet porque seus parametros esto em uma propriedade AsBlob. Se voc est usando componente dataset do BDE ou qualquer outro componente dataset que usem o objeto TParam para parametros, voc ter a opo de usar a propriedade AsBlob. Voc pode usar um PCHAR para armazenar o Blob e informar o PCHAR para o parmetro usando: Query1.ParamByName(BlobData).AsBlob := SomePCharThatContainsTheBlob;
MeGAZINE
19
DELPHI
end; finally Jpg.Free; end; end; Figura 8: Mtodo que mostra um JPEG da tabela em um componente Image. O LoadImageFromFile tem dois parametros. O primeiro o componente Image que ser usado para mostrar a imagem JPEG. O segundo o campo BlobField para o campo que contm a imagem JPEG. O mtodo comea checando se o campo tem alguma informao. Se no, ele configura a propriedade Picture do componente Image para nil. Se o campo contm informao, instancias do objeto TJPEGImage e do objeto MemoryStream sero criadas. Depois o mtodo SaveToStream do objeto BlobField chamado para copiar a imagem JPEG do campo para o MemoryStream. O cdigo do bloco with configura as propriedades do objeto JPEGImage e chama o mtodo LoadFromStream para carregar a imagem JPG no objeto JPEGImage do MemoryStream. Usando a rea de transferncia com um componente Image diferente de usar a rea de transferencia com o componente DBImage, como mostrado na figura 9. Visto que o componente Image no tem o mtodo Clipboard, o objeto Clipboard do Delphi usado para copiar uma imagem fora de, ou colar uma imagem dentro, do componente Image. procedure TfrmJpeg.btnCopyClipboardClick(Sender: TObject); begin Clipboard.Open; Clipboard.Assign(imgJpeg.Picture); Clipboard.Close; end; procedure TfrmJpeg.btnPasteClipboardClick(Sender: TObject); begin imgJpeg.Picture.Bitmap.Assign(Clipboard); end; Figura 9: Cdigo dos botes Copy e Past do form JPEG. A figura 10 mostra como converter uma imagem JPEG para um bitmap e salv-lo em um arquivo. Um objeto Bitmap criado e o mtodo Assign chamado para converter o JPEG do componente Image para um bitmap e l-lo no objeto BitMap. Salvar o bitmap para um arquivo realizado chamando o mtodo SavetoFile do objeto BitMap. procedure TfrmJpeg.btnSaveAsBmpClick(Sender: TObject); var BmpImage: TBitmap; begin BmpImage := TBitmap.CREATE; try BmpImage.Assign(imgJpeg.Picture.Graphic); BmpImage.SaveToFile(ExtractFilePath( Application.ExeName) + gFileDir + Jpeg.bmp); finally BmpImage.Free end; end; Figura 10: Converting um JPEG para um bitmap. Veja o cdigo do evento OnClick boto Save BMP to DB mostrado na figura 11. Este cdigo mostra como usar BlobStream para ler uma imagem de qualquer objeto que tenha um mtodo SaveToStream. Este exemplo cria um objeto Bitmap como um bitmap. O mtodo ento insere um novo registro no ClientDataSet determinando um valor para o campo Blob_Type, cria um objeto BlobStream, e chama o mtodo SaveToStream para carregar o bitmap no campo. Finalmente o BlobStream liberado, o registro gravado e o Bitmap liberado. Note que voc deve liberar o BlobStream antes de gravar o registro ou o campo ser nulo. procedure TfrmJpeg.btnSaveBmpToDbClick(Sender: TObject); var BmpImage: TBitmap; Bs: TStream; begin BmpImage := TBitmap.Create; try BmpImage.Assign(imgJpeg.Picture.Graphic); with dmMain.cdsBlob do begin Insert; dmMain.cdsBlobBLOB_TYPE.AsString := btBmp; Bs := CreateBlobStream( dmMain.cdsBlobBinary_Data, bmWrite); try BmpImage.SaveToStream(Bs); finally Bs.Free;
20
MeGAZINE
DELPHI
end; Post; end; finally BmpImage.Free; end; end; Figura 11: Usando o BlobStream para carregar um BLOB dentro do campo da tabela. Neste caso especifico, onde a imagem era um objeto Bitmap, isto seria mais fcil chamar o mtodo Assign do BlobField para pegar o bitmap do campo. De qualquer forma, se o bitmap ou JPEG era um MemoryStream, FileStream ou qualquer outro onde Assign no poderia ser usado, voc precisaria usar um BlobStream: dmMain.cdsBlobBinary_Date.Assign(BmpImage); O cdigo da figura 12 comea criando um BlobStream. Isto feito atravs do mtodo CreateBlobStream e passando o objeto field para o campo como primeiro parmetro. O segundo parmetro o modo: bmRead, bmWrite ou bmReadWrite. Depois um MemoryStream criado e o dado BLOB copiado no MemoryStream chamando o mtodo Copy do MemoryStream. Copy tem dois parmetros, a origem dos dados, neste caso o BlobStream e o numero de bytes para cpia. A propriedade Size do BlobStream passada como o parmetro de tamanho de forma que os contedos inteiros do campo Blob sejam copiados para o MemoStream. O WAV tocado chamando uma funo da API do Windows chamada Playsound. PlaySound passado como parametro para a procedure Win32Check, que checa o valor retornado PlaySound e apresenta uma exceo se o valor retornado indicar um erro. PlaySound d trs parmetros. O primeiro indica a origem do som e pode ser o nome do arquivo, nome de recurso ou ponteiro para localizao da memria onde o som est localizado. Se o primeiro parmetro indicar um recurso, o segundo parmetro o controle do executvel que contm o recurso; de qualquer forma, o segundo parmetro nil. O terceiro parmetro consiste de uma ou mais constantes logicamente ordenadas juntamente para identificar a origem do som e a ao para tomar. Na figura 12, o terceiro parmetro SND_SYNC ou SND_MEMORY para indicar que o primeiro parmetro um ponteiro para a localizao da memria que contm o inicio do som e que a funo PlaySound no deve retornar at que o som tenha terminado. Finalmente, ambos o MemoryStream e BlobStream so liberados. Voc pode tocar um AVI usando o componente MediaPlayer do Delphi; de qualquer forma o MediaPlayer pode s usar dados em arquivos no disco. A figura 13 mostra o cdigo do evento OnClick do form Other. Este mtodo fecha o MediaPlayer, salva o contedo do campo Binary_Data no registro corrente do ClientDataSet para o disco usando o mtodo SavetoFile do objeto BlobField, ento configura a propriedade FileName do MediaPlayer para o arquivo. O usurio pode agora utilizar os botes do componente MediaPlayer para tocar o AVI. procedure TfrmOther.MediaPlayerClick(Sender: TObject; Button: TMPBtnType; var DoDefault: Boolean); begin
MeGAZINE
21
DELPHI
MediaPlayer.Close; dmMain.cdsBlobBinary_Data.SaveToFile(ExtractFilePath( Application.ExeName) + gFileDir + Temp.avi); MediaPlayer.FileName := ExtractFilePath( Application.ExeName) + gFileDir + Temp.avi; MediaPlayer.Open; end; Figura 13: Evento OnClick do MediaPlayer Bs.Free; end; dmMain.cdsBlob.Post; end; Figura 14: Salvando um array para um campo Blob. A figura 15 mostra o cdigo do boto Save Array. Aqui um BlobStream criado e o mtodo Read chamado para ler os dados do campo Blob no array inteiro. procedure TfrmOther.btnShowArrayClick(Sender: TObject); var A: array[1..10] of Integer; Bs: TStream; I: Integer; S: string; begin // no executar se o tipo no for Binary. if dmMain.cdsBlobBlob_Type.AsString <> btBinary then Exit; // grava o registro se no estiver em modo Browse. if dmMain.cdsBlob.State <> dsBrowse then dmMain.cdsBlob.Post; // Cria o BlobStream. Bs := dmMain.cdsBlob.CreateBlobStream( dmMain.cdsBlobBinary_Data, bmRead); try // Carrega os dados a partir do BlobStream para // o Array. I := Bs.Read(A, Bs.Size); finally Bs.Free; end; // Mostra os valores. for I := 1 to 10 do S := S + IntToStr(A[I]) + -; ShowMessage(S); end; Figura 15: Evento OnClick do boto Show Array
22
MeGAZINE
DELPHI
Trabalhando com texto
O Delphi fornece muitos caminhos para facilmente pegar um texto dentro de, ou fora de, um campo memo da tabela. O componente DBMemo torna isto fcil para os usurios incluirem e editarem o texto. Os mtodos LoadFromFile e SaveToFile do objeto BlobField tornam fcil pegar um texto de, ou export-lo para, um arquivo. O contedo do campo memo pode ser designado para uma varivel string e qualquer string Delphi manipula rotinas usadas para modificar o texto. Se voc quer trabalhar com o conteudo do texto do campo memo via cdigo como um array de linhas, determine o campo para a propriedade Text um StringList. O form Text uma aplicao que demonstra os mtodos LoadFromFile e SaveToField do objeto BlobField, e assim como os mtodos CopyToClipboard e PasteFromClipboard do componente DBMemo. De qualquer forma existem algumas caracteristicas que no esto disponveis no DBMemo. Por exemplo, no h como pegar a posio do cursor como um nmero de linha e coluna. A procedure GetMemoLineCol mostrada na figura 16 mostra como fazer isto usando a API do Windows. Esta procedure pega o componente Memo como primeiro parmetro. Note que o parmetro do tipo TCustomMemo assim voc pode passar tambm um Memo ou um DBMemo. O segundo e o terceiro parmetro so parmetros var usados para retornar os numeros de linha e coluna. A procedure comea chamando a funo SendMessage e passando a propriedade Handle do componente Memo como primeiro parmetro. O segundo parmetro a constante EM_LINEFROMCHAR, que fala ao componente Memo que deveria retornar o nmero da linha que contm a posio de um caracter. O terceiro parmetro a propriedade SelStart do componente Memo, que fornece a posio do cursor como um balano entre o inicio do memo. O quarto parmetro no usado. A coluna que o cursor est calculada subtraindo a posio do cursor do inicio da linha, retornado pelo SendMessage usando a constante EM_LINEINDEX constante na posio do cursor contido na propriedade SelStart. Esta procedure chamada pelo mtodo UpdateCursorPos no form Text, que mostra a linha e a coluna corrente no status bar. UpdateCursorPos chamado no evento OnCreate do form e nos eventos OnKeyDown e OnMouseDown do componente DBMemo. // Retorna a posio do cursor no memo. procedure GetMemoLineCol(Memo: TCustomMemo; var MemoLine, MemoCol: Integer); begin with Memo do begin // linha MemoLine := SendMessage(Handle, EM_LINEFROMCHAR, SelStart, 0); // coluna MemoCol := SelStart - SendMessage ( Handle, EM_LINEINDEX, MemoLine, 0) + 1; end; end; Figura 16: A procedure GetMemoLineCol A procedure MemoCursorTo da figura 17 permite voc configurar a posio do cursor para especificar a linha e coluna. Esta procedure posiciona o cursor do componente Memo determinando um valor para a propriedade SelStart. SelStart deve ser especificada como uma posio do inicio do texto. O nmero da linha convertido para a posio chamando SendMessage com a constante EM_LINEINDEX, apenas com a procedure GetMemoLineCol mostrada na figura 14, e adicionando o nmero da coluna menos um para ele. // Manda o cursor para determinada posio no Memo. procedure MemoCursorTo(Memo: TCustomMemo; MemoLine, MemoCol: Integer); begin with Memo do SelStart := SendMessage(Handle, EM_LINEINDEX, MemoLine, 0) + MemoCol - 1; end; Figura 19: A procedure MemoCursorTo.
Concluso
Trabalhando com campos BLOB no Delphi fcil e flexvel, uma vez voc entendendo as ferramentas que esto disponveis e tambm como us-las. Voc pode armazenar qualquer string de bytes em um campo Blob apesar de que os bytes representam. Eles poderiam ser uma foto, um documento do Word, som, um filme, um array ou qualquer coisa que possa ser armazenada em um arquivo binrio no computador. O download do arquivo est disponvel no endereo: http://www.theclub.com.br/revista/Blobs0302.zip
MeGAZINE
23
DELPHI
FireBird
Interbase 6 Open-Source
Como todos sabem, em meados de Janeiro de 2000 a Borland anunciou a abertura do cdigo fonte do RDBMS Interbase, ou seja, o banco agora Open-Source. O nome Interbase at ento, no era to conhecido como os famosos Oracle e Microsoft SQL Server , ouvamos comentrios de que era um excelente banco de dados, porm devido a falta de informao e mesmo marketing a respeito do produto, o mesmo no era muito popular no Brasil, porm sendo utilizado por um nmero at razovel de Empresas e Desenvolvedores. Porm, agora sendo Open-Source imediatamente houve uma grande euforia por parte de ns Programadores, pois cansados dos problemas com tabelas Paradox ou ainda sem dispor de valores razoavelmente altos para licenciar os Bancos disponveis no mercado, o Interbase caiu do cu. Infelizmente a alegria no durou muito tempo! Pouco tempo aps a Borland anunciaria que o projeto Open-Source no teria continuidade e que verses futuras do Interbase necessitariam de licenas de uso, assim como os famosos bancos de dados j conhecidos por ns, apesar de ter um custo at razovel comparado a outros Bancos de seu porte. Recentemente a Borland lanou o Interbase 6.5 onde traz algumas implementaes, tais como: Metadata Security 64 Bit file I/O Asynchronous Cancel SQL Data Manipulation (ROWS clause) New isc_config/ibconfig File Parameters
Como Funciona?
No desenvolvimento Open-Source existe a colaborao de vrios programadores espalhados pelo mundo inteiro interessados no Projeto, os quais do sua colaborao das mais variadas formas tendo a coordenao de Ann Harrison no caso do FireBird. No site do Projeto FireBird voc poder encontrar diversas informaes sobre o desenvolvimento, bem como a lista completa dos Programadores que esto contribuindo com o Projeto. Veja onde o FireBird pode ser encontrado TOTALMENTE freeware: www.theclub.com.br
24
MeGAZINE
DELPHI
www.ibphoenix.com www.firebirdsql.org http://firebird.sourceforge.net ( /* seus campos */ );
MeGAZINE
25
DELPHI
SELECT RTRIM(NOME), COUNT(*) AS TOTAL FROM CLIENTES GROUP BY RTRIM(NOME); Onde est a funo SUBSTRING que at o Paradox aceita? At o Interbase 6, era necessrio registrar a funo SUBSTR() para fazer a vez do SUBSTRING() to conhecida pelos usurios do Paradox. Porm agora no FireBird ela vem nativa na linguagem SQL no sendo necessrio registrar nenhuma UDF para isso. SELECT SUBSTRING(NOME FROM 1 FOR 10) FROM CLIENTES; Instruo DROP GENERATOR At a verso 6 do Interbase tnhamos que remover um Generator no brao fazendo um DELETE na tabela de sistema RDB$GENERATORS, porm agora possvel via DDL. DROP GENERATOR GEN_ID_CLIENTES; PLANONLY Permite verificar o PLAN escolhido pelo Banco sem que a Query seja executada. Veja mais informaes sobre PLAN em nossa revista de Dezembro/2001 Performance no Interbase. Nova biblioteca de funes de usurio (UDF) O FireBird agora tem uma nova UDF de funes que est contida na FBUDF.DLL e traz vrias funes interessantes. Apesar de ter esta nova biblioteca de funes, a conhecida IB_UDF.DLL (que acompanha o Interbase 6) suportada sem problemas. O que foi corrigido at agora? As implementaes e novidades no seriam completas se no houvesse melhorias no contexto geral do Banco de Dados que infelizmente no est livre de Bugs. At o momento diversos Bugs foram corrigidos e vrios outros detectados e que certamente sero corrigidos em Releases futuros! No site do Projeto FireBird voc poder encontrar documentao completa do que foi corrigido at o momento e o que ainda est para ser corrigido. Meu GDB do Interbase 6 compatvel com o FireBird? Felizmente SIM! Ser necessrio apenas um Backup / Restore para fazer a migrao para o FireBird. Isso poder ser feito via linha de comando atravs do GBAK, vamos a instruo: Ainda no Interbase 6: gbak t seu_banco.gdb seu_banco.gbk user sysdba password masterkey Agora no FireBird 1.00: gbak r p <tam_pag> c:\seu_banco.gbk c:\seu_banco.gdb user sysdba password masterkey Se preferir poder utilizar o IBConsole para fazer o Backup / Restore. Por que devo fazer a migrao? Voc no obrigado fazer a migrao e se preferir poder continuar utilizando o Interbase 6.01 sem problema nenhum! Porm sabemos que por parte da Borland no haver nenhuma implementao ou correo de Bugs no Interbase 6.01 e que se desejar isso dever adquirir licenas do Interbase 6.5 que como j mencionamos no FREEWARE, ao passo que no FireBird voc ter um RDBMS totalmente FREE e com a certeza da continuidade do cdigo fonte aberto ou seja Open-Source, com implementaes, correes de Bugs e a sua participao em tudo isso se desejar! Porm, voc no precisa se desesperar para fazer a migrao. Se seu aplicativo est rodando sem problemas, voc poder com o tempo ir portando seu banco para o FireBird se preferir ou deixla como est. Quanto Instalei o FB no encontrei o IBConsole Bom, o IBConsole na realidade uma entre diversas ferramentas de administrao existentes no mercado. Ela, porm pertence ao Interbase 6 e pelo que pude ver at o momento no acompanha o FiredBird, porm isso no problema! Veja abaixo uma relao de ferramentas que poder utilizar: IBAccess www.ibaccess.org ou http://sourgeforge.net OpenSource/FREE IBExpert www.ibexpert.com Trial QuickDesk www.ems-hightech.com Trial IBworkbench http://www.interbaseworkbench.com/ Trial No endereo http://www.ibphoenix.com/ ibp_contrib_download.html#ADMIN poder ver mais ferramentas para administrao do Interbase e FireBird. Fique atento as novidades sobre o FireBird nos sites do Projeto e aqui na The Club Megazine, pois com certeza, vem mais coisa por ai, at a prxima.
26
MeGAZINE
DELPHI
Eventos
Anderson Haertel Rodrigues
Em linguagens de programao orientada a Objeto, temos a liberdade de criar nossas prprias Classes, nossos prprios Objetos, nossos prprios Componentes, usamos, Herana, Encapsulamento, Polimorfismo, etc, etc, etc.. Podemos tambm criar nossos prprios eventos, isto mesmo, criar nossos mtodos baseados na classe TNotifyEvent e ou ainda, criar novos eventos com parmetros prprios usando ponteiros de mtodos. Na realidade TNotifyEvent tambm um ponteiro de mtodo , declarado na unit: Classes.pas Mas, na realidade, o que um Evento? Evento a capacidade do componente em reagir a algo em que o usurio solicitou. Algo como: A) O Clique do Mouse; B) DragDrop; C) Uma tecla pressionada D) Etc. ... end; Note que temos duas partes na declarao de um evento. Primeiro, um evento requer uma varivel de dados interna, onde nesta varivel que fica armazenado o ponteiro de mtodo, e segunda, criado uma propriedade para permitir ao desenvolvedor criar o Handler de Evento em tempo de projeto.
Handlers de Eventos
So mtodos que geralmente se encontram no formulrio onde se encontra o componente que gerou o evento. O Handler de evento criado quando o usurio seleciona o Object Inspector do Delphi e escreve o mtodo associado ao Evento. Um exemplo seria o evento OnClose do Formulrio.
Eventos Padro
Todos os componentes descendentes da classe TControl herdam um conjunnto de eventos padro e, todos os componentes descendentes da classe TwinControl herdam um conjunto de eventos para controle de janelas.
Estrutura de um Evento
type TControl = Class(TComponent); private FOnClick: TNotifyEvent; FOnMouseDown: TMouseEvent; protected property OnClick : TnotifyEvent read FOnClick write FOnClick; ... property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown public published
MeGAZINE
27
DELPHI
protected procedure Click; Override; end; procedure TButtonNew.Click; begin inherited Click; { Definio do cdigo. } end; utilizamos a mesma palavra reservada do Delphi para criao de propriedades property. Leia novamente Visualizao de eventos no Object Inspector se voc tiver dvidas de como o Delphi sabe diferenciar propriedades de eventos.
then
Ok. No tem mistrios para a chamada do mesmo. Atento para o fato de que o resto do cdigo no necessrio, podendo ser utilizado em vrias situaes. Explicando o cdigo acima: A funo Assigned usada para verificar se o mtodo de despacho est apontando para algo, neste caso, um ponteiro de mtodo. A funo Assigned() no usada apenas para ponteiros de mtodos, pode ser usada para qualquer tipo de ponteiro. Self, o objeto atual. Neste caso, pode ser um: TDataSet, TDBGrid... enfim, vai de acordo com a sua necessidade.
A criao de Eventos
S existem duas formas para criarmos eventos. A) Criarmos eventos descendentes direto de TNotifyEvent; B) Criarmos o nosso prprio tipo de evento, com parmetros personalizados;
28
MeGAZINE
DELPHI
begin protected procedure NumLock; published property OnNumLock: TNumLock read FOnNumLock write FOnNumLock; end; O que devemos fazer agora, criarmos o mtodo de despacho personalizado para o evento: procedure TNumLockStatus.NumLock; end; if Assigned(FNumLock) then FNumLock(Self, IsNumLock) ;
Concluso:
Neste artigo, mostro como criar eventos padro e personalizados para seus componentes. Mostrei o conceito de um evento, onde usa-lo e como criar eventos. A criao de eventos , um poderoso recurso que a linguagem Delphi nos oferece. Sucesso a todos e at a prxima, Anderson Haertel Rodrigues - AHR.
MeGAZINE
29
30
MeGAZINE