30

Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

Embed Size (px)

Citation preview

Page 1: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,
Page 2: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

Revista The Club Megazine - 01/2004A utilização, reprodução, apropriação, armazenamento em banco de dados,sob qualquer forma ou meio, de textos, fotos e outras criações intelectuaisem cada publicação da revista “The Club” são terminantemente proibidos

sem autorização escrita dos titulares dos direitos autorais.Copyright© The Club® 2004

Page 3: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 33333

EDITORIALEDITORIALEDITORIALEDITORIALEDITORIAL

Editorial

Celso Jefferson PaganelliPresidente - The Club

Editorial ............................................................................ 03Write Printer - Criando impressões rápidas para o Delphi ... 04Trabalhando com eventos ................................................. 14Retrospectiva .................................................................... 16Intraweb - Programação Alternativa .................................. 18Usando o Object Repository .............................................. 24Perguntas & Respostas ...................................................... 26

THE CLUBAv. Celso Ferreira da Silva, 190

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

Suporte: (0xx14) 3733-1588 - Fax: (0xx14) 3732-0987

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected]ções: [email protected]

DúvidasCorrespondência ou fax com dúvidas devem serenviados 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 a seção"Tire sua dúvida".

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

armazenamento em banco de dados, sob qualquerforma ou meio, de textos, fotos e outras criações

intelectuais em cada publicação da Revista“The Club” são terminantemente proibidos sem

autorização escrita dos titulares dos direitosautorais.

Copyright© The Club® 2004

Impressão e acabamento:Impressos Gril - Gril Gráfica e Repr. Ind. Ltda.

Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259Rua São Paulo, 447 - Cep 18.740-000

Taquarituba - SPTiragem: 5.000 exemplares

Diretor - Presidente

Celso Jefferson M. Paganelli

Diretor Técnico

Mauro Sant’Anna

ColaboradoresEmerson Facunte

Delphi é marca registrada da Borland International, asdemais marcas citadas são registradas pelos seus

respectivos proprietários.

Primeiramente, gostaria de desejar à todos um 2004 cheio de muito sucesso erealizações e que possamos estar juntos por mais este ano que se inicia!

2004 com certeza será marcado por muitas novidades, começando pelo Delphi 8 quejá está pronto e segundo informações extra-oficiais, sua versão trial estará disponívelaté o final deste mês de janeiro. Nós já tivemos a oportunidade de fazer um test-drivenesta versão, e sinceramente, superou nossas expectativas. O desenvolvimento paraplataforma Microsoft .Net não será o mesmo após o lançamento do Delphi 8, vale apena aguardar!

Enquanto o Delphi 8 não está disponível, vamos começando mais uma The ClubMegazine com um artigo que foi muito solicitado ao nosso setor de suporte, o qual tratasobre a impressão rápida via Delphi, fazendo tratamentos para impressão local e emrede e ainda em portas USB, confira...

Prosseguindo, uma pequena referência sobre a manipulação de eventos no Delphi enosso amigo Emerson Facunte num artigo dividido em duas partes que irá apresentaralguns macetes para desenvolvimento de aplicações para internet via IntraWeb paraobter o melhor resultado.

E para finalizar, algumas dicas sobre o funcionamento do Object Repository doDelphi, recurso bastante interessante e pouco explorado por muitos programadores, eencerramos com a sessão Perguntas & Respostas, onde estão compartilhadas algumasdas dúvidas que passaram pelo suporte neste mês.

Boa leitura e um 2004 cheio de sucesso!

Page 4: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE44444

Sempre que falamos de impressão rápida (padrão DOS)dentro do Delphi, normalmente optamos pela impressão atravésdos comandos AssignFile, ReWrite e Writeln. Esses comandosfuncionam satisfatoriamente, digo satisfatoriamente, porque emalguns casos apresentaram problemas, como por exemplo,ocultar determinados caracteres de uma palavra no meio do textoimpresso, não permite uma verificação se a impressora estápronta para a impressão e também não controlam quando váriaspessoas mandam suas impressões para a mesma impressora e aomesmo tempo.

Diante desses problemas criamos um projeto onde fazemos asimpressões rápidas (padrão DOS) através da procedureWritePrinter da unit WinSpool. Para entendermos um poucomelhor primeiramente vamos verificar quais os recursos queessa procedure nos dará ao utilizá-la e depois passo a passocriaremos os projetos de exemplo.

Como essa impressão irá funcionarO Delphi nos traz já há bastante tempo uma unit chamada

WinSpool que, apesar de não ser muito utilizada, é bastante útilpois contém métodos que permitem fazer uma impressão rápida(padrão DOS) como o Writeln, mas utilizando o Spool daimpressora.

Para isso antes de iniciarmos a impressão executamos umafunction que irá fazer um contato com a impressora verificandose a mesma está pronta para o trabalho, caso positivo fazemosmais algumas inicializações para o Spool e começamos a enviaros trabalhos de impressão. Neste momento se essa impressora jáestá em uso o nosso trabalho de impressão entra na fila do spool efica aguardando a sua vez.

Veja que neste momento já resolvemos alguns dos problemasmencionados no início, que é a verificação se a impressora está

pronta e controlar quando a impressora já está em uso. Mas omais importante é que tudo isso é feito sem perder a velocidadeno momento da impressão.

Na verdade essa unit WinSpool traz inúmeros métodos paracontrole do Spool de impressão e que renderiam várias matériasem nossa revista, mas isso deixaremos para outra oportunidade,pois por enquanto trataremos somente das funções as quaisestaremos utilizando em nosso projeto.

Iniciando os trabalhosNeste primeiro projeto iremos aproveitar para entender um

pouco sobre as funções utilizadas da unit WinSpool para fazer asimpressões. E um detalhe importante é que essas impressõesforam testadas com as versões do Delphi3 e Delphi6 e ambasfuncionaram perfeitamente.

Vamos iniciar os nossos trabalhos criando um novo projeto,chamado Exemplo1.

Neste novo projeto visualize a unit e declare na seçãoimplementation a unit WinSpool.

Em seguida coloque um botão no form e no evento onClickdeste botão inclua as seguintes instruções:

procedure TForm1.Button1Click(Sender: TObject);

var

hPrinter: THandle;

BytesWritten: DWORD;

DocInfo: TDocInfo1;

NomeImp, Texto: String;

begin

NomeImp := LerImpressora;

if not OpenPrinter(PChar( NomeImp ),

hPrinter, nil) then

WritePrinterWritePrinterWritePrinterWritePrinterWritePrinterCriando impressões rápidas para o DelphiCriando impressões rápidas para o DelphiCriando impressões rápidas para o DelphiCriando impressões rápidas para o DelphiCriando impressões rápidas para o Delphi

Por André Colavite

DelphiDelphiDelphiDelphiDelphi

Page 5: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 55555

DelphiDelphiDelphiDelphiDelphi

raise exception.create(‘THE CLUB - Impressora

não encontrada!’);

{ Informações para o spool de impressão }

DocInfo.pDocName := PChar( ‘THE CLUB - Testando

trabalho de impressão’ );

DocInfo.pOutputFile := nil;

DocInfo.pDatatype := ‘RAW’;

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then

Exit;

if not StartPagePrinter(hPrinter) then

Exit;

Texto := ‘Imprimindo Primeira linha’;

WritePrinter(hPrinter, PChar(Texto),

Length(Texto), BytesWritten);

Texto := ‘ Imprimindo Segunda coluna da Primeira

linha’;

WritePrinter(hPrinter, PChar(Texto),

Length(Texto), BytesWritten);

{ Executa um Eject da folha }

