editorial · um novo componente adicionado no delphi 2005 chamado ... e “orientação a objeto...

32

Upload: dodieu

Post on 12-Dec-2018

261 views

Category:

Documents


2 download

TRANSCRIPT

3

THE CLUBAv. Profº Celso Ferreira da Silva, 190

Jd. Europa - Avaré - SP - CEP 18.707-150Informações: (14) 3732-3689

Suporte: (14) 3733-1588 - Fax: (14) 3732-0987

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected]

Informações: [email protected]

DúvidasCorrespondência ou fax com dúvidas devem

ser enviados ao - THE CLUB, indicando"Suporte".

OpiniãoSe você quer dar a sua opinião sobre o clube

em geral, mande a sua correspondência para aseção "Tire sua dúvida".

ReproduçãoA utilização, reprodução, apropriação,

armazenamento em banco de dados, sobqualquer forma ou meio, de textos, fotos e

outras criações intelectuais em cada publicaçãoda revista “The Club Megazine” são

terminantemente proibidos sem autorizaçãoescrita dos titulares dos direitos autorais.

Impressão e acabamento:GRAFILAR

Tel.: (14) 3841-2587 - Fax: (14) 3841-3346Rua Cel. Amando Simôes, 779

Cep 18.650-000 - São Manuel - SPTiragem: 5.000 exemplares

Copyright The Club Megazine 2005

Diretor - PresidenteCelso Jefferson M. Paganelli

Diretor TécnicoMauro Sant’Anna

ColaboradoresFabio Camara, Marcelo Nogueira, Mário

Camilo Bohm,Victory Fernandes

EDITORIAL

Editorial

Editorial .................................................................................. 03Do Basic ao .NET - Uma revisão literária .............................. 04Utilizando VS .NET com “Data Provider” Oracle .................... 06MessageBoxes Avançados .................................................... 09Moda ou .NET?....................................................................... 12Usando RTTI no Delphi .......................................................... 14Delphi 2005 - Criando um grupo de botões por categoria ...... 16Criando Formulários .............................................................. 18Dicas & Truques .................................................................... 20Perguntas & Respostas ......................................................... 26Delphi é marca registrada da Borland International,

as demais marcas citadas são registradaspelos seus respectivos proprietários.

Olá amigos,

Primeiramente, gostaria de agradecer a participação massiva em nossa pesquisa,agora, estamos tabulando os dados e com base na sua opinião poderemos estarmelhorando nossos produtos e serviços, deixando-os cada vez mais a sua cara. E paravocê que ainda não participou, não sinta-se excluído e acesse agora mesmo nosso site,www.theclub.com.br e envie sua opinião.

Começamos esta edição com um artigo do nosso amigo Fábio Câmara, figura muitoconhecida na comunidade Delphi e também .NET pelos seus diversos livros voltados naárea e em seu artigo ele faz uma reflexão da evolução das linguagens de programaçãoaté os dias atuais e também traz um artigo sobre a polêmica do momento: devo usar.NET ou isso é somente um modismo? Ainda falando em .NET, nosso amigo Mário daBohm Soluções continua com sua série de artigos demonstrando a integração do Oraclecom o Microsoft Visual Studio .NET, lembrando que estes mesmos conceitos podem seraplicados ao Delphi 2005.

Victory Fernandes, neste mês traz um artigo bastante interessante sobre caixas demensagens, demonstrando como é possível adicionar mais funcionalidades a mesma,não deixe de conferir e adicionar estas dicas em sua aplicação.

Nosso consultor Claudinei Rodrigues em seu artigo demonstra como você poderáimplementar algumas rotinas genéricas utilizando a informação em tempo de execução,ou seja, a RTTI. Nosso consultor Alessandro Ferreira em seu primeiro artigo apresentaum novo componente adicionado no Delphi 2005 chamado CategoryButtons. Atravésdeste componente é possível implementar uma tool pallete semelhante a do próprioDelphi 2005. Em seu segundo artigo faz uma pequena explanação sobre a criação deformulários no Delphi.

E para finalizar, trazemos nossas consagradas sessões Dicas & Truques ePerguntas & Respostas, compartilhando com você um pouco do que foi solicitado aosnossos consultores neste último mês.

Abraço e sucesso à todos,

4

.NET

Aprender a programar é uma aventura gratificante nestestempos de Internet. Praticamente tudo que precisamos é um bommecanismo de buscas e entrar em alguns grupos de discussão.

Já participo de grupos de discussões há alguns bons anos.Ultimamente até, auto-crítica, não tenho disponibilizado tempocomo deveria para responder e participar destes grupos, masconfesso publicamente o quanto estes grupos foram importantespara minha formação prática como desenvolvedor.

Um dos grandes mistérios acerca deste tópico é se os livrosimpressos irão, ou não, sobreviver a disputa com as informaçõesgratuitas da Internet. Esse tópico também abrange revistas ejornais.

Mesmo com esta polêmica questão, ainda é possível observarem grupos de discussão ou em e-mails que recebo diretamentepessoas solicitando indicações de livros sobre linguagens deprogramação e ferramentas de desenvolvimento.

Com o saudosismo de realizar uma revisão históricafuncional, pretendo comentar nas linhas abaixo os grandes livrosque contribuíram para a consolidação de meus conceitos sobreprogramação, projetos e tecnologias.

Para uma proposta realmente útil, não seria fiel de minhaparte comentar sobre livros de Basic e Cobol que passaram porminha “cabeceira” entre 1984 e 1992. Quero começar esteconjunto literário dentro de uma faixa de 10 anos.

Trabalharemos um universo compreendido entre 1994 e

2004.O escolhido para iniciar nossa avaliação retórica escrita é o

título “Delphi – Kit do Explorador”. Em minha primeira leitura,não entendi quase nada mas achei engraçado o estilo do autor emcontar histórias em um livro técnico. De certa forma, isso depoisveio marcar meu estilo de escrever.

Precisei passar antes por uns livros básicos do tipo passo apasso, escritos pela Adelize Generini, para voltar e entender comoesta obra era valiosa. Como nada acontece por acaso, poucos anosdepois fui convidado para escrever para a editora que lançava oslivros da Adelize – porém isso é outra história.

O livro perde pontos no quesito tradução, entretanto depoispercebi que era melhor não classificar livros neste quesito – amaioria das traduções são péssimas até hoje.

Nesta época eu “comia livros com farinha”, comprei muitos,não consegui ler todos e nenhum me chamou tanto a atençãocomo o título “Delphi 3 – High Performance”, lançado depois noBrasil como “Programando Delphi 3 – Técnicas Avançadas”.

Neste livro senti um “puxão de orelhas” do Don Taylor e JimMischel me mostrando que eu ainda precisava aprender muitosobre Delphi.

Eu atravessava uma fase técnica bem estável e deixei-meentrar na perigosa “zona de conforto”.

O livro trata assuntos que você não precisa saber paraaplicações comerciais, porém seu conteúdo é muito rico se você

Do Basic ao .NETDo Basic ao .NETDo Basic ao .NETDo Basic ao .NETDo Basic ao .NETUma revisão literáriaUma revisão literáriaUma revisão literáriaUma revisão literáriaUma revisão literária

Por Fabio Camara

5

.NET

deseja se destacar como um especialista na linguagem e naferramenta.

Com este novo posicionamento de minha carreira, escrevi umcapítulo extremamente original e prazeroso no livro “Delphi, API’se Sockets”.

O capítulo 8 possui diversas soluções para problemasavançados contadas em forma de “casos engraçados”.Nitidamente influenciado por Sérgio Porto e Carlos EduardoNovaes, misturei sátiras ao tecnicismo proporcionando umaleitura curiosa e inédita.

O livro “Delphi 4 Unleashed” desfilava comigo em todas asviagens de meu trabalho da época. Com uma capa bonita, muitaspáginas e uma imagem de livro avançado, foi por algum tempouma espécie de bíblia para mim. Não cheguei a lercompletamente, mas pratiquei muitas de suas apresentaçõestécnica em meus programas.

Com o livro “Delphi 5 – Guia do Desenvolvedor”, adicionei doisnovos gurus a minha seleta lista. Um livro extremamenteprático, direto, com um texto “leve” e de fácil compreensão, fuiplenamente cativado.

Em minha lista de gurus estavam nesta época: AndersHejlberg, Tom Swan, Don Taylor, Charles Calvert, Steve Teixerae Xavier Pacheco.

Movido pela necessidade de trabalhar com a Web eadaptando-me aos meus desafios novos impostos por umgigantesco projeto – comecei a estudar Windows DNA.

Sem a menor sombra de dúvida, o livro “Soluções baseadasem componentes” da Mary Kirtland é um épico. Nesta fase deminha vida comecei a exercer cargos mais gerenciais e encontreineste livro um forte aliado a problemas com gestão de projetos.

O fruto destes estudos estão espalhados desordenadamenteno livro “Projetos com Windows DNA e .NET”. Esta obra possuicapítulos que considero incríveis e outros nem tanto, mas tenhoorgulho do resultado final.

É diferente você mesmo ler seu livro depois do repetidotrabalho de leitura e revisão na fase de lançamento, contudo járeli depois de impresso pelo menos umas quatro vezes.

Sobre o autorFabio Camara, MCP, MCSA, MCAD Charter, MCDBA e

MCSD.NET – É Diretor da Architettura Soluções emTecnologia. Escreveu os livros “Projetos com WindowsDNA e .NET”, “Dominando o Visual Studio.NET com C#”e “Orientação a Objeto com .NET” dentre outros.

