Anda di halaman 1dari 32

fevereiro 2012

fevereiro 2012

ndice
Editorial
Chegou fevereiro e com ele a nossa maior festa popular. O Carnaval. Ento vamos todos aproveitar e festejar bastante! Sem se esquecer ...

Delphi

Delphi

04 14

Ler e exibir o Contedo de vrios arquivos de texto utilizando DragDrop


Autor: Eduardo Massud

05 28

Criando uma aplicao ClientServer no Delphi - Parte IV


Autor: Luciano Pimenta

08 30
03

Delphi
Android - Criando uma tela de Venda

Delphi
Conexo ao Firebird em Lazarus

Autor: Thiago C. Montebugnoli

Autor: Antonio Spitaleri Neto

22

Mtodos RAVReport - de A a Z parte 4

Autor: Leonora Golin

26

Dicas
- Dicas Delphi

Desafio The Club


- Cruzada

Legenda
Iniciante Intermedirio Avanado
fevereiro 2012

Bem-vindo
Chegou fevereiro e com ele chega nossa maior festa popular. O Carnaval. Ento vamos todos aproveitar e festejar bastante! Sem se esquecer que depois da folia o trabalho prossegue. Ento nada melhor que ler os artigos desse ms para que a volta ao batente seja bem produtiva. Para comear temos o artigo de nosso consultor Eduardo Massud mostrando como manipular arquivos no Delphi utilizando o recurso Drag and Drop. Na sequncia temos o artigo Criando uma aplicao Client Server no Delphi parte 4 onde nosso colaborador Luciano Pimenta segue mostrando como desenvolver uma aplicao Delphi baseada na robustez da arquitetura Client Server. Para quem pretende se aventurar pela plataforma Android, nosso colaborador Thiago Montebugnoli traz esse ms como criar uma tela de venda nesse plataforma. Para finalizar, sigo mostrando a vocs a ferramenta Lazarus. Esse ms trago o artigo Conectando Firebird ao Lazarus, onde demonstro como manipular bases de dados Firebird em Lazarus. isso. Bom carnaval a todos e at maro !
Av. Prof Celso Ferreira da Silva, 190 Jd. Europa - Avar - SP - CEP 18.707-150 Informaes e Suporte: (14) 3732-1529 http://www.theclub.com.br Cadastro: cadastro@theclub.com.br Suporte: suporte@theclub.com.br Informaes: info@theclub.com.br Skype Cadastro: theclub_cadastro Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

Internet

www.twitter.com/theclubbr

Copyright The Club Megazine 2009 Diretor Tcnico Marcos Csar Silva Diagramao Eduardo Massud Capa Vitor Manuel Rodrigues Reviso Eliziane Valentim Colunistas Antonio Spitaleri Neto Eduardo Massud Leonora Golin Luciano Pimenta Thiago Cavalheiro Montebugnoli Impresso e acabamento:
GRIL - Grfica e Editora Taquarituba-SP - Tel. (14) 3762-1345

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 Megazine so terminantemente proibidos sem autorizao escrita dos titulares dos direitos autorais. Delphi marca registrada da Borland International, as demais marcas citadas so registradas pelos seus respectivos proprietrios.

Antonio Spitaleri Neto - Editor Chefe antonio@theclub.com.br


04
fevereiro 2012

Delphi

Ler e exibir o contedo de vrios arquivos de texto utilizando o sistema de arrastar e soltar (Drag Drop).

