EDITORIAL Editorial Olá amigos, THE CLUB Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150 Informações: (14) 3732-3689 Suporte: (14) 3733-1588 - Fax: (14) 3732-0987 Internet http://www.theclub.com.br Cadastro: [email protected] Suporte: [email protected] Informações: [email protected] Dúvidas Correspondência ou fax com dúvidas devem ser enviados ao - THE CLUB, indicando "Suporte". Opinião Se você quer dar a sua opinião sobre o clube em geral, mande a sua correspondência para a seção "Tire sua dúvida". Reprodução A utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais. Impressão e acabamento: Aqui estamos com mais uma edição da The Club Megazine, trazendo o melhor conteúdo sobre programação para facilitar o seu dia-a-dia. Começamos com um artigo apresentando a ferramenta MKR que é um modelador de relatórios para Firebird/Interbase totalmente gratuita desenvolvida por Agnaldo Silva, através da qual você poderá criar relatórios ‘por fora’ de sua aplicação, facilitando a manutenção e atendendo a diferente demanda dos usuários. Depois de um longo tempo, nosso amigo Mário da Bohm Soluções retoma sua coluna em nossa revista e, em seu artigo de reestréia compartilha as inovações que vêm adotando em sua empresa, não deixe de conferir. Prosseguindo com sua série de artigos metodológicos, Marcelo Nogueira demonstra como obter maior qualidade no software a partir de técnicas padronizadas de teste. Entrando no universo do Delphi 2005, nosso consultor Claudinei Rodrigues aborda a utilização de namespaces dentro deste ambiente. E ainda falando em .NET, nosso consultor Alessandro Ferreira apresenta um componente gratuito para criar Menus em páginas ASP.NET, confira! Ainda muito utilizado, o BDE é sempre um incômodo no momento de distribuir a aplicação. Pensando nisso, nosso consultor Alessandro Ferreira demonstra como distribuir o BDE através do InnoSetup, um gerador de instalações que vem se popularizando dia-a-dia meio a comunidade Delphi. E para finalizar, a consagrada sessão Perguntas & Respostas, onde compartilhamos com os leitores algumas das solicitações feitas aos nossos consultores neste mês. Abraço e sucesso à todos, GRAFILAR Tel.: (14) 3841-2587 - Fax: (14) 3841-3346 Rua Cel. Amando Simôes, 779 Cep 18.650-000 - São Manuel - SP Tiragem: 5.000 exemplares Copyright The Club Megazine 2005 Diretor - Presidente Celso Jefferson M. Paganelli Diretor Técnico Mauro Sant’Anna Colaboradores Marcelo Nogueira, Mário Bohm, Aguinaldo P. Silva Delphi é marca registrada da Borland International, as demais marcas citadas são registradas pelos seus respectivos proprietários. Editorial .................................................................................. 03 Modelador de Relatórios para FireBird/Interbase ................... 04 Integrando o melhor “Front-End” com o melhor banco de dados do mundo .................................................................... 08 Buscando qualidade de software com a aplicação de técnicas de teste .................................................................... 10 Usando namespaces no Delphi 2005 .................................... 14 Adicionando menus em aplicações ASP.NET ........................ 16 Instalando o BDE via InnoSetup ............................................. 23 Perguntas & Respostas ......................................................... 27 3 Firebird/Interbase Modelador de Relatórios para FireBird/Interbase por: Agnaldo P. da Silva - [email protected] O software MKR é um modelador de relatórios de alto nível desenvolvido para acessar base de dados Firebird/Interbase. Um dos grandes problemas encontrados hoje pelos desenvolvedores de softwares é a adequação de relatórios às necessidades específicas de seus clientes, trazendo grande transtorno aos mesmos e muitas vezes obrigando-os a compilar e controlar versões individuais de relatórios para cada cliente. Com o MKR os próprios clientes poderão modelar os relatórios e até mesmo alterar o conteúdo filtrado pelo mesmo de forma fácil e visual. Estarei exemplificando a seguir como utilizar o MKR em um relatório mestre-detalhe, assim como acessar este relatório através de sua aplicação. O MKR é um software GRATUÍTO e poderá ser utilizado e distribuído gratuitamente com suas aplicações. Conectado ao banco de dados exemplo que vem com o MKR, o usuário irá clicar sobre o menu <Arquivos><Novo>. Neste instante será acionado uma janela denominada “Gerenciador de Dados”, onde devemos escrever a SQL mestre do relatório. Dentro do MKR a SQL mestre é a responsável por disponibilizar as informações mestre ou principais do relatório, o usuário poderá ainda adicionar quantas SQLs secundárias necessitar, estas por sua vez, serão responsáveis pelas informações de detalhes para a SQL principal. Criando um Relatório Mestre-Detalhe com o MKR Para utilizar o MKR para modelar relatórios dinâmicos devemos primeiramente configurar a conexão ao banco de dados do Interbase/Firebird desejado, para isso clique no menu <Configurações><Conexão> e adicione as informações solicitadas na figura a seguir. Clique sobre a guia <SQLs Secundária> e adicione uma nova fonte de dados denominada “ENDERECOS”. 4 Firebird/Interbase Depois devemos ligar a fonte de dados secundária “ENDERECOS” à tabela mestre. Observe que o campo utilizado para link deve ter o mesmo nome da tabela mestre (CLI_CODIGO). OBS: O relacionamento mestredetalhe também pode ser feito entre fontes secundárias (ver figura ao lado) Criado a SQL mestre e sua detalhe o usuário poderá modelar seu relatório facilmente acrescentando objetos da barra de ferramentas do MKR, o usuário dispõe de um ambiente amigável com recursos como: copiar e colar, excluir, alinhamentos, alterações de propriedades, etc. Começaremos acrescentando duas bandas de relatório, onde, uma será o cabeçalho de páginas e a outra uma detalhe contendo informações adicionais sobre a SQL mestre. 5 Firebird/Interbase 6 Firebird/Interbase Com um duplo clique sobre a banda, o usuário poderá acionar a janela de propriedades e alterar o seu tipo para “Banda cabeçalho de página” para a primeira banda e “Banda Detalhe” para a segunda respectivamente. Vamos agora acrescentar objetos conscientes de dados para apresentar as informações do banco de dados. Acrescente três “Textos de Tabelas”. (ver figura acima ao lado esquerdo) Ao clicar duas vezes sobre o objeto “Texto de Tabela” será acionada a janela de configurações onde podemos alterar as propriedades visuais e de conexão para este objeto. Selecionaremos como fonte de dados a tabela “SQL Mestre” e como campo de tabela “CLI_CODIGO” que nos mostrará o código cadastro do cliente em nossa tabela no banco de dados. Agora é só implementarmos uma função no nosso aplicativo que acione o programa MKR.exe passando parâmetros de conexão e o path para o relatório desejado: Repetimos este processo para os campos “CLI_NOME” e “CLI_DATACAD”. ShellExecute(Application.Handle, ‘open’, ‘C:\MKR\MKR.exe’,’”C:\MKR\Exemplos\MKR.GDB” “SYSDBA” “masterkey” “ “ “none” “C:\MKR\Exemplos\MKR2005.qrp”’, ‘’, SW_NORMAL); Para mostrar os dados de detalhamento da SQL mestre, iremos utilizar uma banda Sub-Detalhe e ligaremos a mesma a fonte de dados “ENDERECOS” em sua janela de propriedades. Dê um duplo clique sobre a banda sub-detalhe e altere esta propriedade agora. (ver figura abaixo ao lado) Adicionaremos um objeto “Texto de Tabela” ligando-o à fonte de dados “ENDERECOS” e o campo de tabela “END_ENDERECO”, agora poderemos visualizar uma prévia de como está nosso relatório clicando no menu <Visualização><Prévia> ou teclando-se <F9>. (figura a direita) Para salvar seu relatório clique no menu <Arquivos><Salvar Como>, selecione um diretório e salve o relatório como MKR2005.qrp. Para mais informações sobre os parâmetros consulte o manual que vem com o MKR. Para baixar o programa com as últimas versões acesse: http://www.tqsplanear.com.br/download/MKR.zip Sobre o autor Agnaldo P. da Silva [email protected] Engenheiro, Analista de Banco de Dados 7 Oracle Integrando o melhor “Front-End” com o melhor banco de dados do mundo Mário Camilo Bohm - [email protected] Em dezembro de 1997, há 5 anos atrás, escrevemos uma das primeiras matérias para a revista, onde fazíamos a apologia do uso de Oracle com Delphi. Na época, o uso de Oracle ainda era muito pouco difundido entre as pequenas e médias corporações e o Delphi estava com sua versão 3.0 recém-lançada. Neste retorno, queremos fazer uma “revisão” dessa matéria e trazer suas conclusões para 2005. Um exercício interessante para orientarmos o início de novos temas que iremos levantar! Relembremos então, um trecho dessa matéria de 1.997: Há apenas 2 anos do final do século, é impossível para um desenvolvedor profissional pensar em construir aplicações complexas sem o suporte de um banco de dados robusto. Todos os problemas que enfrentamos diariamente utilizando arquivos de dados como DBASE ou PARADOX, desaparecem quando utilizamos bancos de dados, como ORACLE, SQL SERVER, SYBASE e DB2. Para as aplicações de gestão que serão exigidas de agora em diante, quando todas as empresas estarão envolvidas em um ambiente empresarial de grande concorrência e precisarão atingir elevados níveis de eficácia, eficiência e produtividade para sobreviverem em um mercado definitivamente globalizado, a utilização de um banco de dados é requisito fundamental (notem que não citamos INTERBASE nem ACCESS como opções, porque não os encaramos como produtos destinados à utilização profissional... Evite utilizá-los!). Alicerces da tecnologia cliente-servidor, que passa para o 8 banco de dados todas as tarefas de manipulação de informações antes executadas nas estações, diminuindo o tráfego da rede e aumentando a produtividade da empresa inteira, os bancos de dados passarão a ser a partir de agora um item indispensável em qualquer computador da face da terra, seja instalado localmente, seja conectado via LAN (rede local), via WAN (rede remota via modem) ou via INTERNET... E porque não usar o melhor, mais robusto, mais rápido e mais vendido banco de dados do mundo??? A ORACLE tem a melhor linha de soluções para utilização nas mais diversas situações... O que deveria mudar, nesta pequena parte da matéria, em junho de 2.005? Nada. Absolutamente nada... Realmente, como já falávamos há 5 anos atrás, as empresas que hoje utilizam aplicações baseadas em bancos de dados (e notem que nós restringimos o “conceito” de banco de dados a algumas poucas opções) estão efetivamente melhor posicionadas em eficiência e produtividade, além de estarem prontas para crescer à qualquer taxa. As empresas mais eficientes estão fundamentadas em bancos de dados e todos os bons sites da internet voltados para relacionamento ou comércio, sem exceção, se fundamentam em bancos de dados. Ao contrário, as empresas que ainda não tem essa condição estão começando a se dar conta da carência e iniciando uma nova “corrida de atualização tecnológica”: a grande maioria das vendas Oracle de ERPs nos últimos 2 anos foi gerada pela necessidade de migração para banco de dados relacionais. Muitas empresas, inclusive algumas de grande porte, que ainda não estão baseadas em bancos de dados relacionais, estão sentindo falta de poderem se integrar com facilidade à internet e de poderem operar com processos operacionais eficientes. E isso está fazendo transparecer: NESTE SÉCULO, O LUCRO DAS ORGANIZAÇÕES ESTARÁ RELACIONADO À ATUALIZAÇÃO TECNOLÓGICA! E dessa realidade se pode tirar outra premissa: não existe atualização tecnológica de fato que não esteja fundamentada em bancos de dados relacionais, para nenhuma empresa do mundo! E que importância tem Oracle neste contexto? De 1.997 para cá muitas tecnologias surgiram, muitas outras morreram... Oracle, no entanto, cresceu em “market share”, cresceu em recursos e teve seu preço por usuário reduzido de US$ 600,00 para US$ 149,00! Em outras palavras, é muito mais usado, ficou muito melhor e muito mais barato. Uma outra mudança significativa nestes 5 anos que se passaram (e não podemos esquecer que estamos num veículo “focado” em desenvolvedores de sistemas) é que os usuários hoje não querem mais aplicações escritas para Windows simplesmente. Querem aplicações escritas para a internet. Prontas para qualquer integração e para acesso fácil em qualquer máquina, de qualquer lugar do mundo... Pois bem. Há 5 anos atrás, em diversas matérias escritas mensalmente, defendíamos fervorosamente um conceito não muito difundido e que ainda hoje a grande maioria dos desenvolvedores “não compra”... Defendíamos que a forma mais inteligente de construir aplicações de negócios era escrever todas (e todas quer dizer todas mesmo, sem exceção!!!) as “regras de negócio” no banco de dados, utilizando o Delphi apenas como “front-end”, ou seja, apenas para construir “interface”. Em 2005 fica evidente porque nós abraçamos esse conceito e não abrimos mão (conceito esse, aliás, que faz nossa empresa crescer quase 60% ao ano em vendas pela satisfação de Clientes no uso de nossas soluções)! Em 2005 fica evidente ainda para todos os desenvolvedores que utilizam Delphi, onde nos incluímos, que a “era Delphi” já acabou! Como acabou a era Clipper... E isso nos trouxe um desafio que é “cíclico” em nosso mercado: escolher uma nova ferramenta de desenvolvimento, o que equivale a dizer “refazer tudo o que já está pronto e funcionando”! Quem, como nós, escreveu todas as “regras de negócio” diretamente no Oracle, não tem que reescrever nada disso. Precisa apenas refazer o “front-end”! Já quem escreveu “regras de negócio” em Delphi para utilizar qualquer coisa como banco de dados, não vai ter muita tranqüilidade nos próximos anos não. Clipper é inesquecível! Delphi nos levou para o mundo Windows... E que ferramenta nos levará para a Internet, com a mesma produtividade? É ainda hoje um desafio para qualquer desenvolvedor que ferramenta utilizar para construir aplicações fundamentadas em bancos de dados e para ambiente web, com a mesma produtividade que nos ofereceram Clipper e Delphi. Muitas opções se colocaram nos últimos anos, mas nenhuma ferramenta que fosse produtiva, simples e fácil de usar e com recursos a altura da nossa criatividade e do nível de exigência do mercado. Quem não se aventurou em escrever aplicações em ASP ou PHP? Pois bem! Nós já fizemos nossa opção: Microsoft Visual Studio .Net. Até com a ajuda do valoroso Mauro Sant’Anna, que corroborou nossa decisão e que treinou nossa equipe interna nos primeiros contatos com a ferramenta, a Bohm tomou a opção estratégica de utilizar Microsoft Visual Studio .Net para construir suas soluções já há mais de 1 ano. E 1 ano depois temos a declarar: já construímos muito mais e já fomos muito mais longe do que poderíamos imaginar e muito mais longe ainda que iríamos com qualquer outra opção disponível no mercado! Evidentemente que estamos reconstruindo apenas “frontend”, já que temos todas as “regras de negócio” escritas no Oracle, mas é fantástico o que se consegue fazer com esta ferramenta... Num mesmo ambiente podemos construir aplicações para Windows (Windows Forms), aplicações para web (Web Forms), aplicações para Windows CE e, melhor, utilizando diversas linguagens: podemos escolher o que usar como linguagem padrão. Nós escolhemos C# e não nos arrependemos em nenhum momento disso. 9 Oracle O leitor mais atento pode argumentar que em Delphi 8 ou 2005 temos quase a mesma realidade, e ainda pode-se “aproveitar” a experiência em Pascal. Sem dúvidas. Mas preferimos optar pelo Visual Studio porque é uma ferramenta nativa do ambiente .NET e oferece uma produtividade fora do comum. Além disso, como dependemos do fabricante das ferramentas que utilizamos, chegamos à conclusão óbvia de que a Microsoft merece mais crédito do que a Borland quanto à continuidade e evolução das ferramentas. Alguém dúvida disso? Portanto, estamos considerando que não há, pelo menos no momento, decisão mais acertada do que construir aplicações de negócios utilizando Visual Studio e acessando bancos de dados Oracle. O leitor mais atento ainda pode argumentar que “Microsoft já era” e que “o negócio agora é Linux”. Para esses quero deixar um desafio: vamos encontrar juntos 3 (apenas 3) empresas sérias, de porte e com representatividade no mercado, que estejam utilizando soluções de gestão escritas para ambiente Linux... Eu não conheço. E é com base nisso que voltaremos a escrever nossas matérias: vamos passar à vocês a experiência, as facilidades e as vantagens em utilizar Microsoft Visual Studio com Oracle. Você usa o que a Microsoft tem de melhor e o que a Oracle tem de melhor. Nada de aventuras, como usar banco de dados da Microsoft ou ferramentas de desenvolvimento da Oracle. É dor de cabeça à vista. Até lá. Sobre o autor Para esses ainda deixo como conclusão que na nossa opção, além de um servidor de aplicações rodando Windows Server 2003 (que é uma plataforma excepcional!) com IIS, podemos ter todas as estações e o servidor Oracle rodando Linux! 10 Mário Camilo Bohm Bohm Soluções Corporativas [email protected] - www.bohm.com.br Software Buscando qualidade de software com a aplicação de técnicas de teste por: Marcelo Nogueira Resumo: Teste de software é um elemento crítico da garantia de qualidade de software e representa a revisão final da especificação, projeto e geração do código. O desenvolvimento de software envolve uma série de atividades de produção em que as oportunidades para injetar a falibilidade humana são enormes. Com a aplicação de técnicas de teste, é possível obter qualidade no processo de desenvolvimento de software. Palavras-chave: Testes, Engenharia de Software. Introdução Apresenta-se neste artigo um conjunto de procedimentos e técnicas para a realização do fluxo de testes de software. Embora menos eficazes que as revisões e inspeções para a remoção de defeitos, os testes são indispensáveis para detectar os defeitos que ainda escapam das revisões e para se avaliar o grau de qualidade de um produto e de seus componentes. O teste exaustivo é geralmente impossível, mesmo para produtos relativamente simples. Para testar um programa cuja entrada seja um texto de dez caracteres, por exemplo, é necessário analisar 2610 . [6] Combinações. Enquanto muitos desses testes são redundantes, a utilização de força bruta pode deixar descoberto muitos casos com alta probabilidade de defeitos, como entradas com mais de 10 caracteres. Focaliza-se aqui o desenho de testes que tenham a mais alta probabilidade de descobrir defeitos com o mínimo de esforço. Relevância Atualmente com a visão global permitindo a participação nas exportações de software para outros países, cada vez mais a qualidade no processo de desenvolvimento e do produto de software ganha maior observação e adoção das melhores práticas e soluções tecnológicas que atendam os requisitos estabelecidos. É nesse âmbito que os testes de software participam em caráter crítico para o sucesso do desenvolvimento. Engenharia de Software Engenharia de Software é a metodologia de desenvolvimento e manutenção de sistemas modulares, com as seguintes características [8]: · Adequação aos requisitos funcionais do negócio do cliente e seus respectivos procedimentos pertinentes; · Efetivação de padrões de qualidade e produtividade em suas atividades e produtos; · Fundamentação na tecnologia da informação disponível, viável e oportuna; · Planejamento e gestão de atividades, recursos, custos e datas. Como conclusão, pode-se relatar que engenharia de software é um conjunto de práticas para desenvolvimento de soluções de software, ou seja, roteiro que pode utilizar diversas técnicas. Objetivos Da Engenharia De Software De um modo geral, considera-se que os objetivos primários da Engenharia de Software são o aprimoramento da qualidade dos produtos de software e o aumento da produtividade dos engenheiros de software, além do atendimento aos requisitos de eficácia e eficiência, ou seja, efetividade [5]. Com base nos objetivos da Engenharia de Software, fica evidente a necessidade da adoção de um modelo sistêmico para padronizar e gerenciar os processos de desenvolvimento de software. Crise do Software Para generalizar o termo, ocorre quando o software não satisfaz seus envolvidos, sejam clientes e/ou usuários, desenvolvedores ou empresa [8] [7]. Esses problemas não se referem apenas a programas que não funcionam.Na verdade, a chamada “Crise do Software” abrange todos os problemas relacionados a [8]: · Como sistemas computacionais são construídos; · Como sistemas computacionais são implantados, referindose aqui ao processo de substituir sistemas antigos, desativando sistemas correntemente em operação, ou ao processo de instalar um sistema inteiramente novo; · Como é provida a manutenção da quantidade crescente de software construído, associado a sistemas computacionais cada 11 Software vez mais complexos; · Como fazer face à crescente demanda para construção de software, visando satisfazer ao conjunto enormemente variado de necessidades, atualmente detectadas na sociedade moderna; · Como administrar as questões comportamentais, envolvendo os clientes e/ou usuários e a política, cultura e filosofia empresarial. Qualidade De Software Atingir um alto nível de qualidade de produto ou serviço é o objetivo da maioria das organizações. Atualmente não é mais aceitável entregar produtos com baixa qualidade e reparar os problemas e as deficiências depois que os produtos foram entregues ao cliente. [9] Abordagens importantes como as normas ISO 9000 e a ISO / IEC 12207, o modelo CMM (Capability Maturity Model) e o SPICE (Software Process Improvement and Capability dEtermination) sugerem que melhorando o processo de software, podemos melhorar a qualidade dos produtos. Prevê-se que na primeira década dos anos 2000, após ajustarem seus processos para a produção de software de qualidade dentro de prazos e orçamentos confiáveis, as organizações serão pressionadas por seus concorrentes a reduzir substancialmente os prazos para a entrega de produtos. Organizações que sejam capazes de integrar, harmonizar e acelerar seus processos de desenvolvimento e manutenção de software terão a primazia do mercado [4]. Requisitos Segundo Pádua, o fluxo de requisitos reúne as atividades que visam a obter o enunciado completo, claro e preciso dos requisitos de um produto de software. [6] Esses requisitos devem ser levantados pela equipe do projeto, em conjunto com representantes do cliente, usuários chaves e outros especialistas da área de aplicação [3]. Objetivos dos Testes O fluxo de testes é crítico para o desenvolvimento de software. Freqüentemente, o fluxo de testes insere tantos erros em um produto quanto à própria implementação. [6] Por outro lado, o custo para correção de um erro na fase de manutenção é de sessenta a cem vezes maior que o custo para corrigi-lo durante o desenvolvimento. Embora as revisões técnicas sejam mais eficazes na detecção e remoção de defeitos, os teste são importantes para complementar às revisões e aferir o nível de qualidade conseguido. A realização de testes é, quase sempre, limitada por restrições de cronograma e orçamento; eles determinam quantos testes será possível executar. É importante que os testes sejam bem planejados e desenhados, para conseguir-se o melhor 12 proveito possível dos recursos alocados para eles. Um objetivo central de toda a metodologia dos testes é maximizar a sua cobertura, ou seja, a quantidade potencial de defeitos que podem ser detectados por meio do teste. Deseja-se conseguir detectar a maior quantidade possível de defeitos que não foram apanhados pelas revisões, dentro de dados limites de custo e prazos. [6] Métodos de Testes Para serem eficazes, os testes devem ser cuidadosamente desenhados e planejados. Testes irreproduzíveis e improvisados são quase inúteis e devem ser evitados. Durante e após a realização dos testes, os resultados de cada teste devem ser minuciosamente inspecionados, comparando-se resultados previstos e obtidos, pois nem sempre é óbvio quando um teste detectou um defeito. [6] Os desenvolvedores não são as pessoas mais adequadas para testar seus próprios produtos. Assim como nas revisões, os autores têm maior dificuldade em enxergar problemas, comparados com pessoas que não participam do desenho e da implementação. O trabalho de testadores independentes é particularmente importante no caso dos testes de aceitação e de integração, que exercitam o produto como um todo. O planejamento e o desenho dos testes devem ser feitos por pessoas experientes, que conheçam adequadamente a metodologia de testes usada. Por outro lado, a realização dos testes baseados em planos e especificações de testes bem-definidos pode ser feita por pessoas menos experientes, ou pode até ser parcialmente automatizada. [6] Os testes são indicadores da qualidade do produto, mais do que meios de detecção e correção de erros. Quanto maior o número de defeitos detectados em um software, provavelmente maior também o número de defeitos não-detectados. A ocorrência de um número anormal de defeitos em uma bateria de testes indica uma provável necessidade de redesenho dos itens testados. Existem basicamente duas maneiras de se construírem testes: · Método da caixa branca: tem por objetivo determinar defeitos na estrutura interna do produto, através do desenho de testes que exercitem suficientemente os possíveis caminhos de execução. · Método da caixa preta: tem por objetivo determinar se os requisitos foram total ou parcialmente satisfeitos pelo produto. Os testes de caixa preta não verificam como ocorre o processamento, mas apenas os resultados produzidos. [6] Bateria de testes A lista a seguir enumera e descreve brevemente os tipos de Software bateria de testes, ou conjuntos de testes de software de determinada categoria: 1. Testes de aceitação têm por objetivo validar o produto, ou seja, verificar se ele atende aos requisitos especificados. No Praxis padrão, são executadas duas baterias de testes de aceitação: ao final da construção, na iteração de testes Alfa, eles são executados no ambiente do fornecedor, no início da transição, na iteração de testes Beta, eles são executados nos ambientes definitivos de operação. Os testes de aceitação podem ser divididos em testes funcionais e não-funcionais. [6} 2. Testes de integração têm por objetivo verificar as interfaces de uma arquitetura de produto. Dentro do praxis, esses testes têm por objetivo verificar se as unidades implementadas em cada iteração funcionam corretamente, em conjunto com as unidades já implementadas em iterações anteriores, realizando corretamente os casos de uso que se quer nessa iteração. No praxis padrão, existe tipicamente uma bateria de testes de integração para a iteração de desenho implementável e para cada liberação. [6] 3. Testes de unidade têm por objetivo verificar um elemento que possa ser logicamente tratado como uma unidade de implementação. Em produtos implementados com tecnologia orientada a objetos, uma unidade é tipicamente uma classe. Em alguns casos, pode ser conveniente tratar como unidade um grupo de classes correlatas. No praxis padrão, apenas unidades especialmente críticas são testadas por baterias formalizadas. Essas seriam unidades cuja falha pudesse acarretar conseqüências graves, como risco de vida ou perdas materiais vultosas. Normalmente, os teste de unidades são feitos pelos próprios desenvolvedores, como parte do fluxo de implementação. [6] No padrão de nomenclatura de software do IEEE, na UML, a bateria de testes para validação do produto como um todo é chamada de testes de sistema, reservando-se o termo testes de aceitação para os testes feitos pelo cliente como parte de um procedimento de aceitação do produto. Como no praxis o conteúdo desses dois grupos de testes é idêntico, preferiu-se chamá-los de testes de aceitação, sejam eles realizados no ambiente do fornecedor (no praxis padrão, na iteração de testes Alfa) ou do cliente (no praxis padrão, na iteração de testes Beta). [6] [1] [2] Uma categoria especial de baterias de teste é formada pelos testes de regressão, que executam novamente um subconjunto de testes previamente executados em uma das baterias acima descritas. Seu objetivo é assegurar que alterações em partes do produto não afetem as partes já testadas. As alterações realizadas, especialmente durante a manutenção, podem introduzir erros nas partes previamente testadas. Os teste de regressão, na prática, devem ser sempre automatizados; as demais baterias podem ser executadas de forma manual ou automatizada. [6] Figura 1: Estrutura de Testes Conclusão É importante que os desenvolvedores de software reconheçam que não é possível desenvolver sistemas com qualidade, cumprir prazos e custos e atender às expectativas dos usuários sem ter um processo de testes definido, compreendido e utilizado por toda a equipe. O nível de complexidade da sua implementação pode ser dimensionado de acordo com o porte do sistema, viabilizando para as pequenas organizações desenvolvedoras de software. Possibilita então ser um dos fatores críticos para o sucesso no desenvolvimento de software. Referências Bibliográficas [1] IEEE STD. 610 12-1990, IEEE Standard Glossary of Software Engineering Terminology, IEEE, Piscataway, NJ, 1997. [2] LEE, RICHARD C. e TEPFENHART, WILLIAM M., UML e C++ - Guia de desenvolvimento orientado a objeto, São Paulo, Ed. Makron , 2002. [3] LEITE, JULIO CESAR SAMPAIO DO PRADO, in WEBER, KIVAL CHAVES, et al. Qualidade e Produtividade em Software, São Paulo, Ed. Makron Books, 2001. [4] MACHADO, CRISTINA ÂNGELA FILIPAK in WEBER, KIVAL CHAVES, et al. Qualidade e Produtividade em Software, São Paulo, Ed. Makron Books, 2001. [5] MAFFEO, BRUNO, Engenharia de Software e Especificação de Sistemas, Rio de Janeiro, Ed. Campus, 1992. [6] FILHO, WILSON DE PÁDUA PAULA, Engenharia de Software, Rio de Janeiro, Ed. LTC, 2003. [7] PRESSMAN, ROGER S., Engenharia de Software, Rio de Janeiro, Ed. McGraw-Hill, 2002. [8] REZENDE, DENIS ALCIDES, Engenharia de Software e Sistemas de Informações, Rio de Janeiro, Ed. Brasport, 1999. [9] SOMMERVILLE, IAN, Engenharia de Software, São Paulo, Ed. Pearson Education, 2003. Sobre o autor Marcelo Nogueira é Mestre em Engenharia de Produção com ênfase em Gestão da Informação, bacharel em Análise de Sistemas, Professor Universitário, Instrutor e Desenvolvedor Delphi desde 1995, Membro fundador do DUG-BR. e-mail: [email protected] 13 Delphi Usando namespaces no Delphi 2005 por: Claudinei Rodrigues - [email protected] No Delphi uma unit é o local onde montamos as nossas rotinas, declaramos nossas variáveis, etc. O Common Language Runtime (CLR) da Microsoft introduziu uma outra camada de organização chamada de namespace. No .NET Framework o namespace é um novo conceito que vai além do conhecemos hoje como unit. No Delphi um namespace pode conter várias units. A inclusão do namespace dá ao Delphi a habilidade de acessar e estender classes no .NET Framework. Diferente das units tradicionais os namespaces podem ser aninhados para formar um conteúdo hierárquico. Um conjunto de namespaces fornece um caminho para organizar os tipos e identificadores, e são usados para diferenciar tipos com o mesmo nome. A partir do momento que eles são um pacote para as units do Delphi, os namespaces podem também diferenciar entre units do mesmo nome, que residem em pacotes diferentes. Por exemplo, a classe TCClass em TCNameSpace é diferente da TCClass em CTNameSpace. Em tempo de execução o CLR sempre se refere à classe e tipo pelos seus nomes completos: o assembly name, seguido pelo namespace que contém o tipo. O próprio CLR não tem o conceito ou implementação de hierarquia de namespace. Ele é puramente uma referência a marcação da linguagem de programação. Declaração de namespaces No Delphi 2005, um arquivo de projeto como programa, biblioteca ou pacotes implicitamente introduzem o seu próprio namespace. Uma unit pode ser um membro do projeto principal ou pode implicitamente declarar o seu próprio namespace. Em outros casos, declarasse uma unit como membro de um namespace no cabeçalho da unit. Por exemplo, considere a seguinte declaração: unit TheClub.TCProg.TCUnit; Primeiro, note que os namespaces são separados por pontos. Os namespaces não incluem nenhum símbolo para identificação entre os pontos; os pontos são partes do nome da unit. O nome do código fonte, por exemplo, é TheClub.TCProg.TCUnit.pas e o arquivo compilado será TheClub.TCProg.TCUnit.dcuil. Veja que os pontos indicam o conceito de agrupamento de um namespace com outro. O exemplo acima declara a unit TCUnit para ser membro do namespace TCProg que está contido no namespace TheClub. Veja que isto é para propósito de documentação. Um namespace do projeto principal declara um namespace para todas as units dentro do projeto. Veja as seguintes declarações. Program TheClub.Programas.TCProg; Library TheClub.Libs.TCLib; Package TheClub.Packages.TCPackage; Estas declarações estabelecem o namespace do projeto para o programa, biblioteca e pacotes respectivamente. O namespace é determinado removendo o identificador mais a direita da declaração. Uma unit que omite um namespace explicito é chamada de unit genérica. Dando procedimento a declaração do programa, a declaração da unit a seguir faria o compilador tratar TCUnit como 14 um membro do namespace TheClub.TCProg. unit TCUnit; O namespace padrão do projeto não afeta o nome do arquivo de origem para uma unit genérica. No exemplo anterior o nome do arquivo de origem deveria ser TCUnit.pas. O compilador coloca o prefixo dcuil no nome do arquivo. O arquivo dcuil no nosso exemplo deveria ser TheClub.TCProg.TCUnit.dcuil. As strings do namespace não são case-sensitive. O compilador considera dois namespaces que só difere no caso de ser equivalente. Porém, o compilador preserva o caso de um namespace e usará o conjunto em um arquivo de saída, mensagens de erro, e identificadores RTTI. O RTTI incluirá para as classes e tipos uma especificação completa do namespace. Procurando Namespaces Uma unit deve ser declarada a outra unit na qual ela é dependente. Como na plataforma Win32, o compilador deve procurar aquelas units. Para units em namespaces explícitos a extensão de procura já é conhecida, mas para units genéricas o compilador deve estabelecer uma extensão de procura de namespace. Considere a seguinte unit e declaração de uses: unit TheClub.Programs.Units.TCUnit1; uses TheClub.Programs.Libs.Unit2, Unit3, Unit4; As declarações estabelecem TCUnit1 como um membro do namespace TheClub.Programs.Units. TCUnit1 depende de três outras units: TheClub.Programs.Libs.Unit2 e as units genéricas Unit3 e Unit4. O compilador pode resolver nomes de identificadores dentro da Unit2 a partir da cláusula uses especificada. Para resolver os nomes de identificadores dentro da Unit3 e Unit4 o compilador deve estabelecer um namespace de pesquisa. Pesquisa de Namespaces Pesquisar localizações pode ser feito de três formas: Compiler Option, o namespace default do projeto e finalmente na unit corrente. Um arquivo de projeto (program, library ou package) pode ocasionalmente especificar uma lista de namespaces para serem localizadas quando resolver o nome das units genéricas. A cláusula namespaces deve aparecer no arquivo do projeto imediatamente após a declaração program, library ou package e antes de qualquer outra cláusula ou qualquer bloco. A cláusula namespaces é uma lista de identificadores namespaces separado por vírgulas. Um ponto e vírgula deve terminar a lista de namespaces. O compilador identifica os nomes na seguinte ordem. 1. O namespace corrente. 2. O namespace do projeto. 3. Os namespaces informados nas opções do compilador. Um exemplo de localização de namespace O seguinte exemplo de projeto e unit usam a cláusula namespace para Delphi especificar uma lista de pesquisa. // Declaração do projeto... program TheClub.Programs.TCProg; namespaces TheClub.Libs.UIWidgets, TheClub.Libs.Network; // Declaração de uma unit unit TheClub.Programs.Units.TCUnit1; Dado o programa de exemplo, o compilador irá procurar os namespaces na seguinte ordem. 1. TheClub.Programs.Units 2. TheClub.Programs 3. TheClub.Libs.Network 4. TheClub.Libs.UIWidgets 5. Namespaces informado em Compiler Options Observe que se a unit corrente for genérica, então a decisão começa com o namespace do projeto padrão. Usando Namespaces A cláusula uses do Delphi traz uma parte dentro do contexto da unit corrente. A cláusula uses deve também referir-se a um contexto pelo seu nome completo, por exemplo, incluindo o namespace completo, ou o nome genérico, através disso contando com os mecanismos de resolução de nomes para localizar a unit. Nomes de units completamente qualificados O exemplo a seguir demonstra o uso da cláusula uses com namespaces. unit TheClub.Libs.TCUnit1 uses TheClub.Libs.Unit2, UnitX; Uma vez que o módulo foi trazido ao contexto, o código de origem pode consultar os identificadores dentro daquele módulo por um nome não qualificado ou pelo nome qualificado. Veja o exemplo a seguir utilizando o writeln: uses TheClub.Libs.Unit2; begin writeln(TheClub.Libs.Unit2.MeuTexto); writeln(MeuTexto); end. Um nome completamente qualificado deve incluir o namespace completo. No exemplo anterior seria um erro referir-se a MeuTexto usando apenas uma parte do namespace: writeln(Unit2.MeuTexto); // -> ERRO writeln(Libs.Unit2.MeuTexto); // -> ERRO writeln(TheClub.Libs.Unit2.MeuTexto); // -> Correto writeln(MeuTexto); // -> Correto Também é um erro referir-se a apenas uma parte do namespace na cláusula uses. Não existe nenhum mecanismo para importar todas as units e símbolos de uma unit. O código a seguir não importa todas as units e símbolos do namespace TheClub. uses TheClub; // -> ERRO Esta restrição também se aplica a instrução with-do. A linha a seguir irá reproduzir um erro: with TheClub.Libs do // -> ERRO Namespaces e Metadatas .NET O compilador do Delphi .NET não retira o nome da unit dentro do código. Ao invés disto, ele apenas reparte o que se encontra mais a esquerda. Tudo até o ultimo ponto é retirado. unit TheClub.TCClasses.TCUnit O compilador irá retirar o namespace TheClub.TCClasses dentro do metadata. Ele faz isto para facilitar que outras linguagens do .NET possam encontrar os códigos em Delphi. Esta diferença é visível apenas em códigos externos que utilizarão este código. O código ainda dentro do Delphi trabalha com o nome completo. Namespaces Multi-Unit Várias units podem ser agrupadas dentro de um namespace usando a extensão in dentro do código fonte. O nome do arquivo pode ser listado em múltiplas units separadas com ponto e vírgula. uses TheClub.TCNamespace in ‘dir/unit1.pas;dir2/ unit2.pas’; Neste exemplo, o namespace TheClub.TCNamespace logicamente contém todos os símbolos de interface da unit1 e unit2. O nome dos símbolos em um namespace deve ser único, por todas as units do namespace. No exemplo anterior, se a unit1 ou unit2 definissem uma variável global com o nome de TCVariavel, o compilador iria retornar um erro na cláusula uses. Você usa um namespace multiunit para especificar o namespace na cláusula uses do arquivo fonte. O código fonte que utilizar um namespace multi-unit implicitamente utiliza todas as units listadas como sendo membros daquele namespace.Todas as units definidas pelo projeto corrente como membro daquele namespace estarão disponíveis para o compilador para busca de símbolos enquanto estiver compilando aquele código fonte. As units individuais agregadas em um namespace não estão disponíveis ao código fonte, a menos que a unit individual esteja explicitamente sendo utilizada na cláusula uses. Em outras palavras, se um código fonte utilizar apenas o namespace, então as expressões de identificador completamente qualificados que recorrem a um símbolo em uma unit naquele namespace tem que usar o nome do namespace, não a unit atual que está definida aquele símbolo. Uma cláusula uses pode referenciar a um namespace assim como uma unit dentro de um namespace. Neste caso, uma expressão completamente qualificada que recorre a um símbolo a partir de uma unit especifica listada na cláusula uses pode recorrer a usar o nome da unit atual ou o namespace para o instrumento. As duas formas de referência são idênticas e recorrem ao mesmo símbolo. Conclusão Estas são algumas novas informações do Delphi 2005 no ambiente .NET. Muitas novidades ainda estão por vir e nós estamos atentos a isto. Nas próximas edições estaremos trazendo mais novidades. Sobre o autor Claudinei Rodrigues, Consultor Técnico do The Club [email protected] 15 Delphi Adicionando menus em aplicações ASP.NET Por Alessandro Ferreira, [email protected] Introdução O desenvolvimento de aplicações com interface web vem crescendo a cada dia que passa e, buscar aprimorar a troca de informações com o usuário deixando-o a vontade para navegar em sua aplicação não é uma tarefa muito fácil, devido uma grande maioria dos programadores Delphi ainda estarem habituados com GUI (interface de formulários no Windows) e quando necessitam desenvolver aplicações ASP.NET, sentem-se um pouco ‘perdidos’ neste ambiente. Contudo, isso é natural, pois toda mudança requer um tempo para adaptação e agora com o Delphi 2005 você poderá aos poucos ir se familiarizando e em pouco tempo tudo se tornará corriqueiro novamente. Neste artigo irei abordar o componente skmMenu, o qual permite criar menus (semelhantes aos menus padrão Windows) em aplicações ASP.NET com um visual bastante atrativo. Vale lembrar que o skmMenu é um componente nativo .NET e como tal, poderá ser utilizado em qualquer IDE de desenvolvimento .NET (Delphi 8, C#Builder, Visual Studio, etc). Instalando o componente Você poderá efetuar download do skmMenu diretamente no site do fabricante: http://skmmenu.com/menu ou se preferir baixar em nosso site no endereço ao final deste artigo. Descompacte o arquivo em uma pasta onde você mantenha seus componentes instalados, abra o Delphi 2005, acesse o menu Component | Installed .NET Components... e com isso irá acessar os componentes .NET instalados em seu Delphi 2005, conforme apresentado na figura 1. Prosseguindo, para instalar, digite ‘skmMenu’ em Category, clique em ‘Select an Assembly’ e localize o arquivo: skmMenu.dll que o componente será instalado automaticamente. Arquivos de estilo (CSS) Os arquivos css (Cascading Style Sheets) são arquivos que possibilitam armazenar códigos para garantir uma formatação homogênea e uniforme em páginas web, bastando fazer referência ao mesmo em sua página (webforms) selecionando um estilo existente no css para alterar o visual da página. Neste artigo, iremos armazenar algumas configurações que serão utilizadas na construção dos menus, por isso, recomendo efetuar download do projeto de exemplo mencionado no final deste artigo, no qual encontrará os arquivos css prontos à serem utilizados. Construindo nosso projeto de exemplo Figura 1 16 Estando com o componente skmMenu instalado, vamos construir nossa primeira aplicação ASP.NET com menu. Para isso, acesse o menu File | New | Asp.Net Web Application e informe Menu no parâmetro ‘Name’, clique OK e salve a aplicação. Altere o nome Delphi deste webform de ‘webform1.aspx’ para ‘index.aspx’. Esta será nossa página principal a partir da qual iremos chamar vários exemplos para demonstrar o skmMenu. Além do index.aspx, adicione oito webforms (acesse o menu File | New | Other | Delphi for .NET Projects | New ASP.NET Files | ASP.NET Page preservando o nome sugerido, ou seja, webform1, webform2 e assim sucessivamente. Para efetuarmos a chamada destas novas páginas, adicione oito componentes HiperLink apontando sua propriedade NavigateURL para webform1.aspx, webform2.aspx e assim sucessivamente. A figura2 ilustra nosso index.aspx. Figura 2 – Index.aspx Exemplo #1 Vamos construir um menu dinâmico, ou seja, adicionando as opções do menu via programação no evento Page_Load de nosso webform1. Primeiro, adicione um componente skmMenu em nosso webform1, depois, acesse o evento Page_Load e adicione as instruções apresentadas na listagem 1. procedure TWebForm1.Page_Load(sender: System.Object; e: System.EventArgs); var submenu1, submenu2, submenu3: skmMenu.MenuItem; begin If not (IsPostBack) Then begin submenu1 := skmMenu.MenuItem.Create (‘<img src=”menublip.gif” align=”absmiddle”>Dynamic Item 1'); submenu1.SubItems.Add(skmMenu.MenuItem. Create (‘Sub Item 1’, ‘page1.html’)); submenu1.SubItems.Add(skmMenu.MenuItem.Create (‘Sub Item 2’, ‘page2.html’)); submenu3 := skmMenu.MenuItem.Create (‘Sub Item 3 ->’, ‘’); submenu3.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 3 - 1’,‘page1.html’)); submenu3.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 3 - 2’,‘page2.html’)); submenu1.SubItems.Add(submenu3); submenu1.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 4’, ‘page4.html’)); submenu1.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 5’, ‘page5.html’)); submenu1.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 6’, ‘page6.html’)); Menu1.Items.Add(submenu1); submenu2 := skmMenu.MenuItem. Create(‘<img src=”menublip.gif” align=”absmiddle”>Dynamic Item 2'); submenu2.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 1’, ‘page3.html’, ‘tooltip1’)); submenu2.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 2’, ‘page4.html’, ‘tooltip2’)); Menu1.Items.Add(submenu2); Menu1.CssClass := ‘menustyle’; Menu1.DefaultCssClass := ‘menuitem’; Menu1.DefaultMouseOverCssClass := ‘mouseover’; Menu1.HighlightTopMenu := True; Menu1.Opacity := ‘75’; Menu1.zIndex := 100; Menu1.ClickToOpen := True; End; end; Listagem 1 – Adicionando itens ao skmMenu. Antes de executar a aplicação, observe que o skmMenu permite a utilização de arquivos de estilo para configuração da aparência através das propriedades CssClass, DefaultCssClass e DefaultMouseOverCssClass. Assim sendo, criamos um arquivo chamado Styles5.css que contém estas definições o qual deverá ser referenciado em nossa página, para isso, acesse o webform1.aspx e adicione as instruções seguintes: <head> <title></title> <link href=”Styles5.css” type=”text/css” 17 Delphi rel=”stylesheet”> </head> Outro aspecto interessante é em relação ao construtor da classe MenuItem, o qual foi sobrecarregado podendo receber até nove combinações diferentes de parâmetro, sendo a mais completa apresentada na listagem 2. public MenuItem( string itemText, string itemUrl, string itemToolTip, string itemCssClass, string itemMouseOverCssClass, string itemMouseDownCssClass, string itemMouseUpCssClass, string itemImage, string itemMouseOverImage, string itemMouseDownImage, string itemMouseUpImage, string itemName ); Listagem 2 – Construtor do MenuItem. Dessa forma, no momento da criação dos itens do menu, poderemos estar definindo todas as configurações necessárias ao mesmo. Vamos agora testar nosso primeiro exemplo, compile e rode a aplicação, clique na primeira opção definida em nosso index.aspx e se tudo estiver OK será apresentado um menu parecido com a figura 3 informações necessárias para compor o menu. Na listagem 3 apresentamos a estrutura do arquivo XML utilizado neste exemplo. <?xml version=”1.0" encoding=”utf-8" ?> - <menu> - <menuItem> <text>XML Item 1</text> - <subMenu> - <menuItem> <text>Sub Item 1</text> <url>page1.html</url> </menuItem> - <menuItem> <text>Sub Item 2</text> <url>page2.html</url> </menuItem> </subMenu> </menuItem> - <menuItem> <text>XML Item 2</text> <cssclass>highlighteditem</cssclass> - <subMenu> - <menuItem> <text>Sub Item 3</text> <url>page3.html</url> </menuItem> - <menuItem> <text>Sub Item 4</text> <url>page4.html</url> </menuItem> </subMenu> </menuItem> </menu> Listagem 3 – Arquivo XML contendo itens do menu. Analisando a estrutura teremos: Figura 3 – Exemplo #1. Exemplo #2 Vamos construir mais um exemplo utilizando o skmMenu, porém, agora buscando os itens a partir de um arquivo XML que deverá conter uma hierarquia a fim de fornecer ítens, sub-ítens, texto dos ítens, a página que o item deverá abrir, enfim, as 18 - <menu> : nó principal indicando menu - <menuitem> : item de menu - <text> : texto que será apresentado no item ou sub-item - <submenu> : abre sessão indicando subitens a partir desse ponto. - <url> : endereço/página à ser aberta. - <cssclass> : estilo (CSS) Prosseguindo, acesse o webform2, adicione um componente skmMenu e depois vá ao evento Page_Load onde vamos efetuar a Delphi carga dos itens do menu a partir do arquivo XML. Na listagem 4 apresentamos esta codificação. procedure TWebForm2.Page_Load(sender: System.Object; e: System.EventArgs); begin If not (IsPostBack) Then begin Menu1.DataSource := Server.MapPath(‘menu2.xml’); Menu1.CssClass := ‘menustyle’; Menu1.HighlightTopMenu := True; Menu1.DataBind(); End; end; Listagem 4 – Page_Load do webform2. Observe que o código é bem simples, bastando passar o caminho e nome do arquivo XML à propriedade DataSource do componente skmMenu. O método MapPath do objeto Server devolve o caminho físico de um arquivo existente em um diretório virtual. Assim como no exemplo anterior, também utilizamos um arquivo CSS para controlar a aparência de nosso menu, então, lembre-se de fazer referência ao mesmo em seu webform2.aspx conforme apresenta a listagem 5. <head> <title></title> <meta name=”GENERATOR” content=”Borland Package Library 7.1"> <link href=”Styles.css” type=”text/css” rel=”stylesheet”> </head> Listagem 5 – CSS. Salve tudo e vamos testar a aplicação, bastando para isso teclar <F9> (ou CTRL+SHIFT+F9 para rodar sem debug), depois clique na opção referente o exemplo#2 e se estiver tudo OK o resultado será parecido com a figura 4. Figura 4 – Exemplo#2. Exemplo #3 Até agora, nossos exemplos foram de menus horizontais. Vale ressaltar que o componente skmMenu possui uma propriedade chamada layout que possibilita definir qual será a orientação do menu, ou seja: horizontal ou vertical. Neste exemplo iremos criar um menu vertical utilizando imagem em cada ítem de menu, além ainda de gerar o efeito Rollover que irá trocar a imagem ao passar o mouse sobre o item. Então, abra o webform3, adicione um skmMenu e ajuste sua propriedade layout para ‘Vertical’. Os itens deste menu serão obtidos a partir de um arquivo XML o qual possui a estrutura apresentada na listagem 6. <?xml version=”1.0" encoding=”utf-8" ?> - <menu> - <menuItem> <image>images/btn_pmt.gif</image> <mouseoverimage>images/btn_pmt_over.gif </mouseoverimage> <url>Page1.html</url> </menuItem> - <menuItem> <image>images/btn_faq.gif</image> <mouseoverimage>images/btn_faq_over.gif </mouseoverimage> <url>Page2.html</url> </menuItem> - <menuItem> <image>images/btn_stm.gif</image> <mouseoverimage>images/btn_stm_over.gif </mouseoverimage> <url>Page3.html</url> </menuItem> - <menuItem> <image>images/btn_mng.gif</image> <mouseoverimage>images/btn_mng_over.gif </mouseoverimage> - <subMenu> - <menuItem> <image>images/btn_mng2.gif</image> <mouseoverimage>images/btn_mng2_over.gif </mouseoverimage> <url>Page1.html</url> </menuItem> - <menuItem> <image>images/btn_mng3.gif</image> <mouseoverimage>images/btn_mng3_over.gif </mouseoverimage> <url>Page2.html</url> 19 Delphi </menuItem> - <menuItem> <image>images/btn_mng4.gif</image> <mouseoverimage>images/btn_mng4_over.gif </mouseoverimage> <url>Page3.html</url> </menuItem> </subMenu> </menuItem> - <menuItem> <image>images/btn_pay.gif</image> <mouseoverimage>images/btn_pay_over.gif </mouseoverimage> - <subMenu> - <menuItem> <image>images/btn_web1.gif</image> <mouseoverimage>images/btn_web1_over.gif </mouseoverimage> <url>Page1.html</url> </menuItem> - <menuItem> <image>images/btn_web2.gif</image> <mouseoverimage>images/btn_web2_over.gif </mouseoverimage> <url>Page2.html</url> </menuItem> - <menuItem> <image>images/btn_web3.gif</image> <mouseoverimage>images/btn_web3_over.gif </mouseoverimage> <url>Page3.html</url> </menuItem> - <menuItem> <image>images/btn_web4.gif</image> <mouseoverimage>images/btn_web4_over.gif </mouseoverimage> <url>Page4.html</url> </menuItem> </subMenu> </menuItem> </menu> Obs.: Neste exemplo estamos assumindo que as imagens estão disponibilizadas em uma pasta chamada Images dentro da pasta principal do projeto. Finalizando, faça a referência ao arquivo styles.css no webform3.aspx e no evento Page_Load a carga dos itens do menu a partir do arquivo XML, veja listagem 8. <head> <title></title> <meta name=”GENERATOR” content= ”Borland Package Library 7.1"> <link href=”Styles.css” type= ”text/css” rel=”stylesheet”> </head> procedure TWebForm3.Page_Load(sender: System.Object; e: System.EventArgs); begin If not (IsPostBack) Then begin Menu1.DataSource := Server.MapPath(‘nav.xml’); Menu1.DataBind(); end; end; Listagem 8 – Aspx e Page_Load. Salve o projeto, compile e o resultado será parecido com o apresentado na figura 5. Listagem 7 – XML. Neste exemplo estamos utilizando todos os parâmetros disponibilizados no construtor do MenuItem. Observe que estamos definindo uma imagem através do parâmetro Image e a imagem que será utilizada no efeito RollOver através do parâmetro MouseOverImage. 20 Figura 5 – Exemplo#3. Obs.: As imagens e o arquivo XML utilizados neste exemplo estão disponíveis para download no endereço ao final deste artigo. Delphi Exemplo #4 Neste exemplo iremos utilizar uma pequena imagem junto ao texto dos itens principais do menu, mesclando código html e texto. Outro aspecto interessante será o efeito Up/Down no momento que o item receber o clique do mouse, ou seja, ao clicar no item ele irá ter o efeito de ‘abaixar’ e ‘voltar’, assim como um botão padrão Windows. Abra o webform4, adicione um componente skmMenu, faça a referência ao Styles2.css utilizando a mesma sintaxe dos exemplos anteriores e no evento Page_Load vamos adicionar os itens ao menu, conforme código apresentado na listagem 9. procedure TWebForm4.Page_Load(sender: System.Object; e: System.EventArgs); var submenu1, submenu2, submenu3: skmMenu.MenuItem; begin If not (IsPostBack) Then begin submenu1 := skmMenu.MenuItem.Create (‘<img src=”menublip.gif” align=”absmiddle”>Dynamic Item 1'); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 1’, ‘page1.html’)); submenu1.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 2’, ‘page2.html’)); submenu3 := skmMenu.MenuItem. Create(‘Sub Item 3 ->’, ‘’); submenu3.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 3 - 1’, ‘page1.html’)); submenu3.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 3 - 2’, ‘page2.html’)); submenu1.SubItems.Add(submenu3); submenu1.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 4’, ‘page4.html’)); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 5’, ‘page5.html’)); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 6’, ‘page6.html’)); Menu1.Items.Add(submenu1); submenu2 := skmMenu.MenuItem.Create (‘<img src=”menublip.gif” align=”absmiddle”>Dynamic Item 2'); submenu2.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 1’, ‘page3.html’, ‘tooltip1’)); submenu2.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 2’, ‘page4.html’, ‘tooltip2’)); Menu1.Items.Add(submenu2); Menu1.CssClass := ‘menustyle’; Menu1.DefaultCssClass := ‘menuitem’; Menu1.DefaultMouseDownCssClass := ‘mousedown’; Menu1.DefaultMouseOverCssClass := ‘mouseover’; Menu1.DefaultMouseUpCssClass := ‘mouseup’; Menu1.HighlightTopMenu := True; Menu1.Opacity := ‘75’; Menu1.zIndex := 100; End; end; Listagem 9 – Page_Load do webform4. Observe que a definição da aparência do menu mais uma vez foi determinada com base no arquivo de estilo. Compile e execute o projeto, o resultado será parecido com a figura 6. Figura 6 – Exemplo#4. Exemplo#5 Este exemplo basicamente possui as mesmas características do exemplo anterior, tendo porém, um visual diferente previamente definido no Styles3.css. Assim sendo, abra o webform5.aspx, faça referência ao arquivo de estilo, adicione um skmMenu e no evento Page_Load adicione o código apresentada na listagem 10. 21 Delphi Menu1.CssClass := ‘menustyle’; Menu1.DefaultCssClass := ‘menuitem’; Menu1.DefaultMouseOverCssClass := ‘mouseover’; Menu1.HighlightTopMenu := True; Menu1.Opacity := ‘75’; Menu1.zIndex := 100; procedure TWebForm5.Page_Load(sender: System.Object; e: System.EventArgs); var submenu1, submenu2, submenu3: skmMenu.MenuItem; begin If not (IsPostBack) Then End; end; begin submenu1 := skmMenu.MenuItem. Create(‘<img src=”menublip.gif” align=”absmiddle”>Dynamic Item 1'); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 1’, ‘page1.html’)); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 2’, ‘page2.html’)); submenu3 := skmMenu.MenuItem.Create (‘Sub Item 3 ->’, ‘’); submenu3.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 3 - 1’, ‘page1.html’)); submenu3.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 3 - 2’, ‘page2.html’)); submenu1.SubItems.Add(submenu3); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 4’, ‘page4.html’)); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 5’, ‘page5.html’)); submenu1.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 6’, ‘page6.html’)); Menu1.Items.Add(submenu1); submenu2 := skmMenu.MenuItem. Create(‘<img src=”menublip.gif” align=”absmiddle”>Dynamic Item 2'); submenu2.SubItems.Add(skmMenu.MenuItem. Create(‘Sub Item 1’, ‘page3.html’, ‘tooltip1’)); submenu2.SubItems.Add(skmMenu. MenuItem.Create(‘Sub Item 2’, ‘page4.html’, ‘tooltip2’)); Menu1.Items.Add(submenu2); 22 Listagem 10 – Page_Load do webform5. Salve, compile e execute a aplicação e selecione o exemplo#5 para ver o resultado. Outros exemplos Os exemplos #6, #7 e #8 basicamente seguem a mesma linha dos exemplos anteriores, apenas com pequenas alterações no layout. Dessa forma, não iremos detalhá-lo aqui, visto que estaríamos apenas repetindo código sem necessidade, contudo, poderá verificá-los no projeto de exemplo disponível para download referente este artigo. Conclusão Procurei demonstrar neste artigo algumas das funcionalidades do componente skmMenu, o qual como pôde ser visto possibilita criar menus em aplicações ASP.NET de forma bastante simples e profissional, além ainda de ser gratuito e compatível com a maioria das IDEs de desenvolvimento .NET. Se você tiver alguma sugestão de artigos que gostaria de ver publicado em nossa revista, sinta-se a vontade em nos escrever, teremos imenso prazer em atendê-lo. Abraço e sucesso à todos, Download O componente skmMenu e o projeto de exemplo referente este artigo encontra-se disponível para download em: http:// www.theclub.com.br/revista/download/skmMenu.zip Sobre o autor Alessandro Ferreira, Consultor Técnico do The Club [email protected] Delphi Instalando o BDE via InnoSetup por: Alessandro Ferreira, [email protected] Introdução O InnoSetup é um gerador de instalações que vem tendo grande aceitação meio a comunidade Delphi principalmente por sua flexibilidade e facilidade, além ainda de ser bastante poderoso e o melhor: é gratuito! Neste artigo irei demonstrar como efetuar a instalação do BDE através do InnoSetup, utilizando a versão: 5.1.4 e a ferramenta IsTool versão: 5.0.8. O InnoSetup está disponível para download em: www.innosetup.com e o IsTool em: http:// www.istool.org. Não irei mencionar aspectos básicos em ambas ferramentas, visto que já publicamos um artigo introdutório a respeito das mesmas em nossa revista de: Agosto/2003 “Criando Instalações personalizadas com o Inno Setup”, assim sendo, caso tenha dúvidas, poderá consultar o artigo que está disponível em nosso site, www.theclub.com.br. Onde conseguir o BDE? Você deve estar se perguntando onde conseguiremos o BDE para utilizarmos como fonte em nossa instalação, correto? Bem, isso será bem simples: na pasta de instalação do BDE, geralmente em: C:\Arquivos de programas\Arquivos comuns\Borland Shared\BDE você encontrará um arquivo chamado: BdeInst.cab o qual nada mais é que um arquivo compactado (formato CAB) o qual possui uma DLL que possibilita efetuarmos a instalação do BDE de forma muito fácil. Poderíamos utilizar o arquivo CAB, contudo, para facilitar vamos descompactá-lo e utilizar diretamente a DLL obtida. Para descompactá-lo utilize a seguinte linha de comando: Figura 1 – Adicionando BdeInst ao instalador O arquivo BdeInst.dll será copiado para a pasta temporária do Windows na máquina onde for instalado visto que este arquivo representa apenas a ‘fonte’ de instalação e não o BDE. Estando o arquivo disponibilizado na máquina para instalação, iremos registrar esta DLL através do comando: RegSvr32 (do próprio Windows) fazendo isso através do próprio instalador. Clique no item ‘Executar na Instalação’ e adicione um novo ítem configurando conforme sugere a figura 2. extract /e bdeinst.cab Pronto! Com isso teremos o BdeInst.dll. Criando o projeto de Instalação Abra o utilitário IsTool e vamos criar nosso projeto para gerar a instalação do BDE o qual iremos salvar com o nome: InstalaBDE.iss. Prosseguindo, selecione o ítem ‘Arquivos e Diretórios’ e vamos adicionar o arquivo: BdeInst.dll informando como destino a pasta temporária do Windows, veja a figura 1. Figura 2 – Registrando o BDE 23 Delphi Finalizando, salve e compile a instalação e com isso já teremos um instalador do BDE prontinho para ser utilizado! Como criar/configurar um Alias? Nosso instalador está pronto, contudo, ele apenas irá instalar o BDE com as configurações padrões e, se estamos utilizando BDE provavelmente será necessário criar e configurar um Alias para nossa aplicação. Para isso vamos utilizar um pequeno programa escrito em Delphi que será embutido e executado pelo instalador recebendo como parâmetros as informações do Alias à ser criado. Na listagem 1 apresentamos o código completo deste projeto: { Programa para adicionar Alias no BDE. parâmetros: 0: nome deste programa + path (padrão) 1: Nome do Alias if começar com ‘-’ então deveremos apagar a primeira posição. 2: path (pasta onde estão as tabelas) 3: Driver utilizado (PARADOX, INTRBASE...) } program AddAlias; uses Windows, SysUtils, BDE; var GAlias: GDriver: GAliasDir: FParams: FDrvName: FDelete: i: string = ‘New’; string = szPARADOX; string; string; string; boolean; integer; function StrToOem(const AnsiStr: string): string; begin SetLength(Result, Length(AnsiStr)); if Length(Result) > 0 then CharToOem(PChar(AnsiStr), PChar(Result)); end; {——————————————————————————————————————} begin { Pega valor dos parâmetros } for i := 1 to ParamCount do begin 24 case i of 1: GAlias := ParamStr(1); 2: GAliasDir := ParamStr(2); 3: GDriver := ParamStr(3); end; end; //default alias if GAliasDir = ‘’ then GAliasDir := ExtractFilePath(ParamStr(0))+’Data’; //a primeira posição é ‘-’? if GAlias[1] = ‘-’ then begin FDelete := True; Delete(GAlias, 1, 1); end else FDelete := False; FDrvName := GDriver; //ajusta parâmetros, driver e server name. if (CompareText(GDriver, szCFGDBSTANDARD) = 0) or (CompareText(GDriver, szPARADOX) = 0) or (CompareText(GDriver, szDBASE) = 0) or (CompareText(GDriver, szFOXPRO) = 0) or (CompareText(GDriver, szASCII) = 0) then begin if (CompareText(GDriver, szCFGDBSTANDARD) = 0) then FDrvName := szPARADOX; //ajusta parâmetros para o novo alias. FParams := Format(‘%s:”%s”’, [szCFGDBPATH, GAliasDir]) + Format(‘;%s:”%s”’, [szCFGDBDEFAULTDRIVER, GDriver]) + Format(‘;%s:”%s”’, [szCFGDBENABLEBCD, szCFGFALSE]); end else begin if (CompareText(GDriver, ‘INTRBASE’) = 0) then FParams := Format(‘%s:”%s”’, [szSERVERNAME, GAliasDir]) else FParams := Format(‘%s:”%s”’, [szDATABASENAME, GAliasDir]); Delphi {No caso do Interbase, adicione aqui outros parâmetros que venham ser necessários} end; DbiInit(nil); try if FDelete then try DbiDeleteAlias(nil, PChar(GAlias)); except end; try DbiAddAlias(nil, PChar(StrToOem(GAlias)), PChar(StrToOem(FDrvName)), PChar(FParams), True); DbiCfgSave(nil, nil, True); except end; finally DbiExit(); end; end. Listagem 1 – Programa AddAlias. Vale lembrar que este pequeno aplicativo foi criado como uma aplicação console, ou seja, não possui formulários. Dando continuidade, vamos adicionar o AddAlias ao nosso instalador e efetuar sua chamada ao término da instalação para criarmos o Alias no BDE recém instalado. Para isso, selecione ‘Arquivo e Diretórios’ e adicione o AddAlias destinando-o à pasta temporária do Windows da mesma forma que fizemos com o BdeInst.cab. Feito isso, acesse ‘Executar na Instalação’ e adicione um novo item para efetuarmos a chamada (execução) do AddAlias, veja a figura 3. SQL-Links Obs.: Os passos a seguir somente serão necessários se você estiver utilizando banco de dados Interbase/Firebird. Quando efetuamos a instalação do BDE através da BdeInst.dll a instalação não leva os drivers referentes servidores SQL, ou seja, a instalação irá funcionar perfeitamente para acesso a tabelas Paradox, contudo, caso utilize Interbase/Firebird será necessário adicionar e configurar mais alguns arquivos. No caso do Interbase/Firebird iremos adicionar os seguintes arquivos (vá em ‘Arquivos e Diretórios’ para adicionar): SQLINT32.DLL SQL_INT.CNF driver do Interbase BDE-config para driver Interbase Além de adicionar estes arquivos será necessário criar chaves no registrador do Windows onde será feita a configuração do referido driver para que possamos estar criando um Alias ‘em cima’ do mesmo. Uma forma bastante prática para isso é acessar o registrador do Windows e exportar a chave desejada para um arquivo REG e depois importá-la via IsTool: Figura 3 – Chamada do AddAlias 1. Abra o registrador do Windows (Executar | RegEdit) 2. Vá até a chave: HKEY_LOCAL_MACHINE\SOFTWARE\ Borland\Database Engine\Settings\ DRIVERS\INTRBASE 3. Clique com o botão direito do mouse e selecione: Exportar 4. Salve como ‘RegistraInterbase.reg’ 25 Delphi Volte ao IsTool e selecione a sessão ‘Registro’, clique com o botão direito, escolha ‘Importar do Arquivo’ e selecione o ‘RegistraInterbase.reg’ e com isso o IsTool irá criar todas as chaves necessárias durante o processo de instalação, configura a figura 4. Salve e compile o projeto e com isso teremos pronta nossa instalação do BDE! Conclusão Mais uma vez você pôde perceber o poder e a facilidade em se utilizar o InnoSetup, lembrando que esta ferramenta têm muito mais à ser explorada. Ela conta com uma boa documentação que poderá ajudar a sanar dúvidas e conhecê-la melhor, ou ainda, você poderá acessar uma lista de discussão mantida pelo fabricante onde programadores de várias partes do mundo trocam informações e Figura 4 – Chaves no registro quando utilizado Interbase/Firebird 26 experiências sobre o IS no endereço: http://www.jrsoftware.org/ newsgroups.php. Abraço e sucesso a todos, Download O exemplo apresentado neste artigo está disponível para download em: http://www.theclub.com.br/revista/download/isbde.zip. Sobre o autor Alessandro Ferreira, Consultor Técnico do The Club [email protected] Perguntas & Respostas Pergunta: Como alterar a impressora padrão para onde o Rave Reports irá enviar a impressão? Resposta: Bastará informar o índice da impressora da seguinte forma: uses RpDevice, Printers; procedure TForm1.Button1Click (Sender: TObject); begin Printer.PrinterIndex := 0; RPDev.DeviceIndex := Printer.PrinterIndex; rvTestes.ExecuteReport(‘Rep_Employee’); end; Dúvida enviada por TEI Informática, Rio de Janeiro/RJ. Pergunta: Gostaria de saber como desenvolver aplicações para internet via Delphi. Resposta: No caso do Delphi 7 você poderá criar aplicações web utilizando o Intraweb que é um framework de desenvolvimento de aplicações para internet. Em nossa revista de Janeiro, Fevereiro e Março de 2004 encontrará artigos a respeito. No caso do Delphi 2005 (que é o mais recomendado para programação web) você poderá criar aplicações web utilizando ASP.NET que é uma das melhores tecnologias para desenvolvimento web no mercado atualmente. Em nossa site encontrará vários artigo (na sessão Revistas) referentes Delphi 8 e Delphi 2005 (ambos para internet). Dúvida enviada por Elson Carlos Almeida, Irecê/BA. Pergunta: Mostro os registros de uma tabela em um DBGrid com os seguintes campos: Código, Nome e Seguimento, como por exemplo: Código -------1 2 3 4 5 Nome ------teste 1 teste 2 teste 3 teste 4 teste 5 Seguimento --------------001 002 003 002 001 Eu gostaria de estar colorindo as linhas do DBGrid definindo um cor para cada seguimento igual. Isso é possível? Resposta: Isso é possível, contudo, dará um pouco de trabalho visto não sabermos exatamente quantos seguimentos teremos na tabela e quais cores estaremos definindo para cada seguimento. Dessa forma, iremos criar uma lista que irá armazenar o código de seguimento e a cor dada ao mesmo para podermos colorir os seguimentos ‘iguais’ com esta mesma cor, tudo isso no evento OnDrawColumnCell do DBGrid, acompanhe o exemplo a seguir: var Form1: TForm1; Regs: TStringList; { Irá guarder a lista de códigos/cores } implementation {$R *.dfm} procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: 27 Perguntas & Respostas TGridDrawState); var Cor: TColor; begin Randomize; { Guarda código e sua respectiva cor } if Regs.IndexOf(FloatToStr(tabItensPartNo. AsFloat)) < 0 then Regs.AddObject(FloatToStr(tabItensPartNo. AsFloat), TObject(RGB(Random($100), Random($100),Random($100)))); Cor := TColor(Regs.Objects[Regs.IndexOf (FloatToStr(tabItensPartNo.AsFloat))]); { Cor do fundo } DBGrid1.Canvas.Brush.Color := Cor; { Cor da fonte } DBGrid1.Canvas.Font.Color := (not Cor) and $FFFFFF; DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State); end; Resposta: Como você está acessando uma página HTTPS é necessário a utilização de mais um componente da palheta Indy chamado IdSSLIOHandlerSocket. Vá até a propriedade IOHandler do componente idHTTP e informe o nome deste novo componente ou seja IdSSLIOHandlerSocket1. O componente IdSSLIOHandlerSocket utiliza duas DLLs chamadas libeay32.dll e ssleay32.dll que não acompanham o Delphi. Assim sendo, você precisa baixar estes dois arquivos de um site de terceiros segundo o fabricante do componente Indy, como você poderá ver as informações no link http://www.indyproject.org/Sockets/SSL.iwp. Após efetuar download, copie estas DLLs para o diretório System do Windows. Feito isto a sua aplicação rodará normalmente. Poderá efetuar download dos arquivos em nosso site, www.theclub.com.br/revista/download/indy_openssl096k.zip. Dúvida enviada por Carlos Norival Espinosa, Pedreira/SP. initialization Regs := TStringList.Create; Pergunta: Hoje preciso de uma ajuda à moda antiga. Preciso criar um arquivo de lote (Bat) que execute a tarefa de criar uma pasta, cujo nome será igual á data do dia corrente no formato ano, mês e dia. Como fazer isso utilizando um arquivo de lote (Bat)? finalization Regs.Free; Resposta: Essa veio do fundo do baú! Poderá criar seu arquivo batch assim: Poderá criar um arquivo batch que o seguinte código: end. Observe que geramos cores aleatórias para cada seguimento, porém, cada grupo de segmentos terá a mesma cor. Dúvida enviada por Donizeti de Paula Ribeiro, Anápolis/GO. Pergunta: Geralmente utilizo o componente IdHTTP para retornar o conteúdo de uma página web, como por exemplo: Var P: String; Begin P := IdHttp.Get (‘http://www.theclub.com.br’); End; FOR /f “tokens=2-4 skip=1 delims= (-)” %%G IN (‘echo.^|date’) DO ( FOR /f “tokens=2 delims= “ %%A IN (‘date /t’) DO ( SET v_all=%%A ) ) SET dia=%v_all:~0,2% SET mes=%v_all:~3,2% SET ano=%v_all:~6,4% MD %ano%%mes%%dia% Dúvida enviada por Carlos Henrique Ciccolani, Campinas/ SP. Isso funciona sem problemas. Porém, estou tentando retornar o código de uma página que está em HTTPS e com isso, o método GET do IdHTTP não está funcionando. Existe alguma forma de obter uma página que está em HTTPS via Delphi? 28 Pergunta: Como faço para criar um determinado número de botões (TSpeedButton) em forma de uma grade (N linhas com Perguntas & Respostas N colunas de botões) em um formulário, adicionando o evento OnClick aos mesmos? Resposta: Para criar N botões em cima de um formulário poderá utilizar um Array de TSpeedButtons, como exemplo: const OffSet = 10; var Botao: Array of TSppedButton; i, Topo: Integer; begin // Define a quantidade de Botoes. Poderá pegar a quantidade de registros. SetLength(Botao, 10); // Top inicial. Topo := 10; // Looping para criar. for i := Low(Botao) to High(Botao) do begin Botao[i] := TSppedButton.Create(Self); with Botao[i] do begin Parent := Self; { onde irá aparecer } Top := Topo; Left := 50; Caption := ‘Botão ‘ + IntToStr(i); OnClick := ClickDosBotoes; Name := ‘sbtnBotao’ + IntToStr(i); end; Topo := Topo + Botao[i].Height + OffSet; end; end; Em relação ao evento OnClick, deverá criar uma procedure em seu formulário assim: procedure TForm1.ClickDosBotoes(Sender: TObject); begin // para saber qual botão: if TSpeedButton(Sender).Name = ‘sbtnBotao1’ then ShowMessage(‘Botão 1’); end; Dúvida enviada por Fundação Assistência Empreg. da Cesan, Vitória/ES. Pergunta: Estou utilizando os componentes da suíte Indy para enviar emails visto através deles ser possível efetuar a autenticação SMTP exigida por alguns provedores, contudo, quando tento utilizar o IG para enviar emails, a autenticação está falhando. Um detalhe interessante: se eu utilizar o discador do IG, consigo enviar o email. O que pode estar ocorrendo? Resposta: Segundo informações obtidas junto ao próprio IG, é necessário efetuar a conexão via discador, pois do contrário não será efetuada a autenticação. Abaixo segue parte do texto disponível no site do IG: Posso configurar o Outlook para receber e enviar mensagens do Big Mail? Sim, através dos servidores: pop.ig.com.br (ou pop3.ig.com.br) e smtp.ig.com.br. Você conseguirá receber mensagens utilizando outro provedor. Mas para enviar, terá que se conectar através do discador iG ou entrar no seu Webmail (acessar o Big Mail colocando o seu email e sua senha na home do iG - www.ig.com.br -, nos campos em branco em frente a iG Mail). Dúvida envida por WSys Produtos Inteligentes Ltda, Rio de Janeiro/RJ. Pergunta: Em uma aplicação MDI, como posso impedir que um mesmo formulário seja aberto mais de uma vez? Resposta: Poderá fazer o seguinte: { Chamada do Form } if fmClientes = nil then Application.CreateForm(tfmClientes, fmClientes); fmClientes.Show; { evento OnDestroy do Form } fmClientes := nil; Dúvida enviada por byte Software e Cons. Ltda, Belo Horizonte/MG. Pergunta: Utilizo Delphi 6 e tabelas Paradox. O cliente está utilizando Windows 98, apenas dois computadores sendo um “servidor”. Em ambos está dando o erro. No “Servidor” está dando 29 Perguntas & Respostas erro, ora “External Exception 46”, ora dá tela azul (ocorreu erro fatal 0E em 0028:C0059C8D) Na estação só está dando a tela azul, com a mesma mensagem. Resposta: As informações que encontramos a este respeito é que aplicações escritas em Delphi 2, 3, 4, 5, 6, 7 que usem ou não acesso a banco de dados ou arquivos de qualquer natureza podem a vir congelar a máquina apresentando este erro. Isso acontece porque as placas mãe que estão sendo produzidas a algum tempo foram “otimizadas” para rodarem com o Windows XP. Sendo assim caso estejamos rodando o Delphi nestas placas com Windows 98 o hardware pode retornar uma instrução diferente da esperada pelo sistema operacional e pelo Delphi ocasionando o erro. Nas mesmas máquinas que apresentavam o erro bastou substituir o sistema operacional para Windows XP que o sistema voltou a rodar sem maiores problemas. Dúvida enviada por Concentro Dist. Mat. Eletr. Hidr. Ltda, Campo Grande/MS. Pergunta: Tenho centenas de arquivos MP3 listados em um componente FileListBox, e gostaria de fazer pesquisas/buscas nesta lista de itens que tenho neste componente. Exemplo: Quero digitar em um TEdit “Minha vida” e aí o FileListBox vai disponilizar todas as músicas que tenham este texto digitado em qualquer parte do texto (nome da música). Resposta: Isto pode ser resolvido de uma forma bastante simples, utilizando a propriedade Mask do componente FileListBox, como exemplo: procedure TForm1.Button1Click(Sender: TObject); begin FileListBox1.Mask := ‘*’+Edit1.Text+’*.*’; FileListBox1.Update; end; Dúvida enviada por Sandro George, Belém/PA. Pergunta: Qual é a função do comando Application.ProcessMessages? Como, quando e onde utilizá-lo? Resposta: Este comando é utilizando com freqüência para 30 liberar recursos para informações a serem apresentadas na tela. Vamos supor que você monte um laço em uma tabela e queira apresentar os registros em um label. Logo após atribuir a informação ao label você pode utilizar este comando. Dúvida enviada por MEC-Q Comércio e Serv. Metrologia, Santo André/SP. Pergunta: Gostaria de saber como obter a lista de usuário conectados em um banco SQLServer 2000. Resposta: O SQLServer 2000 possui uma gama de stored procedures de sistema que retornam várias informações, entre elas, a lista de usuários. Para executar, utilize um AdoQuery assim: procedure TForm1.Button1Click(Sender: TObject); begin ADOQuery1.SQL.Add(‘Exec SP_WHO’); ADOQuery1.Active := True; end; Poderá ligar esta AdoQuery em um DataSource e um DBGrid para visualização dos dados. Dúvida enviada por Almir R. Borges, Araçatuba/SP. Pergunta: No Firebird 1.5 sei que é possível utilizar uma mesma trigger para INSERT, UPDATE e DELETE, contudo, como eu sei qual operação está sendo executada no momento? Resposta: Existem variáveis que controlam isso dentro do Firebird, sendo: INSERTING UPDATING DELETING Exemplo: IF (INSERTING) THEN NEW.ID = GEN_ID(G_GENERATOR_1, 1); Dúvida enviada por Ricardo Romero da Silva, Fartura/SP. Pergunta: Gostaria de saber se existe alguma instrução que, após a utilização de um arquivo texto no Windows (seja Perguntas & Respostas leitura ou gravação) eu consiga liberar o arquivo para outros aplicativos. Tenho notado que o arquivo fica em uso e apenas após fechar minha aplicação é que ele está sendo realmente liberado. As instruções utilizadas estão basicamente assim: var f : TextFile; 2. aponte a propriedade Engine do RvProject para o RvSystem 3. expanda a propriedade SystemPreview do RvSystem e configure: . FormHeight = 0 . FormWidth = 0 . FormSytle = wsMaximize 4. Estes valores devem estar = 0. Dúvida de Paulo Henrique Geloramo Esteves, Assis/SP. begin AssignFile(f, ‘c:\teste.txt’); ReWrite(f); WriteLn(F, ‘meu texto’); CloseFile(f); end; Resposta: Existe um API do Windows chamada FlushFileBuffers que ‘força’ descarregar e liberar o arquivo em disco e é bem simples de ser utilizada, acompanha o código abaixo: var f : TextFile; begin AssignFile(f, ‘c:\teste.txt’); ReWrite(f); WriteLn(F, #27); FlushFileBuffers(TTextRec(f).Handle); CloseFile(f); end; Dúvida de Eccus Informatica Ltda – Me, Guariba/SP. Pergunta: Estou portando uma aplicação escrita em Delphi 7 para Delphi 2005 (Win32) e utilizo o Rave Reports como gerador de relatórios. No Delphi 7, eu configurei através do RvSystem para que a visualização do relatório ficasse em tela maximizada, contudo, ao compilar a aplicação no Delphi 2005 esta configuração foi ignorada e a visualização não fica maximizada. Como resolver? Resposta: Estivemos realizando testes e detectamos que para a visualização no Rave Reports (Delphi 2005) funcionar corretamente é necessário ajustar as seguintes propriedades no componentes RvSystem: 1. adicione um componente RvSystem Pergunta: Utilizo um componente DataGrid em uma aplicação ASP.NET escrita em Delphi 8 e gostaria que ao clicar em um template button que tem a função de apagar o registro, efetivar esta exclusão. Como fazer? Resposta: Quando o usuário clicar no botão ‘excluir’ em seu DataGrid será acionado o evento DeleteCommand e neste evento você poderá adicionar instruções para excluir o registro, veja o código a seguir: procedure TWebForm1.DataGrid1_DeleteCommand(source: System.Object; e: System.Web.UI.WebControls.DataGridCommandEventArgs); begin with BdpDataAdapter1 do begin DeleteCommand.Connection.Open; DeleteCommand.Parameters[0].Value := DataTable1.Rows[e.Item.DataSetIndex] [‘name’].ToString(); DeleteCommand.ExecuteNonQuery; DeleteCommand.Connection.Close; end; DataTable1.Rows[e.Item.DataSetIndex].Delete(); DataTable1.AcceptChanges(); DataGrid1.DataBind; end; Ou ainda, trabalhar diretamente com o DataTable: DataTable1.Rows[e.Item.DataSetIndex].Delete(); BdpDataAdapter1.Update(DataTable1); DataGrid1.DataBind; Dúvida enviada por Cial Informática Ltda, Cruzeiro/SP. 31