Neste livro percebesse uma forte influência do professorAntonio Meneghetti, famoso italiano que escreve sobre liderançae relações humanas – assunto que venho estudando com afinco.

Voltado a aprender mais sobre gestão de projetos, encontreiconceitos muito práticos e funcionais nos livros “Code Complete” e“Rapid Development” do Steve McConnell e estudeiprofundamente MSF – Microsoft Solutions Framework. Estesconceitos adquiridos nesta época regem até hoje todos os meusdesafios técnicos.

Mesmo não atuando mais como programador, vi no .NETuma oportunidade ímpar de renovar muitos conceitos, quebrarparadigmas e me posicionar melhor no mercado de trabalho.

Aproveitando uma entressafra de projetos na empresa emque trabalhava, dediquei como nunca antes 3 meses inteirossomente de estudos, testes com códigos e provas de certificação. Lidiversos livros, os marcantes foram: “C# Essentials” e“Apresentando C#”.

Depois de tantos livros, não acreditava mais em surpresaspositivas até encontrar o título “C# for Experienced Program-mers” da Deitel.

Simplesmente fabuloso, destacando o tempo todo dicas emacetes, apresentando de forma simples – porém completa – osmais importantes tópicos para você desenvolver com estamagnífica linguagem de programação. Saudavelmente invejoeste livro como uma realização que ainda devo alcançar.

Concluindo, vejo o objetivo de permitir que outrosdesenvolvedores trilhem por um caminho que considero positivoliterariamente, se assim desejarem, alcançado nestas linhasescritas com transparência e satisfação.

Como 10 anos passam rápido...

6

Oracle

Utilizando VS .NET comUtilizando VS .NET comUtilizando VS .NET comUtilizando VS .NET comUtilizando VS .NET com“Data Provider” Oracle...“Data Provider” Oracle...“Data Provider” Oracle...“Data Provider” Oracle...“Data Provider” Oracle...

Como foi apresentado no artigo anterior, o ORACLE DEVEL-OPER TOOLS FOR VISUAL STUDIO.NET oferece diversasferramentas para o dia-a-dia do desenvolvedor, trazendo paradentro do Visual Studio todo o poder do Oracle, e pode serencontrado em:

http://www.oracle.com/technology/tech/dotnet/index.htmlNeste artigo veremos algumas das principais funcionalidades

desta poderosa ferramenta.

Conexão com o OracleCom o Oracle Developer Tools for Visual Studio.Net instalado,

o primeiro passo para podermos trabalhar com o Oracle sem sairdo Visual Studio.Net é criarmos uma conexão, para isto no menuView selecione Oracle Explorer.

Clique no sinal de “+” para adicionar uma nova conexão:

clique no botão “Test connection”.

Pronto, uma vez conectado já podemos criar e visualizartabelas, editar relacionamentos, criar procedures e muito mais, etudo isto sem sair do ambiente do Visual Studio.Net.

Criando TabelasPara criar uma tabela basta selecionar a opção Tables na

base de dados conectada e em seguida New Relational Table

Será aberto um assistente que solicitará o DataSource,UserName e Password, após fornecer estes dados vocêpoderá testar se a conexão foi efetuada com sucesso, para isto

Sobre o autorMário Camilo Bohm - Bohm Soluções [email protected] - www.bohm.com.br

Parte 2 - Utilizando o Oracle Developer tools for .NetParte 2 - Utilizando o Oracle Developer tools for .NetParte 2 - Utilizando o Oracle Developer tools for .NetParte 2 - Utilizando o Oracle Developer tools for .NetParte 2 - Utilizando o Oracle Developer tools for .Net

7

Oracle

Será aberto um assistente que permite editar as colunas databela, criar índices e Constraints além de outras opções

Para visualizar e editar os dados das tabelasclique com o botão direito sobre ela e selecione aopção Retreive Data

Como pode ser visto, a partir deste mesmo menu também épossível alterar a estrutura da Tabela selecionando Design e atéadicionar uma Trigger .

Stored Procedures

A criação e execução de Stored Procedures também pode serrealizada diretamente do Oracle Explorer no Visual Studio.Net , oassistente é bastante simples e permite que visualmente se editeos parâmetros de entrada e saída da procedure entre outrasfacilidades.

8

Oracle

Para executar uma Procedure clique em Run no menuacionado com o botão direito sobre o seu nome e forneça osparametros.

Editor de PL/SQLPara quem prefere criar ou editar manualmente os objetos da

Base de Dados a ferramenta também disponibiliza um editor dePL/SQL totalmente integrado com o Visual Studio.Net.

Conclusão

Neste artigo vimos como manipular o Oracle sem sair doVisual Studio.Net, usando o que a Microsoft e a Oracle tem demelhor, e tudo em um único ambiente.

No endereço:http://www.oracle.com/technology/docs/tech/windows/odpnet/index.html vocêtem acesso a muita documentação à respeito dessas ferramentas.

9

Delphi

MessageBoxes AvançadosMessageBoxes AvançadosMessageBoxes AvançadosMessageBoxes AvançadosMessageBoxes AvançadosPor Victory Fernandes

Cite um programa que não use caixas de mensagem? Caixasde mensagem são uma das funcionalidades mais comuns nodesenvolvimento de aplicativos. São tão usados que existemdiversos aplicativos que implementam uma interface visual paraa rápida geração do código da caixa de mensagem com base naseleção do usuário, conforme mostrado na Figura 01.

Figura 01: Aplicativo de geração automática de código paracaixas de mensagem

Ao clicar o botão Ok na tela mostrada na Figura 01 o seguintecódigo é gerado automaticamente:

MessageDlg(‘Teste de Caixa de Mensagem’,mtWarning, [mbYes,mbNo], 0);

Caso não esteja familiarizado com o código gerado, antes deseguir para as avançadas de geração de caixas de mensagem,vale revisar as principais funções e parâmetros de geração decaixas de mensagem no Delphi.

procedure ShowMessage(const Msg: string);

Função mais comum para geração de caixas de mensagem.Contém apenas um parâmetro de entrada que é a mensagem aser apresentada ao usuário, juntamente com o botão Ok.

function MessageDlg(const Msg: string;DlgType: TMsgDlgType; Buttons:TMsgDlgButtons; HelpCtx: Longint): Word;

Função para apresentação de mensagens e obtenção deresposta do usuário. Possui uma série de parâmetros de entrada,são eles:

Msg – Mensagem a ser apresentada ao usuário

DlgType – Descreve o tipo de mensagem apresentada, e podeassumir os seguintes valores:

type TMsgDlgType = (mtWarning, mtError,mtInformation, mtConfirmation, mtCustom);

Buttons – Indica quais botões devem aparecer na caixa demensagem, e pode assumir os seguintes valores:

type TMsgDlgBtn = (mbYes, mbNo, mbOK,mbCancel, mbAbort, mbRetry, mbIgnore, mbAll,mbNoToAll, mbYesToAll, mbHelp);

function MessageBox(const Text, Caption:PChar; Flags: Longint = MB_OK): Integer;

Bastante semelhante à função anterior, a função MessageBoxpermite também a definição do título da janela de mensagem.

O parâmetro Flags define os tipos de botões e ocomportamento da tela podendo assumir os seguintes valores:

MB_ABORTRETRYIGNORE, MB_OK, MB_OKCANCEL,MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL

10

Delphi

A função MessageBox retorna os seguintes valores:

IDOK, IDCANCEL, IDABORT, IDRETRY, IDIGNORE,IDYES, IDNO

A questão é que todos nós estamos acostumados às caixas demensagem padrões e provavelmente a maioria dos leitores jáconheciam as funções apresentadas anteriormente, quedisponibilizam poucos recursos visuais necessários em algumasaplicações específicas.

Neste artigo apresentamos algumas abordagens parageração de caixas de mensagens avançadas, contendo checkboxes,timers e etc.

Timeout MessageBoxEm algumas aplicações é preciso apresentar uma caixa de

mensagem que feche automaticamente após um determinadotempo. Para fazer esta implementação podemos utilizar umafunção não documentada da API localizada na user32.dll, a funçãoMessageBoxTimeout.

A função retorna um valor inteiro que pode ser igual aMB_TIMEDOUT (indica que o tempo determinado paraapresentação da mensagem foi atingido e a mesma fechouautomaticamente) ou o valor irá representar a botão clicado pelousuário.

Para fazer o teste crie um novo projeto e adicione o seguintecódigo à seção interface do mesmo:

//interface declarationconst MB_TIMEDOUT = 32000;function MessageBoxTimeOut(hWnd: HWND;lpText: PChar; lpCaption: PChar; uType: UINT;wLanguageId: WORD; dwMilliseconds: DWORD):Integer; stdcall; external user32 name‘MessageBoxTimeoutA’;Adicione um TButton ao formulário e digite oseguinte código no evento OnClick do mesmo:procedure TForm1.Button1Click(Sender:TObject) ;var iRet: Integer; iFlags: Integer;begin iFlags := MB_OK or MB_SETFOREGROUND orMB_SYSTEMMODAL or MB_ICONINFORMATION; MessageBoxTimeout(Application.Handle,‘Timeout em 2 segundos’, ‘ FunçãoMessageBoxTimeout ‘, iFlags, 0, 2000) ;

iFlags := MB_YESNO or MB_SETFOREGROUND orMB_SYSTEMMODAL or MB_ICONINFORMATION; iRet :=MessageBoxTimeout(Application.Handle, ‘Timeouem 5 segundos’, ‘Função MessageBoxTimeout’,iFlags, 0, 5000) ; case iRet of IDYES: ShowMessage(‘Sim clicado’) ; IDNO: ShowMessage(‘Não clicado’) ; MB_TIMEDOUT: ShowMessage(‘Tempo expirou’) ; end;end;

