Escolar Documentos
Profissional Documentos
Cultura Documentos
julho
julho
2013
04
FastReport no Delphi
Autor: Luciano Pimenta
05
Editorial
TConexao:
Autor: Hamden Vogel
11
Android
Trabalhando com o TouchScreen
19
ndice
27
03
Editorial
Caro Leitor! sempre com muita alegria e satisfao que finalizamos mais uma revista aos senhores. Aproveito tambm para agradecer s pessoas que vem acessando o contedo de nosso site, portanto a cada dia que passa estamos adquirindo mais acessos e cadastros. Que continuemos assim! Para este ms, nosso consultor tcnico Jos Antonio nos trouxe direto do forno as principais novidades do Delphi XE4 com o intuito de sempre mant-los bem informados com as ltimas tecnologias lanadas no mercado. Nosso colunista mensal Luciano Pimenta aborda o uso do gerador de relatrios FastReport, uma boa opo para quem trabalha com o Delphi. Podemos considerar esta ferramenta como a opo oficial para quem utiliza as novas verses do Delphi. J nosso colaborador Hamden Voguel desenvolveu um componente prprio para gerenciar projetos em ambientes Multi-Plataforma, o TConexao. Nesta primeira parte ele ir nos auxiliar na gerncia de Projetos utilizando diversos tipos de Banco de Dados. Importante salientar que este componente est disponvel gratuitamente em nosso site. Eu continuo apresentando recursos do Sistema Android, sendo que neste ms ensino a trabalhar com o TouchScreen, descrevendo suas principais classes e mtodos para realizar esta tarefa. Recomendo a leitura deste artigo para quem est comeando a desenvolver aplicativos e para quem deseja aprimorar seus conceitos em relao a este artifcio.
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 2013 Diretor Tcnico Marcos Csar Silva Diagramao Vitor M. Rodrigues Design Vitor M. Rodrigues Reviso Drielly Cristini Patrinhani Colunistas Joo Marcos Sakalauska Jos Antonio P. M. de Paula Lucas de Oliveira Luciano Pimenta Thiago Cavalheiro Montebugnoli Juninho Jeferson Silva de Lima
Impresso e acabamento:
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.
04
julho
2013
FastReport no Delphi
A ferramenta ainda possui suporte (adquirido separadamente) para .NET, Mono e Lazarus. Possui ainda uma ferramenta chamada FastCube para anlise de dados e construo de relatrios e grficos (OLAP), uma ferramenta de scripts (FastScript) e o FastQueryBuilder, construtor visual de consultas SQL. Para ver exemplos e outras informaes sobre essas ferramentas, acesse: www.fast-report.com/pt/. Nesse artigo, vamos conhecer a verso do FastReport que acompanha o Delphi XE4, aprendendo a criar relatrios simples, agrupados, formataes e muitos outros exemplos.
astReport um gerador de relatrios presente no Delphi desde a sua verso 4. A partir da verso XE2, passou a ser a ferramenta de relatrios oficial do Delphi. Com o FastReport podemos criar poderosos relatrios pra nossas aplicaes Win32 e FireMonkey com Delphi.
Trabalharemos para criar relatrios simples, usando dois componentes: o frxReport e o frxDBDataSet. O primeiro o editor de relatrios, onde basta dar um duplo clique que teremos o ambiente de criao dos relatrios (Figura 2). O segundo faz a ponte, entre os dados e o relatrio.
Conhecendo a ferramenta
Ao abrir o Delphi e criar um projeto VCL Foms, podemos visualizar a aba FastReport 4.0 (Figura 1).
Figura 2. Ambiente de desenvolvimento de relatrios (fonte: FastReport Users Manual)
Baseado na Figura 2, destacamos a seguir as principais janelas e editores. 1. Report designer: local onde vamos adicionar as bandas e os objetos para o relatrio; 2. Barra de menus; 3. Barra de ferramentas: botes com as opes de carregar relatrios, criar novos, salvar etc; 4. Barra de ferramentas do objeto: objetos que podem ser adicionados ao relatrio; 5. Report page tabs: abas para configurao da pgina do relatrio; 6. Report tree: janela onde podemos visualizar as bandas e objetos inseridos no relatrio; 7. Object Inspector: janela para definio das propriedades dos objetos do relatrio; 8. Data tree: janela com os objetos de dados do relatrio. Podemos
2013
julho
05
arrastar facilmente um campo para o relatrio; 9. Rgua; 10. Status line: semelhante a uma barra de status, com informaes sobre o objeto selecionado no relatrio.
Adicione os tipos: Page Header, Page Footer e Master Data. O Master Data, abre um editor, solicitando o respectivo DataSet da aba. Selecione frxDBDataSet1. Existem duas maneiras de adicionar os campos na banda Master Data para exibir os dados. Arraste os campos da janela Data tree para o relatrio. Note que aps inserir os campos, ao passar o mouse, mostrado uma seta, onde podemos clicar e ser exibido um menu com os campos do DataSet, assim fica fcil modificar o objeto para outro campo da consulta (Figura 5).
Primeiro exemplo
Volte ao Delphi e adicione um frxDBDataSet (um frxReport tambm deve estar no formulrio). Crie uma conexo com o banco de dados de sua preferencia (usarei no artigo, o Firebird). Usarei no artigo um Data Module para conter os componentes de conexo com o banco, pois usaremos vrios exemplos. Vincule o frxDBDataSet com o DataSet que retorna os dados da sua consulta. D um duplo clique no frxReport para abrir o editor. Primeiramente, vamos vincular o frxDBDataSet com o nosso relatrio, acessando o menu Report>Data. No editor que abrir, escolha o respectivo controle de dados (Figura 3).
Vamos agora, adicionar as bandas do relatrio. Clique no boto Insert Band na barra de ferramentas de objetos. Conforme vemos na Figura 4 mostrado um menu suspenso que todas as opes de banda.
Outra maneira de adicionar os campos no relatrio escolhendo um Text object na barra de ferramentas e adicionando o mesmo no relatrio. Ser aberto um editor com alguns botes (Figura 6).
No editor, temos abas onde vamos configurar o formato do campo, formataes de fonte etc. o primeiro boto da aba Text, acessa outro editor, onde podemos escolher os campos da consulta, variveis do relatrio, funes, etc (Figura 7).
Figura 4. Adicionando bandas ao relatrio
06
julho
2013
Formatao de objetos
Como podemos ver no relatrio que criamos, o campo Salary, esta como texto, sem a devida formatao. Para ajustar isso, abra o relatrio e d um duplo clique no campo. No editor, acesse a aba Format e configure, conforme a Figura 10, onde indicamos o tipo de formatao e o separador decimal (vrgula) do formato.
Podemos usar o editor do Text Object para apenas adicionar rtulos (textos) no relatrio, onde basta digitar o texto desejado na aba Text. Na barra de ferramentas temos as funcionalidades necessrias para formatar os textos digitados nesse objeto. Note que ao adicionarmos um Text Object ou mesmo adicionar um campo usando a janela Data tree, existem linhas que nos auxiliam para que os controles fiquem alinhados tanto horizontalmente, como verticalmente (Figura 8).
Figura 10. Relatrio de listagem em execuo
Nem precisamos executa o projeto novamente, basta acessar o boto de preview no prprio ambiente do relatrio para visualizar as modificaes. E se precisssemos modificar a formatao de um objeto (fonte, cor etc) de acordo com algum parmetro que existisse, como faramos? bastante simples. Acesse o objeto que deseja modificar a formatao. D um duplo clique para acessar o editor e a aba Highlight. Na opo Condition, digite: <frxDBDataset1.SALARY> > 50000. Marque em Font a opo Bold. O boto Color, indica a cor do texto quando a condio do objeto for verdadeira. Voc tambm pode usar o boto para acessar o editor de expresses para montar a mesma manualmente. De acordo com o configurado antes, o campo Salary do relatrio deve aparecer em vermelho quando o valor desde for maior que 50.000,00. Veja na Figura 11 nosso exemplo em execuo.
Feche o relatrio. No Delphi, adicione um boto e adicione o seguinte cdigo em seu evento OnClick: frxReport1.ShowReport(); Execute a aplicao e visualize o relatrio em funcionamento (Figura 9).
Caso voc deseje mudar a formatao de todo a linha, para que no precise fazer manualmente a configurao de cada objeto, basta selecionar todos os objetos e acessar a propriedade HighLight>Condition e fazer a mesma configurao anterior.
Figura 9. Relatrio de listagem em execuo
2013
julho
07
a pgina atual do relatrio. O FastReport possui variveis que retornam essas informaes e que so fceis de serem utilizadas. Acesse a aba Variables do Data tree e arraste para o formulrio um Date e um TotalPages. Para customizar esses variveis, basta dar um duplo clique e digitar o texto que deseja. Veja na Figura 12 o rodap do relatrio (modifiquei o mesmo para mostrar mais de uma pgina).
Cdigo 02
select EMPLOYEE.first_name, EMPLOYEE.last_name, employee.salary, DEPARTMENT. department from EMPLOYEE inner join DEPARTMENT on DEPARTMENT.dept_no = EMPLOYEE. dept_no order by DEPARTMENT.department
Nota: Para adicionar um texto, basta digit-lo no editor, tomando o cuidado de no remover a varivel.
Crie um novo frxReport (se desejar, em outro formulrio). Caso seja carregado o relatrio anterior, crie um novo. No esquea de modificar o Data do relatrio. Caso tenha criado um novo formulrio, atende para o nome do formulrio no editor de seleo de DataSets (Figura 3). De um duplo clique no Master Data e vincule com o DbDataSet. Adicione uma banda Group Header. Um editor aberto para configurarmos a banda do grupo. Vamos indicar que o agrupamento se dar pelo campo Department. Podemos ainda indicar uma expresso para o agrupamento. Nas opes de agrupamento, podemos configurar para que a cada grupo, seja mostrado em uma nova pgina ou drill-down, onde clicamos sobre o grupo para mostrar os dados.
Arquivos de relatrios
Para voc que estava acostumado com o Rave Reports, vai notar uma diferena interessante no FastReport. Cada relatrio um arquivo FR3. No Rave, o arquivo RAV era de projeto e dentro poderamos ter vrios relatrios. No FastReport, cada FR3, apenas um relatrio. Salve o arquivo e modifique o cdigo do boto para o seguinte cdigo:
Cdigo 01
Dica: caso voc escolha a opo drill-down ao executar o relatrio, apenas os grupos sero mostrados. necessrio clicar em cima do mesmo para exibir os registros.
Nota: caso o FastReport no encontre o arquivo, nenhum erro mostrado, apenas o relatrio no exibe nenhum registro.
Arraste a banda para que fique acima da Master Data. Veja na Figura 13 o relatrio agrupado em execuo.
Usamos o mtodo LoadFromFile para carregar o arquivo de relatrio no frxReport. Isso nos d a facilidade de termos apenas um controle e vrios relatrios, sendo carregados de acordo com a nossa necessidade.
Agrupamento
Outro exemplo muito usado em relatrios o de agrupamento de dados. Neste exemplo, vamos fazer a mesma listagem anterior, com a diferena que vamos retornar todos os empregados, agrupados pelo seu departamento. Veja o SQL da consulta:
08
julho
2013
Somatrio
Sempre que usamos agrupamento de dados em um relatrio, precisamos somar um determinado campo ou contar a quantidade de registros. Vamos aproveitar esse relatrio para fazer esse exemplo. Adicione uma banda GroupFooter no relatrio. Adicione um Text Object e acesse o boto Insert Aggregate da aba Text. No editor, vamos configurar um campo que ter seu valor somado, que no caso Salary. Veja na Figura 14 como ficou a configurao.
Master/detail
Outro exemplo muito comum em relatrio e de mostrar os dados master e os details. Exemplo clssico: nota fiscal, os dados referente ao cliente (comprador) podemos considerar o master, e as informaes dos produtos da nota, so o detail. Essas duas fontes de dados, precisam ter um relacionamento. Primeiro, teremos duas consultas separadas, uma para a master e outra para detail. Nesse exemplo, estou pesquisando os empregados (Employee) e o histrico de salrios (Salary_History). Precisaremos, portanto de dois frxDBDataSet (um para cada consulta). O relacionamento, faremos nos componentes de consulta, o que bastante simples. Adicione um DataSource e faa a ligao com a consulta master. No componente (ClientDataSet, Query, Table etc) com os dados da consulta detail, acesse a propriedade MasterSource e escolha o DataSet anterior. Em MasterFields, acesse o editor e configure o campo de relacionamento (nesse caso Emp_no). Crie um novo relatrio e adicione as seguintes bandas: Page Header, Master Data, Detail Data e Page Footer. Na Master Data voc deve configurar o frxDBDataSet que tem os dados do mster (no exemplo, Employee) e consequentemente, para o Detail Data, os dados do detail (Salary_History). Veja na Figura 16 a disposio dos campos nas duas bandas.
Faa a formatao no campo, semelhante ao campo Salary. Rode o relatrio e note que temos o somatrio por grupo. Mas e se quisermos o valor total no final do relatrio? Basta adicionar uma banda ReportSummary e fazer a mesma configurao anterior. Veja na Figura 15 o relatrio com somatrio do grupo e somatrio total.
Execute o relatrio e veja que os dados esto agrupados de acordo com o nome do empregado.
Exportao de relatrios
Uma caracterstica interessante que observei no FastReport a quantidade de opes de tipos de exportaes para os relatrios. Veja na Figura 17 a aba de exportaes do FastReport.
Dica: temos uma opo bem interessante na configurao do somatrio. Caso precisssemos mostrar um somatrio acumulado por grupos, basta marcar a opo Running total na janela Insert Agreggate (Figura 14). Assim, a cada final de grupo, teramos um somatrio acumulado.
Figura 17. Tipos de exportaes do FastReport julho
2013
09
Para exportar, por exemplo, um relatrio para HMTL, basta adicionar no formulrio um frxHTMLExport. Acesse a IDE de desenvolvimento e execute o preview do relatrio. Note que um boto foi adicionado para exportar o relatrio. Para cada tipo de exportao, um item de menu ser adicionado no preview do relatrio (Figura 18).
Figura 19. Editor para envio por e-mail do relatrio Figura 18. Opes de exportao no preview do relatrio
Na verso comercial do FastReport, diferente da verso que acompanha o Delphi, existe a opo de envio do relatrio por e-mail. Ao clicar no componente, um editor ser mostrado. Nele, na aba E-mail configuramos para quem o relatrio ser enviado, assunto, corpo do e-mail e escolhendo o formato desejado (Figura 19). Na aba Account, configuramos o e-mail de envio, ou seja, as nossas configuraes de e-mail para o envio do mesmo.
Concluses
Vimos nesse artigo como trabalhar com o FastReport, a nova ferramenta para gerar relatrios no Delphi. Existem muitas outras possibilidades para criarmos relatrios profissionais para suas aplicaes Delphi, assim, no prximo artigo veremos como criar grficos, cross-tab, trabalhar com templates (semelhante herana) etc. Um grande abrao a todos e at a prxima!
Sobre o autor
Luciano Pimenta
Luciano Pimenta (NOVO DOMINIO: www.lucianopimenta.com) desenvolvedor Delphi/C# para aplicaes Web com ASP.NET, Windows com Win32 e Windows Forms com .NET. Palestrante da 4 edio da Borland Conference (BorCon) e da 1 Delphi Conference. MVP Embarcadero, grupo de profissionais que ajudam a divulgar o Delphi no mundo. Atualmente desenvolvedor da SoftDesign fbrica de softwares em Porto Alegre-RS. Autor de mais de 90 artigos e de mais de 600 vdeos aulas publicadas em revistas e sites especializados, alm de treinamentos presenciais e multimdias. consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programao e banco de dados.
www.lucianopimenta.net
10
julho
2013
TConexao: Gerenciando
Ns temos a seguinte misso de fazer todo o meio-de-campo entre a camada de apresentao e a de negcio: enquanto as telas do cliente fazem as chamadas para as classes de negcio, elas por sua vez vo se comunicar com a nossa classe de conexo para chamar o banco de dados desejado, processando a chamada (select, update, etc) e finalmente a retornando (um dataset, stringlist, etc) - conforme pode ser entendido pela figura abaixo:
Figura 01 - Como as camadas se comunicam com a classe TConexao. Enquanto que uma camada chama, outra sempre a escuta e resolve.
Esta funcionalidade interessante pela praticidade, como dito anteriormente, pois o aplicativo fica livre de implementaes distintas de acesso aos dados; apenas a nossa classe de conexes far este trabalho de carregamento e alterao deles toda visualizao produzida pelo carregamento do componente TClientDataSet ele sempre ser alimentado pela nossa classe portanto eles sempre andaro juntos um sempre se comunicando com o outro e consequentemente a base em que ele acessar ser sempre desligada, esperando algum evento do usurio ou sistema, como por exemplo de comitar um update ou carregar uma lista (para inicializao de uma tela ou um refresh). Abaixo pode ser visualizado o diagrama de sequncia do componente, a fim de exemplificar o seu funcionamento na prtica; no complicado perceber sua idia bsica de funcionamento.
2013
julho
11
Agora, finalmente, o processo completo de funcionamento de acordo com a orientao a objetos juntamente com a nossa classe:
nem tampouco as camadas de negcio (nosso exemplo o TUsuario) acessem quaisquer parmetros de banco de dados ou sequer se comuniquem com ele: tudo isso dever EXCLUSIVO da classe TConexao. Portanto, basicamente o processo de criao para um novo banco finaliza-se aqui; no difcil estend-lo.
Figura 03 - Explicao da operacionalizao do funcionamento das camadas juntamente com as regras negociais e com a classe TConexao.
O importante sempre criar um banco de dados primeiro e depois suas implementaes, sempre estendendo a classe TConexao, criando uma nova subclasse que ir sobreescrever os mtodos BancoExiste, FecharBanco, CarregarBanco, RecordCount, RetornaDataSet e ObterDataSet cruciais para operaes bsicas de funcionamento consulta, incluso, alterao e excluso alm de outros mtodos descendentes de TDataSet (recordcount). A seguir, um trecho do cdigo-fonte do mtodo CarregarBanco de uma conexo para o Firebird:
Cdigo 01
12
function TConexaoFirebird. CarregarBanco(const cDiretorio: string): Boolean; begin Result := True; if (cDiretorio = EmptyStr) then begin fVendorLib := FMyGDSVendorLib; fLibraryName := FMyDBXExpress FirebirdLibraryName; fPathDataBase := FUsuariosFDB; end else if (cDiretorio = default) then begin fVendorLib := FMyGDSVendorLib; fLibraryName := ExtractFilePath(Application. ExeName) + IncludeTrailingPathDelimiter (BD\FIREBIRD) + FMyDBXExpressFire birdLibraryName; fPathDataBase := ExtractFilePath (Application.ExeName) + IncludeTrailingPathDelimiter (BD\FIREBIRD) + fPathDataBase; end else begin fVendorLib := cDiretorio + FMyGDSVendorLib;
julho
2013
fLibraryName := cDiretorio + FMyDBXExpress FirebirdLibraryName; fPathDataBase := cDiretorio + fPathDataBase; end; Result := ( (DirectoryExists (fPathDataBase)) and (FileExists (fLibraryName)) ); if not Result then Exit; dmFirebird := TdmFirebird. Create(nil); try try with dmFirebird. SQLConnection do begin Connected := False; VendorLib := dbVendorLib; LibraryName := dbLibraryName; Params. Values[Database] := fPathDataBase + FUsuariosFDB; end; finally dmFirebird.SQLConnection. Connected := True; dmFirebird.SQLQuery.Open; end; except on E: Exception do begin Raise EInvalidDataBase. Create (EErroGeralBancoDeDados + #13#10 + E.Message); Result := False; end; end; end;
CREATE TABLE USUARIOS ( CD_USUARIO INTEGER, NOME VARCHAR(200), DATANASCIMENTO DATE, ENDERECO VARCHAR(200), CIDADE VARCHAR(10), ESTADO VARCHAR(3), CEP VARCHAR(20), CARGO VARCHAR(200), SETOR VARCHAR(200), TELEFONE VARCHAR(20), FOTO BLOB SUB_ TYPE 0 SEGMENT SIZE 500, VLR_SALARIO FLOAT, NR_MATRICULA INTEGER );
No nosso projeto foram criados campos dos tipos String, Integer, Float e Blob. Todos os tipos sero validados de acordo com o formato suportado pelo banco isto nem todos possuem as mesmas validaes para data, ponto flutuante, etc. Um ponto importante a ser mencionado que todos os setters so do tipo String isso facilita os testes de validao de tipo de dados antes de sua converso para o seu formato original. Alguns campos so obrigatrios, requeridos nos setters e retornando um campos de mensagens de retorno (FCodigoMensagem e FMensagem). Uma amostra do fonte da propriedade da data de nascimento (mtodo write):
Cdigo 02
Nossa classe tem 3 bancos pr-definidos e configurados que j podem ser prontamente utilizados em qualquer aplicao, dando incio a um desenvolvimento de cdigo mais facilitado graas a esta abstrao de conexes, porque no ser mais necessrio criar outras conexes para o mesmo banco em diferentes forms ou um criar um data-mdulo e associ-lo aplicao, pois como isso tudo j foi feito, basta apenas chamar a classe de negcio (no nosso caso de exemplo, a TUsuario). So os Bancos:
procedure TUsuario. setDataNascimento(const Value: String); //obrigatrio var AuxDia, AuxMes, AuxAno, fValue: string; begin fValue := Value; fValue := Conexao. GetDateFormat(Value); if not (Biblioteca. EmptyDate(fValue)) then
2013
julho
13
begin if not Biblioteca. IsValidDate(fValue) then begin FCodigoMensagem := CodMensagemCampoInvalido; FMensagem := Campo Data Nascimento Invlido!; FDataNascimento := ; end else begin FCodigoMensagem := CodMensagemNormal; FMensagem := EmptyStr; FDataNascimento := Conexao. FormatDefaultDate(fValue); // Trim(Value); end; end else begin FDataNascimento := fValue; FCodigoMensagem := CodMensagemCampoEmBranco; FMensagem := Campo Data Nascimento em Branco!; Alterou := False; end; end; Agora, um exemplo do cdigo-fonte padro para verificar se existe um registro e em caso positivo atualiz-lo:
Cdigo 03
, CIDADE = + QuotedStr(Cidade) + , ESTADO = + QuotedStr(Estado) + , CEP = + QuotedStr(CEP) + , CARGO = + QuotedStr(Cargo) + , SETOR = + QuotedStr(Setor) + , TELEFONE = + QuotedStr(Telefone) + , VLR_SALARIO = + (Conexao. FormatFloat(Salario)) + , NR_MATRICULA = + (Conexao. FormatInteger(Matricula)) + WHERE NOME = + QuotedStr(Nome); Conexao.Executar(Query); end Explicao: A classe TConexao, atravs de GetConexao, e utilizando o type tBDConexao (type tBDConexao = (bdConexaoXML, bdConexaoDBISAM, bdConexaoFirebird) far a instanciao com a subclasse desejada de acesso ao banco, e a melhor de todas as coisas que em runtime os bancos podem ser trocados selecionando, alterando, etc com a maior versatilidade! Em suma, toda vez que uma classe quiser acessar um banco, ela na verdade acessa uma instncia da classe de conexo (TConexao), onde esta por sua vez referenciar-lo em memria. Toda a interface de comunicao e operacionalizao ser realizada somente atravs dela, estando disponvel at ser destruda. Abaixo, uma seleo de alguns mtodos importantes utilizados na classe TConexao - detalhe para os mtodos ObterDataSet, CarregarFoto e GetConexao (sintaxe: Conexao := Conexao.GetConexao(fbdConexao)) - que so os mtodos mais importantes do processo de comunicao entre os objetos de negcio e dados.
Cdigo 04
Query := SELECT * FROM USUARIOS WHERE NOME = + QuotedStr(Nome); if Conexao.RecordCount(Query) > 0 then //atualiza begin Query := UPDATE USUARIOS SET ENDERECO = + QuotedStr(Endereco) + , DATANASCIMENTO = + QuotedStr(Conexao. FormatDate(DataNascimento)) +
procedure TConexao. ObterDataSet(const myDataSet: TDataSet; var myClientDataSet: TClientDataSet); var fDataSet: TDataSet; i {, k}: integer; FName: string; begin if not Assigned(myDataSet) then Exit; if not Self.BancoInstanciado then begin Application.MessageBox(PCha r(Format(EBancoNaoInstanciado, [FUsuariosFDB])), ETituloErro, MB_OK + MB_ICONERROR);
14
julho
2013
Abort; end; fDataSet := TClientDataSet(myDataSet); fDataSet.First; if not myClientDataSet.Active then myClientDataSet. CreateDataSet else myClientDataSet. EmptyDataSet; myClientDataSet. DisableControls; try while not fDataSet.Eof do begin myClientDataSet.Insert; for i := 0 to fDataSet. FieldCount - 1 do begin // myClientDataSet. Fields[i].Assign(fDataSet. Fields[i]); myClientDataSet. FieldDefs.Items[i].DataType := (fDataSet.FieldDefs.Items[i]. DataType); myClientDataSet. FieldDefs.Items[i].DisplayName := (fDataSet.FieldDefs. Items[i].DisplayName); case myClientDataSet. FieldDefs.Items[i].DataType of ftString: myClientDataSet.Fields[i]. AsString := Self. DefaultDateFormat2(fDataSet. Fields[i].AsString); ftDate: myClientDataSet.Fields[i]. AsString := Self. DefaultDateFormat2(fDataSet. Fields[i].AsString); ftFloat: myClientDataSet.Fields[i]. AsFloat := Biblioteca. ArredondaComDecimais( fDataSet. Fields[i].AsFloat, 2); else myClientDataSet. Fields[i].AsString := fDataSet.Fields[i].AsString; end;
end;
myClientDataSet.Post; fDataSet.Next; end; finally myClientDataSet. EnableControls; end; end; procedure TConexao. ObterDataSet(const myDataSet: TDataSet; var myStringList: TStringList); var fDataSet: TDataSet; i: integer; begin if not Assigned(myDataSet) then Exit; fDataSet := TClientDataSet(myDataSet); fDataSet.First; if not Assigned(myStringList) then myStringList := TStringList.Create; while not fDataSet.Eof do begin myStringList.Add(fDataSet. Fields[0].AsString); fDataSet.Next; end; end; function TConexao. RecordCount(Query: String): integer; begin if Self is TConexaoDBISAM then Result := TConexaoDBISAM(Self). RecordCount(Query) else if Self is TConexaoXML then Result := TConexaoXML(Self). RecordCount(Query) else if Self is TConexaoFirebird then Result := TConexaoFirebird(Self). RecordCount(Query); end; function TConexao.
2013
julho
15
RecordCount(const myDataSet: TDataSet): integer; begin Result := (TDataSet(myDataSet). RecordCount); end; function TConexao. RetornaDataSet(Query: String): TDataSet; begin if Self is TConexaoDBISAM then Result := TConexaoDBISAM(Self). RetornaDataSet(Query) else if Self is TConexaoXML then Result := TConexaoXML(Self). ExecutaSelect(Query) else if Self is TConexaoFirebird then Result := TConexaoFirebird(Self). RetornaDataSet(Query); end; function TConexao. CarregarFoto(const MyFile: string; const myDataSet: TDataSet; const MyFieldName: string = FOTO): Boolean; function GetTableNameFromXMLSyntax(const mySQLXML: string): string; begin if System. Pos(AnsiUpperCase(where), AnsiUpperCase(mySQLXML)) > 0 then Result := trim(Before(af ter(AnsiUpperCase(mySQLXML), FROM), WHERE)); end; var S: TFileStream; fClientDataSet: TClientDataSet; auxTableName: string; auxFilterFields: string; begin if Self is TConexaoXML then begin if (Self.FiltroXML = ) then Exit;
auxTableName := GetTableNameFromXMLSyntax(Self. FiltroXML); auxTableName := auxTableName + .xml; fClientDataSet := TConexaoXML(Self). CarregarBanco(auxTableName); auxFilterFields := Before(after(AnsiUpperCase(Self. FiltroXML),WHERE), ORDER); fClientDataSet.Filter := auxFilterFields; fClientDataSet.Filtered := True; try fClientDataSet.Close; fClientDataSet.Open; if not (fClientDataSet. state in dsEditModes) then fClientDataSet.Edit; TBlobField(fClientDataSet. FieldByName(MyFieldName)). LoadFromFile(MyFile); fClientDataSet.Post; fClientDataSet. SaveToFile(TConexaoXML(Self). CaminhoXMLAtual, dfXML); except on E: Exception do begin Raise EInvalidDataBase. Create(EErroGeralBancoDeDados + #13#10 + E.Message); Result := False; end; end; end else if Self is TConexaoDBISAM then begin S := TFileStream. Create(MyFile ,fmOpenRead); with (myDataSet) do begin try try Edit; TBlobField(Fie
16
julho
2013
ldByName(MyFieldName)). LoadFromStream(S); Post; except on E: Exception do begin Raise EInvalidDataBase. Create(EErroGeralBancoDeDados + #13#10 + E.Message); Result := False; end; end; finally S.Free; end; end; end else if Self is TConexaoFirebird then begin fClientDataSet := dmFirebird.ClUsuario; try fClientDataSet.Close; fClientDataSet.Open; fClientDataSet.Refresh; if not (fClientDataSet. state in dsEditModes) then fClientDataSet.Edit; TBlobField(fClientDataSet. FieldByName(MyFieldName)). LoadFromFile(MyFile); fClientDataSet.Post; fClientDataSet. ApplyUpdates(0); except on E: Exception do begin Raise EInvalidDataBase. Create(EErroGeralBancoDeDados + #13#10 + E.Message); Result := False; end; end; end; end; function TConexao. GetConexao(const typeConexao:
tBDConexao): TConexao; begin if Assigned(Result) then closeConexao; case typeConexao of bdConexaoDBISAM: Result := TConexaoDBISAM.create; bdConexaoXML: Result := TConexaoXML.create; bdConexaoFirebird: Result := TConexaoFirebird.create; end; end;
Ns s precisamos tambm criar uma classe negocial no nosso caso a classe de usurios TUsuario que far a ponte entre a camada de apresentao com ela, provendo por meio do encapsulamento funcionalidades bsicas negociais disponveis para os mdulos de apresentao requeridos no interessante modularizar? Alteraes em apenas um lugar e todas as chamadas automaticamente atualizadas abstrao gera produtividade se bem empregada, como demonstra esta nossa construo. Abrir um conjunto de dados (select) agora ficou mais simples de escrever - somente uma chamada de mtodo (no caso, AbreTabelaUsuarios) necessria. Evoluindo o processo, temos inmeras vantagens: Implementao da Orientao a Objetos: como citado acima, a facilidade em reutilizao de cdigo em mdulos, outros sistemas, etc; Abstrao realizada pelas classes de conexo: no preciso (e nem deve) executar quaisquer comandos SQL ou acessar quaisquer base de dados diretamente na camada de apresentao; Encapsulamento de DataSets: essa nossa infraestrutura padronizou a nomenclatura bsica de execuo de SQLs, onde cada sentena uma constante passada como parmetro em um mtodo de obter dataset do objeto TConexao. Logo abaixo segue um exemplo destacado deste item:
Cdigo 05
function TUsuario. AbreTabelaUsuarios: TDataSet; begin Result := Conexao.RetornaData Set(sqlSelectAllFieldsOrderByNo me); end; Abaixo mostrado o mtodo SetDataBase, onde solicitada a troca de um banco. Note que o nome dos bancos fazem parte
2013
julho
17
de um tipo chamado tBDConexao, como citado acima, que referenciado como um parmetro constante: type tBDConexao = (bdConexaoXML, bdConexaoDBISAM, bdConexaoFirebird); procedure TForm1. cbSelecionaBDChange(Sender: TObject); begin case cbSelecionaBD.ItemIndex of 0: Usuario. SetDataBase(bdConexaoXML); 1: Usuario. SetDataBase(bdConexaoDBISAM); 2: Usuario. SetDataBase(bdConexaoFirebird); end; Usuario. CarregaUsuarios(ClUsuario); mskCarregaNomes.Text := ClUsuarioNome.AsString; mskCarregaNomesExit(Self); end; Nossa classe TConexao tambm possui mtodos de formatao especficos nossos prprios FormatDate, FormatFloat, dentre outros. Isso porque o Firebird aceita o formato yyyy-mm-dd enquanto que o XML, por exemplo, aceita somente o formato dd/mm/yyyy. J o FormatInteger formata o XML para o formato (com aspas simples) meu nmero enquanto que o Firebird aceita tanto o nmero puro (sem aspas) quanto com aspas simples. J o banco DBISAM aceita o formato numrico somente sem aspas. Portanto, a classe far o intercmbio de formatos distintos de acordo com a instncia apropriada. Uma coisa interessante o mtodo GetNextId: ele tem a finalidade de recuperar o prximo valor de um cdigo, por exemplo, para inseri-lo como uma chave-primria, ou apenas um valor normal, etc; so vrias as possibilidades de utilizao. Ele faz o select de um Max(coluna)+1, para retornar sempre o prximo item sequencial de um registro. Um detalhe especial como o processo feito para o nosso banco XML ele faz um Max em um campo agregado de um TClientDataSet em criado em tempo de execuo!
Cdigo 06
var fId: string; begin fId := TCustomSQLDataSet(Self.Retorna DataSet(Format(sqlMaxIndexFrom FieldNameFormat1, [fFieldName, fTable]))).Fields[0].AsString; if (fId = ) then fId := 1; Result := fId; end;
Finalmente, o mtodo CarregaUsuarios alimenta um objeto TClientDataSet de retorno, onde como j mencionado anteriormente armazenar dados apenas read-only: a aplicao jamais sensibilizar-los diretamente na base de dados. Todo este acesso somente a classe TConexao realizar e de forma abstrata. E isso um dos pontos mais interessantes deste projeto: imagina trocar um banco de dados com sua aplicao rodando, ou envi-la ao cliente em uma demonstrao do produto com algumas funcionalidades disponveis e na verso paga alterar o banco de dados para uma nova base de dados mais robusta e profissional; esta funcionalidade tornar sem dvida sua aplicao isenta de implementaes amarradas de dentro da camada de apresentao (mtodo tradicional de programao), trazendo mais produtividade em termos de manuteno e desenvolvimento, e consequentemente mais agilidade e praticidade durante todo o ciclo de vida da aplicao. Com isso, finaliza-se a primeira parte deste artigo. Na prxima revista falaremos sobre a implementao de um parser SQL para XML, utilizao do componente de minha autoria para visualizao e validao de dados, interagindo por debaixo dos panos o TMaskeditHV (explicado em edies anteriores), explicao sobre importantes mtodos da nossa classe e finalmente o desenvolvimento de nosso programa de exemplo utilizando esta nossa classe, em uma simulao real de sua implementao, obtendo e alternando bases de dados distintas em tempo de execuo. At a prxima, e boa leitura!
Sobre o autor
Hamden Vogel
Analista de Sistemas ps-graduado em Engenharia de Software pela UPIS e Programador Delphi com larga experincia desde 2000, tem desenvolvido e vendido softwares em Delphi para a frica e Estados Unidos, alm do mercado nacional. Colaborou com dicas e componentes para sites especializados em Delphi. Tambm desenvolve em outras linguagens como C/C++, ASP, PHP e .NET.
18
suporte@theclub.com.br
2013
Android
Trabalhando com o TouchScreen
m dos recursos mais poderosos e fascinantes no desenvolvimento utilizando o sistema android a possibilidade de poder interceptar eventos na tela com o toque do dedo, o TouchScreen. Temos classes especficas para este trabalho, a minha idia neste ms descrever as principais funcionalidades destas classes junto com seus mtodos criando exemplos didticos e de grande utilidade no dia-a-dia.
para serem implementados, sendo: onKeyDown (int, KeyEvent) - Chamado quando apertamos alguma tecla. onKeyUp (int, KeyEvent) - Chamado quando soltamos alguma tecla. onTrackballEvent (MotionEvent) - Chamado quando ocorre um evento de movimento. onTouchEvent (MotionEvent) - Chamado quando ocorre um evento de movimento da tela com o toque do dedo. onFocusChanged (boolean, int, Rect) - Chamado quando recebemos ou perdemos o foco. Demonstrei os mtodos acima a fim de apresentar os manipuladores existentes. Daremos importncia ao evento OnTouchEvent.
2013
julho
19
Como foi discutido anteriormente, devemos utilizar a classe View para implementarmos o mtodo OnTouchEvent().
Classe CriarImagem.java
Antes de iniciarmos a codificao desta classe ser necessrio adicionar uma imagem qualquer em nosso aplicativo. Basta copiar e colar no diretrio res/drawable-hdpi. Ver Imagem 03.
Observao Importante:
Esta imagem dever ser do tipo .png ou jpg possuindo o nome escrito especificamente em caixa baixa para assim evitar problemas de compilao. Logo em seguida importaremos as bibliotecas que sero utilizadas ao decorrer do desenvolvimento.
Cdigo 01
package pct.Android_ OnTouchEvent; import android.content.Context; import android.graphics.Canvas; import android.graphics. drawable.Drawable; import android.util. AttributeSet; import android.view.MotionEvent;
20
julho
2013
import android.view.View; public class CriarImagem extends View { private Drawable imagem; private int x, y, largura, altura; private boolean Clicou; public int movimento = 12; A classe principal CriarImagem herdar da classe View. Utilizaremos algumas variveis privadas, sendo uma do tipo Drawable responsvel por trabalhar com a imagem, outras do tipo int onde definimos a largura, altura, as coordenadas X, Y e uma booleana indicando se clicamos ou no na imagem.
Cdigo 02
Para desenhar a imagem foi necessrio reescrever o mtodo OnDraw() tendo como parmetro a classe Canvas. Passamos as coordenadas X e Y e a largura e altura utilizando o mtodo setBounds() e redesenhamos com o draw() usando a classe Canvas. Este mtodo disparado sempre quando necessitamos redesenhar a imagem.
Cdigo 04
public CriarImagem(Context context, AttributeSet attrs) { super(context, attrs); imagem = context. getResources().getDrawable(R. drawable.theclub); largura = imagem. getIntrinsicWidth(); altura = imagem. getIntrinsicHeight(); x = 150; y = 300; setFocusable(true); } No mtodo Construtor passamos dois parmetros: o Context o Contexto da aplicao e o AttributeSet que significa uma coleo de atributos que podem ser utilizados dentro deste mtodo. O mtodo context.getResources(). getDrawable() ir recuperar a imagem, os mtodos getIntrinsicWidth() e getIntrinsicHeight() iro retornar a largura e altura respectivamente, x e y sero as coordenadas para posicionamento da imagem em relao a tela do dispositivo. J o mtodo setFocusable() definir se a view ir ou no receber o foco enquanto estiver em modo TouchScreen. Deixaremos como true
Cdigo 03
public boolean onTouchEvent(MotionEvent motionEvent) { this.x = (int)motionEvent. getX(); this.y = (int) motionEvent. getY(); switch(motionEvent. getAction()) { case MotionEvent.ACTION_ DOWN: { Clicou = imagem. copyBounds().contains(x,y); break; } case MotionEvent.ACTION_ MOVE: if (Clicou) { this.x = x (largura/2); this.y = y (altura/2); break; } case MotionEvent.ACTION_ UP : { Clicou = false; break; } } invalidate(); return true; } Este o principal evento que iremos trabalhar. Ele tem como parmetro de entrada a classe MotionEvent e retorna um valor booleano. No primeiro momento iremos atribuir s variveis globais X e Y as respectivas coordenadas com os mtodos getX() e getY(). Faremos um Case para comparar
2013
julho
21
as Constantes do mtodo GetAction(), o mesmo que recebe a ao que foi executada, fornecendo constantes para determinar a ao. Na constante ACTION_DOWN com o mtodo copyBounds() indicamos que clicamos na imagem informando suas coordenadas. A constante ACTION_MOVE, faz o ato de mover em si, movimentamos a figura fazendo o clculo das coordenadas menos o tamanho dividido por dois, dando uma impresso de movimento. Por final retiramos o foco com a constante ACTION_UP. Resumindo, este mtodo ir movimentar a Imagem conforme o toque do dedo.
por exemplo: a cor cinza que preencher o fundo onde movimentaremos a imagem. Ver cdigo abaixo:. <?xml version=1.0 encoding=utf-8?> <resources> <string name=hello>Trabalhando com o evento OnTouchEvent!</string> <string name=app_name>The Club - Android</string> <color name=cinza>#D0D0D0</color> </resources>
Configuraes no AndroidManifest.xml
Nas configuraes do arquivo AndroidManifest.xml no faremos praticamente nada de mirabolante, apenas setamos o uso da Activity Android_OnTouchEventActivity que ser comentado logo a seguir. Ver em seguida a listagem completa.
Cdigo 04
<?xml version=1.0 encoding=utf-8?> <manifest xmlns:android=http:// schemas.android.com/apk/res/ android package=pct.Android_ OnTouchEvent android:versionCode=1 android:versionName=1.0> <uses-sdk android:minSdkVersion=8 /> <application android:icon=@ drawable/icon android:label=@ string/app_name> <activity android:name=.Android_ OnTouchEventActivity android:label=@string/app_ name> <intent-filter> <action android:name=android.intent. action.MAIN /> <category android:name=android.intent. category.LAUNCHER /> </intent-filter> </activity> </application> </manifest> Configuraes no Strings.xml Este arquivo ir definir algumas constantes que sero abordadas ao decorrer do projeto, como
Criando o Lay-Out
O aplicativo possuir um LinearLayout onde conter um TextView e um componente chamado desenho que faz referncia classe CriarImagem. Ver Imagem 04.
22
2013
O XML correspondente:
Cdigo 05
Cdigo 06
<?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 > <TextView android:layout_width=fill_ parent android:layout_height=wrap_ content android:text=@string/ hello /> <pct.Android_OnTouchEvent. CriarImagem android:id=@+id/desenho android:layout_width=fill_ parent android:layout_height=fill_ parent android:background=@ color/cinza /> </LinearLayout>
package pct.Android_ OnTouchEvent; import android.app.Activity; import android.os.Bundle; public class Android_ OnTouchEventActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super. onCreate(savedInstanceState); setContentView(R. layout.criarimagem); } } O SetContentView() ser o mtodo que ir chamar a tela de nosso aplicativo. Ver Imagem 06.
Exemplo em Run-Time
Percebam que interessante, conseguimos chamar diretamente uma classe (no caso uma View) de dentro do XML, fantstico!
Codificando o exemplo 1
Seguindo a lgica, a atividade Android_OnTouchEventActivity que codificaremos a seguir, possuir uma chamada para o lay-out criarimagem. xml que dentro do mesmo teremos a classe CriarImagem.java, na qual est localizada toda a codificao de nosso exemplo.
2013
julho
23
Path entre outras. Os passos so idnticos ao do exemplo anterior, por isto detalharei um pouco menos para ficar menos cansativo abordando apenas os conceitos inditos. Chega de conversa e vamos ao trabalho!
Classe PintarTela.java
Utilizaremos algumas bibliotecas adicionais para desenvolver este exemplo, veja abaixo:
Cdigo 07
paint.setStrokeWidth(6); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style. STROKE); paint.setStrokeJoin(Paint. Join.ROUND); } Temos o mtodo setAntiAlias() que serve para suavizar as bordas de nosso toque, o setStrokeWidh() o tamanho da linha, o setColor() para definir a cor, o setStyle() o estilo e o setStrokeJoin() um tratamento especfico para quando as linhas se juntarem.
Cdigo 10
package pct.Android_ OnTouchEvent; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util. AttributeSet; import android.view.MotionEvent; import android.view.View; Temos a classe android.graphics.Paint sendo especfica para pintura, estilo, cor. Ela tambm oferece base para desenhar geometrias, texto e bitmaps. J a classe android.graphics.Path permite realizar contornos e formas geomtricas como: segmentos de linhas retas, curvas quadrticas e cbicas.
Cdigo 08
@Override protected void onDraw(Canvas canvas) { canvas.drawPath(path, paint); } Mtodo que ir desenhar usando as configuraes definidas anteriormente na classe Paint.
Cdigo 11
public class PintarTela extends View { private Paint paint = new Paint(); private Path path = new Path();
@Override public boolean onTouchEvent(MotionEvent motionEvent) { float eventX = motionEvent.getX(); float eventY = motionEvent.getY(); switch (motionEvent. getAction()) { case MotionEvent. ACTION_DOWN: path. moveTo(eventX, eventY); return true; case MotionEvent. ACTION_MOVE: path. lineTo(eventX, eventY); break; default: return false; }
Esta classe tambm herdar da classe View e utilizar dois objetos, do tipo Paint e Path.
Cdigo 09
24
2013
O XML correspondente:
Cdigo 13
Usaremos apenas as constantes ACTON_DOWN para dar incio do movimento de acordo com as coordenadas definidas fazendo o uso do mtodo MoveTo() e a ACTION_MOVEpara adicionar uma linha a partir do ltimo ponto especificado pelas coordenadas (x, y).
<?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 > <TextView android:layout_width=fill_ parent android:layout_height=wrap_ content android:text=@string/ hello /> <pct.Android_OnTouchEvent. PintarTela android:id=@+id/desenho android:layout_width=fill_ parent android:layout_height=fill_ parent /> </LinearLayout>
Configuraes no AndroidManifest.xml
Adicionaremos algumas configuraes bsicas neste arquivo j comentado mais acima, veja o trecho:
Cdigo 12
... <activity android:name=. Android_OnTouchEventActivity_2 android:label=@string/app_ name> <intent-filter> <action android:name=android.intent. action.MAIN /> <category android:name=android.intent. category.LAUNCHER /> </intent-filter> </activity> ...
Codificando o Exemplo 2
Seguindo os passos que j foram descritos acima foi necessrio criar uma classe estendendo de uma Activity para invocarmos o XML contendo a classe PintarTela. O mtodo SetContentView() ir chamar a tela de nosso aplicativo. Ver Imagem 08. Abaixo cdigo completo.
Cdigo 14
Criando o Lay-Out
Teremos um LinearLayout onde conter um TextView e um componente chamado desenho que faz referncia classe Pintartela. Ver Imagem 07.
package pct.Android_ OnTouchEvent; import android.app.Activity; import android.os.Bundle; public class Android_ OnTouchEventActivity_2 extends Activity { @Override public void onCreate(Bundle savedInstanceState)
Figura 07: Lay-Out do exemplo 2.
2013
julho
25
Referncias
http://developer.android.com/reference/android/view/MotionEvent.html http://developer.android.com/reference/android/view/View.html
Concluses
Uma das formas de interceptar os eventos de interao do usurio com o aplicativo capturar estes eventos dentro de uma regio chamada View. a partir desta classe que discorremos o artigo deste ms. Trabalhamos com o evento OnTouchEvent(), que o evento que capta o toque do dedo na tela do dispositivo e a classe MotionEvent, classe base para suporte para esta tarefa junto com mtodos e constantes. No primeiro exemplo procurei demonstrar como movimentar uma imagem com o TouchScreen, j no segundo como pintar e escrever na tela do aplicativo. Esta uma das inmeras formas de usar os recursos TouchScreen na programao Android. Espero que tenham gostado! Deixo aqui um abrao e nos vemos no ms que vem!
Exemplo em Run-Time
Sobre o autor
Thiago Cavalheiro Montebugnoli
adora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de Botucatu SP (FATEC), 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 colunista mensal da Revista The Club Megazine e consultor Tcnico do The Club. 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
Figura 08: Desenhando e Pintando em Run-Time.
26
julho
2013
Selecionando o componente TcalendarEdit, no Object Inspector, abriremos a aba Events clicando duas vezes no espao vazio ao lado de onchange. Escreveremos o cdigo da seguinte forma:
procedure TForm25. CalendarEdit1Change(Sender: TObject); begin ShowMessage(FormatDateTime(d ddddd, CalendarEdit1.Date)); end; Podemos tambm usar um componente de boto com estilos diferentes em um aplicativo iOS como mostra a figura 02.
2013
julho
27
Essa ferramenta conta com diversos recursos, porm, no entraremos em detalhes neste artigo. Agora veremos como usar o componente TWebBrowser em um aplicativo iOS. Utilizaremos os seguintes componentes: TToolBar TButton TEdit A aplicao vai ficar como a figura 05:
Usando componentes combobox para escolher itens de uma lista em um aplicativo iOS como mostra a figura 03.
Depois de adicion-lo, podemos observar o componente ComboBox no form, clicando com o boto direito do mouse no componente ComboBox e selecionando itens do editor, abri-r uma janela como mostra a figura 04.
28
julho
2013
Antes de implementar manipuladores de eventos, primeiramente implantaremos um mtodo comum para abrir uma pgina web com base na propriedade Text do Tedit.
Cdigo 02
procedure OpenURL; next to { Private declarations } type Tform34 = class(TForm) ToolBar1: TToolBar; Button1: TButton; Edit1: TEdit; WebBrowser1: TwebBrowser; private Procedure OpenURL; Public end; Aperte CTRL + SHIFT + C para criar o procedimento.
Cdigo 03
Suporte a cliente multicamadas para DataSnap, web services e bancos de dados corporativos
O Delphi XE4 inclui conectividade integrada a banco de dados de classe corporativa ou ISV, computao nas nuvens e middleware. Voc conta com suporte integrado a SQL Server, Oracle, Sybase, DB2, InterBase, SQL Anywhere, SQLite, MySQL e muitos outros bancos de dados embutidos e de servidor, assim como servios nas nuvens, incluindo Windows Azure e Amazon.
Acesse mais bancos de dados em mais dispositivos e com maior facilidade com a FireDAC
A FireDAC d a voc acesso direto, nativo e de alta velocidade do Delphi a InterBase, SQLite, MySQL, SQL Server, Oracle, PostgreSQL, DB2, SQL Anywhere, Advantage DB, Firebird, Access, Informix, DataSnap e muitos outros bancos de dados mobile e corporativos, locais ou embutidos. Migre com facilidade do BDE e de outras tecnologias.
A linha WebBrowser1.Navigate(Edit1.text); iremos programar conforme o nome componente. No evento OnChange do edit digite OpenURL; E no evento KeyDown do edit digite o seguinte cdigo.
Cdigo 04
Procedure Tform34. Edit1KeyDown(Sender; bar Key: Word; var KeyChar: char; Shift: TshiftState); Begin If (key = vkReturn) then Begin OpenURL; Button1.SetFocus; end; end; Pronto agora s testar e usar a criatividade para melhorar a interface da aplicao.
Novo Compilador
Para oferecer suporte aos dispositivos mveis foram criados dois novos compiladores, um para o simulador do iOS e outro para o dispositivo fsico (ARM), j que as arquiteturas so distintas.Desta forma agora temos: Win32 compiler (DCC32) Win64 compiler (DCC64) Mac compiler (DCCOSX) iOS Simulator compiler (DCCIOS32) iOS ARM compiler (DCCIOSARM)
A novidade est nos dois ltimos, os quais seguem um desenho totalmente novo, baseados em um padro chamado LLVM (http://llvm.org). Podemos
2013
julho
29
entender o LLVM como um conjunto de mdulos e ferramentas reutilizveis para compiladores, utilizados amplamente por diversos compiladores nativos, entre eles o prprio Xcode, nativo da Apple.
faa uso de construes como TStringBuilder e TStringHelper para a manipulao de strings. Um trecho de cdigo utilizando estas classes para ilustrar:
Outras mudanas
1. Ponteiros no so suportados no mundo mobile 2. No h suporte para Inline assemby 3. Evite chamadas a APIs diretamente, esteja pronto para as novas plataformas que viro. 4. Prefira utilizar as units cross-plataform, especialmente ao manipular arquivos (unit IOUtils) Informaes e recursos para pesquisa 5. Pginas principais dos produtos: RAD Studio, Delphi, C++ Builder, HTML5 Builder 6. Documentao on line: http://docwiki.embarcadero.com/RADStudio/XE4/en 7. Tutorial Delphi para iOS: Delphi iOS Application Development 8. Link para download do trial: https://downloads.embarcadero.com/ free/rad-studio 9. Trial via Instant Trial (AppWave): http://windowsapps.com/rad-studio-trial.html?trial=1 10. Tudo o que h de novo no Delphi e C++ Builder XE4 11. O que h de novo especificamente no C++ Builder 64 bit 12. Lista de correes do Delphi e C++ Builder XE4: http://edn.embarcadero.com/article/43068 13. White Paper do Marco Cantu sobre todas as mudanas na linguagem: http://www.embarcadero.com/resources/white-papers/application-development
Class procedure TMySimpleClass. CreateOnly; Var MyObj: TMySimpleClass; Begin MyObj := TMySimpleClass.Create; MyObj.DoSomething; End; No exemplo acima, o objeto MyObj ser removido da memria assim que sair do escopo. Importante ressaltar que a sintaxe tradicional (try/finally fazendo o Free manual do objeto) continua suportada, portanto as migraes de cdigo esto garantidas. Tambm est disponvel o pattern Dispose e suporte a [Weak] References. Voc pode encontrar mais sobre isso aqui: http://edn.embarcadero.com/ article/43073.
Concluso
Espero que tenham gostado do artigo, resumi as principais alteraes que foram feita no Delphi XE4 que considero importante. At a prxima.
Tipo String
Todos os tipos string existentes (AnsiString, UTF8String, RawByteString, WideString, AnsiChar, PAnsiChar, PWideChar, OpenString, ShortString) agora esto simplificados em um nico: String. Alm disso, as strings agora so 0-based ao invs de 1-based. Isso significa que alguns cdigos podem precisar de reviso, mas as funes de manipulao de strings j esto preparadas para esta mudana. Outra importante mudana que as strings passaro a ser imutveis, devido ao gerenciamento de memria dos dispositivos mveis. Nesta verso do compilador tudo continua conforme anteriormente, voc receber apenas uma warning alertando que, futuramente, construes como a exibida abaixo no ser mais suportada: str1[3]:=w;
Sobre o autor
Jos Antnio P. M. de Paula
Consultor Tcnico no The Club. Cursa o ltimo perodo da FATEC (Botucatu) no curso de Informtica para Negcios.
zeca@datasmart.com.br
30
2013
2013
julho
05
julho
2013