Android Criando Uma Tela de Vendas

Embed Size (px)

Citation preview

  • fevereiro 2012

  • fevereiro 2012

  • fevereiro 2012 03

    Desafio The Club

    - Dicas Delphi

    Dicas

    - Cruzada

    30

    Delphi Delphi

    DelphiDelphi

    Conexo ao Firebird em Lazarus Mtodos RAVReport - de A a Z - parte 4

    ndiceCriando uma aplicao Client-Server no Delphi - Parte IV

    Editorial

    08Chegou fevereiro e com ele a nossa

    maior festa popular. O Carnaval. Ento va-mos todos aproveitar e festejar bastante! Sem se esquecer ... 04

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

    Android - Criando uma tela de Venda

    14

    28

    22

    LegendaInicianteIntermedirioAvanado

    Autor: Luciano Pimenta

    Autor: Thiago C. Montebugnoli

    Autor: Eduardo Massud

    Autor: Antonio Spitaleri Neto 26Autor: Leonora Golin

  • fevereiro 201204

    Bem-vindo

    Delphi marca registrada da Borland International, as demais marcas citadas so registradas

    pelos seus respectivos proprietrios.

    Antonio Spitaleri Neto - Editor [email protected]

    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 Mas-sud 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

    Internethttp://www.theclub.com.br

    Cadastro: [email protected]: [email protected] Informaes: [email protected] Cadastro: theclub_cadastro

    Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

    www.twitter.com/theclubbr

    Copyright The Club Megazine 2009

    Diretor TcnicoMarcos Csar Silva

    DiagramaoEduardo Massud

    CapaVitor Manuel Rodrigues

    RevisoEliziane Valentim

    ColunistasAntonio Spitaleri Neto

    Eduardo MassudLeonora Golin

    Luciano PimentaThiago Cavalheiro Montebugnoli

    Impresso e acabamento:GRIL - Grfica e Editora

    Taquarituba-SP - Tel. (14) 3762-1345

    ReproduoA 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.

  • fevereiro 2012 05

    Delphi

    A funo de arrastar e soltar tem tido grande viabilidade, por ser bem mais intuitiva de que a busca com a caixa de dilogo, utili-zando 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: TWMDro-pFiles); message WM_DROPFILES; ela a responsvel por interpretar e gerenciar todo arquivo que arrastado para a aplicao.

    unit FmMain;

    interface

    uses Windows, Messages, SysUtils, Classes,

    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):

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

  • fevereiro 201206

    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

    Na clausula Uses da seo implementation devemos declarar as funes ShellAPI e UFileCa-tcher 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

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

    { TForm1 }

    Para que possamos habilitar o sistema de ar-rastar e soltar devemos criar 3 procedimentos que sero de inicializao, finalizao e do momento em que estes arquivos so transferidos, e outro

    que servir para consultar se o arquivo permitido ou invlido

    procedure TForm1.FormCreate(Sender: TObject);

    begin DragAcceptFiles(Self.Handle, True);end;

    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 if ArquivoSuportado(Arquivo) then

    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.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 procedure Exibir carregamos todos os arquivos para os componentes que iro permitir que sejam visualizados

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

  • fevereiro 2012 07

    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;

    Mesmo se tratando de um component Drag Drop, o Delphi executar algumas funes neces-srias 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.ListBox1Click(Sender: TObject);begin Exibir(ListBox1.ItemIndex);end;

    procedure TForm1.

    Open1Click(Sender: TObject);begin if (OpenDialog1.Execute) then Incluir(OpenDialog1.FileName);

    end;

    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.

    Figura 1 Aplicao em Execuo

    Consultor Tcnico The Club.

    Sobre o autor

    Eduardo Massud

    [email protected]

  • fevereiro 201208

    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.

    Criando a Ordem de servio

    Precisamos saber qual o oramento vincula-remos 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

    tela. Uma caracterstica que precisamos ter aqui ser de armazenar em memria, as peas/servios adicionados para a OS.

    Seria problemtico, em termos de performan-ce, 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 possa-mos 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 mo-dificao 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 mui-to 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 as Stored Procedures

    Veja na Listagem 1 o cdigo das duas Stored

  • fevereiro 2012 09

    Procedures que criaremos.

    Listagem 1. Stored Procedures

    CREATE PROCEDURE SP_ORDEM_SERVICO @nCdVeiculo int, @nCdOrcamento int, @sDsObservacoes varchar(max), @nCdOrdem int outputASBEGIN 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)ASBEGIN INSERT INTO OS_DETALHE (nCdOrdem, nCdPeca, nQtPeca, nVlUnitario) VALUES (@nCdOrdem, @nCdPeca, @nQtPeca, @nVlUnitario) 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

    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 Lis-

    tagem 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 thenbegin 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) thenbegin nCdOrcamento := DM.cdsOrcamentoPlacanCdOrcamento.AsInteger; nCdVeiculo := DM.cdsOrcamentonCdVeiculo.AsInteger;end;

    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

    Figura 1. Tela de cadastro da OS.

  • fevereiro 201210

    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.nCdVeiculoWHERE V.sNrPlaca = :PLACA and O.nIdStatus = 1

    Um detalhe importante, veja que estamos pesquisando somente nos oramentos ativos (nI-dStatus = 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 pro-dutividade 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 formul-rio que ter os seguintes campos: cdigo da pea, nome da pea, quantidade e preo. Veja na Figura 3 os campos do ClientDataSet.

    Figura 3. Campos do cdsItens

    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 respon-svel por adicionar os itens em memria no Clien-tDataSet. 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 4. Finalizando o formulrio de cadastro de OS

    Figura 5. Menu de contexto no grid

  • fevereiro 2012 11

    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;

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

    ficamos se o ClientDataSet no esta ativo, assim, criamos o mesmo em memria usando o mtodo CreateDataSet.

    Para inserir um registro no controle, chama-mos 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 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 de-sabilitar (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

    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

    Figura 6. Cadastro de oramento em execuo

  • fevereiro 201212

    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.RollbackIncompleteFreeAndNil(TransDesc); end;

    //comita as alteraes no banco SysCar.ommitFreeAndNil(TransDesc);

    Result := bRetorno;end;

    O cdigo esta comentado, mas vamos en-tender 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 po-demos 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 Roll-backIncompleteFreeAndNil para no efetivar nada no banco de dados.

    Se no ocorrer nenhum problema, o fluxo con-tinuar, 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.

    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.

    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)elsebegin 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;

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

    Figura 7. Parmetros das Stored Procedures configurados no componente

  • fevereiro 2012 13

    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 or-dem de servio que deseja alterar.

    Para finalizar completamente, aps confir-mar, 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 OramentoData module

    procedure TDM.AlterarStatusOrcamento(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;

    Formulrio da OS

    ...

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

    DM.AlterarStatusOrcamento(nCdOrcamento);...

    Concluses

    Finalizamos neste artigo a nossa aplicao no

    Figura 8. Salvando uma ordem de servio

    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 Bussi-ness em Florianpolis-SC.

    Sobre o autor

    Luciano Pimenta

    www.lucianopimenta.net

    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 prin-cipais, 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!

  • fevereiro 201214

    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 fun-cionalidades na prtica e algumas classes teis ao decorrer do desenvol-vimento 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 apren-dizado 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:

  • fevereiro 2012 15

    schemas.android.com/apk/res/android android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent >

    Figura 01: Recursos no Sistema Android.

    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.

    Hello World! Vendas The

    Club

    Figura 02: Hierarquia de Componentes Utilizados.

    Bem, como este no nosso primeiro projeto, esta varivel hello no ser utiliza-

    da, portanto podemos exclu-la tanto de nossa tela de recursos quanto na tela principal.

    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:

    LinearLayout(Horizontal): Possibilita a disposio horizontal dos componentes

    da tela.

    Exemplo:

  • fevereiro 201216

    A tela de venda possuir a seguinte estrutura:

    Nome Cliente

    Cidade

    Estado

    Produtos

    o The Club Lite (Delphi)

    o The Club Lite (C#,.NET)

    o The Club Professional

    o The Club Student

    Boto Efetuar Compra

    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:

  • fevereiro 2012 17

    android:layout_gravity=center>

    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.

    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:

    AC AL AM BA CE ES GO MA MT MS MG PA PB PR PE PI RJ RN RS RO RR SC SP SE TO

    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

  • fevereiro 201218

    Figura 03: Tela de Vendas.

    Figura 04: Criando uma classe Registro.

    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

    { String cliente, cidade, estado; int curso;}Codificando o Boto Efetuar CompraO 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;

  • fevereiro 2012 19

    @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 usurioMensagemAlerta(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 projetopublic 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 201220

    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 mes-mo. 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!

    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 Proces-samento de Dados da Prefeitura Municipal de Ita-SP. Possui as seguintes certificaes: MCP - Microsoft Certified Professional, MCTS - Microsoft Certi-fied Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

    Sobre o autor

    Thiago Cavalheiro Montebugnoli

    [email protected]

  • fevereiro 2012 21

  • fevereiro 201222

    Em artigo anterior, apresentei a vocs a ferramenta Lazarus. Relembrando, Lazarus um projeto independente OpenSource, desenvolvido em Linux, possui sua IDE ba-seada 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, Win-dows 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

    ferramenta.

    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 exis-tentes: 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!

    Conhecendo os componentes de conexo

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

    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; SQLite; Interbase/Firebird

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

    Conexo ao Firebird em Lazarus

  • fevereiro 2012 23

    retirando e passando informaes para a base de dados.

    No artigo, estaremos utilizando o ltimo com-ponente, para Interbase/Firebird.

    Tambm estaremos utilizando dessa aba os componentes de consulta, no caso o SqlQuery.

    Conectando ao Firebird

    Conforme j mencionado, estaremos utilizan-do 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 The-Club_Lazarus_Teste.

    Veja o script de criao da base:

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

    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.

    Abra o cdigo da unit e na clusula uses colo-que a unit: IBConnection.

    Na seo implementation declare a funo conforme mostrado abaixo:

    function ConexaoFirebird(DataBaseHost,DataBaseName,UserName,Password:String):TIBConnection;var ConnAux:TIBConnection;begin ConnAux:=TIBConnection.Create(nil); ConnAux.HostName:=DataBaseHost; ConnAux.DatabaseName:=DataBaseName; ConnAux.UserName:=UserName; ConnAux.Password:=Password; ConnAux.Connected:=True;

    if(ConnAux.Connected)then Result:=ConnAux

    else Result:=nil;end;

    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 ban-co 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:

    procedure TForm1.FormCreate(Sender: TObject);var Conn:TIBConnection;begin Conn:=ConexaoFirebird(localhost,C:\TheClub_Lazarus_Teste,SYSDBA ,masterkey);

    if(Connnil)then Caption:=Conexo OK else Caption:=No foi possvel realizar a conexo;

    end;

    Veja o resultado na figura 2.

    Figura 1

    Figura 2

  • fevereiro 201224

    Repare que no topo da pgina ir aparecer a mensagem avisando que a conexo est fun-cionando.

    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 in-sero 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.

    Create(nil); // Criamos a transao para a conexo

    if(Connnil)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

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

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

    except // Se ocorrer erro cancela a transao Trans.Rollback; end; finally Trans.Free; Conn.Free; end; end;end;

    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 com-ponentes fixos:

    SqlQuery: Aba sqlDB; DataSource: Aba DataAccess; DbGrid: Aba DataControls;

    Figura 3

    Figura 4

  • fevereiro 2012 25

    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:

    SELECT * FROM THE_CLUB_NOMES.

    Na funo de atualizar a consulta, iremos criar a instncia da conexo e ligar a Query a essa instn-cia para gerarmos a consulta ao abrirmos a Query.

    Vamos agora ao cdigo do boto Atualizar Consulta:

    procedure TForm1.Button2Click(Sender:

    TObject);var Conn:TIBConnection;

    Trans:TSQLTransaction;begin try SQLQuery1.Close; // Conectamos ao banco Conn:=ConexaoFirebird(localhost,C:\TheClub_Lazarus_Teste,SYSDBA,masterkey);Trans:=TSQLTransaction.

    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;

    Veja a consulta em execuo na figura 6:

    Com a parte de consulta fechamos nosso exemplo de manipulao do banco de dados Fire-bird com Lazarus.

    Concluso

    Nesse segundo artigo sobre Lazarus, demons-trei 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 fer-ramenta 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 pr-ximos 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!

    Consultor Tcnico The Club.

    Sobre o autor

    Antonio Spitaleri Neto

    [email protected]

    Figura 5

    Figura 6

  • fevereiro 201226

    X

    MTODOS RAVEReportde A a Z

    WWRITE NULL DATA este mtodo escreve

    um valor nulo dentro do evento OnGetRow de um componente de conexo de dados. Os da-dos para os campos personalizados devem ser escritos na mesma ordem em que os campos foram definidos no evento OnGetCols.

    Example (Delphi)

    Connection.WriteNullData( );

    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 cam-pos foram definidos no evento OnGetCols. Os parmetros formatdata definem o valor formatado do campo, mas podem ficar em

    branco se no for necessria uma sada pr--formatada. Parmetros NativeData devem conter o contedo no modificvel do campo.

    Example (Delphi)

    Connection.WriteStrData( ,CustomerName );

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

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

    pontos (dots) para unidades (units) (definida por Unidades em UnitsFactor)

    Example (Delphi)

    XPos := RvNDRWriter1.XD2U( 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 unInchCurrXDots := RvNDRWriter1.XI2D( RvNDRWriter1.XPos );

    XI2U este mtodo converte a medida horizontal de inch (polegadas) para unit (de-finida pela Units e UnitsFactor).

    Example (Delphi)

  • fevereiro 2012 27

    YZ

    XPos := RvNDRWriter1.XI2U( LastXInch );

    XU2D este mtodo converte a medida horizontal de units (definida pelas Units e UnitsFactor) para pontos (dots).

    Example (Delphi)

    CurrXDots := RvNDRWriter1.XU2D( RvNDRWriter1.XPos );

    XU2C este mtodo converte a medida horizontal de units (definida pelas Units e UnitsFactor) para polegadas (inches).

    Example (Delphi)

    //com units configuradas para unCMCurrXInch := RvNDRWriter1.XU2I( RvNDRWriter1.XPos );

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

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

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

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

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

    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)

    Consultora Tcnica The Club.

    Sobre o autor

    Leonora Golin

    [email protected]

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

    ZOOM IN este mtodo adiciona Zoo-mInc ao ZoomFactor atual e aumenta a ima-gem 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;

    ZOOM OUT - este mtodo subtrai Zoo-mInc do ZoomFactor atual e diminui a imagem na tela. Se um evento OnZoomChange for definido, ento ser chamado e ser respon-svel por redesenhar a pgina, caso contrrio, a tela redesenhada.

    Example (Delphi)

    RvRenderPreview1.ZoomOut;

  • fevereiro 201228

    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 }

    Criamos duas funes, uma que ir receber os dados da conexo, retor-nando 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;

    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;

    Iremos agora copiar o texto da varivel Aplicativo para armazen-la na varivel Arquivo, depois, selecionar o diretrio padro d mquina correspon-dente, 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;

    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 con-siderado 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;

    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

  • fevereiro 2012 29

    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.

    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.

    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 }

    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 }

    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;

    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 par-metros 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);

    Aps identificado o formulrio da aplicao iremos armazen-la na varivel do tipo HWND que controla os processo em execuo e o GetWindowThrea-dProcessID, identificando a janela e o ndice do processo

    HWNDJanela:= FindWindow(Classe, Janela); GetWindowThreadProcessID(HWNDJanela, @IDProcesso);

    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 201230

    VerticalHorizontal

  • fevereiro 2012

  • fevereiro 2012