Após a execução do código o resultado são dois MessagesBoxes, oprimeiro expira em 2 segundos e o segundo em 5 segundos.

MessageBoxes customizadosPara aplicações específicas é possível se criar MessageBoxes

customizados adicionando tantos quantos componentes foremnecessários. Para isso utilizamos um TForm criado em tempo deexecução através do uso da função CreateMessageDialog, eadicionamos os componentes desejados bem como sua formataçãoconforme o código a seguir:

procedure TForm1.Button1Click(Sender:TObject);Var AMsgDialog: TForm; ACheckBox: TCheckBox;begin AMsgDialog := CreateMessageDialog(‘Minhamensagem de teste’, mtWarning, [mbYes,mbNo]); ACheckBox := TCheckBox.Create(AMsgDialog); with AMsgDialog do try Caption := ‘Titulo da Mensagem’ ; Height := 169; With ACheckBox do begin Parent := AMsgDialog; Caption := ‘Meu CheckBox de teste’; top := 121; Left := 8; Width := 145; font.color := clred; end;

11

Delphi

Case ShowModal of ID_YES: ;//seu código depois do clique em Sim vem aqui ID_NO: ;//seu código depois do clique em Não vem aqui end; If ACheckBox.Checked then begin//seu código caso o checkbox tenha sidoclicado vem aqui end; finally ACheckBox.Free; Free; end;

end;

O resultado da execução do código anterior é uma caixa demensagem conforme a Figura 02. Note que nela foi adicionada umTCheckbox na cor vermelha, e o código anterior também permite adetecção de quais botões foram clicados e se o checkbox foi ou nãomarcado.

Figura 02: Caixa de mensagem customizada

Agora é possível incrementar seus programas com caixas demensagens customizadas para cada tipo de aplicação, com adiçãode diversos componentes além de formatação das propriedadesdos mesmos.

Sobre o autorVictory Fernandes é Engenheiro Mestrando em Redesde Computadores, e desenvolvedor sócio da TKSSoftware - Soluções de Automação e SoftwaresDedicados. Pode ser contatado [email protected], ou através dos siteswww.igara.com.br - www.victory.hpg.com.br

12

.NET

Eu gostaria de fazer uma pequena reflexão. Você se lembradas primeiras declarações sobre a Internet?Não se preocupe,nãoserei repetitivo. Você já deve ter lido várias reportagens oumatérias sobre este assunto.

Minha abordagem é mais direta. Quantos anos têm alinguagem de programação mais nova disponível?Compare suaidade com a idade da compreensão dos negócios que se podeconstruir com a Internet.

—Matematicamente”,temos uma boa diferença.

Esta é a reflexão necessária para correta análise da proposta.NET. Em outras palavras,todas as oportunidades de soluções

baseadas em Internet são novas,algumas até não plenamentecompreendidas,e este fato por si já justifica —com folga” anecessidade de uma nova linguagem, solução,ou melhor,um novoFramework!

Naturalmente —encarar” novos desafios assusta a maioriados técnicos experientes. Quebrar paradigmas é uma ação dignade seções em consultórios psicológicos,desde que você já tenhaquebrado o paradigma que psicólogos não trabalham com —malucos”.

Entretanto,quando se é mais jovem em experiênciastécnicas,o medo do novo se transforma em oportunidade. Ojulgamento de ter pouca —coisa a arriscar e perder,move commais intensidade os técnicos mais jovens ao encontro dos novosdesafios. Este comportamento é classificado erroneamente como—fanatismo por novas tecnologias”. Esta classificação em parte éoriunda do comportamento mercadológico em adotar ou não

uma nova tecnologia. Seria como uma espécie de —modatecnológica, algumas —pegam e dão muito certo e outras nãoultrapassam a empolgação de alguns fanáticos.

O conceito sobre moda,compreendido no trecho anterior,definitivamente não se aplica ao .NET.

Mesmo contra sua argumentação que o .NET é muito novo epossivelmente ainda não —pegou”,não se faz necessário possuirdotes visionários para separar os modismos tecnológicos daproposta da Microsoft para a estratégia .NET.

Se realmente entendemos o por quê da resistência a novastecnologias dos profissionais mais experientes e tambémcompreendemos o por quê de jovens especialistas adotarem commais facilidade novas tecnologias,aonde esta a frase mágica?

Simples!O.NETnão esta baseado em novas propostas desoluções para velhos problemas. A proposta .NET é resolver novosproblemas com soluções exatas,realmente projetadas para estesproblemas,que em sua maioria nasceram a partir das novasoportunidades de negócios da Internet.

Em face desta afirmação fica fácil concluir que o .NETnão éenão será um modismo tecnológico.

Não se preocupe com a informação de não existe muitosprofissionais disponíveis com experiência em .NET nomercado,este argumento inclusive reforça a afirmativa a respeitode modismo, pois não estamos observando um movimentofanático em que os profissionais autônomos migram para atecnologia e depois as empresas de tecnologia acompanham amigração.

Moda ou .NET?Moda ou .NET?Moda ou .NET?Moda ou .NET?Moda ou .NET?Por Fabio Camara

13

.NET

O que claramente observamos hoje é que as grandescompanhias estão construindo suas novas soluções com o .NET,independentemente do movimento dos profissionais autônomos.

Em outras palavras,diferentemente de como funcionou coma maioria das linguagens de programação,o .NETesta seconsolidando de cima para baixo,ou seja,das grandes companhiaspara os profissionais autônomos.

Em análise ao comportamento de conquista do .NET, serádifícil prever as famosas leis de mercado?Quando a demandaémaior que a oferta,os primeiros desenvolvedores serão bemremunerados e isso rapidamente vai alertar todo o mercado detécnicos em programação. Conclusão:Todos desejarão trabalharcom .NET.

Tratando de contextos mais técnicos, é neste quesito queencontramos muito mais afirmações a respeito da solidez do.NETcomo proposta tecnológica.

Imagino que sua empresa ainda possui aplicativos tipo —middleware” que provêem integrações baseadas em arquivostexto posicionais. E se sua necessidade de integração entreaplicativos ultrapassar os limites de sua rede LAN?

Não se esforce muito para responder esta pergunta,pois nãoencontrarás uma resposta que implemente segurança.

Novamente,qual a palavra mágica?WebServices!Sim,umaimplementação fácil de integração baseada em http e XML. Isso éque se chama de solução nova para problema novo.

No escopo do novo,pense comparativamente qual o temponecessário para implementação de uma página de negócios Web ede um formulário Windows Forms na arquitetura cliente /servidor. Considerando-se as funcionalidades idênticas para osdois desenvolvimentos,chegamos as seguintes conclusões:

1 -É muito mais rápido desenvolver Windows Forms emcomparação a Web Forms.

2 -Mesmo com um esforço insano na construção do WebForm,o formulário Windows proverá muito mais funcionalidades.

3 -Mesmo com mais esforço insano ainda, será muito maisfácil na perspectiva de um usuário utilizar o formulário no

Padrão Windows do que a página Web.Não desejando me alongar demais,então por quê muitas

direções de desenvolvimento optam por desenvolvimento desoluções baseadas em páginas Web?

Podem existir diversas razões,talvez a mais usual seja afacilidade de distribuição nas estações clientes,visto que com estaarquitetura não é necessário instalar nada localmente nasestações para que seja possível executar a solução.

Avaliando a questão sob esta ótica, configuramos um novoproblema:Como desenvolver soluções de forma tão fácil e rápidacomo é com Windows Forms e com as vantagens de distribuiçãoWeb Forms?

Mais uma vez o .NETfoi projetado pensando nisso. Problemasnovos,soluções novas. Apalavra mágica éSmart Client.

Uma solução baseada na arquitetura Smart Client é umasolução implementada com Windows Forms (semelhante àarquitetura Cliente / Servidor)distribuída pela Internet atravésdo browser Internet Explorer existente na estação cliente.Éfascinante desenhar uma solução baseada em Smart Client.

Agora me ocorreu um pensamento. Será que você irá acharque Smart Client éum modismo tecnológico? Seja lá o que estaspensando,o .NET apresentou uma nova solução para um novoproblema que talvez você nem tivesse percebido que ele existia.

E com foco no tema novos problemas,qual o comportamentode sua tecnologia atual para soluções em Mobile Devices?Seráquesua tecnologia consegue interagir com Pocket PC?

Será que o seu aplicativo é capaz de funcionar em dispositivoscom o sistema operacional Windows CE?

Todas estas respostas são positivas se você utiliza soluçõesbaseadas em Smart Devices do Visual Studio .NET2003. Tãosimples como a palavra simples é pronunciada.

Conclusivamente, por mais que seja assustador para vocêpensar em Web Services,Smart Client e Smart Devices,entendaque naturalmente você necessitará resolver problemas em queestas são as soluções mais adequadas. Será que estes problemassão modismos?

Sobre o autorFabio Camara, MCP, MCSA, MCAD Charter, MCDBA e

MCSD.NET – É Diretor da Architettura Soluções emTecnologia. Escreveu os livros “Projetos com WindowsDNA e .NET”, “Dominando o Visual Studio.NET com C#”e “Orientação a Objeto com .NET” dentre outros.

14

Delphi

O Runtime Type Information (RTTI) ou Informações de Tipoem Tempo de Execução é um recurso que o Delphi traz e muitosprogramadores ainda não o conhecem por causa da falta dedocumentação existente sobre o assunto. Com o Runtime TypeInformation (RTTI) nós podemos obter a informação sobre umtipo de dado de um objeto que está gravado na memória emtempo de execução.