A funo de arrastar e soltar tem tido grande viabilidade, por ser bem mais intuitiva de que a busca com a caixa de dilogo, utilizando um mtodo muito mais simples e eficaz que agiliza no reconhecimento dos arquivos, interagindo e dinamizando nos modos de integrao do aplicativo desenvolvido com o Sistema Operacional Ao criarmos a unit ser implementada a procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES; ela a responsvel por interpretar e gerenciar todo arquivo que arrastado para a aplicao.

Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, Menus, ExtCtrls, Grids, DBGrids, DB, DBClient, OleCtrls, SHDocVw; type TForm1 = class(TForm) Memo1: TMemo; StatusBar1: TStatusBar; OpenDialog1: TOpenDialog; ListBox1: TListBox; DataSource1: TDataSource; WebBrowser1: TWebBrowser; procedure Open1Click(Sender:

TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Close1Click(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure ListBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private function ArquivoSuportado(const Extensao: string):
fevereiro 2012

unit FmMain; interface uses Windows, Messages, SysUtils, Classes,

05

Boolean; procedure Incluir(const Arquivo: string); procedure Exibir(I: Integer); procedure WMDropFiles(var Msg: TWMDropFiles); message WM_ DROPFILES; public { Public declarations } end; var Form1: TForm1; implementation

que servir para consultar se o arquivo permitido ou invlido

procedure TForm1. FormCreate(Sender: TObject); begin DragAcceptFiles(Self. Handle, True); end;

Exibir(ListBox1.Items. Add(Arquivo)) else ShowMessageFmt('Tipo de Arquivo no suportado', [Arquivo]); end;

Ao fecharmos o executvel, removemos todos os arquivos listados e abertos pelo ListBox, limpando-o

procedure TForm1. FormDestroy(Sender: TObject); begin DragAcceptFiles(Self. Handle, False); end; procedure TForm1. WMDropFiles(var Msg: TWMDropFiles); var I: Integer; Catcher: TFileCatcher; begin inherited; Catcher := TFileCatcher. Create(Msg.Drop); try for I := 0 to Pred(Catcher.FileCount) do Incluir(Catcher. Files[I]); finally Catcher.Free; end; Msg.Result := 0; end; procedure TForm1. Incluir(const Arquivo: string); begin procedure TForm1. Close1Click(Sender: TObject); var ItemIdx: Integer; begin ItemIdx := ListBox1. ItemIndex; if ItemIdx > -1 then begin ListBox1.Items. Delete(ItemIdx); if ItemIdx >= ListBox1.Items.Count then Dec(ItemIdx); Exibir(ItemIdx); end; end;

Na clausula Uses da seo implementation devemos declarar as funes ShellAPI e UFileCatcher que sero responsveis por reconhecer o arquivo recebido.

uses ShellAPI, UFileCatcher; {$R *.dfm}

Ser includa tambm uma constante com o nome de Extenses, que receber todas as extenses que podero permitir que os arquivos possam ser interpretados ao serem selecionados

Na procedure Exibir carregamos todos os arquivos para os componentes que iro permitir que sejam visualizados

const Extensoes = '*.txt;*. log;*.html;*.htm;*.xml;'; { TForm1 }

Para que possamos habilitar o sistema de arrastar e soltar devemos criar 3 procedimentos que sero de inicializao, finalizao e do momento em que estes arquivos so transferidos, e outro
06
fevereiro 2012

if ArquivoSuportado(Arquivo) then

procedure TForm1.Exibir(I: Integer); var FileName: string; begin if I >= 0 then begin FileName := ListBox1. Items[I]; ListBox1.ItemIndex := I; Memo1.Lines.

LoadFromFile(FileName); WebBrowser1. Navigate(FileName); StatusBar1.SimpleText := FileName; end else begin Memo1.Clear; StatusBar1.SimpleText := 'Nenhum arquivo selecionado!'; end; end; function TForm1. ArquivoSuportado(const Extensao: string): Boolean; begin Result := Pos('*' + ExtractFileExt(Extensao) + ';', Extensoes) > 0; end;

Figura 1 Aplicao em Execuo

Mesmo se tratando de um component Drag Drop, o Delphi executar algumas funes necessrias para que o arquivo seja recebido, como a listagem de registros ao selecionar o listbox e a utilizao do componente OpenDialog, que ir reconhecer o caminho daquele arquivo.

procedure TForm1. ListBox1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin try if Key = VK_DELETE Then ListBox1.Items. Delete(ListBox1. ItemIndex); Memo1.Clear; WebBrowser1.

Navigate('about:blank'); except end; end; end.

Veja a Figura 1

Concluso
O Sistema de arrastar e soltar sempre trouxe muito mais agilidade e simplicidade aos aplicativos por ser um mtodo mais intuitivo ao usurio.

procedure TForm1. ListBox1Click(Sender: TObject); begin Exibir(ListBox1. ItemIndex); end; procedure TForm1. Open1Click(Sender: TObject); begin if (OpenDialog1.Execute) then Incluir(OpenDialog1. FileName); end;

Sobre o autor
Eduardo Massud
Consultor Tcnico The Club.

eduardo@theclub.com.br

fevereiro 2012

07

Criando uma aplicao client-server no Delphi Parte IV


Continuaremos neste artigo a criao da nossa aplicao client-server com o Delphi. Fizemos no artigo anterior uma das partes mais importante do sistema, o cadastro de oramento. Agora, veremos outra parte importantssima que o cadastro de Ordem de servio. No sistema, pedido do nosso cliente, uma Ordem de servio, esta vinculada a um oramento. tela. Uma caracterstica que precisamos ter aqui ser de armazenar em memria, as peas/servios adicionados para a OS. Seria problemtico, em termos de performance, se fossemos adicionando ou removendo no banco, as peas/servios que faro parte da OS. Vamos colocar os dados em memria, e quando o usurio finalizar a OS, incluiremos tudo no banco de dados. Usaremos nesse exemplo, Stored Procedure, juntamente com uma transao, para que possamos incluir a OS e suas peas/servios sem termos problemas, caso algum erro ocorra. Sobre as vantagens das Stored Procedure, podemos inumerar: - Diminui a quantidade de trfego na rede, pois podemos ou no usar parmetros para a execuo de todo o comando no servidor; - Plano de execuo mais otimizado, pois a mesma compilada no banco de dados; - Segurana: podemos dar acesso ao usurio do sistema para execuo da Stored Procedure em vez de acesso a tabela do banco de dados; - Facilidade: se precisarmos fazer uma modificao na Stored Procedure, basta alter-la no banco de dados que os clientes da aplicao j estaro aceitando/recebendo essas modificaes (desde que no seja alterado os parmetros da Stored Procedure); - Regras de negcio: isso uma discusso muito grande, deixar as regras no banco ou aplicao. A minha opinio de que, cada caso um caso. Dependendo, teremos vantagens em ter a regra no banco, em outro projeto, a vantagem pode estar em ter a regra do negcio na aplicao.

Criando a Ordem de servio


Precisamos saber qual o oramento vincularemos a essa OS. Vamos pesquisar o oramento, atravs da placa do veculo, uma das maneiras mais indicadas. Na tela da OS, utilizaremos novamente, a tela de pesquisa genrica. Mostraremos a mesma, quando a pesquisa pelo oramento retornar mais de um para a mesma placa ( possvel). Assim, ao escolher o oramento, alguns dados sero mostrados em
08
fevereiro 2012

Criando as Stored Procedures


Veja na Listagem 1 o cdigo das duas Stored

Procedures que criaremos.


Listagem 1. Stored Procedures

CREATE PROCEDURE SP_ORDEM_ SERVICO @nCdVeiculo int, @nCdOrcamento int, @sDsObservacoes varchar(max), @nCdOrdem int output AS BEGIN INSERT INTO OS (nCdVeiculo, nCdOrcamento, tDtOrdem, sDsObservacoes) VALUES (@nCdVeiculo, @ nCdOrcamento, getdate(), @ sDsObservacoes) select @nCdOrdem = @@identity from OS; END CREATE PROCEDURE SP_ORDEM_ SERVICO_DETALHES @nCdOrdem int, @nCdPeca int, @nQtPeca numeric(9,2), @nVlUnitario numeric(9,2) AS BEGIN INSERT INTO OS_DETALHE (nCdOrdem, nCdPeca, nQtPeca, nVlUnitario) VALUES (@nCdOrdem, @ nCdPeca, @nQtPeca, @ nVlUnitario) END Figura 1. Tela de cadastro da OS.

que os itens esto vinculados. Tudo isso, dentro de uma transao, feita pela aplicao. No podemos ter itens da OS inseridos, sem a vinculao do cdigo da OS.

Criando o cadastro
Vamos criar agora, o cadastro da nossa OS. Veja na Figura 1 a tela de OS da aplicao. No Click do boto, usamos o cdigo da Listagem 2 para pesquisar os dados do oramento. Listagem 2. Pesquisa de Oramento pela placa
DM.cdsOrcamentoPlaca. Close; DM.cdsOrcamentoPlaca. Params[0].AsString := edtPlaca.Text; DM.cdsOrcamentoPlaca.Open; if DM.cdsOrcamentoPlaca. RecordCount > 1 then begin try frmPesquisa := TfrmPesquisa.Create(self); frmPesquisa.dsPesquisa. DataSet :=

DM.cdsOrcamentoPlaca; frmPesquisa.Descricao := 'Nome da pea/servio'; frmPesquisa. ShowModal; finally frmPesquisa.Free; end; end; if (DM.cdsOrcamentoPlaca. RecordCount > 1) or (DM.cdsOrcamentoPlaca. RecordCount = 1) then begin nCdOrcamento := DM.cdsO rcamentoPlacanCdOrcamento. AsInteger; nCdVeiculo := DM.cdsOrcamentonCdVeiculo. AsInteger; end;

Note que na SP_ORDEM_SERVICO, temos no final um cdigo para selecionar o valor inserido no campo chave (nCdOrdem) da tabela OS, que ser retornado nos parmetros (do tipo output) da Stored Procedure. Assim, com o retorno desse valor, podemos indicar para a SP_ORDEM_SERVICO_DETALHES que vai inserir os itens (peas/servios), o cdigo da OS

Temos a mesma funcionalidade anterior, caso a consulta retorne mais de um registro, mostramos a tela de pesquisa genrica para que o usurio possa escolher o respectivo oramento. Veja que no final
fevereiro 2012

09

do cdigo, preenchemos variveis auxiliares com o cdigo do oramento e veculo para serem usadas na confirmao da OS. O comando SQL do cdsOrcamentoPlaca que preenche os dados do oramento:
select O.nCdOrcamento, O.nCdVeiculo, O.sNmCliente, O.sDsParecer, V.sNmModelo from ORCAMENTO O INNER JOIN VEICULO V ON V.nCdVeiculo = O.nCdVeiculo WHERE V.sNrPlaca = :PLACA and O.nIdStatus = 1

Figura 4. Finalizando o formulrio de cadastro de OS

Um detalhe importante, veja que estamos pesquisando somente nos oramentos ativos (nIdStatus = 1), para que a pesquisa seja correta e no traga oramentos que j foram usados no veculo. Usando a pesquisa genrica no precisamos criar outra tela de consulta, ganhamos assim produtividade em nossa aplicao.

Adicionando peas/servios na OS
Precisamos adicionar em memria as peas/ servios escolhidos pelo usurio. No seria correto, ficar adicionando e excluindo os itens no banco de dados. Seria uma degradao de performance muito grande. Vamos adicionar um ClientDataSet no formulrio que ter os seguintes campos: cdigo da pea, nome da pea, quantidade e preo. Veja na Figura 3 os campos do ClientDataSet. Figura 5. Menu de contexto no grid Criamos um campo calculado para saber o subtotal da pea (quantidade * preo). Adicione um DataSource no formulrio e faa a ligao do mesmo com o ClientDataSet e tambm do DBGrid com o DataSource. Configure os campos do ClientDataSet no Grid. Veja na Figura 4 como ficou nosso formulrio. Vamos agora implementar o mtodo responsvel por adicionar os itens em memria no ClientDataSet. Veja na Listagem 3, o mtodo IncluirItem. Listagem 3. Incluindo o item em memria
procedure TfrmOrdem. IncluirItem; begin //validaes if edtPeca.Text = '' then MessageDlg('Campo Pea/servio: preenchimento obrigatrio.', mtError, [mbNo], 0) else if (edtQuantidade. Text = '') then MessageDlg('Campo Quantidade: preenchimento obrigatrio.', mtError, [mbNo], 0) else if edtPreco.Text = '' then MessageDlg('Campo Preo: preenchimento obrigatrio.', mtError, [mbNo], 0) else begin //verifica se ClientDataSet ativo

Figura 3. Campos do cdsItens

10

fevereiro 2012

Grid para que fique dentro do GroupBox, assim o mesmo tambm fica desabilitado. Voc tambm pode desabilitar o campo Observaes e o boto de confirmar. Uma melhoria bem legal que poderamos fazer, mas deixo para voc exercitar, seria o de trazer o valor da pea/servio cadastrado no banco no campo Preo. Usaramos apenas como sugesto, pois o usurio poderia modificar o valor. Vamos agora, confirmar nosso oramento.

Usando transao com o dbExpress


Como estamos usando o dbExpress, usar transao de dados com o mesmo, muito fcil. Vamos primeiramente, adicionar e configurar dois SQLStoredProc no Data Module para vincul-los com as Stored Procedures criadas anteriormente. Acesse a propriedade Params dos controles e veja que o mesmo j configura os parmetros das Stored Procedures (Figura 7). Precisamos ento criar um mtodo que faa a insero dos dados, usando Stored Procedure e transao. Na Listagem 4, temos o cdigo do InserirOS criado no Data Module. Listagem 4.Inserindo a Ordem de servio no banco
function TDM. InserirOS(nCdOrcamento, nCdVeiculo: integer; cdsItens: TClientDataSet; sDsObservacoes: string): Boolean; var TransDesc: TDBXTransaction; nCdOrdem: integer; i: integer; bRetorno: Boolean; begin bRetorno := false; //inicia a transao TransDesc := SysCar. Transaction(TDBXIsolations. ReadCommitted); try //insere o oramento
fevereiro 2012

Figura 6. Cadastro de oramento em execuo ficamos se o ClientDataSet no esta ativo, assim, criamos o mesmo em memria usando o mtodo CreateDataSet. Para inserir um registro no controle, chamamos o Insert, preenchemos os campos e por fim, executamos o mtodo Post. Para excluir um item, vamos usar um menu de contexto. Adicione um PopupMenu no formulrio. Crie um item de menu chamado Excluir. No evento OnClick do menu, digite o seguinte cdigo:

if not cdsItens.Active then cdsItens. CreateDataSet; //inclui o item cdsItens.Insert; cdsItensnCdPeca. AsInteger := nCdPeca; cdsItenssNmPeca. AsString := edtPeca.Text; cdsItensnQtde. AsInteger := StrToInt(edtQuantidade. Text); cdsItensnVlPeca.AsCurrency := StrToCurr(edtPreco. Text); cdsItens.Post; //limpa campos edtPeca.Text := ''; edtQuantidade.Text := ''; edtPreco.Text := ''; end; end;

if cdsItens.Active then cdsItens.Delete;

Estamos verificando se o ClientDataSet esta ativo, ento chamamos o Delete para excluir o item da memria. Precisamos apenas vincular o controle com a propriedade PopupMenu do grid. Veja na Figura 5 o uso do menu de contexto no Grid. Para finalizarmos o nosso cadastro, vamos implementar algumas regras na tela para que o processo seja executado sem falhas. Vamos desabilitar (propriedade Enabled) o GroupBox com os dados do item para quando o usurio abrir o formulrio, no possa adicionar itens, sem antes pesquisar um oramento. Vamos habilitar o mesmo somente quando for encontrado um oramento. Por isso, modifiquei o

Veja que fizemos algumas validaes simples, antes de inserir o item. Poderamos ter mais validaes, como valor e quantidade maior que zero etc. A insero do item, simples, primeiro veri-

11

Caso tenha alguma dvida sugiro uma pesquisa para entender o funcionamento de transao no dbExpress. Nota: a partir da verso 2010 do Delphi, essa a implementao para utilizao de transao no dbExpress. Em verses anteriores, a lgica a mesma, apenas muda as classes e mtodos.

Figura 7. Parmetros das Stored Procedures configurados no componente

spOS.Params[0].AsInteger := nCdVeiculo; spOS.Params[1]. AsInteger := nCdOrcamento; spOS.Params[2]. AsString := sDsObservacoes; spOS.ExecProc; //armazena o valor inserido no banco nCdOrdem := spOS. Params[3].AsInteger; //percorre os itens e insere no banco for i := 0 to cdsItens. RecordCount - 1 do begin //insere os itens spOS_Itens. Params[0].AsInteger := nCdOrdem; spOS_Itens. Params[1].AsInteger := cdsItens. FieldByName('nCdPeca'). AsInteger; spOS_Itens. Params[2].AsInteger := cdsItens. FieldByName('nQtde'). AsInteger; spOS_Itens. Params[3].AsCurrency := cdsItens. FieldByName('nVlPeca'). AsInteger; spOS_Itens. ExecProc; end; bRetorno := true; except //caso ocorra algum

erro, da roolback SysCar.RollbackInco mpleteFreeAndNil(TransDe sc); end; //comita as alteraes no banco SysCar. ommitFreeAndNil(TransDesc); Result := bRetorno; end;

Cadastrando uma OS
Para finalizar nosso cadastro, vamos codificar o Confirmar na tela de OS, para que chame o mtodo do Data Module, conforme a Listagem 5. Listagem 5. Chamando a insero da OS
if (not cdsItens.Active) or (cdsItens.RecordCount = 0) then MessageDlg(' necessrio incluir peas/servios para confirmar a Ordem de servio.', mtError, [mbNo], 0) else begin if DM.InserirOS(nCdOrcamento, nCdVeiculo, cdsItens, mmObservacoes.Text) then begin MessageDlg('Registro inserido com sucesso.', mtInformation, [mbNo], 0); dsOrcamento.DataSet. Close; cdsItens.Close; end else MessageDlg('Ocorreu um erro. Contate o suporte', mtError, [mbNo], 0) end;

O cdigo esta comentado, mas vamos entender seu funcionamento. Primeiro, declaramos algumas variveis para auxiliar-nos. A varivel do tipo TDBXTransaction, parmetro para o mtodo que inicia a transao. Dentro de um bloco try...except, configuramos os parmetros necessrios para a insero da OS e de seus itens. Algo bastante simples, como podemos perceber. A Stored Procedure que insere a OS, retorna o cdigo da mesma em seu ltimo parmetro. Assim, armazenamos esse valor para us-lo na insero dos itens da OS. O bloco except, ser executado, caso ocorra algum erro, assim, chamamos o RollbackIncompleteFreeAndNil para no efetivar nada no banco de dados. Se no ocorrer nenhum problema, o fluxo continuar, sem executar o roolback e assim, executar o CommitFreeAndNil, que a insero dos dados, efetivamente, no banco. Veja que criamos uma function, que retorna um boolean, para sabermos se a insero foi realizada corretamente. Usamos uma varivel, que preenchida como false, pois se ocorrer erro, o retorno dever ser falso. Preenchemos a varivel com true, somente se o fluxo ocorreu corretamente e no gerou erro.

Veja que validamos se o ClientDataSet esta ativo ou se existem itens cadastrados. Em caso negativo, emitimos uma mensagem, seno, chamamos a funo para inserir. Assim, verificamos se a mesma retornou com sucesso, para emitir a devida mensagem.

12

fevereiro 2012

Poderamos emitir a mensagem retornada para o usurio. Fica a seu critrio implementar isso. Execute o projeto e faa um teste (Figura 8). Poderamos incrementar nosso cadastro, validando os campos Quantidade e Preo. Caso voc deseje alterar a ordem de servio, teramos que rever a parte do carregamento de itens, onde apenas precisaramos preencher o cdsItens com as peas/servios cadastrado no banco. Teramos que ter tambm, obviamente, uma pesquisa para que o usurio possa escolher a ordem de servio que deseja alterar. Para finalizar completamente, aps confirmar, precisamos mudar o status do oramento vinculado a OS. Caso voc deseje implementar a funcionalidade de editar os itens da OS, voc deve atentar para mudar a lgica referente a status do Oramento e da OS. Listagem 6. Alterando o status do Oramento Data module
procedure TDM.AlterarStat usOrcamento(nCdOrcamento: integer); var sql: string; Query: TSQLQuery; begin sql := 'update ORCAMENTO set nIdStatus = 0 where nCdOrcamento = ' + IntToStr(nCdOrcamento); Query := TSQLQuery. Create(nil); try Query.SQLConnection := SysCar; Query.SQL.Clear; Query.SQL.Add(sql); Query.ExecSQL(); finally Query.Free; end; end;

Figura 8. Salvando uma ordem de servio que se refere a cadastros, pois j implementamos os principais. Criamos os cadastros que podemos chamar de auxiliares (cliente, peas e veculos), pois eles abastecem os cadastros principais, bem como os cadastros que so os principais (oramento e ordem de servio) do nosso projeto. No prximo e ltimo artigo, vamos finalizar o projeto com a parte de relatrios, onde criaremos listagens, relatrios com parmetros etc. Um grande abrao a todos e at a prxima!

Sobre o autor
Luciano Pimenta
Tcnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicaes Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4 edio da Borland Conference (BorCon). Autor de mais de 60 artigos e de mais de 300 vdeos aulas publicadas em revistas e sites especializados. consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programao e banco de dados. desenvolvedor da Paradigma Web Bussiness em Florianpolis-SC.

Formulrio da OS
...

MessageDlg('Registro inserido com sucesso.', mtInformation, [mbNo], 0); DM.AlterarStatusOrcamento(nCdOrcamento); ...


Concluses

www.lucianopimenta.net

Finalizamos neste artigo a nossa aplicao no


fevereiro 2012

13

Android Criando uma tela de Venda


Neste artigo montaremos uma tela simples de venda de produtos, no nosso caso utilizaremos como exemplo o The Club. A inteno desta matria de trabalhar com alguns componentes, mostrando suas funcionalidades na prtica e algumas classes teis ao decorrer do desenvolvimento deste artigo. Eu considero este tipo de assunto um passo importante para quem est comeando a trabalhar com o Sistema Android, para quem no sabe, programao em Android nada mais que uma mistura do XML com o Java. Portanto, especificamente neste artigo trabalharemos com o XML e programaremos alguma coisa em Java, a fim de possibilitar um aprendizado fcil e intuitivo.

Conceitos Bsicos e Essenciais


Para isto abra seu Eclipse e clique em File/New/Android Project e crie um projeto em Android, recomendo a criao na verso 2.2 ou 2.3. A primeira tela que vemos quando estamos criando um projeto em Android a clssica telinha Hello World, que todo mundo j est careca de saber e montar como primeiro projeto de exemplo. Mas explicarei alguns detalhes interessantes em relao da mesma, para isto clique em seu cdigo XML e teremos um idntico com este abaixo:
<?xml version=1.0 encoding=utf-8?> <LinearLayout xmlns:android=http://

14

fevereiro 2012

schemas.android.com/apk/res/android android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent > <TextView android:layout_width=fill_parent android:layout_height=wrap_content android:text=@string/hello /> </LinearLayout>

<string name=hello>Hello World!</string> <string name=app_name>Vendas The Club</string> </resources>

Figura 02: Hierarquia de Componentes Utilizados. Bem, como este no nosso primeiro projeto, esta varivel hello no ser utilizada, portanto podemos exclu-la tanto de nossa tela de recursos quanto na tela principal. Figura 01: Recursos no Sistema Android.

Criando uma interface grfica


Para construirmos nossa tela, obrigatrio saber que o primeiro componente que devemos inserir na tela so os denominados Layouts, os quais definem a orientao da insero dos componentes na tela. Ele pode ser encontrado na paleta com o mesmo nome. Os mais utilizados so: LinearLayout(Vertical): Possibilita a disposio vertical dos componentes da tela. Exemplo:

Pergunta: O que seria a palavra @string na linha android:text=@ string/hello ? Resposta: uma referncia que temos no nosso arquivo de recursos strings.xml encontrado no caminho /res/values. Para entendermos melhor d um clique no mesmo e ver uma tela parecida com a Figura 01. Temos aqui uma tela de recursos para o Sistema Android, ou seja, podemos mudar nosso valor da varivel hello ou da app_name que seria o ttulo de nosso exemplo. Em Resources Elements temos vrios elementos que podemos trabalhar e explorar nos possibilitando a criao e manipulao de variveis muito teis ao decorrer de nossa necessidade. Neste mesmo artigo criaremos uma do tipo Array que iremos aprender um pouco mais adiante. importante tambm ter em mente que podemos realizar este trabalho por XML, veja o cdigo equivalente a Figura 01.

<LinearLayout android:orientation=vertical> <LinearLayout>

LinearLayout(Horizontal): Possibilita a disposio horizontal dos componentes da tela. Exemplo:

<?xml version=1.0 encoding=utf-8?> <resources>

<LinearLayout android:orientation=horizontal> <LinearLayout>


fevereiro 2012

15

A tela de venda possuir a seguinte estrutura: o o o o Nome Cliente Cidade Estado Produtos The Club Lite (Delphi) The Club Lite (C#,.NET) The Club Professional The Club Student Boto Efetuar Compra

android:layout_width=match_parent android:id=@+id/linearLayout1 android:orientation=horizontal> <LinearLayout android:layout_ height=match_parent android:orientation=vertical android:layout_width=wrap_content android:id=@+id/linearLayout4> <TextView android:layout_ width=wrap_content android:id=@+id/textView3 android:layout_height=wrap_ content android:text=Cidade></TextView> <EditText android:id=@+id/ edtCidade android:layout_height=wrap_ content android:layout_width=206dp></ EditText> </LinearLayout> <LinearLayout android:layout_ height=match_parent android:orientation=vertical android:id=@+id/linearLayout3 android:layout_width=match_ parent> <TextView android:layout_ width=wrap_content android:id=@+id/textView2 android:layout_height=wrap_ content android:text=Estado></TextView> <Spinner android:id=@+id/ spnEstado android:entries=@array/uf android:layout_height=wrap_ content android:layout_width=match_ parent></Spinner> </LinearLayout> </LinearLayout> <TextView android:textAppearance=?and roid:attr/textAppearanceMedium android:id=@+id/textView4 android:layout_height=wrap_ content android:text=PRODUTOS android:layout_width=wrap_content

Para obtermos um resultado legal trabalharemos corretamente com os componentes de Layouts acima descritos. Por padro nosso projeto criado com um LinearLayout(Vertical). A descrio dos componentes utilizados e a disposio em nossa tela principal. Veja a Figura 02 para melhores detalhes. importante entender o funcionamento destes dois principais tipos de componentes de layouts, pois possvel manej-los da forma que desejar, colocando um dentro do outro, entre outros tipos de configuraes. Podemos conferir o cdigo XML correspondente abaixo:

<?xml version=1.0 encoding=utf-8?> <LinearLayout xmlns:android=http:// schemas.android.com/apk/res/android android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent> <LinearLayout android:layout_ height=wrap_content android:orientation=vertical android:layout_width=wrap_content android:id=@+id/linearLayout2> <TextView android:layout_ width=wrap_content android:text=Nome Cliente: android:id=@+id/textView1 android:layout_height=wrap_ content></TextView> <EditText android:layout_ width=316dp android:id=@+id/edtCliente android:layout_height=wrap_ content></EditText> </LinearLayout> <LinearLayout android:layout_ height=wrap_content

16

fevereiro 2012

android:layout_gravity=center></ TextView> <RadioGroup android:id=@+id/rgCursos xmlns:android=http://schemas. android.com/apk/res/android android:orientation=vertical android:layout_width=fill_parent android:layout_height=wrap_ content> <RadioButton android:id=@+id/ rbLiteDelphi android:layout_width=wrap_content android:layout_height=wrap_content android:text=The Club Lite (Delphi) - R$ 59,90></RadioButton> <RadioButton android:id=@+id/ rbLiteC android:layout_width=wrap_content android:layout_height=wrap_ content android:text=The Club Lite (C#,. NET) - R$ 59,90></RadioButton> <RadioButton android:id=@+id/ rbProfessional android:layout_width=wrap_content android:layout_height=wrap_ content android:text=The Club Professional - R$ 88,00></RadioButton> <RadioButton android:id=@+id/ rbStudent android:layout_width=wrap_content android:layout_height=wrap_ content android:text=The Club Student - R$ 25,00></RadioButton> </RadioGroup> <Button android:id=@+id/btnEfetuar android:layout_height=wrap_content android:layout_width=match_parent android:text=Efetuar Venda></Button> </LinearLayout>

O componente Spinner parecido com o Combobox do Delphi, ou seja, podemos armazenar uma lista de Strings nele. Neste caso armazenaremos via XML todos os estados do Brasil, para isto acesse o caminho \values\strings.xml e adicionaremos uma varivel do tipo Array. Podemos fazer isto via cdigo XML ou utilizando a interface grfica. Veja abaixo o XML correspondente:

<string-array name=uf> <item >AC </item> <item >AL </item> <item >AM </item> <item >BA </item> <item >CE </item> <item >ES </item> <item >GO </item> <item >MA </item> <item >MT </item> <item >MS </item> <item >MG </item> <item >PA </item> <item >PB </item> <item >PR </item> <item >PE </item> <item >PI </item> <item >RJ </item> <item >RN </item> <item >RS </item> <item >RO </item> <item >RR </item> <item >SC </item> <item >SP </item> <item >SE </item> <item >TO </item> </string-array>

Prontinho... Criamos agora mais um recurso no Android que poder ser utilizado em qualquer tela que precisarmos, no legal? Para carregarmos estes recursos utilizamos a funo entries, veja abaixo o XML completo deste componente. Podemos rodar o exemplo e teremos uma tela parecida com a da Figura 03

Devemos dar uma ateno especial no componente RadioButton em conjunto com o RadioGroup, ele nos possibilita a criao de um grupo que permite apenas selecionar um tipo de Produto, que no nosso caso especfico o que devemos fazer.

<Spinner android:id=@+id/spnEstado android:entries=@array/uf android:layout_height=wrap_ content android:layout_ width=match_parent> </Spinner>


fevereiro 2012

17

Criando uma classe para armazenar os registros


Para guardar nossos dados em memria deveremos criar uma classe para esta finalidade e consequentemente aprenderemos como criar uma classe no Java. Para isto clique com o boto direito no pacote Pct.Tela_Venda_Artigo localizado no diretrio / src e escolha new/Class e deixe e escolha o Nome Registro. Ver Figura 04. Adicionaremos algumas variveis para armazenar o registro, sendo trs do tipo string cliente, cidade e estado e uma do tipo inteiro para o curso escolhido, sendo:

1 - The Club Lite (Delphi) 2 - The Club Lite (C#,.NET) 3 - The Club Professional 4 - The Club Student

Cdigo correspondente:

package Pct.Tela_Venda_Artigo; public class Registro {

Figura 03: Tela de Vendas.

String cliente, cidade, estado;

int curso; } Codificando o Boto Efetuar Compra O primeiro passo abrir o arquivo principal .java, localizado em /src/Pct. Tela_Venda_Artigo. Importaremos a classe Widget para criarmos nossas variveis. Import android.widget; O cdigo comentado ficou da seguinte maneira: public class Tela_Venda_ArtigoActivity extends Activity { //Variveis que sero teis no exemplo RadioGroup rgCursos; RadioButton rbLiteDelphi, rbLiteC, rbProfessional, rbStudent; TextView txtCliente, txtCidade, txtEstado; Spinner spEstado; Button btEfetuar; Figura 04: Criando uma classe Registro.

18

fevereiro 2012

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Fazendo o denominado casting dos componentes utilizados rgCursos = (RadioGroup) findViewById(R.id.rgCursos); rbLiteDelphi = (RadioButton) findViewById(R.id.rbLiteDelphi); rbLiteC = (RadioButton) findViewById(R.id.rbLiteC); rbProfessional = (RadioButton) findViewById(R.id.rbProfessional); rbStudent = (RadioButton) findViewById(R.id.rbStudent); txtCliente = (TextView) findViewById(R.id.edtCliente); txtCidade = (TextView) findViewById(R.id.edtCidade); spEstado = (Spinner) findViewById(R.id.spnEstado); btEfetuar = (Button) findViewById(R.id.btnEfetuar); //Acionar o evento setOnClickListener para o boto Efetuar btEfetuar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { //Instanciar a classe Registro para atribuir os dados digitados pelo usurio Registro reg = new Registro(); reg.cliente = txtCliente.getText().toString(); reg.cidade = txtCidade. getText().toString(); reg.estado = spEstado. getSelectedItem().toString(); //Utilizar o Id do RadioGroup para identificar o tipo de curso switch (rgCursos. getCheckedRadioButtonId()) { case R.id. rbLiteDelphi : reg.curso = 1; break; case R.id.rbLiteC : reg.curso = 2; break; case R.id. rbProfessional : reg.curso = 3; break; case R.id. rbStudent : reg.curso = 4; break; } //Utilizao da Classe Builder para emitirmos um Alerta ao usurio MensagemAlerta(Resultado, Venda Efetuada com sucesso! + \n + ------------------------------------- + Cliente: + reg. cliente + \n+ Cidade: + reg. cidade + / Estado: + reg. estado + \n + Cd. Curso: + reg.curso); } }); } //Implementao de uma funo genrica para utilizar no nosso projeto public void MensagemAlerta(String titulo, String corpo) { AlertDialog.Builder infoResultado = new AlertDialog.Builder(Tela_Venda_ ArtigoActivity.this); infoResultado.setTitle(titulo); infoResultado.setMessage(corpo); infoResultado.setNeutralButton(Ok,null); infoResultado.show(); }

fevereiro 2012

19

Concluso
Este artigo nos demonstrou vrias ideias e conceitos em relao ao Sistema Android. Como sabemos que uma mistura de XML com o Java, primeiramente exploramos os denominados resources com exemplos e utilizaes prticas do mesmo. Procurei trabalhar com componentes diversificados a fim de proporcionar um melhor aprendizado. Trabalhei em cima do evento setOnClickListener para finalmente explorar um pouco da classe Builder que muito utilizada. Como se trata de um exemplo prtico foi criado uma classe para armazenar os registros e futuramente consult-los ou at mesmo gravar em uma base de dados. Espero que vocs estejam gostando desta srie de Artigos de Android, vou ficando por aqui, um forte abrao e at o ms que vem!

Sobre o autor
Thiago Cavalheiro Montebugnoli
Thiago Cavalheiro Montebugnoli tecnlogo, formado pela Faculdade de Tecnologia de Botucatu SP (FATEC) foi consultor tcnico do The Club, j desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Processamento de Dados da Prefeitura Municipal de Ita-SP. Possui as seguintes certificaes: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

thiago@theclub.com.br

20

fevereiro 2012

fevereiro 2012

21

Conexo ao Firebird em Lazarus


ferramenta. Em artigo anterior, apresentei a vocs a ferramenta Lazarus. Relembrando, Lazarus um projeto independente OpenSource, desenvolvido em Linux, possui sua IDE baseada no Delphi e utiliza como compilador o FreePascal, que um compilador j com tradio no mundo OpenSource. Nesse artigo anterior mostrei a ferramenta Lazarus no como um substituto, mas sim como uma alternativa ou at mesmo um complemento ao uso do Delphi. Lazarus vem apostando bastante no conceito da multiplataforma, possibilitando hoje a gerao de executveis para ambientes 32 e 64 bits, Windows e Linux, alm de gerar programas para Mac OS e tambm j existem testes para a gerao de aplicativos para plataformas mveis como Android. Hoje o principal projeto que existe em Lazarus o projeto ACBr, que uma sute de componentes para automao comercial. O projeto ACBr hoje desenvolvido em parte em Lazarus e com isso vem chamando ateno da comunidade Delphi para a
22
fevereiro 2012

Para quem tem pensado em comear a utilizar Lazarus, nesse artigo estarei mostrando mais uma faceta da ferramenta, a importantssima conexo a banco de dados. Lazarus hoje possui conexes nativas para os principais bancos gratuitos existentes: PostgreeSql, MySql, Sqlite e Firebird, alm de possuir conexes para Oracle e ODBC, com a conexo ODBC disponvel, podemos, em ambiente Windows utilizar o Lazarus com Sql Server, um dos bancos de dados mais robustos do mercado. As opes como vimos so variadas, e nesse artigo estarei mostrando a conexo do Lazarus com o banco de dados Open Source mais utilizado pela comunidade Delphi: Firebird. Mos a obra ento!

Com o Lazarus devidamente instalado, abra-o. A primeira caracterstica que verificamos que, comparado com o Delphi, Lazarus possui bem menos abas de componentes. Para nossa tarefa, a aba mais importante a SqlDB. nela que se encontram os componentes que realizam a conexo com as diversas bases de dados que so suportadas pelo Lazarus. A aba SqlDB pode ser vista na figura 1: Os oito ltimos componentes dessa aba so os conectores, que realizam a conexo Lazarus Bancos de dados. Pela ordem temos as seguintes opes de conexo: PostgreeSQL; Oracle; ODBC; Os trs seguintes so para diversas verses do MySQL;

Conhecendo os componentes de conexo


Nesse artigo no estarei abordando a instalao do Lazarus j que no artigo anterior j mostrei como procedemos para realizar o Download e instalar o mesmo.

SQLite; Interbase/Firebird

Os quatro componentes que iniciam a aba so os componentes de consulta, onde estaremos

Figura 1

retirando e passando informaes para a base de dados. No artigo, estaremos utilizando o ltimo componente, para Interbase/Firebird. Tambm estaremos utilizando dessa aba os componentes de consulta, no caso o SqlQuery.

Abra o cdigo da unit e na clusula uses coloque a unit: IBConnection. Na seo implementation declare a funo conforme mostrado abaixo:
function ConexaoFirebird(D ataBaseHost,DataBaseName,U serName,Password:String):T IBConnection; var ConnAux:TIBConnection; begin ConnAux:=TIBConnection. Create(nil); ConnAux. HostName:=DataBaseHost; ConnAux. DatabaseName:=DataBaseName; ConnAux. UserName:=UserName; ConnAux.
Password:=Password; ConnAux. Connected:=True; then

Essa funo receber pela ordem, o servidor, ou ip do servidor de banco de dados (em geral localhost), o caminho e nome do arquivo de banco de dados, o nome de usurio e a senha e nos devolver, caso a conexo se realize, um objeto IBConnection com a conexo. Vamos testar a conexo. No evento OnCreate do formulrio principal da aplicao que criamos, iremos chamar essa funo e mostrar o resultado no Caption da janela. Veja o cdigo do evento OnCreate do formulrio:

Conectando ao Firebird
Conforme j mencionado, estaremos utilizando o componente de conexo ao Interbase/Firebird para construirmos um exemplo de manipulao de uma base de dados Firebird. O primeiro passo criarmos nossa base de dados de exemplo. Chamarei a mesma de TheClub_Lazarus_Teste. Veja o script de criao da base:

procedure TForm1. FormCreate(Sender: TObject); var Conn:TIBConnection; begin Conn:=ConexaoFirebird( localhost,C:\TheClub_ Lazarus_ Teste,SYSDBA ,masterkey); if(Conn<>nil)then Caption:=Conexo OK
else Caption:=No foi possvel realizar a conexo; end;

CREATE DATABASE C:\THE_ CLUB_LAZARUS_TESTE.fdb page_size 4096 user SYSDBA password masterkey CREATE TABLE THE_CLUB_ NOMES ( ID_NOME INTEGER NOT NULL, NOME VARCHAR(50), RG VARCHAR(20), CPF VARCHAR(20) );

if(ConnAux.Connected) Result:=ConnAux else Result:=nil;

end;

Veja o resultado na figura 2.

Aps criarmos a base de dados, faremos o projeto no Lazarus. Abra o Lazarus e inicie um novo projeto do tipo Application.

Por ora no estaremos montando o layout da aplicao. Estaremos criando a funo de conexo ao banco de dados Firebird.

Figura 2
fevereiro 2012

23

QuotedStr(edtCPF.Text)]); try try // Iniciamos a transao e executamos o insert via conexo Trans. StartTransaction; Conn. ExecuteDirect(Sql); Trans.Commit;

Figura 3

ShowMessage(Registro inserido com sucesso); Create(nil); // Criamos a transao para a conexo if(Conn<>nil)then // Se a conexo estiver ok, fazemos a insero dos dados begin Conn. Transaction:=Trans; // Ligamos o componente de transao a conexo // Montamos a frase Sql de insero Sql:=Format(INSERT INTO THE_CLUB_NOMES except // Se ocorrer erro cancela a transao Trans.Rollback; end; finally Trans.Free; Conn.Free; end; end; end;

Repare que no topo da pgina ir aparecer a mensagem avisando que a conexo est funcionando. Essa funo que criamos bastante til porque cria a instncia da conexo ao ser chamada. Isso possibilita utilizarmos uma conexo por acesso ao banco, reduzindo o trfego em uma nica conexo. Na sequncia, faremos a funo de insero de dados em nossa tabela. Utilizaremos essa funo de conexo e atravs dela passaremos os valores via Sql direto. Para inserirmos dados, agora precisamos ter um layout de tela com alguns objetos. Iremos aproveitar o formulrio j existente e montaremos o layout conforme a figura 3. Com o layout criado, faremos a rotina de insero dos dados diretamente no boto Inserir. Criaremos, alm da conexo, um objeto do tipo SqlQuery para inserir os dados. Veja o cdigo do OnClick do boto Inserir:
procedure TForm1. Button1Click(Sender: TObject); var
Sql:string; Conn:TIBConnection; Trans:TSQLTransaction; begin // Conectamos ao banco Conn:=ConexaoFirebird( localhost,C:\TheClub_ Lazarus_Teste, SYSDBA,masterkey); Trans:= TSQLTransaction.

Veja o aplicativo em execuo na figura 4: Para finalizar, vamos completar nosso exemplo com a consulta aos dados. Utilizaremos a mesma tela que estamos utilizando para inserir os dados para essa consulta. S que utilizaremos trs componentes fixos: SqlQuery: Aba sqlDB; DataSource: Aba DataAccess; DbGrid: Aba DataControls;

VALUES(%s,%s,%s,%s), [edtCodigo. Text,QuotedStr(edtNome. Text),QuotedStr(edtRG. Text),

Figura 4

24

fevereiro 2012

Create(nil); // Criamos a transao para a conexo Conn.Transaction:=Trans; SQLQuery1. DataBase:=Conn; SQLQuery1.Open;// Abrimos a query finally Conn.Free; Trans.Free; end; end;

Figura 5

Veja a consulta em execuo na figura 6: Com a parte de consulta fechamos nosso exemplo de manipulao do banco de dados Firebird com Lazarus.

Figura 6

Concluso
TObject); var Conn:TIBConnection; Trans:TSQLTransaction; begin try SQLQuery1. Close; // Conectamos ao banco Conn:=ConexaoFi rebird(localhost,C:\ TheClub_Lazarus_Teste, SYSDBA,masterkey); Trans:=TSQLTransaction.

Colocaremos tambm um button com o texto Atualizar Consulta para mostrarmos os dados atualizados aps as inseres. Veja como ficar o layout na figura 5 Ligue o DataSource ao SqlQuery atravs da propriedade DataSet e o Dbgrid no DataSource atravs da propriedade DataSource. Na propriedade Sql do SqlQuery coloque a frase:

Nesse segundo artigo sobre Lazarus, demonstrei como utilizar a ferramenta no trato com um dos bancos de dados mais utilizados pela comunidade Delphi atualmente: O Firebird. Firebird um banco que a cada dia vem se tornando mais robusto e confivel. Ento toda ferramenta de automao comercial precisa possuir uma boa integrao com esse banco, e nessa parte Lazarus se mostra totalmente efetivo. Alm do Firebird, estarei mostrando nos prximos artigos como podemos conectar o Lazarus a outros bancos de dados como SqlLite e MySql, excelentes opes de bancos Open Source. isso, espero que tenham gostado e at a prxima!

SELECT * FROM THE_CLUB_NOMES.

Na funo de atualizar a consulta, iremos criar a instncia da conexo e ligar a Query a essa instncia para gerarmos a consulta ao abrirmos a Query. Vamos agora ao cdigo do boto Atualizar Consulta:
procedure TForm1. Button2Click(Sender:

Sobre o autor
Antonio Spitaleri Neto
Consultor Tcnico The Club.

antonio@theclub.com.br

fevereiro 2012

25

MTODOS RAVEReport
de A a Z
W
WRITE NULL DATA este mtodo escreve um valor nulo dentro do evento OnGetRow de um componente de conexo de dados. Os dados para os campos personalizados devem ser escritos na mesma ordem em que os campos foram definidos no evento OnGetCols. Example (Delphi)
Connection.WriteNullData( );

branco se no for necessria uma sada pr-formatada. Parmetros NativeData devem conter o contedo no modificvel do campo. Example (Delphi)
Connection.WriteStrData( ,CustomerName );

pontos (dots) para unidades (units) (definida por Unidades em UnitsFactor) Example (Delphi)
XPos := RvNDRWriter1.XD2U( LastXDots );

X
XD2I este mtodo converte a unidade de medida horizontal da tela de impressora de pontos (dots) para polegadas (inches). Example (Delphi)
// Com Units atualmente configuradas para unInch XPos := RvNDRWriter1.XD2I( LastXDots );

XI2D este mtodo converte a unidade de medida horizontal da tela da impressora de inch (polegadas) para pontos (dots). Example (Delphi)
// Com Unidades atuais configuradas para unInch CurrXDots := RvNDRWriter1. XI2D( RvNDRWriter1.XPos );

WRITE STRING DATA Este mtodo grava o contedo de um campo String personalizado (de tipo dtString) dentro do evento OnGetRow de um componente de conexo de dados. Os dados para campos personalizados devem ser escritos na mesma ordem em que os campos foram definidos no evento OnGetCols. Os parmetros formatdata definem o valor formatado do campo, mas podem ficar em
26
fevereiro 2012

XI2U este mtodo converte a medida horizontal de inch (polegadas) para unit (definida pela Units e UnitsFactor). Example (Delphi)

XD2U este mtodo converte a unidade de medida horizontal da tela da impressora de

XPos := RvNDRWriter1.XI2U( LastXInch );

YI2D este mtodo converte a unidade de medida vertical da tela da impressora de polegadas para pontos. Example (Delphi)
// com Units configurada para unInch CurrYDots := RvNDRWriter1. YI2D( YPos );

// Com units configuradas para unCM CurrYInch := RvNDRWriter1. YU2I( RvNDRWriter1.YPos );

XU2D este mtodo converte a medida horizontal de units (definida pelas Units e UnitsFactor) para pontos (dots). Example (Delphi)
CurrXDots := RvNDRWriter1. XU2D( RvNDRWriter1.XPos );

ZOOM IN este mtodo adiciona ZoomInc ao ZoomFactor atual e aumenta a imagem na tela. Se um evento OnZoomChange for definido, ento ser chamado e ser responsvel por redesenhar a pgina, caso contrrio, a tela redesenhada. Example (Delphi)
// este cdigo faz com que o ZoomFactor seja incrementado por ZoomInc. RvRenderPreview1.ZoomIn;

XU2C este mtodo converte a medida horizontal de units (definida pelas Units e UnitsFactor) para polegadas (inches). Example (Delphi)
//com units configuradas para unCM CurrXInch := RvNDRWriter1. XU2I( RvNDRWriter1.XPos );

YI2U este mtodo converte a unidade de medida vertical da tela da impressora para unidades de medidas (definida pela Units e UnitsFactor). Example (Delphi)
RvNDRWriter1.YPos := RvNDRWriter1. YI2U( LastYInch );

Y
YD2I este mtodo converte a unidade de medida vertical da tela da impressora de pontos (dots) para polegadas (inches). Example (Delphi)
// com unidades configuradas para unInch YPos := RvNDRWriter1.YD2I( LastYDots );

YU2D este mtodo converte a unidade de medida vertical da tela da impressora DE unidades de medidas (definida pela Units e UnitsFactor) para pontos (dots). Example (Delphi)
CurrYDots := RvNDRWriter1. YU2D( RvNDRWriter1.YPos );

Z
ZOOM OUT - este mtodo subtrai ZoomInc do ZoomFactor atual e diminui a imagem na tela. Se um evento OnZoomChange for definido, ento ser chamado e ser responsvel por redesenhar a pgina, caso contrrio, a tela redesenhada. Example (Delphi)
RvRenderPreview1.ZoomOut;

YU2I este mtodo converte a unidade de medida vertical da tela da impressora de unidades de medidas (definida pela Units e UnitsFactor) para polegadas (inches). Example (Delphi)

YD2U este mtodo converte a unidade de medida vertical da tela da impressora de pontos (dots) para unidades de medidas (definidas pela Units e UnitsFactor). Example (Delphi)
RvNDRWriter1.YPos = RvNDRWriter1.YD2U( LastYDots );

Sobre o autor
Leonora Golin
Consultora Tcnica The Club.

antonio@theclub.com.br

fevereiro 2012

27

Dicas DELPHI
Alterando as configuraes de Rede
Nessa dica ser criado um exemplo de como alterar as propriedades da rede fazendo com que os dados sejam recriados, como o IP, a mscara de rede e o gateway, diretamente pela aplicao.
unit AlteraIP; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations } public { Public declarations }

Iremos agora copiar o texto da varivel Aplicativo para armazen-la na varivel Arquivo, depois, selecionar o diretrio padro d mquina correspondente, e novamente copiar, s que desta vez copiando o contedo da varivel Diretrio para a varivel WorkDir
begin StrPCopy(Aplicativo, Arquivo); GetDir(0, WorkDir); StrPCopy(Diretorio, WorkDir);

Logo fazemos a verificao de dados inicializados, atravs da procedure FillChar, que ir identificar a quantidade de bytes utilizados no processo, iremos trazer as informaes de inicializao e a condio da sua execuo
FillChar(Inicializacao, Sizeof(Inicializacao), #0); Inicializacao.cb := Sizeof(StartupInfo); Inicializacao.dwFlags := STARTF_ USESHOWWINDOW; Inicializacao.wShowWindow := Visibilidade;

Criamos duas funes, uma que ir receber os dados da conexo, retornando se uma conexo existente ou no, e outra que aguarda a execuo do momento necessrio.
function MudarIp(Conexao, Ip, Mascara, Gateway: string):boolean; function ExecutarAguardando(Arquivo: string; Visibilidade: integer):integer; end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } function TForm1. ExecutarAguardando(Arquivo: string; Visibilidade: integer): integer;

Logo em seguida, caso o processo no seja criado, retornamos o resultado com o valor de -1, para considerar inutilizado o processo, mas caso j seja considerado um processo criado, ele ir aguardar o processo, retornar o cdigo de sada do processo e exibir o resultado.
if not CreateProcess(nil, aplicativo, nil, nil, false, CREATE_NEW_CONSOLE or NORMAL_ PRIORITY_CLASS, nil, nil, Inicializacao, Processo) then Result := -1 else begin WaitforSingleObject(Processo. hProcess, INFINITE); GetExitCodeProcess(Processo. hProcess,Resultado); Result := Resultado; end;

E por ultimo, a principal alterao, que recupera os dados de configurao de rede e altera de acordo com os dados informados.
begin Result:=(ExecutarAguardando( Configurar o endereco IP netsh +Conexao+ + estatico +Ip+ +Mascara + +GateWay+ 1, SW_ HIDE)=0); end;

O primeiro passo criarmos 6 variveis que serviro para identificar o caminho do diretrio, as informaes de inicializao e de execuo e o resultado geral de hardware
var Aplicativo, Diretorio, WorkDir: string; Inicializacao: TStartupInfo; Processo: TProcessInformation; Resultado: DWord; 28
fevereiro 2012

E para que tenhamos certeza de que as alteraes dos dados da conexo tenham sido realmente alteradas precisamos verificar utilizando a funo MudarIp, se os dados tiveram validade

begin if not MudarIp(Local Area Connection, 192.168.10.22, 255.255.255.0, 192.168.10.90) then ShowMessage(Erro na alterao do IP) else ShowMessage(IP alterado sem erros); end; end; end.

Depois de criada a procedure, utilizada a constante PROCESS_TERMINATE que indexa o caminho do processo declarado, fazendo com que se encerre, alm das variveis que serviro para verificar o formulrio ativo do sistema
procedure TForm1. FinalizaPorCaption(const frmClasse, frmJanela: string); const PROCESS_TERMINATE = $0001; var HWNDJanela: HWND; HandleProc: THandle; IDProcesso: Integer; Classe, Janela: PChar;

Essa dica til pra quem precisa administrar uma rede e necessita de alteraes dos valores dos dados estticos de suas conexes, atravs da prpria aplicao facilitar e exigir menos contato com interno as configuraes do sistema operacional.

A procedure verifica se a classe e a janela esto vazias e ento declarando seus valores como nil, caso no, ela resgata os valores passados pelos parmetros da procedure, fornecidas pelo usurio.
begin try if Classe = then Classe:= nil else Classe:= PChar(Classe); if Janela = then Janela:= nil else Janela:= PChar(Janela);

Fechar sistema ao acessar uma janela da aplicao

Essa dica utiliza um procedimento que ir controlar a restrio de acesso determinados formulrios fechando a aplicao, de acordo com o Caption do formulrio ao tentar acess-la
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations }

Aps identificado o formulrio da aplicao iremos armazen-la na varivel do tipo HWND que controla os processo em execuo e o GetWindowThreadProcessID, identificando a janela e o ndice do processo
HWNDJanela:= FindWindow(Classe, Janela); GetWindowThreadProcessID(HWNDJa nela, @IDProcesso);

importante declar-la como sendo pblica para que todas as outras units possam enxerga-la.
public { Public declarations } procedure FinalizaPorCaption(const frmClasse, frmJanela: string); end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 }

E fechando o metodo try...finally encerramos o processo pelo ID definido

finally HandleProc:= OpenProcess(PROCESS_TERMINATE, False, IDProcesso); TerminateProcess(HandleProc, 4); end; end; end.

Concluso
Esse procedimento serve como, por exemplo, para as permisses de usurio, ou encerrar foradamente um acesso no permitido, ocasionando o encerramento do sistema.
fevereiro 2012

29

Horizontal

Vertical

30

fevereiro 2012

fevereiro 2012

fevereiro 2012

Anda mungkin juga menyukai