WritePrinter(hPrinter, PChar(#13+#10),

Length(#13+#10), BytesWritten);

Texto := ‘Imprimindo Segunda linha do relatorio’;

WritePrinter(hPrinter, PChar(Texto),

Length(Texto), BytesWritten);

EndPagePrinter(hPrinter);

EndDocPrinter(hPrinter);

ClosePrinter(hPrinter);

end;

Neste evento onClick executamos uma function chamada

LerImpressora ao qual será criada com a seguinte

estrutura:

function LerImpressora: String;

var

MyPrinter, MyDriver, MyPort: array[0..100] of

Char;

DevMode: THandle;

begin

Printer.GetPrinter(MyPrinter, MyDriver, MyPort,

DevMode);

Result := MyPrinter;

end;

Para essa function LerImpressora funcionar devemosdeclarar a unit Printers na seção implementation e tambémdeclarar essa function acima da seção var da unit. Conformeexemplo abaixo:

function LerImpressora: String;

var

Form1: TForm1;

Neste momento podemos gravar o projeto e testá-lo, ao qualfará a impressão na impressora selecionada como padrão noWindows.

Entendendo os comandos utilizados.Como podemos observar, é bastante simples a criação de

relatórios utilizando essas funções da unit WinSpool. Sendoassim vamos aproveitar para verificar os detalhes de cada funçãoutilizada no Exemplo1.

OpenPrinter(PChar( NomeImp ), hPrinter, nil)Retorna o controle identificando a impressora ou servidor de

impressora especificado.Param1 - String que especifica o nome da impressora ou

servidor de impressora.Param2 - Variável que recebe o handle de identificação da

impressora aberta.Param3 - Este valor pode ser nulo.

StartDocPrinter(hPrinter, 1, @DocInfo)Informa ao Spooler de impressão que o documento pode ser

armazenado no Spool para impressão.Param1 – Identifica a impressoraParam2 – Especifica a versão da estrutura a ser usada. Para

o Windows 95 devemos especificar o valor 2 e as demais versõesdevemos especificar o valor 1.

Param3 – Variável do tipo TDocInfo1

StartPagePrinter(hPrinter)Informa ao Spooler que uma página está a ponto de ser

impressa na impressora especificada.Param1 – Identifica a impressora

WritePrinter(hPrinter, PChar(Texto),Length(Texto), BytesWritten);

Informa ao Spooler quais os dados a serem enviados para aimpressora selecionada.

Param1 – Identifica a impressoraParam2 – Array de bytes que contém os dados que deverão

ser enviados para a impressoraParam3 – Especifica o tamanho, em bytes, do Array

Page 6: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE66666

DelphiDelphiDelphiDelphiDelphi

Param4 – Variável que conterá a quantidade de bytesenviados para a impressora.

EndPagePrinter(hPrinter);Informar o fim da página atual e o começo da página

seguinte para a impressora especificada.Param1 - Identifica a impressora

EndDocPrinter(hPrinter);Finaliza o trabalho de impressão.Param1 - Identifica a impressora

ClosePrinter(hPrinter);Fecha a impressora especificada.Param1 - Identifica a impressora a ser fechada.

Maiores detalhes sobre essas e outras funções existentes naunit WinSpool recomendo que sejam verificadas através do helpdo Delphi.

Criando um projeto mais complexo.Como agora já conhecemos um pouco como trabalhar com

essas funções, deixaremos as idéias fluírem e começaremos autilizá-las de uma forma mais complexa. Como por exemplo,criar um projeto onde fazemos a impressão de dados de um bancode dados separando os campos por coluna, e fazendo o controle daimpressão de cabeçalho. Sendo assim mãos a obra.

Primeiro passo crie um novo projeto no Delphi, chamadoExemplo2, e em seguida adicione um novo form neste projeto.

Para o Form principal deixaremos o nome Form1 mesmo,para o segundo form coloque FrmPreview e unPreview para asua unit.

A idéia desse projeto é criar uma estrutura genérica paraimpressão de relatórios utilizando as funções da unit WinSpool,sendo assim essa unit unPreview com o FrmPreview poderão serutilizados em outros projetos para a geração de relatórios rápidos.

Começaremos a montar o FrmPreview, sendo assim coloqueneste form um componente Memo, altera a sua propriedadeAlign para o valor alClient e na propriedade Font / Nameselecione a fonte Courier New.

DeclaraçõesVisualize a unit unPreview e nesta unit faça as declarações

que estão especificadas a seguir:

Declarar na seção Private uma variável do tipo string

chamada ArqPreview

private

ArqPreview: String;

public

end;

Declarar acima da seção var as Functions e Procedures queimplementaremos na unit, veja a seguir:

function GeraArqTemp: String;

function LerImpressora: String;

function Imp_Inicio(Const pNomeImp, pNomeTrabalho,

pTipo: String; pPreview: Boolean): Boolean;

procedure Imp_InicializaPagina;

procedure Imp_Fim;

procedure Imp_Linha(SaltaLin, EspacoCol: Integer;

Texto: String; TamTotal: Integer; Alinha: Char);

procedure Imp_Ejeta;

Declarar na seção var duas variáveis, veja a seguir:

var

FrmPreview: TFrmPreview;

hPrinter: THandle;

BytesWritten: DWORD;

E na seção implementation declarar as units WinSpool ePrinters, veja a seguir:

implementation

Uses WinSpool, Printers;

Implementando as Functions e ProceduresA primeira function que iremos implementar na unit, será a

LerImpressora que é responsável por retornar informações daimpressora atualmente selecionada para impressão. Essafunction ficará com a seguinte estrutura:

function LerImpressora: String;

var

MyPrinter, MyDriver, MyPort: array[0..100]

of Char;

DevMode: THandle;

begin

Printer.GetPrinter(MyPrinter, MyDriver,

MyPort, DevMode);

Result := MyPrinter;

end;

Page 7: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 77777

DelphiDelphiDelphiDelphiDelphi

A próxima function é a Imp_Inicio ao qual será responsávelpor inicializar a impressão passando as informações necessáriaspara o Spool da impressora. Nesta function utilizaremos osseguintes parâmetros:

pNomeImp – Nome da impressora para onde o trabalho deimpressão será enviado

pNomeTrabalho – Nome do trabalho de impressão que seráapresentado na fila do Spool

pTipo – Passar o valor RAW ou TEXT. RAW - deixou a impressão na matricial mais rápida TEXT - imprimiu com impressora USBpPreview – Indica se iremos mostrar um preview do relatório

Essa function Imp_Inicio tem um retorno do tipo Boolean aoqual indicará se a inicialização do relatório foi realizada comsucesso e se podemos começar a impressão dos dados. Veja aestrutura da function Imp_Inicio a seguir:

function Imp_Inicio(Const pNomeImp, pNomeTrabalho,

pTipo: String; pPreview: Boolean): Boolean;

var

DocInfo: TDocInfo1;

begin

Result := False;

if not WinSpool.OpenPrinter(PChar( pNomeImp ),

hPrinter, nil) then

raise exception.create(‘THE CLUB -

Impressora não encontrada!’);

DocInfo.pDocName := PChar( pNomeTrabalho );

DocInfo.pOutputFile := nil;

if pPreview then

begin

DocInfo.pOutputFile := PChar( GeraArqTemp );

FrmPreview := TFrmPreview.Create( Nil );

FrmPreview.ArqPreview := DocInfo.pOutputFile;

end;

DocInfo.pDatatype := PChar( pTipo );

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then

Exit;

if not StartPagePrinter(hPrinter) then

Exit;

Result := True;

end;

Nesta function Imp_Inicio fazemos uma chamada para afunction GeraArqTemp, ao qual será responsável pela criação donome do arquivo temporário que armazenará o relatório para serapresentado no Preview, caso o usuário selecione visualizar orelatório no Preview. Essa function terá a seguinte estrutura:

function GeraArqTemp: String;

var

TempDir: array[0..MAX_PATH] of char;

Buffer : array[0..MAX_PATH] of Char;

begin

GetTempPath(MAX_PATH, @TempDir);

GetTempFileName(@TempDir, ‘CLUB’, 0, Buffer);

Result := Buffer;

end;

Esta procedure GetTempfileName utilizada necessita dosseguintes parâmetros:

Parametros 1. Diretorio, 2. Prefixo, 3. 0 -> indica que não irá repetir o nome do arquivo, 4. Variável que irá receber o nome gerado

A procedure Imp_InicializaPagina é responsável pelainicialização da página que será enviada para o Spool deimpressão. Essa procedure terá a seguinte estrutura:

procedure Imp_InicializaPagina;

begin

if not StartPagePrinter(hPrinter) then

raise exception.create(‘THE CLUB -

Problemas na inicialização da página!’);

end;

Em seguida iremos criar a próxima function que será aImp_Fim, ao qual será responsável pela finalização do relatório.Essa procedure terá a seguinte estrutura:

procedure Imp_Fim;

begin

EndPagePrinter(hPrinter);

EndDocPrinter(hPrinter);

WinSpool.ClosePrinter(hPrinter);

if Assigned( FrMPreview ) then

begin

try

FrmPreview.Memo1.Lines.LoadFromFile

( FrmPreview.ArqPreview );

FrMPreview.ShowModal;

{ Exclui o arquivo temporário }

try

DeleteFile( FrmPreview.ArqPreview );

except end;

Page 8: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE88888

DelphiDelphiDelphiDelphiDelphi

finally FreeAndNil( FrMPreview ); end; end;end;

Nesta procedure também iremos apresentar o form contendoa visualização dos dados em preview. Mas iremos observar que éum preview bem simples, ao qual foi criado para mostrar quepodemos criar um arquivo contendo os dados enviados para aimpressora.

A próxima procedure a ser criada é a Imp_Linha ao qual seráutilizada para fazer a impressão das linhas do relatório. Nestaprocedure implementamos alguns controles a mais, como porexemplo, impressão da linha com ou sem o salto da linha,espaçamento para fazer impressão em coluna e alinhamento adireita ou a esquerda dessas colunas.

Os parâmetros criados para essa procedure foram:SaltaLin - Qtde de linhas que saltará a partir da última linha

impressaEspacoCol - Espaço em caracteres que existirá entre as

colunasTexto - String a ser impressaTamTotal - Tamanho total da string, utilizado para

impressão em colunaAlinha - Alinhamento da coluna E = Esquerda - D = Direita

A estrutura da procedure ficará da seguinte forma:

procedure Imp_Linha(SaltaLin, EspacoCol: Integer;

Texto: String; TamTotal: Integer; Alinha: Char);

var

i: integer;

Espaco: string;

begin

{ adiciona as linhas }

for i:=1 to SaltaLin do

WritePrinter(hPrinter, PChar(#13+#10),

Length(#13+#10), BytesWritten);

{ Calcula o espaço q determinado o tamanho total

do campo }

Espaco := StringOfChar(‘ ‘, TamTotal-

Length(Texto));

if Alinha = ‘E’ then

Texto := Texto+Espaco

else if Alinha = ‘D’ then

Texto := Espaco+Texto;

{ adiciona espaço entre as colunas }

Texto := StringOfChar(‘ ‘, EspacoCol)+Texto;

{ Imprime o texto }

WritePrinter(hPrinter, PChar(Texto),

Length(Texto), BytesWritten);

end;

A última procedure a ser implementada nesta unit é aprocedure Imp_Ejeta, ao qual será responsável pela salto depágina e pela controle de finalização da página atual no Spool.

A estrutura dessa procedure ficará da seguinte forma:

procedure Imp_Ejeta;

var ch: Char;

begin

ch:= #12;

WritePrinter( hPrinter, @ch, 1, BytesWritten );

EndPagePrinter(hPrinter);

end;

Pronto, neste momento finalizamos a criação da unit quepoderá ser utilizada na criação de qualquer relatório em nossosprojetos.

Utilizando a unit unPreviewA segunda parte desse projeto será a utilização dessas

functions e procedures que criamos na unit unPreview. Sendoassim volte ao form principal do nosso projeto e coloque osseguintes componentes descritos a seguir:

Table,DataSource,DBNavigatorDBGridPrintDialogPanel - Dentro desse Panel coloque os seguintes componentes:GroupBox - Dentro desse GroupBox coloque um Label3 componentes ButtonRadioGroupCheckBox

Esses componentes serão configurados da seguinte forma:

Componente TableName: Table1DatabaseName: DBDEMOSTableName: Employee.db

Componente DataSourceName: DataSource1DataSet: Table1

Page 9: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 99999

DelphiDelphiDelphiDelphiDelphi

Componente DBNavigatorName: DBNavigator1Align: alTopDataSource: DataSource1

Componente PanelName: Panel1Align: alBottomCaption: vazio

Componente DBGridName: DBGrid1Align: alClientDataSource: DataSource1

Componente PrintDialogName: PrintDialog1

Componente GroupBoxName: GroupBox1Caption: Impressora selecionada

Componente LabelName: Label1

Componente RadioGroupName: RadioGroup1Caption: TipoColumns: 1ItemIndex: 0Items: RAW TEXT

Componente CheckBoxName: CheckBox1Caption: Preview

Componentes ButtonsName: Button1Caption: Imprimir registros

Name: Button2Caption: Selecionar Impressora

Name: Button3Caption: Relatório Simples

Após configurar todos esses componentes o form ficaráparecido com a imagem 1. (abaixo)

No evento onclick dos botões iremos montar os relatóriosutilizando as instrução da unit unPreview, sendo assim oprimeira passo é declarar na seção implementation a unitunPreview, conforme exemplo a seguir:

implementation

Uses UnPreview;

Iniciaremos com o Button2 onde iremos chamar oPrintDialog para que assim o usuário possa selecionar aimpressora a ser utilizada:

procedure TForm1.Button2Click(Sender: TObject);

begin

Page 10: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 01 01 01 01 0

DelphiDelphiDelphiDelphiDelphi

if PrintDialog1.Execute then

Label1.Caption := LerImpressora;

end;

No evento onclick do Button3 criaremos um relatóriobastante simples ao qual nos permitirá fazer um teste deimpressão. A instrução desse evento ficará da seguinte forma:

procedure TForm1.Button3Click(Sender: TObject);

{ Observação: Caracteres utilizados para impressora

Epson }

Const

NegOn = #27+#71; NegOff = #27+#71;

ItaOn = #27+#52; ItaOff = #27+#52;

CondOn = #15; CondOff = #18;

begin

{ Imprimindo um simples relatório com

EPSON FX-1170 }

if Imp_Inicio( Label1.Caption, ‘Impressão de

relatório Simples - THE CLUB’, ‘RAW’,

CheckBox1.Checked) then

begin

Imp_InicializaPagina;

Imp_Linha(01, 00, ‘Essa e a primeira linha

do relatorio’, 0, ‘D’);

Imp_Linha(00, 20, ‘Segunda coluna impressa’,

0, ‘D’);

Imp_Linha(01, 00, NegOn+’Negrito’+NegOff, 0,

‘D’);

Imp_Linha(00, 10, ItaOn+’Italico’+ItaOff, 0,

‘D’);

Imp_Linha(00, 10, CondOn+’Condensado Primeira

linha’, 0, ‘D’);

Imp_Linha(00, 10, ‘Condensado Segunda

linha’+CondOff, 0, ‘D’);

Imp_Ejeta;

Imp_InicializaPagina;

Imp_Linha(01, 00, ‘Imprimindo a próxima

página do relatório’, 0, ‘D’);

Imp_Linha(01, 00, ‘Segunda linha impressa’, 0,

‘D’);

Imp_Ejeta;

Imp_Fim

end;

end;

Finalizando iremos criar o relatório principal ao qual imprimeos dados do componente Table e faz o controle de cabeçalho ecoluna. A seguir podemos verificar as instruções criadas dentrodo evento onClick do Button1.

procedure TForm1.Button1Click(Sender: TObject);

var nLin: Integer;

Tipo: String;

procedure Cabecalho;

begin

Imp_InicializaPagina;

{ Impressão do Cabeçalho }

Imp_Linha(01, 00, ‘Código’, 6, ‘E’);

Imp_Linha(00, 03, ‘Nome’, 15, ‘E’);

Imp_Linha(00, 02, ‘Sobrenome’, 24, ‘E’);

Imp_Linha(00, 02, ‘Data’, 10, ‘E’);

Imp_Linha(00, 01, ‘Valor’, 12, ‘D’);

Imp_Linha(01, 00, StringOfChar(‘-’, 80), 80,

‘E’);

nLin := nLin + 2;

end;

begin

Table1.First;

if RadioGroup1.ItemIndex = 0 then

Tipo := ‘RAW’ // Dica: Imprime com matricial

// Epson mais rápido

else

Tipo := ‘TEXT’; // Dica: Funciona para

// impressora USB

if Imp_Inicio( Label1.Caption, ‘Impressão de dados

Employee - THE CLUB’, Tipo, CheckBox1.Checked) then

begin

{ Impressão dos dados }

nLin := 0;

While not Table1.Eof do

begin

if nLin = 0 then

begin

Cabecalho;

end;

Imp_Linha(01, 00, Table1.FieldByName

(‘EmpNo’).AsString, 5, ‘D’);

Imp_Linha(00, 04, Table1.FieldByName

(‘FirstName’).AsString, 15, ‘E’);

Imp_Linha(00, 02, Table1.FieldByName

(‘LastName’).AsString,

Table1.FieldByName(‘LastName’).

DisplayWidth, ‘E’);

Imp_Linha(00, 02, FormatDateTime

(‘dd/mm/yyyy’, Table1.FieldByName

(‘HireDate’).AsDateTime), 10, ‘E’);

Imp_Linha(00, 01, FormatFloat(‘###,##0.00’,

Page 11: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 11 11 11 11 1

DelphiDelphiDelphiDelphiDelphi

Table1.FieldByName(‘Salary’).asFloat),

Table1.FieldByName(‘Salary’).DisplayWidth, ‘D’);

Inc( nLin );

if nLin >= 62 then

begin

Imp_Ejeta;

nLin := 0;

end;

Table1.Next;

end;

Imp_Ejeta;

Imp_Fim

end;

end;

Pronto, neste momento estamos com o projeto de relatórioquase pronto, faltando somente implementar o evento onShow doForm onde abriremos a Table1 e iremos mostrar qual aimpressora que está selecionada como padrão. Veja exemplo doevento onShow do form a seguir:

procedure TForm1.FormShow(Sender: TObject);

begin

Table1.Open;

Label1.Caption := LerImpressora;

end;

Agora podemos compilar o nosso projeto e efetuar os testes deimpressão e de apresentação do preview.

Redefinindo o Whiteln da unit SystemEspero que não estejam cansados, pois temos um último

exemplo a seguir ao qual nos ajudará bastante caso já tenhamoscriado algum relatório utilizando os comandos AssignFile,ReWrite, Writeln e CloseFile da unit System.

A idéia desse novo projeto é redirecionar as chamadas dasprocedures da unit System para as procedures da unit queiremos criar, sendo assim toda vez que seu projeto chamar umaimpressão pelo Writeln ele estará chamando a procedure Writelnque iremos criar ao qual usará a impressão pelo WritePrinter.Vamos entender melhor assim que criarmos o projeto de exemplo,portanto mãos a obra.

Crie um novo projeto, chamado Exemplo3, e neste novoprojeto crie uma nova unit sem form chamada unImpTH.

Nesta unit unImpTH iremos iniciar os trabalhos com asdeclarações, pois precisamos declarar na seção Uses as seguintes

units:

Uses Windows, WinSpool, Printers, SysUtils, Dialogs;

Depois necessitamos declarar as procedure e functions queserão criadas posteriormente.

function LerImpressora: String;

procedure AssignFile(var FTH: TextFile;

FileNameTH: String);

procedure CloseFile(var FTH: TextFile);

procedure WriteLn(var FTH: TextFile;

TextoTH: String);

procedure ReWrite(var FTH: TextFile);

E para finalizar as declarações iremos declarar duasvariáveis na seção var.

var

hPrinter: THandle;

BytesWritten: DWORD;

Agora iremos implementar as procedures e function, sendoassim iniciaremos com a function LerImpressora, ao qualconterá as seguintes instruções:

function LerImpressora: String;

var

MyPrinter, MyDriver, MyPort: array[0..100]

of Char;

DevMode: THandle;

begin

Printer.GetPrinter(MyPrinter, MyDriver,

MyPort, DevMode);

Result := MyPrinter;

end;

Em seguida criaremos a procedure AssigFile ao qual devemoscriar com parâmetros idênticos aos da procedure da unit System,ficando a procedure da seguinte forma:

procedure AssignFile(var FTH: TextFile; FileNameTH:

String);

var

DocInfo: TDocInfo1;

PD: TPrintDialog;

begin

{ Chama o PrintDialog para selecionar a

impressora }

PD := TPrintDialog.Create(Nil);

Page 12: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 21 21 21 21 2

DelphiDelphiDelphiDelphiDelphi

try

if not PD.Execute then

Exit;

finally

PD.Free;

end;

if not WinSpool.OpenPrinter(PChar( Printer.

Printers[Printer.PrinterIndex] ),

hPrinter, nil) then

raise exception.create(‘THE CLUB -

Impressora não encontrada!’);

DocInfo.pDocName := ‘Impressão THE CLUB’;

DocInfo.pOutputFile :=

PChar( FileNameTH );//’c:\arq.txt’;

{ Foi testado o DataType com o valor RAW e TEXT

RAW -> deixou a impressão matricial mais rápida

TEXT -> imprimiu com impressora USB }

DocInfo.pDatatype := ‘RAW’;

if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then

Exit;

if not StartPagePrinter(hPrinter) then

Exit;

end;

A próxima procedure será a ReWrite, mas essa somente serácriada para anular a chamada da procedure da unit System, poisnão implementaremos nenhuma funcionalidade na mesma. Vejaa procedure a seguir:

procedure ReWrite(var FTH: TextFile);

begin

// criado somente para anular a

// function da unit System

Exit;

end;

A procedure CloseFile é a próxima a ser criada e esta seráutilizada para finalizar a impressão da página e do relatório,conforme pode ser observado a seguir:

procedure CloseFile(var FTH: TextFile);

begin

EndPagePrinter(hPrinter);

EndDocPrinter(hPrinter);

WinSpool.ClosePrinter(hPrinter);

end;

E para finalizar criaremos as procedures Write e Writeln aoqual farão a impressão dos dados para a impressora, veja queseguem com os mesmos parâmetros das originais.

procedure Writeln(var FTH: TextFile; TextoTH:

String);

begin

TextoTH := TextoTH + #13+#10;

WritePrinter(hPrinter, PChar(TextoTH),

Length(TextoTH), BytesWritten);

end;

procedure Write(var FTH: TextFile; TextoTH: String);

begin

WritePrinter(hPrinter, PChar(TextoTH),

Length(TextoTH), BytesWritten);

end;

Bem neste momento finalizamos a criação da unit unImpTHe agora podemos fazer o teste implementando no projeto umsimples relatório usando o Writeln para impressão.

No início usaremos o Writeln da unit System e depois iremosdeclarar a nossa unit unImpTH e poderemos observar o mesmorelatório sendo impresso utilizando o Spool de impressão.

Implementando o form Principal do projetoNo form principal coloque dois botões, configurando-os da

seguinte forma:

Button1Caption: Exemplo de Whiteln – 1

Button2Caption: Exemplo de Writeln – 2

Após configurar os dois botões o form do projeto ficaráparecido com a imagem2. (abaixo)

Page 13: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 31 31 31 31 3

DelphiDelphiDelphiDelphiDelphi

No evento onclick do Button1 iremos incluir a seguinteinstrução:

procedure TForm1.Button1Click(Sender: TObject);

var F: TextFile;

begin

{ Manda para impressora na rede }

AssignFile(f, ‘\\Servidor\EpsonFX’);

Rewrite(f);

Writeln(f, ‘Linha1’);

Write(f, ‘Linha1’);

Writeln(f, ‘Linha2’);

CloseFile(f);

end;

No evento onclick do Button2 iremos incluir a seguinteinstrução:

procedure TForm1.Button2Click(Sender: TObject);

var Texto1 : string;

F : TextFile;

Valor : Extended;

T : Integer;

begin

{ Gerar um arquivo }

AssignFile(F,’c:\writeln.txt’);

Rewrite(F);

T := 21; { Tamanho total da string,

que deverá ser impresso }

Texto1 := ‘THE CLUB’;

Valor := 1.00;

Writeln(F,Format(‘%s%’+IntToStr

(T-Length(Texto1))+’s%8.2f’,

[Texto1,’ ‘,Valor])+

‘Fim da linha’);

Texto1 := ‘THE CLUB DELPHI DELP’;

Valor := 100.21;

Writeln(F,Format(‘%s%’+IntToStr

(T-Length(Texto1))+’s%8.2f’,

[Texto1,’ ‘,Valor])+’Fim da linha’);

Texto1 := ‘THE’;

Valor := 1000.10;

Writeln(F,Format(‘%s%’+IntToStr

(T-Length(Texto1))+’s%8.2f’,

[Texto1,’ ‘,Valor])+’Fim da linha’);

Writeln(F,#12); // Ejeta a página

CloseFile(F);

end;

Vejam que esses dois exemplos foram criados utilizando aprocedures da unit System do Delphi.

Neste momento se compilarmos o projeto poderemos observarque os relatórios serão impressos sem passar pelo Spool deimpressão.

Agora para passarmos a utilizar as procedures da nossa unitunImpTH, basta declará-la na seção implementation do seuprojeto.

Um detalhe importante, sempre essa unit unImpTH deve serdeclarada depois da unit System, por esse motivo que a colocamosna seção implementation, conforme exemplo abaixo:

implementation

Uses UnImpTH;

Pronto, faça novamente os testes no relatório e poderáobservar que o mesmo foi impresso utilizando o spool daimpressora e as procedure da nossa unit unImpTH.

ConclusãoBem, aqui finalizamos um artigo que gostei bastante, pois

nos trará um pouco mais de recurso para as impressões rápidaspelo Delphi.

Um grande abraço a todos e um 2004 com muita Paz, Saúdee bons negócios.

Até a próxima.

DownloadOs projetos de exemplo deste artigo estão disponíveis para

download em:

http://www.theclub.com.br/revista/download/Imp-WritePrinter.zip

Sobre o autorAndré ColaviteConsultor Técnico do The [email protected]

Page 14: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 41 41 41 41 4

DelphiDelphiDelphiDelphiDelphi

Quase todos os códigos que você escreve são executados diretaou indiretamente em resposta a algum evento. Um evento é umtipo especial de propriedade que representa uma ocorrência emtempo de execução, muitas vezes uma ação do usuário. O códigoque responde diretamente a um evento, chamado controlador deevento, é uma procedure do Delphi.

Gerando um novo controlador de eventoVocê pode gerar um esqueleto de um evento para ser utilizado

por um form ou para outros componentes. Para criar umcontrolador de evento faça o seguinte:

1 – Selecione um componente.2 – Vá até o Object Inspector e clique na aba Events. A partir

daí você terá acesso a todos os eventos do componente selecionado.3 – Selecione o evento que você quiser e então dê um duplo

clique ou pressione as teclas Ctrl+Enter simultaneamente. Istofará com que o editor de código do Delphi seja acionado e o cursorseja posicionado dentro do esqueleto do evento, mais precisamentedentro do bloco begin...end.

4 – Agora basta você digitar o código que você quer que sejaexecutado assim que este evento for disparado.

Gerando um controlador para um evento default.Alguns componentes tem um evento default, que é o evento

chamado com mais freqüência. Por exemplo, o evento padrão docomponente Button é o evento OnClick. Para saber qual é oevento default de um determinado componente basta que emtempo de desenvolvimento você dê um duplo clique sobre ocomponente. Então o editor de código do Delphi será acionado e ocursor será posicionado dentro do esqueleto do evento, no blocobegin...end. Mas vale lembrar que nem todos os componentes temevento default. Alguns componentes como o TBevel por exemplonão responde a qualquer evento. Outros componentes respondemde forma diferente quando se dá um duplo clique. Por exemplo,alguns componentes abrem um editor de código ou uma janela dediálogo.

Localizando eventosSe você gerou um evento default para um determinado

componente através de um duplo clique, você pode localizaraquele evento da mesma forma, ou seja, dê um duplo clique sobre

o componente e então o editor de código do Delphi será acionado eo cursor será posicionado dentro do esqueleto do evento. Paralocalizar um evento que não é default, faça o seguinte:

1 – No form, selecione o componente ao qual você querprocurar pelo evento.

2 – Vá até o Object Inspector e clique na aba Events3 – Selecione o evento que você quiser e então dê um duplo

clique ou pressione as teclas Ctrl+Enter simultaneamente. Istofará com que o editor de código do Delphi seja acionado e o cursorseja posicionado dentro do esqueleto do evento, mais precisamentedentro do bloco begin...end.

Associando um evento com outro evento jáexistente

Você pode reutilizar um código fazendo que um determinadoevento responda para mais de um evento. Por exemplo, muitasaplicações fazem com que alguns botões sejam equivalentes acomandos do menu. Sendo assim em sua aplicação, quando umbotão for executar a mesma coisa que um determinado item domenu você pode fazer com que eles compartilhem do mesmoevento.

Vamos fazer um teste:1 – No form inclua um componente MainMenu e um

componente Button.2 – Dê um duplo clique no componente Button para que o

evento default seja ativado e então digite o seguinte:

procedure TForm1.Button1Click(Sender: TObject);

begin

ShowMessage(‘Evento OnClick do botão.’);

end;

3 – Agora crie alguns itens no componente MainMenu.Selecione um dos itens e vá até o Object Inspector. Clique na abaEvents e selecione o evento OnClick. Clique no botão onde temuma setinha para baixo. Fazendo isto lhe aparecerá o nome doevento OnClick do botão, por exemplo Button1Click. Selecioneeste item e compile o programa.

Agora você pode clicar no botão ou no item do menu do quevocê escolheu que ambos usarão a mesma procedure ou evento.

Trabalhando com eventosTrabalhando com eventosTrabalhando com eventosTrabalhando com eventosTrabalhando com eventosPor Claudinei Rodrigues

Page 15: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

DelphiDelphiDelphiDelphiDelphi

Este é o caminho mais simples para se reutilizar eventos. ODelphi também fornece o Action Lists, Action Bands que tambémpermitem este reaproveitamento de código. Mas falaremos maissobre estes componentes numa outra oportunidade.

Usando o parâmetro SenderO parâmetro Sender de um evento indica qual componente

chamou um determinado evento. Algumas vezes ele é muito útilquando se tem vários componentes compartilhando o mesmoevento comportando-se de forma diferente dependendo de qualcomponente o chamou. Você pode fazer isto utilizando oparâmetro Sender em uma instrução if...then....else.

Tomando como exemplo a rotina que escrevemosanteriormente, vamos fazer uma modificação no evento OnClickdo botão. Como você pode ver a seguir nós estamos verificandoatravés do Sender qual o componente que chamou o evento.Outro detalhe interessante é que o Sender tem uma propriedadechamada ClassName que retorna o nome da classe docomponente que a chamou.

procedure TForm1.Button1Click(Sender: TObject);

begin

if Sender = Button1 then

ShowMessage(‘Este evento foi chamado pelo

Button1.’)

else

ShowMessage(‘Este evento foi chamado

pelo ‘+Sender.ClassName); end;

Deletando eventosQuando você deleta um componente do form, o próprio Delphi

remove a declaração do componente da unit, mas os eventos nãosão removidos. Caso você tenha algum outro componenteassociado ao evento deste componente que você acabou de deletar,ele continuará funcionando. Você pode deletá-los manualmente,mas se você for fazer isto, não esqueça que além da procedurevocê também deve remover a declaração que está no inicio daunit. Caso isto não seja feito, um erro ocorrerá no sistema.

ConclusãoO objetivo deste artigo foi dar uma idéia de como se utilizar os

eventos no Delphi para programadores iniciantes nestaferramenta. O Delphi é uma linguagem muito poderosa que nosdá inúmeros recursos.

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

Page 16: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 61 61 61 61 6

RetrospectivaRetrospectivaRetrospectivaRetrospectivaRetrospectiva

RetrospectivaRetrospectivaRetrospectivaRetrospectivaRetrospectiva

Este mês em nossa restrospectiva, chegamos a 1998, com o lançamento do Delphi4 e claro, sua grande aceitação por parte do mercado.

Também tivemos uma matéria sobre o ADO, tecnologia recém lançado pelaMicrosoft e que viria a se tornar um padrão para acesso à banco de dados empraticamente todas as linguagens de programação. Esta matéria, escrita por MauroSant’Anna, mostrou que a utilização do ADO deixava mais rápido o acesso ao bancode dados do que as outras tecnologias existentes. No mercado também começavama aparecer empresas que vendiam componentes ADO específicos, como oADOSolutions, Adonis, etc.

O nosso amigo Mário Camilo Bohm também participou, com uma matéria sobretravamento de registros com o banco de dados Oracle.

Importante lembrar também que haviam pessoas neste ano que ainda estavamresistentes a trocar o seu velho Windows 95 pelo Windows 98, o que gerava muitosproblemas e aborrecimentos, tantos para nós desenvolvedores quantos para osusuários finais.

Em Setembro/98 a Microsoft estava para saber o que iria acontecer sobre oprocesso que a Sun moveu contra ela, por causa do Java, alegando que a Microsofthavia alterado o código do Java, assim quebrando a filosofia do "escreva uma vez,rode em qualquer lugar". Mais tarde veríamos que o Java, apesar de uma linguagempoderosa, não costumava "rodar em qualquer lugar", e tampouco houveconsequências graves para a Microsoft, apesar dos apuros que ela passou, inclusivecom o processo dos mais de 20 estados americanos, com a acusação de monopólio.

Enfim, 98 foi um ano interessante e cheio de novidades! Ele deixou saudades...

Até o mês que vem!

Page 17: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,
Page 18: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE1 81 81 81 81 8

DelphiDelphiDelphiDelphiDelphi

Salve, salve Delphianos!

Antes de concluir a última parte do artigo sobre WebServices,vamos iniciar uma luta inglória contra o Intraweb. Calma,calma! Não quero destruir o Intraweb, e sim demonstrar o queresta de bom nesta “fantástica” ferramenta.

Neste artigo, iniciaremos o desenvolvimento de aplicaçãocompleta para Intraweb, extraída do meu livro Delphi 7 Internete Banco de Dados.

Antes de iniciar nosso projeto com banco de dados, devemoscriar nossa base no Firebird/Interbase.

Figura 1 Registrando Servidor Local Interbase Figura 2 criação do banco de dados Clientes.GDB

Entre no IBConsole e caso não tenha registrado o ServidorLocal, selecione a opção Server/Register e informe aspropriedades conforme a figura 1.

No campo UserName digite SYSDBA (com letras maiúsculas),e no campo PassWord digite masterkey (com letras minúsculas).Estas informações são para o usuário padrão.

Agora vamos criar o banco de dados Clientes.GDB.

Selecione a opção DataBase/Create Database e crie um novobanco de dados como ilustra a figura 2.

Por Emerson Facunte

IntraWebIntraWebIntraWebIntraWebIntraWebProgramação AlternativaProgramação AlternativaProgramação AlternativaProgramação AlternativaProgramação Alternativa

Page 19: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 1 91 91 91 91 9

DelphiDelphiDelphiDelphiDelphi

Agora iremos criar os objetos do banco de dadosClientes.GDB.

Dentro do Interative SQL execute os seguintes comandos:

Criação da Tabela TBCLIENTEcreate table tbcliente( cod_cliente integer not null, razao_social varchar(50), endereco varchar(50), cidade varchar(50), estado varchar(2), cep varchar(8), email varchar(50), primary key (cod_cliente) );

Execute o comando através das teclas CTRL-E.

Criação do Generatorcreate generator gen_clientes;

Execute o comando através das teclas CTRL-E.

Criação da Trigger TGClientesset term ||;

CREATE TRIGGER TG_CLIENTES FOR TBCLIENTEACTIVE BEFORE INSERT POSITION 0A SBEGIN NEW.COD_CLIENTE = GEN_ID(GEN_CLIENTES,1);END ||SET TERM;

Execute o comando através das teclas CTRL-E. Com issofinalizamos a criação dos objetos.

Finalize o IBConsole, e vamos iniciar nossas atividades noDelphi.

Através das opções File/New/Other..., selecione a seçãoIntraweb e escolha o modelo Stand Alone Application with DataModule (figura 3).

Selecione o DataModule e insira um objeto do tipoTSQLConnection. Através do duplo-clique, já na tela deconfiguração, aponte para a nossa conexão Clientes, criadaanteriormente.

Figura 3 Iniciando a aplicação

Altere também a propriedade LoginPrompt para false.Nunca esqueça de fazer esta alteração, pois numa aplicaçãoservidora, não existe a possibilidade do usuário interagir no logindo banco de dados.

Agora vamos inserir o objeto para manipular nossa tabela declientes. Insira um objeto do tipo TSQLDataSet, e altere asseguintes propriedades:

Objeto de InclusãoInsira um objeto do tipo TSQLQuery e altere as propriedades

que seguem.

Na propriedade PARAMS do SQLInclui altere os tipos dosparâmetros para String.

Page 20: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 02 02 02 02 0

DelphiDelphiDelphiDelphiDelphi

Objeto de AlteraçãoInsira um objeto do tipo TSQLQuery e altere as propriedades

que seguem.

Na propriedade PARAMS do SQLAltera altere os tipos dosparâmetros para String, com exceção do parâmetro PCODIGO,que deve ser Integer.

Objeto de ExclusãoInsira um objeto do tipo TSQLQuery e altere as propriedades

que seguem.

Na propriedade PARAMS do SQLExclui altere o tipo doparâmetro para Integer.

Criando o Formulário PrincipalNo formulário principal (FormMain), adicione um componente

do tipo TMainMenu, e configure as opções como segue:

Arquivo SobreInclusão Clientes InformaçõesManutenção/ConsultaFinaliza

A figura 4 ilustra o nosso menu principal.

Insira um objeto do tipo TIWMenu (seção IW Standard), ealtere a propriedade Attached Menu para MainMenu1. Narealidade estamos vinculando nosso objeto MainMenu1 com oIWMenu1 do Intraweb.

Figura 4 Menu Principal

Configure a propriedade BackGroundColor do objeto FormMainpara $00DDFFFF. Amigos, isto é apenas uma sugestão de cor.

Insira os componentes que seguem no FormMain.

A figura 5 ilustra o nosso formulário principal.

Figura 5 Formulário principal

Page 21: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 12 12 12 12 1

DelphiDelphiDelphiDelphiDelphi

Agora iremos codificar duas opções do menu principal:Finaliza e Informações/Sobre.

Selecione a opção Finaliza no objeto MainMenu1 e insira o códigoque segue no evento OnClick.

WebApplication.Terminate(‘Até logo !’);

Neste evento estamos finalizando a aplicação e apresentandoa mensagem “Até Logo !”, ao usuário.

Agora selecione a opção Informações/.Sobre e insira o código quesegue.

WebApplication.ShowMessage(‘Cadastro de Clientes’

+#13#10+ ‘Versão 1.0’,smAlert);

Neste evento apresentamos uma janela de diálogo ao usuário,com as informações da aplicação. Bastante simples, não?

Criando o Formulário de Inclusão

Através das opções File/New/Other..., selecione a seçãoIntraweb e escolha o modelo Application Form (figura 6).

Figura 6 Criando um novo formulário

Altere a propriedade Name do formulário para FmInclusao eBackGroundColor para $00DDFFFF. . Grave a unit com o nomeun_inclusao.

Insira os componentes que seguem no FmInclusao..

Page 22: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 22 22 22 22 2

DelphiDelphiDelphiDelphiDelphi

Agora vamos codificar o formulário.

Insira a unit DataModuleUnit na cláusula uses do formulário.

uses

ServerController, DatamoduleUnit;

No evento OnClick do objeto btDesiste insira o código que segue:

Hide;

Para que possamos retornar ao formulário de origem,utilizamos o método Hide do formulário.

Agora vamos codificar o evento OnClick do objeto btConfirma.

try

{Inclui Cliente}

with DataModule1.SQLInclui do

begin

ParamByName(‘prazao’).Value:=edRazao.Text;

ParamByName(‘pendereco’).Value:=

edEndereco.Text;

ParamByName(‘pcidade’).Value:=edCidade.Text;

ParamByName(‘pestado’).Value:=edUf.Items

[edUf.ItemIndex];

ParamByName(‘pcep’).Value:=edCep.Text;

ParamByName(‘pemail’).Value:=edEmail.Text;

ExecSQL;

end;

WebApplication.ShowMessage(‘Cliente incluido

com sucesso’,smSameWindow);

except

WebApplication.ShowMessage(‘Houve um problema

na inclusão do cliente’, smSameWindow);

end;

Hide;

Vamos analisar o código.

Page 23: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 32 32 32 32 3

DelphiDelphiDelphiDelphiDelphi

Nesta primeira parte, iniciamos um bloco protegido.

try

Em seguida, estamos atribuindo parâmetros ao objetoSQLInclui do DataModule1.

{Inclui Cliente}

with DataModule1.SQLInclui do

begin

ParamByName(‘prazao’).Value:=edRazao.Text;

ParamByName(‘pendereco’).Value:=

edEndereco.Text;

ParamByName(‘pcidade’).Value:=edCidade.Text;

ParamByName(‘pestado’).Value:=edUf.Items

[edUf.ItemIndex];

ParamByName(‘pcep’).Value:=edCep.Text;

ParamByName(‘pemail’).Value:=edEmail.Text;

E finalmente executando a operação e apresentando amensagem de sucesso na operção.

ExecSQL;

WebApplication.ShowMessage(‘Cliente incluido com

sucesso’,smSameWindow);

Figura 7 Formulário inclusão de clientes

Em caso de erro, estamos criando o bloco except.

except

WebApplication.ShowMessage(‘Houve um problema

na inclusão do cliente’, smSameWindow);

end;

E apresentando a mensagem do problema.

A figura 7 ilustra o nosso formulário de inclusão de clientes.

Concluímos a primeira parte do nosso tutorial. Até apróxima.

Imensa luz e sucesso a todos.

Sobre o autorEmerson Facunte é Consultor de Tecnologia

com diversos livros publicados, especialista emdesenvolvimento de aplicações e-businessutilizando a ferramenta Delphi, baseado emwebSnap, dataSnap, BizSnap e ISAPI/ApacheModules.

[email protected]

Page 24: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 42 42 42 42 4

DelphiDelphiDelphiDelphiDelphi

O Object Repository torna mais fácil o compartilhamento deformulários, caixas de diálogo, frames e data modules. Eletambém fornece templates para novos projetos e wizards queguiam o usuário na criação de forms e projetos. O repositório émantido no arquivo Delphi32.dro que fica por default nosubdiretório \BIN. Este arquivo é do tipo texto que contém asreferências para itens que aparecem na caixa de diálogoRepository e New Items.

Compartilhando itens dentro de um projetoVocê pode compartilhar itens dentro de um projeto sem que

seja necessário adicioná-los ao repositório. Quando você abre acaixa de diálogo New Itens, File | New | Other, você verá umapágina com o nome do seu projeto. Esta página lista todos osforms, data modules constantes no seu projeto. Você pode derivarum novo item a partir de um item já existente e modificá-lo deacordo com a sua necessidade.

Adicionando itens ao Object RepositoryVocê pode adicionar seu próprio projeto, forms, frames e data

modules para aqueles já disponíveis no Object Repository. Paraadicionar um item ao Object Repository faça o seguinte:

1 – Se o item é um projeto ou está em um projeto, abra oprojeto.

2 – Para um projeto, escolha Project | Add To Repository.Para um form ou data module, clique com o botão direito no iteme escolha a opção Add To Repository.

3 – Digite uma descrição, titulo e autor.

4 – Informe em qual página você quer que o item apareça nacaixa de diálogo New Item, então digite o nome da página ouselecione alguma que esteja disponível no combobox Page. Se vocêdigitar o nome de uma página que não exista, o Object Repositorycriará uma nova página.

5 – Escolha Browse para selecionar um ícone pararepresentar o objeto no Object Repository.

6 – Clique em OK.

Compartilhando objetosVocê pode compartilhar objetos com o seu grupo de trabalho

ou time de desenvolvimento tornando o repositório disponível narede. Para utilizar um repositório compartilhado, toda a equipedeve acessar o mesmo diretório compartilhado. Sendo assim façao seguinte:

1 – Com o Delphi aberto escolha a opção Tools | EnvironmentOptions.

2 – Na página Preferences, localize o painel SharedRepository.

Em Directory informe o diretório onde você quer localizar orepositório compartilhado. Esteja ciente de informar um diretórioonde toda a equipe de desenvolvimento tenha acesso.

A primeira vez que um item for adicionado ao repositório, umarquivo DELPHI32.DRO será criado no diretório que estácompartilhado.

Usando um item do Object Repository no projeto

Usando oUsando oUsando oUsando oUsando oObject RepositoryObject RepositoryObject RepositoryObject RepositoryObject Repository

Por Claudinei Rodrigues

Page 25: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 52 52 52 52 5

DelphiDelphiDelphiDelphiDelphi

Para acessar um item no Object Repository, escolha File |New | Other.

A caixa de diálogo New Items aparecerá mostrando todos ositens disponíveis. Dependendo do tipo de item que você queirausar, você terá três opções para adicionar o item ao seu projeto:

· Copy· Inherit· Use

Copy - Copiando um itemEscolha Copy para fazer uma cópia exata de um item

selecionado e adicioná-lo em seu projeto. Futuras modificaçõesfeitas no item no Object Repository não serão refletidas em suacópia e as alterações feitas na cópia não irão alterar a original.

Inherit - Herdando um itemEscolha Inherit para derivar uma nova classe a partir de um

item selecionado no Object Repository e adicionar uma novaclasse para o seu projeto. Quando você recompila o seu projeto,qualquer modificação que tenha sido feita para o item no ObjectRepository será refletida em sua classe derivada. As modificaçõesfeitas na classe derivada não terão efeito no item do ObjectRepository. Inherit está disponível para forms, caixa de diálogo edata modules, mas não para projetos. Esta opção é apenas parareutilização de itens dentro de um mesmo projeto.

Use - Usando um itemEscolha a opção Use quando você quiser que o próprio item

selecionado torne-se parte de seu projeto. As modificações feitasneste item serão refletidas em todos os projetos que tem este itemadicionado. Utilize esta opção com muita atenção. A opção Useestá disponível para forms, caixa de diálogos e data modules.

Usando templates de projetosOs templates são projetos pré-designados que você pode usar

como ponto de partida para novos projetos. Para criar um novoprojeto a partir de um template, faça o seguinte:

1 – Escolha File | New | Other para que você tenha acesso acaixa de diálogo New Items.

2 – Escolha a página Projects.3 – Selecione o projeto de template que você quer e pressione

OK.4 – Na caixa de diálogo Select Directory, informe um diretório

onde será armazenado o novo projeto.

Os arquivos de template são copiados para o diretórioespecificado, onde você poderá modificá-los. O projeto original nãoserá afetado.

Modificando os itens compartilhados.Se você modificar um item no Object Repository, sua

modificação irá afetar a todos os novos projetos que usem esteitem assim como os projetos existentes que tenham adicionado oitem com a opção Use ou Inherit. Para evitar a propagação demodificações para outros projetos, você pode fazer o seguinte.

· Copie o item e modifique-o apenas no projeto corrente.· Copie o item para o projeto corrente, modifique-o, e então

adicione-o ao repositório com um outro nome.

Especificando um projeto default, um novo form e um novoform principal

Por default, quando você escolhe File | New | Application ouFile | New | Form, um form em branco aparece.

Você pode modificar este comportamento reconfigurando orepositório.

1 - Vá até o menu do Delphi e clique em Tools|Repository.2 – Se você quiser especificar um projeto default, selecione a

página Projects e escolha um item abaixo de Objects. Entãoselecione o checkbox New Project.

3 – Se você quiser especificar um form default, selecione umapágina do repositório como por exemplo Forms, selecione ocheckbox New Form. Para especificar o form principal para onovo projeto, selecione o checkbox Main Form.

4 – Agora clique em OK.

ConclusãoEste artigo tem o objetivo de oferecer uma explanação sobre o

trabalho com o repositório de objetos. Mais uma opção do Delphique nos auxilia muito no dia a dia. E pra você que ainda nãoconhecia, com certeza isto também lhe será muito útil.

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

Page 26: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 62 62 62 62 6

Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas

Pergunta: Migrei minha aplicação para o IntraWeb 5 eencontrei uma série de problemas. Quais os passos necessáriospara compatibilizar minha aplicação com o IW5?

Resposta: O primeiro passo é ignorar todos os avisos queforem gerados ao abrir o IWForm. Após isso, acesse o arquivo deprojeto DPR e faça as seguintes alterações:

{ Versão Anterior }

program Fishfact;

uses

IWInitStandAlone,

Main in ‘Main.pas’ {formMain: TIWFormModuleBase},

ServerController in ‘ServerController.pas’

{IWServerController: TIWServerControllerBase};

{$R *.res}

begin

IWRun(TFormMain, TIWServerController);

end.

{ Nova Versão }

program Fishfact;

uses

DBClient,

Forms,

IWMain,

Main in ‘Main.pas’ {formMain: TIWFormModuleBase},

ServerController in ‘ServerController.pas’

{IWServerController: TIWServerControllerBase};

{$R *.res}

begin

Application.Initialize;

Application.CreateForm(TformIWMain, formIWMain);

Application.Run;

end.

Agora, abra o formulário principal do projeto IW e adicione aseguinte instrução, antes do final da unit, ou seja, anotes “end.”:

initialization

TformMain.SetAsMainForm;

è TformMain é a classe do seu formulário principal.

Agora, abra o seu ServerController...

{ Versão Anterior }

unit ServerController;

{PUBDIST}

interface

uses

SysUtils, Classes, Forms, IWServerControllerBase;

Page 27: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 72 72 72 72 7

type

TIWServerController =

class(TIWServerControllerBase)

private

public

end;

implementation

{$R *.dfm}

end.

{ Nova Versão }

unit ServerController;

{PUBDIST}

interface

uses

SysUtils, Classes, Forms, IWServerControllerBase;

type

TIWServerController =

class(TIWServerControllerBase)

private

public

end;

implementation

{$R *.dfm}

initialization

TIWServerController.SetServerControllerClass;

end.

Pronto, com isso poderá recompilar e executar a aplicaçãosem problemas!

Dúvida enviada por AT&M Informática Ltda, Sapiranga/RS.

Pergunta: Encontrei um código para registrar um arquivoOCX no registro do Windows mas o mesmo não estáfuncionando! Gostaria de saber o que está errado ou caso tenhaoutro código que faça a mesma coisa, favor me enviar.

Os erros gerados durante a compilação são os seguintes:

[Error] Unit1.pas(30): Undeclared identifier:

‘TDllRegisterServer’[Warning] Unit1.pas(34): Comparing signed and unsigned

types - widened both operands[Fatal Error] Project1.dpr(5): Could not compile used unit

‘Unit1.pas’

Resposta: As classes mencionadas da mensagem de errofazem parte da unit ActiveX, assim sendo, bastará declarar aunit “ActiveX” na lista de units que irá compilar sem problemas.

implementation

uses ActiveX;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

var

OCXHand: THandle;

RegFunc: TDllRegisterServer;

begin

OCXHand := LoadLibrary (‘SeuArquivo.ocx’);

RegFunc:= GetProcAddress

(OCXHand, ‘DllRegisterServer’);

if RegFunc < 0 then

ShowMessage(‘Erro!’);

FreeLibrary (OCXHand);

end;

Dúvida enviada por Atual Tecnologia Em Informatica,Araçatuba/SP.

Pergunta: Gostaria de saber como verificar a versão doDAO instalado na máquina.

Resposta: Para retornar a versão do DAO instalado namáquina, poderemos tentar instanciar um objeto DAO via OLEAutomation, veja o código a seguir:

implementation

Uses comObj;

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

const

DAOConst36 = ‘DAO.DBEngine.36’;

DAOConst35 = ‘DAO.DBEngine.35’;

var DBEngine: Variant;

begin

try

DBEngine := CreateOLEObject(DAOConst36);

Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas

Page 28: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE2 82 82 82 82 8

// DBEngine := CreateOLEObject(DAOConst35);

showmessage( ‘DAO, versão ‘+DBEngine.Version+’

está instalado’ );

except On E: Exception do

ShowMessage(E.Message+’ DAO não instalado ‘);

end

end;

Dúvida enviada por Elmar Processamento De Dados Ltda,João Pessoa/PB.

Pergunta: O gerador de relatórios Report Builder possuirecursos para que o usuário final possa desenvolver seus própriosrelatórios, inclusive gerando consultas SQL. Porém, não estouconseguindo utilizá-lo corretamente com dbExpres e IBExpressvisto estar apresentando alguns problemas. O que necessito fazerpara utilizar o RB corretamente com estas engines de acesso?

Resposta: Para utilizar o acesso ao DBExpress e IBExpresspelo Report builder do Delphi7 devemos adicionar os pacotesreferentes a esses acessos, pois os mesmos não foram adicionadosao Delphi. Portanto para adicioná-los devemos fazer os seguintespassos:

Instalando o DBExpress:Abra o Delphi e acesso o menu Component opção Install

Packages, clique no botão Add e no diretório do System ouSystem32 do Windows selecione o arquivo rbDBE77.bpl

Instalando o IBExpress:Para o IBExpress foi necessário abrir o DPK e compilá-lo, pois

somente adicionando o pacote ocorreu um erro devido a diferençade versões. Portanto selecione no Delphi o menu File opção Open,depois no diretório Source do Report Builder selecione o arquivorbIBE77.dpk. Estando com o pacote aberto clique no botãoCompile e depois no botão Install e pronto pode fechar o pacote,pois o mesmo já está instalado no delphi.

Fazendo esses dois passos você habilitará o acesso do ReportBuilder do Delphi7 para o DBExpress e IBExpress.

Dúvida enviada por Procel Informática Ltda, Florianópolis/SC.

Pergunta: Gostaria de saber como obter a lista dos tipos depapéis disponíveis no QuickReport.

Resposta: No caso do QReport, o mesmo possui uma

tipagem própria com nomes dos papeis que não coincidem com ostipos pré-definidos no Windows. Assim sendo, adicione estesvalores “fixos” ao seu ComboBox, pois, estes são dos tipos possívelaceitos pelo QR:

TQRPaperSize = (Default, Letter, LetterSmall,

Tabloid, Ledger, Legal, Statement, Executive, A3,

A4, A4Small, A5, B4, B5, Folio, Quarto, qr10X14,

qr11X17, Note, Env9, Env10, Env11, Env12,

Env14, CSheet, DSheet, ESheet, Custom)

Para pegar o valor do ComboBox e alterar no QReport, utilizeo seguinte:

implementation

uses QrPrNtr, TypInfo;

{$R *.dfm}

procedure SetPaper(const PaperName: string; QR:

TQuickRep);

var

Paper : TQRPaperSize;

begin

Paper := TQRPaperSize(GetEnumValue(TypeInfo

(TQRPaperSize),PaperName));

QR.Page.PaperSize := Paper;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

SetPaper(‘LetterSmall’, QuickRep1);

// ou

SetPaper(ComboBox.Items[ComboBox.ItemIndex],

QuickRep1);

end;

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

Pergunta: Tentei abrir a seguinte instrução e ocorreu umerro:

select codigo , sum(quantidade) from tabela1

where (sum(quantidade))>100

group by codigo

Constatei que é pela cláusula “where”, então pergunto, não épossível fazer where por campo calculado? Qual a maneiracorreta de abrir uma instrução do tipo? Onde o campo a sercomparado é um SUM?

Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas

Page 29: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE 2 92 92 92 92 9

Resposta: A condicional referente ao SUM deve seraplicada ao GROUP BY e não na cláusula where. Isso pode serfeito através da cláusula HAVING (que funciona como umWHERE para o GROUP), veja abaixo:

SELECT Company, SUM(sales) AS TOTALSALES

FROM Sales1998

WHERE (State = “CA”)

GROUP BY Company

HAVING (SUM(Sales) >= 1000)

ORDER BY Company

Dúvida enviada por CyberSul - Soluções em Informática,Porto Alegre/RS.

Pergunta: Com faço para ativar/desativar uma triger noInterbase, via programação Delphi.

Resposta: Poderá utilizar o componente IBScript e nesteadicionar a seguinte instrução para desativar sua trigger:

ALTER TRIGGER SUA_TRIGGER

INACTIVE BEFORE INSERT POSITION 0

AS

BEGIN

/* instruções da Sua_Trigger */

END

Para executar utilize:

IBScript.ExecuteScript;

Dúvida enviada por Sinval Alcântara Lopes, São Paulo/SP.

Pergunta: Por que quando eu vou digitar algum códigopara um evento qualquer no Delphi 7 ele coloca automaticamentelogo após a palavra “begin” a palavra de herança “inherited”?

Exemplo:

procedure

TFormCadastroCidade.IBQueryQtdSecoesNUMERO_SECOESGetText(

Sender: TField; var Text: String; DisplayText:

Boolean);

begin

inherited; // <-

end;

Resposta: Isso ocorre porque possivelmente o Sr. estejatrabalhando com herança de formulários, ou seja, oTformCadastroCidade foi herdado com opção inherit a partir deum outro formulário.

Quando trabalhamos com este tipo de arquitetura, o Delphiinsere esta chamada automaticamente, porque ele “imagina” quevocê possa ter um código no formulário “base” que deverá serexecutado neste formulário herdado.

Por exemplo, no formulário “base” você possui no eventoOnClose a instrução:

Action := CaFree;

Em todos os formulários herdados a partir deste formulário“base”, automaticamente irão executar esta mesma instrução.Suponhamos que em um destes formulários herdados vocênecessite acrescentar algum código específico:

Inherited;

ShowMessage(‘Meu Código!’);

A cláusula Inherited irá forçar a execução do código originalexistente no formulário “base” e logo em seguida o seu códigoespecífico.

A cláusula Inherited irá aparecer nos formulários herdados,mesmo que não haja código para aquele evento no formulário“base”, contudo, não trás nenhum problema e recomendo nãoremovê-la.

Dúvida enviada por Rodrigo José Marques, Itaúna/MG.

Pergunta: Conforme exemplo que estou envinado emanexo, estou tentando alterar uma Query, mas ao tentar fazeresta operação, ocorre a seguinte mensagem: Query: Canoot modify a read-only dataset.

Gostaria que vocês me apontassem o que estou fazendo deerrado neste programa.

Resposta: Quando adicionamos instruções um pouquinhomais complexas em um Query, como exemplo um ORDER BY, amesma tornar-se-a read-only. Nestes casos, para que possamoseditá-la é necessário utilizar um componente UpdateSQL, bemcomo alterar a propriedade CachedUpdates da Query para True.Veja seu projeto com esta implementação.

Dúvida enviada por Infoque Informatica Produtos ServicosLtda, São Roque/SP.

Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas

Page 30: Revista The Club Megazine - 01/2004 · Texto := ‘Imprimindo Segunda linha do relatorio’; WritePrinter(hPrinter, PChar(Texto), ... Primeiro passo crie um novo projeto no Delphi,

MeGAZINEMeGAZINEMeGAZINEMeGAZINEMeGAZINE3 03 03 03 03 0

Perguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & RespostasPerguntas & Respostas

Pergunta: Usando o Interbase tem como fazer segurançade tabelas a nível de registro? Exemplo: Temos um cadastro deconta bancaria. Alguns usuários poderão acessar apenas a conta“25889-3” E outros usuários poderão acessar apenas a conta“71658-9”. Hoje temos no sistemas segurança a nível de tela e debotão, mas não sabemos como dar acesso a nível de registro, comopoderíamos fazer isso?

Resposta: Infelizmente não existe este tipo de controle porparte do Interbase, sendo necessário você efetuar um controle“manual” para seus usuários. Uma alternativa seria você criaruma tabela onde ficarão cadastrados seus usuários/senhas, euma tabela “detalhe” ligada a esta tabela onde irão ficar asconfigurações a que cada usuário terá direito. Dessa forma, aoiniciar o aplicativo você irá solicitar o login do usuário e tendocom isso as opções que o mesmo poderá ter acesso. No casoespecífico de “registros”, ao entrar no formulário de contas,recomendaria você utilizar um componente Query com um“Select” que não mostre nenhum registro a princípio:

Select * From Contas where ID is null;

Quando o usuário acessar o Form, você irá solicitar umapesquisa para que o mesmo escolha a conta que deseja acessar.Após a pesquisa, faça uma comparação entre a conta escolhida ea conta configurada na tabela de permissões e caso não hajarestrição, permita ou não o acesso.

Temos um exemplo de controle de usuários publicado emnossa revista de Junho/2003 “Acesso - Controlando eIdentificando Usuários”. Caso não possua a revista poderáacessar em nosso site, www.theclub.com.br.

Dúvida enviada por New Century Gestão e Informática,Santo André/SP.

Pergunta: Como faço pra construir aqueles forms comformato e desenhos diferenciados, como imitando um aparelho desom, com fundo semelhante a metal lixado, cantos arredondados,contornos e coisas do tipo? Como exemplo, veja o form usado noQuick Time, Media Player, etc. Tentei deixar meu formtransparente, e deu pra causar alguns efeitos, mas o que maisposso fazer? Inserir um BMP no form com o formato desejado?

Resposta: Estas aplicações trabalham com “Skins” quepossibilitam “moldar” o formulário de acordo com imagens. Existeuma suite de componentes da empresa KsDev que possibilitamudar a aparência dos formulários via Delphi. Poderá baixaruma cópia de avaliação no site do fabricante, www.ksdev.com,não é gratuíto.

Existe um outro componente chamado “Scheme VCL” o qualé gratuíto, porém, mais simples. Poderá baixar em: http://www.torry.net/vcl/forms/effects/ksscheme.zip.

Dúvida enviada por Samuel Della Savia de Oliveira, SãoPaulo/SP.

Pergunta: Gostaria de fazer um cálculo registro a registrono Rave Report imprimindo a diferença de dias entre uma datagravada em um campo e a data atual do sistema. Como possofazer isso?

Resposta: Isso poderá ser feito programando o eventoOnGetRow do componente RvCustomDataSet, onde iremospesquisar os componentes “dentro” do projeto Rave e atribuirvalores aos mesmos. Exceto o fato de termos que pesquisarcomponentes, a abordagem fica bem parecieda com o queestamos acostumados a fazer no QuickReport. Veja o código aseguir:

implementation

uses RVClass, RVProj, RvCsData;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

rvTestes.ExecuteReport(‘Rep_Employee’);

end;

// evento OnGetRow do componente RvDataSetConnection

procedure TForm1.rvdsEmployeeGetRow(Connection:

TRvCustomConnection);

var

Dias: Double;

P: TRavePage;

D: TRaveDataText;

begin

// Pesquisa o Report e a Página.

P := RvTestes.ProjMan.FindRaveComponent

(‘Rep_Employee.MainPage’, nil) as TRavePage;

// Localiza o DataText D := RvTestes.ProjMan.FindRaveComponent

(‘DataText4’, P) as TRaveDataText;

// Cálcula # dias

Dias := Date - tabEmployee.FieldByName

(‘HireDate’).AsDateTime;

// Atribui ao Datatext

D.Text := FormatFloat(‘000’, Dias);

Connection.DoGetRow; end;

Dúvida enviada por Denis Fonseca Loureiro, Salvador/BA.