O RTTI fornece um caminho para determinar se um tipo deobjeto é de uma classe em particular ou de seus descendentes. Osoperadores is e as normalmente utilizados no Delphi, contam coma presença de alguma forma de RTTI. O operador is, o qualexecuta uma verificação de tipo dinâmica, é usado para verificarem tempo de execução a classe de um objeto. O operador asexecuta uma verificação de typecasts. No Delphi 7 e no Delphi2005 a unit typinfo define tipos, classes e objetos que você usaquando for trabalhar com RTTI.

O ambiente de desenvolvimento do Delphi nos permitedesenhar forms que são usados em nossos programasvisualmente. Ele armazena as informações dentro de um arquivobinário com a extensão .DFM. Neste arquivo são incluídos ostipos de todos os componentes incluídos no formulário e tambémos nomes e valores de todas as propriedades do componente. Emtempo de execução o arquivo do .DFM que foi transformado emum recurso em seu executável no momento da compilação é lido eseu executável cria todos os objetos

Para obter de uma string, significando o nome da classe,para um objeto criado do tipo exigido você vai precisar do RTTI.Além disso, para gravar os valores das propriedades nomeadasnos objetos criados, tendo em mente que eles podem ser de muitostipos, também requer RTTI.

Exemplos de RTTIVeja no exemplo da listagem 1 a utilização do RTTI. Neste

exemplo é mostrado como obter a origem de um componenteusando as propriedades ClassType e ClassParent. Neste exemplo

nós utilizamos um componente Button e um componenteListBox. Quando você clicar no botão o nome da classe do botão eos nomes das classes parentes serão adicionadas no ListBox.

procedure TForm1.Button1Click(Sender: TObject);

var ClassRef: TClass;begin ListBox1.Clear; ClassRef := Sender.ClassType; while ClassRef <> nil do begin ListBox1.Items.Add(ClassRef.ClassName) ; ClassRef := ClassRef.ClassParent; end;end;

Listagem 1: Obtendo a origem

Vamos ver agora na listagem 2 como executar uma proce-dure ou função através do seu nome.

private { Private declarations } procedure Executa(Objeto: TObject;NomeMetodo: string) ;.........var Form1: TForm1;

type TExec = procedure of object;

Implementation...

Usando o RTTI no DelphiUsando o RTTI no DelphiUsando o RTTI no DelphiUsando o RTTI no DelphiUsando o RTTI no DelphiPor Claudinei Rodrigues – [email protected]

15

Delphi

...

...procedure TForm1.Executa(Objeto: TObject;NomeMetodo: string) ;var Rotina: TMethod; Exec: TExec;begin Rotina.Data := Pointer(Objeto) ; Rotina.Code :=Objeto.MethodAddress(NomeMetodo) ; if not Assigned(Rotina.Code) then Exit; Exec := TExec(Rotina) ; Exec;end;

procedure TForm1.NossaProcedure(Sender:TObject) ;begin ShowMessage(‘THE CLUB!’) ;end;

procedure TForm1.Button2Click(Sender:TObject);begin Executa(Form1, ‘NossaProcedure’) ;end;

Listagem 2: Executando uma função ou procedure

Vamos ver na listagem 3 como podemos converter um tipoenum para string.… TProgrammerType = (tpTheClub, tpAspNet,tpDotNet) ;………procedure TForm1.Button3Click(Sender:TObject);var s : string;begin s := GetEnumName(TypeInfo(TProgrammerType),integer(tpTheClub)) ; ShowMessage(s);end;

Listagem 3: Convertendo do tipo Enum para string

Vamos ver na listagem 4 como configurar a propriedadeDataSource de diversos componentes utilizando apenas umachamada.

procedure LigaDS(Controles : array ofTControl; DS: TDataSource) ;var i: Integer; PropInfo: PPropInfo;begin for i := Low(Controles) to High(Controles)do begin PropInfo :=GetPropInfo(Controles[i].ClassInfo,

‘DataSource’) ; if Assigned(PropInfo) then SetOrdProp(Controles[i], PropInfo,LongInt(DS)) ; end;end;

// Veja a seguir como chamar este procedure:

procedure TForm1.Button4Click(Sender:TObject);begin LigaDS([DBNavigator1, DBEdit1, DBEdit2],DataSource1) ;end;

Listagem 4: Configurando a propriedade DataSource

Conclusão.Este é um recurso muito interessante que pode ajudar a

resolver certos problemas que seriam bem mais complicados deresolver de outras formas. Mas devo advertí-lo que estas técnicaspodem tornar seu código confuso e difícil de depurar. Euaconselho que se você tiver alguma alternativa que seja maissimples e objetiva, utilize-a.

Até a próxima e um grande abraço a todos.

Download em:http://www.theclub.com.br/revista/download/RTTI082005.zip

Sobre o autorClaudinei Rodrigues,Consultor Técnico do The [email protected]

16

Delphi

Delphi 2005 – Criando um grupo deDelphi 2005 – Criando um grupo deDelphi 2005 – Criando um grupo deDelphi 2005 – Criando um grupo deDelphi 2005 – Criando um grupo debotões por categoriabotões por categoriabotões por categoriabotões por categoriabotões por categoria

Conhecendo o componenteConhecendo o componenteConhecendo o componenteConhecendo o componenteConhecendo o componenteTCategoryButtonsTCategoryButtonsTCategoryButtonsTCategoryButtonsTCategoryButtons

IntroduçãoO Delphi 2005 em meio a tantas inovações, continua

possibilitando ao programador desenvolver aplicações paraambiente Win32, tendo uma versão melhorada do Delphi 7 nestepacote. Dentre estas melhorias, destacam-se inovações na IDE,na linguagem e também novos componentes.

Neste pequeno artigo irei demonstrar como construiruma barra de componentes igual a existente na IDE do Delphi2005 (Tool Pallete) utilizando o componente CategoryButtons,lembrando que este componente também está disponível paraWin32.

ProjetoCrie um novo projeto Win32 conforme sugere a figura 1.

Figura 1 – Novo propjeto Win32

Estando com o novo projeto, adicione um componenteCategoryButtons (disponível no grupo Additional). Após isso, alteresua propriedade Align para alRight e dê um duplo clique nocomponente para adicionarmos as categorias. Para este exemplo,adicione três categorias: Cadastros, Financeiro e Ferramentas,conforme sugere a figura 2.

Figura 2 – Adicionando categorias

A primeira vista o resultado ainda não é o esperado, contudo,isso é só questão de alguns cliques e teremos uma ‘Tool Pallete’igualzinha a do Delphi 2005, para isso, ajuste as seguintespropriedades abaixo:

Figura 3 – CategoryButtons

ButtonOptions

boFullSize True

boVerticalCategoryCaption False

boUsePlusMinus True

boBoldCaptions True

Realizadas estas configurações,rode a aplicação e teremos oresultado apresentado na figura 4

17

Delphi

Figura 4 – Nossa Tool Pallete.

Bem, a este ponto já temos uma barra de ferramentas (ouopções, como preferir) muito parecida com o Tool Pallete existentena IDE do Delphi 2005.

Podemos ainda incrementar a aparência adicionandoimagens à cada opção, bastando para isso adicionarmos umcomponente ImageList e a este adicione uma imagem para cadaopção.

Após adicionar as imagens, ligue o CategoryButtons aoImageList através da propriedade Imagens.

Agora, para definir uma imagem para cada opção, acesse oEditor de categorias (clique duplo no CategoryButtons), selecioneo grupo e acesse sua propriedade Items e através da propriedadeImageIndex de cada opção, escolha a imagem correspondente.Rodando o projeto, teremos um resultado parecido com a figura 5.

Figura 5 – Nossa Tool Pallete com imagens

Adicionando funcionalidade

Até o momento, apenas configuramos o visual de nossa toolpallete, contudo sem nenhuma codificação... Adicionarfuncionalidade a cada opção é muito simples e poderá ser feitobasicamente de duas maneiras.

A primeira, bastará acessar o Editor de categorias (duploclique no CategoryButtons), selecionar o grupo, acessar suapropriedade Items, selecionar a opção e programar seu eventoOnClick, veja a figura 6.

A segunda forma seria utilizar o componente ActionListdefinindo ações através do mesmo e ligar a propriedade Action daopção diretamente a uma ação pré-definida no ActionList(componente este existente no Delphi há um bom tempo).

Conclusão

O componente CategoryButtons permite ao desenvolvedorimplementar um novo conceito de interface com o usuário, sendoeste bastante simples e intuitivo, além ainda de ser muito bonito.

Demonstrei aqui um exemplo muitíssimo simples, contudoeste componente possui várias propriedades que permitem outroslayouts para o CategoryButtons.

Um abraço, sucesso à todos,

DownloadO projeto de exemplo apresentado neste artigo está disponível

para download em http://www.theclub.com.br/revista/downloads/CatButtons.zip

Sobre o autorAlessandro Ferreira,Consultor Técnico do The [email protected]

Figura 6 – Evento OnClick do item

18

Delphi

IntroduçãoQuando criamos um objeto dinamicamente no Delphi, seja

um objeto herdado de um TControl, ou seja um TForm (querepresenta um formulário/janela em aplicações Delphi), oconstrutor destes objetos espera um parâmetro informando‘quem’ é o ‘proprietário’ do objeto à ser criado. Você já deve tervisto em muitos casos a utilização de nil, self e application sendoutilizados como parâmetro, contudo qual você deveria estarutilizando? Pois bem, é isso que tentarei explicar de formabastante simples neste artigo.

Como funciona...Suponha que você tem um formulário TMeuForm em uma

aplicação e você quer instanciar o mesmo em modo de execução. Aclasse TForm possui um construtor que cria e inicializa um novoobjeto TForm (ou descendente):

constructor Create(AOwner: TComponent) ;

O parâmetro AOwner é o proprietário do objetoT(Custom)Form. O proprietário do formulário é o responsável emliberar a memória que foi alocada pelo form no ato de sua criação,além ainda, dos componentes existentes sobre o mesmo.Outrodetalhe importante, é que o formulário será destruídoautomaticamente quando seu proprietário for destruído, sendoeste um aspecto muito importante à ser observado. Sendo assim,o que você deve utilizar como proprietário do seu formulário, nil,self ou application? Para um melhor entendimento, primeiro vocêdeverá saber o significado de cada uma delas.

Nil:Especifica que nenhum objeto é proprietário do formulário, e

então, o programador (você) é responsável em liberar a memóriaalocada para o referido formulário, chamado explicitamente ométodo free do mesmo.

Self:Especifica que o objeto que está criando o formulário é o

proprietário do mesmo. Por exemplo, se você está criando umanova instância de um formulário TMeuForm dentro do eventoOnClick de um botão (onde este botão está sobre um formulário)ou em um ítem de menu qualquer que hipoteticamente estejamem seu MainForm, passando self estará passando informando aonovo formulário que seu proprietário é o MainForm e dessa

Criando FormuláriosCriando FormuláriosCriando FormuláriosCriando FormuláriosCriando FormuláriosEntenda as diferenças entre nil, self e applicationEntenda as diferenças entre nil, self e applicationEntenda as diferenças entre nil, self e applicationEntenda as diferenças entre nil, self e applicationEntenda as diferenças entre nil, self e application

Por Alessandro Ferreira, [email protected]

forma, quando destruir o MainForm automaticamente todos osformulários que o tiverem como proprietário serão liberados.

Application:Especifica a variável global TApplication que é criada quando

você executa/carrega sua aplicação. “Application” encapsula suaaplicação, além de prover acesso a muitas funções que ocorremem background durante a execução da aplicação.

Exemplos- Formulários modais (ShowModal):Ao criar um formulário à ser exibido como modal e que será

destruído logo quando o usuário fechar o mesmo, você poderáutilizar “nil” como proprietário deste form:

var myForm : TMyForm;begin myForm := TMyForm.Create(nil) ; try myForm.ShowModal; finally myForm.Free; end;end;

- Formulários “Modeless” (Show):Nestes casos, você poderá utilizar “Application” como

proprietário do novo form:

var myForm : TMyForm;... myForm := TMyForm.Create(Application) ;

Com isso, quando você finalizar sua aplicação (sair damesma), o objeto “Application” irá liberar todos os formulários aoqual é proprietário.

- Quando usar “Self”?Se o formulário que você necessita criar não for modal e não

for criado a partir do formulário principal da aplicação e vocêutilizar self com proprietário, no momento que você fechar oformulário proprietário automaticamente estará liberando o form

19

Delphi

que foi instanciado da memória.

Em geral, ao criar instâncias de novos formulários, você nãodeveria utilizar self e sim, utilizar “nil” ou “application” (modal/modeless). “Self” deve ser utilizando quando você quiser que aofechar o formulário proprietário, qualquer outro formulário quepossua este proprietário seja destruído automaticamente com ele.No caso de formulários que devam ficar instanciados durante ociclo de vida da aplicação, utilize “nil” ou “application”.

Contudo, toda regra tem sua exceção, e no caso do self, mais euma exceção! Por exemplo, existem situações onde você podenecessitar saber qual formulário criou/chamou determinadoform e nestes casos torna-se interessante passar self comoproprietário, pois com isso poderemos facilmente saber ‘quemcriou/chamou’ o referido form simplesmente analisando suapropriedade Owner:

if (Owner <> nil) then ShowMessage(‘Fui chamado por: ‘ +Owner.Name);

Outra exceção a regra: Supondo que todos os seusformulários sejam chamados a partir de seu MainForm(formulário principal da aplicação) e você passar self comoproprietário dos mesmos, não terá problema algum, pois, aofechar o MainForm automaticamente estará encerrando aaplicação que por sua vez irá liberar todos os formuláriosinstanciados pelo MainForm.

Como destruir meus formulários?A forma que iremos liberar nossos formulários da memória

está ligada diretamente a forma que efetuamos a chamada domesmo. Por exemplo, quando efetuamos a chamada de umformulário como modal (através do método ShowModal)costumeiramente logo após a execução do mesmo iremos chamaro método free caso desejemos liberá-lo da memória:

var myForm : TMyForm;begin myForm := TMyForm.Create(nil) ; try myForm.ShowModal; finally myForm.Free; end;end;

Já no caso de chamadas “não-modais” (através do métodoShow) muito comum em aplicações MDI não podemos chamar ométodo free logo abaixo, visto que chamadas “não-modais” nãoaguardam a execução e o free seria executado imediatamente ecom isso o formulário nem seria apresentado.

Neste caso, considerando a chamada via método Show (não-modal), o evento OnClose provê um parâmetro de ação (do tipoTCloseAction) que você pode utilizar para especificar o que iráacontecer quando o usuário tentar fechar o formulário, onde, sevocê especificar “Action := caFree;” automaticamente irá liberar oformulário da memória.

Obs: em aplicações de SDI, quando o usuário fecha oformulário (clicando no botão [x]) o formulário ainda permaneceem memória, ou seja, ele é apenas escondido. Em aplicações deMDI, ao fecharmos o formulário (clicando no botão [x]), eletambém permanece em memória, sendo apenas minimizado.

Como saber se o formulário já está criado?Uma pergunta muito comum, principalmente quando

chamamos formulários não-modais (usando Show) é saber se oformulário já está em memória para não instanciarmosnovamente.

Existe um artifício bastante simples para efetuar estecontrole bastando verificar se o formulário está igual a “nil” antesde criar:

if MeuForm = nil thenbegin MeuForm := TMeuForm.Create(Self);] MeuForm.Show;endelse ShowWindow(MeuForm.Handle, sw_restore); { apenas restaura o form }{ apenas restaura o form }{ apenas restaura o form }{ apenas restaura o form }{ apenas restaura o form }

Importante: No evento OnDestroy do MeuForm você deveráatribuir “nil” ao mesmo:

MeuForm := nil;

ConclusãoProcurei demonstrar neste artigo as diferenças e quando

utilizar “nil”, “application” e “self” como proprietários aoinstanciar objetos. Trata-se de um assunto bastante simples,porém muitos programadores utilizam sem saber exatamentepara que cada um deles realmente servem. Dessa forma, ummelhor entendimento ajuda e facilita o melhor aproveitamento daprogramação orientada a objetos oferecida pelo Delphi.

Saúde e sucesso à todos,

Sobre o autorAlessandro Ferreira,Consultor Técnico do The [email protected]

20

Dicas & Truques

Como procurar arquivos com determinadoconteúdo

Neste exemplo iremos implementar um sistema de busca dearquivos semelhante a ferramenta ‘Procurar’ do WindowsExplorer, com a possibilidade de informar máscara para o tipo dearquivo (Ex: *.PAS) e também, arquivos que contenham umdeterminado texto. Crie um novo projeto e adicione 3componentes Edit (edTipo, edTexto e edLocal), 4 componentesLabel (‘Tipo de arquivo’, ‘Que contenham o texto’, ‘Localização’ e‘Resultado’), 2 componentes Button (btLocalizar = ‘Localizar’ ebtCancelar = ‘Cancelar’), 1 componente SpeedButton (sbtnLocal= ‘?’), um componente ListBox (lbArquivos) e 1 componenteAnimate (Animate1). Na figura 1 sugerimos um layout para esteformulário.

Antes de partirmos para os procedimentos, declare umavariável que será utilizada para cancelarmos o processamentoatravés do botão ‘Cancelar’:

var Form1: TForm1; Canc: Boolean;

implementation

{$R *.dfm}

Agora, vamos partir para implementação dos procedimentos

responsáveis em localizar os arquivos e pesquisar o texto dentrodos mesmo. Nossa primeira função será a ‘ScanFile’ que iráreceber como parâmetro o nome do arquivo, o texto à serprocurado e finalmente um parâmetro lógico informando se abusca será sensitiva (caixa alta/baixa) ou não, veja a listagem 1.

function ScanFile(const FileName: string; const forString: string; caseSensitive: Boolean): Longint;

Figura 1

21

{ retorna a posição da substring na string ou-1 caso não encontre }const BufferSize = $8001; { 32K+1 bytes }var pBuf, pEnd, pScan, pPos: PChar; filesize: LongInt; bytesRemaining: LongInt; bytesToRead: Integer; F: file; SearchFor: PChar; oldMode: Word;begin Result := -1; { assume falha. } if (Length(forString) = 0) or(Length(FileName) = 0) then Exit; SearchFor := nil; pBuf := nil;

{ abre o arquivo como binário } AssignFile(F, FileName); oldMode := FileMode; FileMode := 0; { acesso somente leitura } Reset(F, 1); FileMode := oldMode; try { aloca memória para o buffer } SearchFor := StrAlloc(Length(forString) +

1); StrPCopy(SearchFor, forString); if not caseSensitive then { converte

para uppercase } AnsiUpper(SearchFor); GetMem(pBuf, BufferSize); filesize := System.Filesize(F); bytesRemaining := filesize; pPos := nil; while bytesRemaining > 0 do begin if bytesRemaining >= BufferSize then bytesToRead := Pred(BufferSize) else bytesToRead := bytesRemaining;

BlockRead(F, pBuf^, bytesToRead, bytesToRead);

pEnd := @pBuf[bytesToRead]; pEnd^ := #0; pScan := pBuf; while pScan < pEnd do

begin if not caseSensitive then { converte

para maiucula } AnsiUpper(pScan); pPos := StrPos(pScan, SearchFor); {

procura a substring } if pPos <> nil then begin { Achou! } Result := FileSize - bytesRemaining

+ Longint(pPos) - Longint(pBuf); Break; end; pScan := StrEnd(pScan); Inc(pScan); end; if pPos <> nil then Break; bytesRemaining := bytesRemaining -

bytesToRead; if bytesRemaining > 0 then begin Seek(F, FilePos(F) -

Length(forString)); bytesRemaining := bytesRemaining +

Length(forString); end; end; { While } finally CloseFile(F); if SearchFor <> nil then StrDispose(SearchFor); if pBuf <> nil then FreeMem(pBuf, BufferSize); end;end; { ScanFile }

Listagem 1 – Função para pesquisar texto em arquivos.

Nosso próximo procedimento será o responsável em buscar osarquivos em um path informando como parâmetro. Osparâmetros deste procedimento serão a máscara para filtrar otipo de arquivo, a lista (TStrings) onde o resultado seráadicionado e o texto à ser procurado nos arquivos, acompanha alistagem 2.

procedure GetAllFiles(mask: string; Lista:TStrings; ToSearch: string);

var search: TSearchRec; directory: string;

Dicas & Truques

22

begin directory := ExtractFilePath(mask);

// procura arquivos. if FindFirst(mask, $23, search) = 0 then begin repeat // adiciona na lista. if ScanFile(directory + search.Name,

ToSearch, false) >= 0 then Lista.Add(directory + search.Name); Application.ProcessMessages; if Canc then Break; until FindNext(search) <> 0; end;

// Sub-Pastas. if FindFirst(directory + ‘*.*’,faDirectory, search) = 0 then begin repeat if ((search.Attr and faDirectory) =

faDirectory) and (search.Name[1] <> ‘.’) then GetAllFiles(directory + search.Name +

‘\’ + ExtractFileName(mask), Lista, ToSearch); Application.ProcessMessages; if Canc then Break; until FindNext(search) <> 0; FindClose(search); end;end;

Listagem 2.

Vamos agora codificar o evento OnClick do botão ‘Confirma’,veja a listagem 3.

procedure TForm1.btnLocalizarClick(Sender:TObject);var directory, mask, ToSearch: string;begin Canc := false; lbArquivos.Items.Clear; directory := IncludeTrailingBackslash

(edLocal.Text);

mask := edTipo.Text; ToSearch := edTexto.Text;

Animate1.Visible := true; btnLocalizar.Enabled := false; btnCancelar.Enabled := true;

try GetAllFiles(directory + mask,lbArquivos.Items, ToSearch); finally Animate1.Visible := false; btnLocalizar.Enabled := true; btnCancelar.Enabled := false; end; ShowMessage(IntToStr(lbArquivos.Items.Count)

+ ‘ arquivos encontrados!’);end;

Listagem 3 – Evento OnClick do botão Confirma.

Neste momento, nosso projeto já está funcionando e efetua abusca de arquivos que contenham determinado texto.Prosseguindo, vamos codificar o botão sbtnLocal através do qualchamaremos uma caixa padrão do Windows para o usuárioselecionar o path onde será efetuada a busca, veja a listagem 4.

procedure TForm1.sbtnLocalClick(Sender:TObject);var s: string;begin if SelectDirectory(‘Localização’, ‘’, s)then edLocal.Text := s;end;

Listagem 4 – Botão para selecionar path.

OBS. Declare a unit FileCtrl na lista uses para poder utilizar‘SelectDirectory’.

E por fim, adicione o código para o botão ‘Cancelar’:

procedure TForm1.btnCancelarClick(Sender: TObject);

begin Canc := true;end;

Dicas & Truques

23

Download: http://www.theclub.com.br/revista/download/ProcuraArquivos.zip

Figura 2 – Aplicação em execução.

Rodando a aplicação, você terá um resultado parecido com afigura 2

Como imprimir um texto na verticalNeste exemplo iremos demonstrar como efetuar a impressão

de um texto via Printer.Canvas com a possibilidade de definir oângulo da impressão, e neste caso, se definirmos 90º estaremosimprimindo o texto na vertical. Crie um novo projeto, adicione 1componente Label (‘Ângulo’), 1 componente SpinEdit(spinAngulo, Value = 90), 1 componente PrintDialog e 1componente Button (‘Imprimir’), a figura 3 sugere um layoutpara este formulário.

Figura 1

Declare a unit Printers na lista uses e no evento OnClickadicione o código apresentado na listagem 5.

procedure TForm1.btImprimirClick(Sender:TObject);var lf : TLogFont; OldFont : hFont; NewFont : hFont;begin if PrintDialog1.Execute then begin with Printer, Printer.Canvas do begin BeginDoc; Font.Name := ‘Arial’; Font.Size := 24; Font.PixelsPerInch := GetDeviceCaps

(Handle, LOGPIXELSY); GetObject(Font.Handle, SizeOf(lf),

@lf); lf.lfEscapement := spinAngulo.Value *

10; lf.lfOrientation := 300; NewFont := CreateFontIndirect(lf); OldFont := SelectObject(Handle,

NewFont); Windows.TextOut(Printer.Canvas.Handle,

200, 200, ‘Rotated Text!’, 13); SelectObject(Handle, OldFont); DeleteObject(NewFont); EndDoc; end; end;end;

Listagem 5.

O ângulo de impressão será definido no objeto ‘TLogFont’através da propriedade lfEscapement.

Download: http://www.theclub.com.br/revista/download/ImpTextoVertical.zip

Como ler informações da BIOS no Windows XPNeste exemplo iremos demonstrar como obter informações da

BIOS no Windows XP. No Windows 9x utilizávamos algunscódigos em Assembler os quais devido a questões de arquiteturano Windows XP, deixaram de funcionar. Aqui, iremos ler asinformações da BIOS com base em informações armazenadas noregistrador do Windows, o que torna esta tarefa bem simples.Crie um novo projeto Delphi, adicione 2 componentes Label(lbData e lbNumero) e 1 componente Button. Agora, vamos

Dicas & Truques

24

implementar a rotina responsável em efetuar a leitura dasinformações da BIOS a partir do registro do Windows, veja alistagem 6.

implementationuses Registry;{$R *.dfm}

procedure Get_BIOS_Info(var Data, Name:string);const sNT_SYSTEM_REGKEY =

‘\HARDWARE\DESCRIPTION\System’;var BIOSDate: string; BIOSName: array[0..128] of Char; Reg: TRegistry;begin try Reg := TRegistry.Create; with Reg do begin RootKey := HKEY_LOCAL_MACHINE; try if OpenKey(sNT_SYSTEM_REGKEY, False)

then begin BIOSDate := ReadString

(‘SystemBiosDate’); ReadBinaryData(‘SystemBiosVersion’,

BIOSName, Sizeof(BIOSName) - 1); Data := BIOSDate; Name := BIOSName; end; finally Free; end; end; except on E: Exception do ShowMessage(‘Problemas ao retornar

informações da BIOS: ‘ + E.Message); end;end;

Listagem 6.

OBS. É necessário declarar a unit Registry na lista uses.

Estando pronto nosso procedimento, vamos apenas efetuar achamada do mesmo no evento OnClick do botão, veja a listagem 7.

procedure TForm1.Button1Click(Sender: TObject);

var Data, Nome: String;begin Get_BIOS_Info(Data, Nome); lbData.Caption := ‘Data: ‘ + Data; lbNumero.Caption := ‘Número: ‘ + Nome;end;

Listagem 7.

Pronto, execute o projeto e o resultado será parecido com oapresentado na figura 4.

Figura 4 – Data e número da bios

Download: http://www.theclub.com.br/revista/download/LerBIOS.zip

Como distribuir aplicações baseadas emdbExpress

A distribuição de aplicações que fazem acesso a banco dedados via dbExpress é muito simples. A distribuição de aplicaçõesque utilizam dbExpress na conexão com o banco de dados é bemsimples. Basicamente, você deverá fazer o seguinte:

No servidor:

1. instalar o Firebird/Interbase Server no servidor;2. instalar sua aplicação juntamente com o banco de dados no

servidor;3. copiar os arquivos MIDAS.DLL, DBEXPINT.DLL,

GDS32.DLL e ARQUIVO.INI para mesma pasta do EXE de suaaplicação no servidor;

4. compartilhar a pasta onde está o EXE de sua aplicação noservidor;

Nas estações:Apenas puxar um atalho do EXE existente na pasta

compartilhada no servidor.

Dicas & Truques

25

* Caso necessite ter um EXE por estação, deverá copiar oEXE e os demais arquivos mencionados no passo “3”anteriormente.

A seguir, vou listar algumas dicas para conexão com o bancode dados em rede:

1. Certifique-se de que a rede esteja trabalhando comprotocolo TCP/IP e que o servidor possua um endereço IP fixo, ouseja, não utilize IP dinâmico no servidor;

2. Certifique-se de que não exista nenhuma aplicação quepossa ‘barrar’ a conexão entre as estações e o servidor, como porexemplo, Firewall e Anti-Vírus. No caso do Firewall, existe umaconfiguração para liberar as portas TCP e UDP 3050 que é aporta utilizada pelo Interbase/Firebird. Maiores informaçõespoderão ser encontradas em nossa revista de Novembro/2004“Ajustes no Firewall do Windows XP Service Pack 2 para rodar oInterbase/Firebird”. Caso não possua a revista poderá acessar emnosso site, www.theclub.com.br.

3. A string de conexão, ou seja, o path do banco de dadosdeverá ser composto assim:

172.16.172.1:D:\PASTA\BANCO.FDB

Sendo:172.16.172.1 = IP do servidorD:\PASTA = Nome da pasta no servidorBANCO.FDB = Nome do banco dentro da pasta no servidor

* Não utilize nomes de compartilhamento, e sim, o nome dapasta física que existe no servidor.

4. Estas configurações são aplicáveis à qualquer versão doWindows e estando dessa forma deverá funcionar semproblemas.

InnoSetup - Como adicionar um programa parainiciar com o Windows

O InnoSetup é uma gerador gratuito de instalações que vêmdia-a-dia se popularizando meio a comunidade Delphi. A seguir,apresentamos uma dica para adicionar sua aplicação para iniciarjunto com o Windows.

[Code][Setup]AppName=Adicionar no iniciar.AppVerName= Adicionar no iniciar.DefaultDirName={pf}\ Adicionar no iniciar.DisableStartupPrompt=true

Uninstallable=falseDisableDirPage=trueOutputBaseFilename=Adicionar no iniciar.[Files]Source: C:\teste.exe; DestDir: {userstartup};DestName: teste.exe

Veja que o ‘segredo’ está no diretório de destino da aplicaçãoou atalho da mesma, o qual deverá ser destinado para {userstartup}que representa um path especial que o Windows irá buscar nomomento que estiver iniciando.

Windows - Como verificar a versão do Windows.Neste exemplo apresentamos uma rotina para verificar qual

a versão do Windows. O que diferencia esta rotina de outras jáapresentadas é que ela consegue distinguir entre todas as versõesdo Windows, ou seja, se é Windows 95, 98, ME, NT 4, 2000 ouXP.

function GetWinVersion: String;begincase Win32MajorVersion of3: Result := ‘Windows NT 3.51’; // NT 3.514: // WIn9x/ME, NT 4case Win32MinorVersion of0: Result := ‘Windows 95’;10: Result := ‘Windows 98’;90: Result := ‘Windows ME’;elseif (Win32Platform and VER_PLATFORM_WIN32_NT)<> 0 thenResult := ‘Windows NT 4.0’elseResult := ‘SO desconhecido’;end;5: // Win2K, XPcase Win32MinorVersion of0: Result := ‘Windows 2000’;1: Result := ‘Windows XP or .NET server’;elseResult := ‘SO desconhecido’;end;elseResult := ‘SO desconhecido’;end;

end;// Chamada:{ mostrar em um label }OSVersion.Caption := GetWinVersion;

Dicas & Truques

26

Pergunta: Preciso executar o UltraVNC Server em meusclientes, porém na maioria dos casos, o firewall do Windows estáhabilitado. Gostaria de saber como criar uma aplicação em Delphi5 que crie uma exceção no firewall do Windows permitindo que oUltraVNC Server funcione. Manualmente nós sabemos comofazer isto, mas ocorre que muitas vezes o cliente lá do outro lado éiniciante ou não possui conhecimento suficiente para criar estaexceção com segurança. Existe alguma API do Windows quepermita este tipo tarefa?

Resposta: As aplicações consideradas exceções ficamarmazenadas no registrador do Windows, mais especificamentena chave:

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\AuthorizedApplications\List

Assim sendo, bastará você criar uma chave no registrador.Para conferir ‘o que’ você deverá adicionar, acesse o registradorda sua máquina e encontrará uma chave referente aoUltraVNC.

Exemplo de acesso ao Registrador do Windows via Delphi:

implementationuses registry;

{ Atribui um informacao para o Registry }procedure TForm1.BitBtn2Click(Sender:TObject);Var Reg : TRegistry;begin Reg := Tregistry.Create; With TRegistry.Create do begin

RootKey:= HKEY_USERS; OpenKey(‘TheClub\curso\teste’, True); WriteString(‘Teste_Reg1’,’Teste

Teste’); Free; end;end;

{ Recupera um valor do Registry }procedure TForm1.BitBtn7Click(Sender:TObject);Var Reg : TRegistry; Value : string;begin Reg := Tregistry.Create; With TRegistry.Create do begin RootKey:= HKEY_USERS; OpenKey(‘TheClub\curso\teste’, True); Caption := ReadString(‘Teste_Reg1’); Free; end;

end;

Dúvida enviada por Cial Informática Ltda, Cruzeiro/SP.

Pergunta: Gostaria de saber a sintaxe para criar um índicedentro de uma TQuery em design time, ou seja, eu preciso deixaro código SQL já pronto dentro da propriedade SQL do componenteTQuery. Preciso dos dados da criação da tabela e a criação doindice juntos no componente, isso é possível?

Resposta: O componente Query não é preparado para rodarscripts SQL subseqüentes desta natureza. Uma alternativa neste

Perguntas & Respostas

27

Perguntas & Respostas

caso é o componente SQLScript que acompanha a suíte decomponentes gratuita RxLib, a qual está disponível paradownload em nosso site, www.theclub.com.br.

Dúvida enviada por Associação Brasileira Distrib. VWCaminhões, São Paulo/SP.

Pergunta: Tentei passar duas instruções SQL separadaspor “;” em um IBQUERY, e depois dar ExecSQL. Porém, meretornou um erro de sintaxe. Então, tentei usando o IBSCRIPT edeu certo, contudo, gostaria de saber como fazer para passarparâmetros para um IBSCRIPT, como exemplo, executar umUPDATE <tabela> SET <campo> = :PARAMETRO;

Resposta: Poderá passar parâmetros em um IBScriptassim:

/* instrução no IBScript */

UPDATE TABELA SET CAMPO = %sWHERE OUTROCAMPO = ‘%s’

// Antes de executar:

with IBScript1 do begin Script.Text := Format(Script.Text,

[‘PrimeiroValor’, ‘SegundoValor’]); ExecuteScript; end;

Observe que os ‘%s’ serão substituídos pelos valores naseqüência.

Dúvida enviada por Domingos Waller, Porto Alegre/RS.

Pergunta: Tem como verificar a velocidade do processador?

Resposta: Poderá obter esta informação assim:

function GetCPUSpeed: Double;const DelayTime = 500;var TimerHi, TimerLo: DWORD; PriorityClass, Priority: Integer;

begin PriorityClass := GetPriorityClass

(GetCurrentProcess); Priority := GetThreadPriority

(GetCurrentThread); SetPriorityClass(GetCurrentProcess,

REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread,

THREAD_PRIORITY_TIME_CRITICAL); Sleep(10); asm dw 310Fh // rdtsc mov TimerLo, eax mov TimerHi, edx end; Sleep(DelayTime); asm dw 310Fh // rdtsc sub eax, TimerLo sbb edx, TimerHi mov TimerLo, eax mov TimerHi, edx end; SetThreadPriority(GetCurrentThread,

Priority); SetPriorityClass(GetCurrentProcess,

PriorityClass); Result := TimerLo / (1000.0 * DelayTime);end;

procedure TForm1.Timer1Timer(Sender:TObject);var CPUSpeed: Double;begin CPUSpeed := GetCPUSpeed; Label1.Caption := FormatFloat

(‘0.00 MHz’, CPUSpeed);end;

Dúvida enviada por Elson Carlos Almeida, Irecê/BA.

Pergunta: No Paradox, arquivos com senha são facilmenteabertos. Até quanto, utilizando um banco de dados Firebird, vai asegurança quanto a quebra de senha? Senhas maiores, comcaracteres diversificados ajudam na contenção?

Resposta: Por enquanto, a segurança no Firebird dependedo sistema operacional onde o banco está disponibilizado, ou seja,

28

Perguntas & Respostas

os usuários não poderão ter acesso ao arquivo físico do banco dedados, pois se este for copiado para um máquina que possua oFirebird instalado com usuário e senha padrões, o acesso seráfeito ao seu banco de dados sem nenhum problema. Isso ocorreporque o usuário e senha não ficam armazenados no SEU bancode dados e sim em um banco de dados de SISTEMA chamadaSECURITY.FDB. Alterar a senha do SYSDBA/masterkey éinteressante para prevenir que usuários curiosos venham a‘fuçar’ no banco de dados, contudo, não irá garantir o sigilo dosdados.

Para saber mais:

Permissões de usuários no Firebird, revista: Janeiro/2003.Caso não possua a revista poderá acessar em nosso site,www.theclub.com.br.

Dúvida enviada por Francisco José Riva, São Jose do RioPreto/SP.

Pergunta: Recebi uma rotina para adicionar um campo auma tabela PARADOX e estou tentando passar para o um valorpara o objeto “MyChangeRec.szName” advindo de um Edit,porém, está dando erro de incompatibilidade. Como posso efetuaresta atribuição?

MyChangeRec.szName :=

QuotedStr(edtNovoCampo.Text);

Resposta: Veja abaixo um simples exemplo de como efetuaresta atribuição:

type ChangeRec = packed record szName: DBINAME; iType: Word; iSubType: Word; iLength: Word; iPrecision: Byte;end;

var Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender:

TObject);var MyChangeRec: ChangeRec; s: String;begin s := ‘SeuCampo’; StrPCopy(MyChangeRec.szName, s); ShowMessage(MyChangeRec.szName);end;

Dúvida enviada por Olavo Tessaro, Atibaia/SP.

Pergunta: Como Acessar o Access pelo dbExpress?

Resposta: Você pode fazer este tipo de acesso utilizando umdriver ODBC juntamente com o DBExpress. Veja a seguir:

1 - Inclua o componente SQLConnection no form2 - Informe na propriedade ConnectionName um nome

qualquer, por exemplo MinhaConexao3 - Informe na propriedade DriverName um nome qualquer,

por exemplo MeuDriver4 - Informe na propriedade GetDriverFunc a string

getSQLDriverODBC5 - Informe na propriedade LibraryName o nome da DLL de

acesso, por exemplo dbexpodbc.dll. Copie esta DLL para o diretório c:\windows\system326 - Informe a string de conexão para o parametro Database

na propriedade Parameters

Para Access =“Driver={Microsoft Access Driver (*.mdb)};DBQ=..\Data\Northwind.mdb;

Dúvida enviada por João Roberto da Silva, São José do RioPreto – SP.

Pergunta: Eu gostaria de saber se tem como trocar a cor dealgumas linhas do CheckListBox.

Resposta: Existe uma forma simples de fazer este tipo detrabalho. Inclua alguns itens no seu CheckListBox, vá até apropriedade Style e altere para lbOwnerDrawVariable, agora váaté ao evento OnDrawItem e inclua o código abaixo:

CheckListBox1.Canvas.FillRect(Rect); if not (odFocused in State) then begin

29

Perguntas & Respostas

if CheckListBox1.Checked[index] then begin CheckListBox1.Canvas.Font.Color :=

clRed; CheckListBox1.Canvas.Brush.Color :=

clWhite; end else begin CheckListBox1.Canvas.Font.Color :=

clBlack; CheckListBox1.Canvas.Brush.Color :=

clWhite; end; end; CheckListBox1.Canvas.TextOut(Rect.Left+2,

Rect.Top,CheckListBox1.Items.Strings[Index]);

Dúvida enviada por Everson S. Batista, Ararangua – SC.

Pergunta: Gostaria de saber se existe alguma função quecopia um diretório com todos os seus arquivos e diretórios e sub-diretorios?

Resposta: Para fazer este tipo de trabalho nós precisamosrecorrer a utilização de API´s do Windows. Veja o exemplo:

implementationuses ShellAPI;{$R *.DFM}

procedure CopiaPasta(Origem, Destino:String);

var FOS :TSHFileOpStruct;begin with FOS do begin Wnd := Form1.Handle; wFunc := FO_COPY; pFrom := PChar(Origem); pTo := PChar(Destino); fFlags := FOF_NoConfirmMkDir; end; SHFileOperation(FOS);end;

// Veja como utilizar

procedure TForm1.Button1Click(Sender: TObject);

begin CopiaPasta(‘d:\Revista’, ‘d:\Rev2’);end;

Dúvida enviada por Rodrigo Polis, Goiânia – GO.

Pergunta: Preciso de alguma função que verifique se umprograma já está aberto, caso não estiver abrí-lo.

Resposta: Existe uma forma que é pegando o nome dajanela. Veja o exemplo abaixo que trabalha com a calculadora doWindows.

procedure TForm1.Button1Click(Sender:TObject); var

TheWindow: HWND;begin {find a handle to the Windows Explorer

window} TheWindow:=FindWindow(nil,’Calculadora’); if TheWindow <> 0 then // Chama calculadora se já estiver

// carregada SetForegroundWindow(TheWindow) else // Carrega calculadora se estiver

// fechada ShellExecute(Handle, ‘Open’,

‘Calc.exe’, nil, ‘c:\windows’,sw_shownormal);

end;

Dúvida enviada por Vagner Azanha, Campinas – SP.

Pergunta: Quais as opções disponíveis para acessar oFirebird 1.5xx com o Delphi 2005?

Resposta: No Delphi 2005, você pode utilizar os driversFirebird .NET Data Provider e o Borland Data Provider forFirebird para aplicações .NET.

Você pode fazer o download destes drivers a partir deste link,http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_download_dotnet. Já paraaplicações Win32 você pode utilizar o DBExpress.

Dúvida enviada por Leandro do Couto, Novo Hamburgo – RS

30

Perguntas & Respostas

Pergunta: Como instalar meus componentes em um novopacote, ou seja, gostaria de criar meu próprio pacote para contermeus componentes.

Resposta: Abaixo segue um passo a passo de como instalarcomponentes em um novo pacote.

1. Vá ao menu File | New | Other e selecione Package:

3. Para instalar seus componentes, clique em “Add” eselecione a unit do componente:

4. Após selecionar a unit do componente, bastará clicar emOK. Repita este processo para os demais componentes que vocêpossua.

2. Estando com o novo pacote criado, salve com um novosugestivo, como exemplo: pkgMeusComponentes.

5. Quando terminar o processo para todos os componentes,clique no botão ‘Compile’ e depois em ‘Install’.

6. Pronto, com isso seus componentes estarão instalados,bastará fechar e salvar o pacote.

Obs. Não se esqueça de configurar o <path> onde estão asunits dos componentes em: Tools | Environment Options |Library | Library Path.

Dúvida enviada por Joâo Augusto Hintz, Ijui/RS.

Pergunta: Tenho uma aplicação e recentemente instalei emuma máquina com Windows XP e acontece o seguinte problema:as janelas do sistema ficam dentro de barras de rolagem, como seelas não coubessem no formulário. Se eu desligar os temas do XP,ou seja, trabalhar em modo clássico o layout fica correto. Comoposso resolver este problema?

Resposta: O que ocorre é que os temas no Windows XPdeixam a área “cliente” do formulário menor devido a barra detítulo ser uma pouco mais alta que no padrão “clássico”. Nestecaso, você tem duas alternativas:

1. a primeira, você já descobriu por conta própria: usar opadrão “clássico”.

2. Implementar uma rotina que aumente o tamanho doformulário até que as barras de rolagem desapareçam. Vamosefetuar esta implementação.

Primeiro, vamos codificar uma procedure que irá receber umformulário como parâmetro e em cima deste iremos efetuar umlooping aumentando seu tamanho enquanto a barra de rolagemvertical estiver aparecendo e depois, repetindo o mesmo para abarra de rolagem horizontal, veja a procedure

31

Perguntas & Respostas

AcertaTamanhoDoForm:

procedure AcertaTamanhoDoForm(Form: TForm);var i: Integer;begin LockWindowUpdate(Form.Handle); try whileForm.VertScrollBar.IsScrollBarVisible do Form.Height := Form.Height + 1; whileForm.HorzScrollBar.IsScrollBarVisible do Form.Width := Form.Width + 1; finally LockWindowUpdate(0); end;end;

Esta procedure terá que ser chamada cada vez quechamarmos um formulário de nossa aplicação, assim sendo,iremos utilizar o evento OnActiveFormChange do objeto Screen.Para isso, primeiro crie um método em seu formulário principalcomo apresentado abaixo:

procedure TForm1.OnActiveFormChange(Sender:TObject);begin if Screen.ActiveForm <> nil then AcertaTamanhoDoForm(Screen.ActiveForm);end;

Obs. Lembre-se de declarar este método dentro da classe deseu formulário, para isso bastará teclar a combinação de teclas:CTRL+SHIFT+C.

No evento OnCreate do formulário principal iremos fazer aligação do evento OnActiveFormChange ao nosso método, veja aseguir:

procedure TForm1.FormCreate(Sender: TObject);begin Screen.OnActiveFormChange :=OnActiveFormChange;end;

E por fim, no evento OnClose do formulário principal iremosdesligar o evento OnActiveControlChange.

procedure TForm1.FormClose(Sender: TObject;

var Action: TCloseAction);begin Screen.OnActiveFormChange := nil;end;

end.

Com isso, todo e qualquer formulário que for chamado emsua aplicação terá seu tamanho redimensionadoautomaticamente para não apresentar as barras de rolagem.

Dúvida enviada por Almir Rodrigues Borges, Araçatuba/SP.

Pergunta: Estou tendo problemas freqüentes de corrupçãoem tabelas Paradox rodando em máquinas com Windows XP e2000. Minha aplicação faz uso do BDE como engine de acesso adados. Esta mesma aplicação roda em diversos clientes comWindows 98 e não tenho problemas desta natureza, somente noWindows XP e 2000. Existe alguma dica a respeito para diminuira corrupção de tabelas Paradox em XP e 2000?

Resposta: O Windows possui um sistema de cache que porpadrão vem habilitado para melhorar a performance, contudotemos percebido que o BDE/Paradox e o cache não conseguem seentender muito bem, resultando em corrupção das tabelas. Asolução neste caso seria desabilitar este sistema de cache, issopoderá ser feito assim:

// Windows 2000, XP e 2003

1.Duplo clique em ‘Meu computador’. Clique da direita emseu drive “C”, Propriedades.

2.Clique na aba Hardware. Selecione seu HD e depois cliqueno botão Propriedades.

3.Vá na aba Diretivas (WinXP/2003) ou Propriedades deDisco (W2K).

4.Desmarque a opção: Ativar gravação em cache no disco.

// Windows 95,98 e ME

1. Clique com o botão direito em ‘Meu Computador’,‘Propriedades’

2. Clique em ‘Sistemas de Arquivos’3. Clique na aba ‘Disco Removível’4. Desmarque a opão ‘Ativar o cache de gravação temporária

em todas as unidades...’

Dúvida enviada por RRC Informática e Comércio Ltda., SãoPaulo/SP.