You are on page 1of 367
so10a2020 POF js viewer Documento de padr6ées de codificagao Introdugao Regras gerais de formatagao sobre o cédigo-fonte Object Pascal Arquivos Formulérios e médulos de dados Pacotes Componentes O texto completo deste capitulo aparece no CD-ROM que acompanha este livro. oczz.com.bridoc!46131/delph-5-—guia-do-desenvolvedor_capitulos-do-cd CAPITULO sv967 so10a2020 PDFs viewer Introdugao Este documento descreve os padres de codificagdo para a programagéo em Delphi, conforme usados no Guia do Programador Delphi 5. Em geral, 0 documento segue as orientagdes de formatacgo constante- mente “néo-pronunciades'’, usadas pela Borland International com algumas poucas excegdes. A finalida- de de incluir este documento no Guia do Programador Delphi 5 ¢ apresentar um método pelo qual as equines de desenvolvimento possam impor um estilo coerente para a codificagao realizada. A intengao fazer isso de modo que cada programador em uma equipe possa entender o cédigo sendo escrito pelos outros programadores. Iss0 € feito tornando-se 0 cédigo mais legivel através da coeréncia. Este documento de maneira alguma inclui tudo 0 que poderia existir em um padrao de codificagso. No entanto, ele contém detalhes suficientes para que voc possa comecar. Fique @ vontade para usar € modificar esses padres de acordo com as suas necessidades. No entanto, nao recomendamos que vocé se desvie muito dos padres utilizados pelo pessoal de desenvolvimento da Borland. Recomendamos isso porque, 4 medida que vocé traz novos programadores para a sua equipe, os padres com que eles prova- velmente estarao mais acostumados s#o os da Borland. Como a maioria dos documentos de padres de codificacao, este documento sera modificado conforme a necessidade. Portanto, voc encontrard a ver- so mais atualizada on-line, em wv.xapware.con/ddg, Este documento no aborda padrées de interface com o usuario. Esse & um tépico separado, porsm igualmente importante. Muitos livros de terceiros e documentacéo da prépria Microsoft aborda tais ori- entagdies, e por isso dacidimos nao replicar essas informagées, mas sim indicarmos a Microsoft Develo- pers Network e outras fontes onde essa informagao se encontra & sua disposi Regras gerais de formatagao sobre o cddigo-fonte Endentacdo A endentacdo seré de dois espacos por nivel. Nao salve caracteres de tabulagdo nos arquivos-fonte. O motivo para isso que os caracteres de tabulagdo sto expandidos para diferentes larguras, conforme as diferentes configuragdes dos usuarios e de acordo com os utilitérios de gerenciamento de cédigo-fonte (impresséo, arquivamento, controle de verséo etc.) Vooé pode desativar 0 salvamento de caracteres de tabulagéo desmarcando as caixas de selegdo Use Tab Character (usar caracter de tabulac3o) e Optimal Fill (preenchimento ideal) na pagina General da cai- xa de didlogo Editor Properties (propriedades do editor), acessada por melo de Tools, Editor Options, Margens ‘As margens serdo definides em 80 caracteres. Em geral, 0 cédigo-fonte nao deve exceder esse limite, com @ excego para terminar uma palavra. No entanto, essa orientagdo ¢ um tanto flexivel. Sempre que poss! vel, as instrugSes que excedem uma linha devem ser quebradas apés uma virgula ou um operador. Quan- do uma instrugao quebrada, ela deve ser recuada em dois caracteres a direita do inicio da linha da ins- trucdo original Par begin..end A instrugdo begin aparece na sua propria linha. Por exemplo, a primeira linha a seguir esta incorreta; a se- gunda linha esta correta: for 1 := © to 10 do begin // Errado, begin na mesma linha de for for 1-6 t0.10 do // Correta, begin en una Tinha separaca begin Uma excepo a essa regra 6 quando a instruggo begin aparece como parte de uma cléusula else. Veja um exemplo: doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 2087 so10a2020 PDFs viewer 4 alguna instrugdo = then begin end else begin Algunaoutratastrucdo; ends ‘A instrugo end sempre aparece em sua propria linha. Quando a instrug2o begin no fizer parte de uma cléusula else, a instrugdo end correspondente sem- pre serd recuada para corresponder a sua parte begin Object Pascal Parénteses Nunea devera haver espago em branco entre um paréntese inicial e 0 caractere seguinte. Da mesma for- ma, nunca devera haver espaco em branco entre um paréntese final e o caractere anterior. O exemplo a seguir ilustra 0 espagamento incorreto e correto com relagdo aos parénteses: callProc( aparaneter ); // incorreto CallProc(AParaneter); // correto Nunca inclua parénteses desnecessérios em uma instrugdo. Os parénteses s6 devem ser usados onde for necessério para gerar 0 significado desejado no eddigo-fonte. Os exemplos a seguir ilustram o uso in- correto e correto: if (I= 42) then {/ incorrate - parénteses desnecessarios if (1 = a2) or (3 = 42) then // correto - parérteses necessérios Palavras reservadas e palavras-chave ‘As palavras reservadas @ as palavras-chave da linguagem Object Pascal sempre deverdo estar completa- mente em mintsculas. Procedimentos e funcées (rotinas) Nomeacdo/formatacao ‘Os nomes de rotines sempre deveréo comecar com uma letra maidiscula e utilizar maisculas nas palavras intermedirias, para melhorar a legibilidade. A seguir vemios um exemplo de um nome de procedimento formatado incorretamente: Procedure estenonederotinaestéfornatadoincorretanente; Agora veja um exemplo de um nome de rotina com ini is maitiscules epropriadas: procedure EstenoneveRotinatstéhuitomaisLegivel; ‘As rotinas deverdo receber nomes significativos para o seu contetido. As rotinas que causam uma ago terdo como prefixo 0 verbo da apo. Veja um exemplo: procedure Fornatarpiscorigido; As rotinas que definem valores de parametros de entrada deverdo ter como prefixo a palavra set (definir): procedure Setionausuario As rotinas que recuperam um valor deverao ter como prefixo a palavra get (obter): function GetlioneUsuério: strings 3 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 087 so10a2020 PDFs viewer Parametros formais Formatagao (Onde for possivel, os pardmetros formais do mesmo tipo deverdo ser combinados em uma instrugdo: procedure Foo(Farant, Paramz, Params: Integer; Parana: string); Nomeacao Todos os nomes de parémetros formais deverdo ser indicativos de sua finalidade, e normalmente sero baseados no nome do identificador que foi passado para a rotina. Quando for apropriado, os nomes de pardmetro deverdo ter como prefixo 0 caracter a: procedure AlgumProced(AnoneUsuério: string; AidadeUsuario: integer); prefixo a é uma convendo usada para retirar a ambigilidade quando o nome do parametro for igual ao nome de uma propriedade ou campo na classe. Ordenagao de parametros A ordenago de pardmetros formais a seguir enfatiza 0 aproveitamento das convengbes de chamada de registro. (Os pardmetros mais usados (por quem chama) deverao estar nos primeiros lugares. Os parametros menos usados deverdo ser listados depois, na ordem da esquerda para a direita. As listas de entrada deverao vir antes das listas de saida, na ordem da esquerda para a direlta. Coloque os parametros mais genéricos antes dos parémetros mais especificos, na ordem da esquer- da para a direita. Por exemplo: alguproced(aplaneta, Acontinente, Apais, Aestado, Acidade) Existem excegdes a regra de ordenagéo, como no caso dos manipuladores de evento, onde um paré- metro chamado sender do tipo object normalmente é passado como primeiro parametro. Parametros constantes Quando parmetros do tipo de registro, array, shortstring OU interface no sao modificados por uma ro- tina, os parametros formais para essa rotina devergo marcar o parémetro como const. Isso garante que O compilador geraré cédigo para passar esses parametros nao modificados da maneira mais eficiente (Os parametros dos outros tipos podem opcionalmente ser marcados como const se ndo forem modi- ficados por uma rotina. Embora isso no tenha efeito sobre a eficiéncia, oferece mais informagées sobre © uso do parametro para quem chamou a rotina. Colisées de nomes Ao usar duas unidades que contém rotinas do mesmo nome, a rotina que reside na unidade que aparece Por Ultimo na cléusula uses seré chamada se voo8 chamar essa rotina. Para evitar essas ambiglidades de- pendentes da cldusula uses, sempre use como prefixo dessas chamiadas de método o nome da unidade de- sejada. Veja dois exemplos: sysutils.Findclose(sR); e endows. Findclose (Handle); Varidveis Nomeacio e formatacao de variaveis ‘As varidveis devergo ter nomes que indicam sua finalidade. Varidveis de controle de loop geralmente recebem um Unico caracter, como 1, 3 ou x. Também & 4 aczitavel usar um nome mais significativo, como tndiceusuario doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 4087 so10a2020 PDFs viewer (Os nomes de varidveis Booleanas deverao ser descritivos o suficiente para que o significado dos va- lores 1 se seja claro. Variaveis locais As varldveis locais usadas dentro dos procedimentos sequem as mesmas convenoes de uso € nomeagdo de todas as outras varidveis. As variaveis temporarias deverao ter nomes apropriados. Quando for necessério, a inicializac&o de variaveis locais ocorrerd imediatamente na entrada da ro- tina. As varidveis Ansistring locals séo inicializedas automaticamente com uma string vazia, variaveis lo- cais do tipo interface e dispinterface s&o inicializadas automaticamente como nil, @ variaveis locais do tipo veriant € oleveriant sé inicializadas automaticamente como Unassigned. Uso de variaveis globais O uso de varidveis globais é desencorajado. No entanto, elas podem ser usadas quando for necessério. ‘Quando isso acontecer, vooé deverd manter as variaveis globais dentro do contexto em que séo usadas. Por exemplo, uma varidvel global poderd ser global apenas dentro do escopo da segao de implementaao de uma tnica unidade. (Os dads globais a serem usados por diversas unidades deverdo ser movidos para uma unidade co- mum, usada por todas. (Os dadios globais podem ser inicializadas com um valor diretamente na seo80 var. Lembre-se de que todos 0s dados globais s80 automaticamente inicializados com zero; portanto, néo inicialize variaveis globais como valores “vazios”, como o, nil, ”?, unassigned e assim por diante. Um motivo para isso é que 08 dados globais inicializados com zero no ocupam espago no arquivo EXE. Dados inicializados com Zero sao armazenados em um segmento de dados virtual alocado apenas na meméria quando a aplicagdo ¢ inicializada. Dados globais inicializedos com valor diferente de zero ocupam espaco no arquivo EXE do disco. Tipos Convengao para uso de maiusculas ‘Os nomes de tipo que so palavres reservades ficaréo completamente em mindiscules. Os tipos da API do \Win32 geralmente eparecem totalmente em maiuisculas, ¢ vocé devera seguir a conven¢o para um nome: de tipo em particular, mostrado na unidade windoxs.9as OU outra unidade da API, Para outros nomes de variaveis, a primeira letra deverd ser mailscula eo restante deverd usar mailisculas no inicio de cada pala- vra intermediaria. Veja alguns exemplos: nystring: strings // palavra reservada hindowandle: MD; // tipo da apr do win32 I: Integers // Adentificador de tipo introduzido na unidade System Tipos de ponto flutuante © uso do ripo reat é desencorajado, pois s6 existia por compatibilidade com o cédigo mais antigo do Pascal. Embora agora ele seja 0 mesmo que Double, esse fato poderd ser confuso para outros programa- dores. Use double para as necessidades gerais de ponto flutuante. Além disso, as instrucdes e os barra- mentos do processador sao otimizados para trabalhar com pouble, sendo também o formato de dados Padrdo definido pelo IEEE. Use extended apenas quando for necesséria uma faixa maior do que a ofere- Cida por double. Extended é um tipo especifico da Intel, e nao é aceito em Java, Use single apenas quan- do 0 tamanho fisico dos bytes da variavel de ponto flutuante for significativo (como ao usar DLLs de outras linguagens), doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed S87 so10a2020 PDFs viewer Tipos enumerados ‘Os nomes para tipos enumerados deverdo ser significativos para a finalidade da enumeragao. O nome do tipo deve ter como prefixo o caracter 1 para anota-lo como uma declaragdo de tipo. A lista de identifica dores do tipo enumerado devera conter um prefixo de dois ou trés caracteres minusculos, que 0 relacio- ne com o nome do tipo enumerado original. Veja um exemplo: TTiponisica = (steock, stClassical, stcountry, stalternative, steavywetal, stsospel); As inst€ncias de variavel de um tipo enumerado receberdo o mesmo nome do tipo, sem o prefixo T (Tipctisica), a menos que hala um motivo para dar & variavel um nome mais especifico, como em Tiperi- sicaFavoritet, TipatisicaFavorita2 ete, Tipos Variant e OleVariant © uso dos tipos variant € olevariant & desencorajado em geral, mas esses tipos s#o necessérios & programa- 80 quando os tipos de dados so conhecidos apenas em runtime, como normalmente acontece no de- senvolvimento COM e de banco de dados. Use olevariant para a programagao baseada em COM, como controles Automation ¢ ActiveX, e use variant para a programagéo que nao seja COM. O motivo é que uma variant pode armazenar de modo eficiente as strings nativas do Delphi (como uma string var), mas olevariant converte todas as strings em strings OLE (strings widecnar) endo so contadas como referéncia: em vez disso, elas s80 sempre copiadas. Tipos estruturados Tipos de array (Os nomes para os tipos de array devem ser indicativos da finalidade do array. O nome do tipo deveré ter como prefixo o caracter r. Se for declarado um ponteiro para o tipo de array, ele deverd ter como prefixo o caracter » e deverd ser declarado antes da declarago de tipo. Veja um exemplo: type ParrayCiclo = *TArrayCiclos TarrayCiclo = array[1..100] of integers Quando for pratico, as instancias de varidveis do tipo array deverdo receber o mesmo nome do tipo sem o prefixo r. Tipos de registro Um tipo de registro devera receber um nome indicativo de sua finalidade. A declaracao de tipo devera ter como prefixo o caracter 1. Se for declarado um ponteiro para o tipo de registro, ele deverd ter como pre~ Tixo 0 caracter p e devera ser declarado antes da declaracao de tipo. A declaragao de tipo para cada ele- mento poderd ser alinhada opcionalmente em uma coluna @ direita. Veja um exemplo. type Pruncionérdi uncionérios Truncionario = record oneFunc: string Salariofunc: Doubles ends doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed e087 so10a2020 PDFs viewer Instrugdes Instrugdes if (© caso mais provavel de ser executado em uma instruoo if/then/else devera ser colocado na cléusula then, com 8 casos menos provaveis residindo najs) cléusula(s) eise. Tente evitar 0 encadeamento de instrugdes if e use instrugdes case sempre que possivel Nao aninhe instrugdes if com mais de cinco niveis de profundidade. Crie um método mais claro para o cédigo. Nao use parénteses desnecessarios em uma instrugao if Se varias condigdes estiverem sendo testaclas em uma instrugdo if, as condigdes deverdo ser organi- zadas da esquerda para a direita na ordem de intensidade de célculos, da menor para a maior. Isso permi= te que 0 seu cédigo aproveite a légica de avaliaggo Boolean de curto circuito embutida no compilador. Por exemplo, se @ Condicaot for mais répida do que @ Condi¢a02, @ @ Condi¢a02 for mais répida do que a condi- 203, entdo a instrugdo if deverd ser construida da seguinte forma Sf Condi¢got and Condig02 and Condi¢303 then Instrugées case Tépicos gerais Os casos individuais em uma instruego case deverdo ser ordenados pela constante de caso, seja numérica ou alfabeticamente. As instrucdes de agbes de cada caso deverdo ser simples e geralmente ndo deveréo exceder quatro ou cinco linhas de cédigo. Se as aodes forem mais complexas, o c6digo deverd ser colocado em um proce- dimento ou fungéo separada ‘A cléusula else de uma instruggo case devera ser usada apenes para padres legitimos ou para detec- tar erros. Formatacao As instrugGes case seguem as mesmas rearas de formatagao das outras construges com relagéo és con- vengbes de endentacdo e nomeagéo. Instrugées while (O.us0 do procedimento exit para sair de um loop while é desencorajado; sempre que possivel, vooé deve- ra sair do loop usando apenas a condigo do loop. Todo 0 cédigo de inicializagao de um loop white deverd ocorrer diretamente antes da entrada do loop [whilem] © nio devers ser separado por outras instrucBes ndo relacionadas. Qualquer trabalho de encerramento devera ser feito imediatamente apds o loop. Instrugées for As instrugdes for deverdo ser usadas no lugar das instrugdes while quando o cédigo tiver de ser executado Por um numero conhecido de incrementos. Instrugdes repeat AAs instruges repeat séo semelhantes a0 loops while e deverdo seguir as mesmas orientagbes gerais. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed vst so10a2020 PDFs viewer Instrugées with Tépicos gerais A instrugdo with deverd ser usada com reservas @ com considerdvel atengéo. Evite o uso demasiado de ins- truges with € cuidade com 0 uso de vérios objetos, registros etc. na instrugdo with. Por exemplo: with Registrot, Registro2 do pode confundir 0 programador ¢ facilmente levar a bugs diffoais de se detectar. Formatacao As instrugées with seguem as mesmas regras de formatago em relagdo as convengdes de nomeagao e en- dentagdo, descritas anteriormente neste documento. Tratamento estruturado de excecdes Topicos gerais tratamento de excegdes deverd ser usado abundantemente para corregao de erro e proteggo de recursos. Isso significa que, em todos 08 casos em que so alocados recursos, um try. .Finally devera ser usado para garantir a desalocapdo correta do recurso. A excecdo a essa regra envolve casos nos quais 0s recursos S80 alocados/liberados na inicializagso/finalizagéo de uma unidade ou do construtor/destruidor de um objeto. Uso de try..finally Sempre que possivel, cada alocagao deverd ser combinada com uma construgo try...finally. Por exem- plo, 0 cédigo a seguir poderia levar a possiveis bugs: AlgunaClasse1 :- TAlgunaClasse.create; Algunaclasse2 := TalgunaClasse.create; try { reatiza algum cédigo } finally Algunaclasset.Free; Algunaclassez.Frees ends Um método mais seguro para a alocago anterior seria este: AlgunaClasse1 :- TAlgunaClasse.create try AlgunaClasse? := TAlgunaClasse. Creates try { reatiza olgun cédigo } Finally Algunaclassez.Free; ends finally AlgunaClassel.frees ends Uso de try..except Use try. .except apenas quando vooé quiser realizar alguma tarefa se surgir alguma excecdo. Em gerel, Voo8 ndo devera usar try. .except simplesmente para mostrar uma mensagem de erro na tela, pois isso ser doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 087 so10a2020 PDFs viewer feito automaticamente no contexto de uma aplicacdo pelo objeto application. Se vocé quiser chamar o tratamento padiréo de excec4o depois de ter realizado alguma tarefa na clausula except, use raise para le- vantar @ excego novamente para o préximo manipulador. Uso de try..except..else © uso da cléusula e1se com try..except € desencorajado, pois bloqueard todas as excegdes, até mesmo aquelas para as quais vooé pode nao estar preparado. Classes Nomeacao/formatacao (Os nomes de tipo para as classes deverdo indicar claramente a finalidade da classe. © nome do tipo deve- ra ter 0 prefixo T para indicé-lo como uma defini¢éo de tipo. Veja um exemplo: type Teliente = class(robject) (Os nomes de insténcia para as classes geralmente combinaro com o nome do tipo da classe, mas sem 0 prefixo 7 Cliente: TeLientes NOTA Consulte segao “Padres de nomeacao de tipo de componente" para obter mais informagoes sobre ano- meagao de componentes, Campos Nomeagdo/formatagao (Os nomes de campo de classe seguem as mesmas convengdes de nomeago dos identificadores de varid- vel, exceto por terem a indicagao + como prefixo, indicando que so nomes de campo (field). Visibilidade Todos os campos deveréo ser privados. Os campos que séo acessiveis fora do escopo da classe deverdo se tornar acesstveis através do uso de uma propriedade. Métodos Nomeagao/formatagao (Os nomes de métodos sequem as mesmas convengdes de nomeacdo descritas para procedimentos e fun- ges neste documento. Uso de métodos estaticos Use métodos estéticos quando voc nao quiser que um método seja modificado por classes descendentes. Uso de métodos virtuais/dinamicos Use métodos virtuais quando quiser que um método seja modificado por classes descendentes. Os méto- dos dindmicos s6 deverdo ser usados em classes das quais haverd muitos descendentes (diretos ou indire- 9 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 967 so10a2020 PDFs viewer tos). Por exemplo, 2o trabalhar com uma classe que contenha um metodo pouco modificado e 100 clas- ses descendentes, vocé deveré tornar método dinamico, a fim de reduzir 0 uso de meméria pelas 100 classes descendentes. Uso de métodos abstratos Nao use métodos abstratos sobre classes das quais serao criadas instancias. Use métodos abstratos apenas sobre classes basices que nunca ser&o criadas. Métodos de acesso a propriedades Todos 0s métodos de acesso deverdo parecer nas sees private OU protected da definigao de classe. ‘As convengies de nomeacao para os métodos de acesso a propriedades seguem as mesmas regras dos procedimentos e fungdes. O método de acesso de leitura (método leitor) deverd ter como prefixo a palavra cet: ‘© método de acesso de escrita (método escritor) deverd ter como prefixo a palavra set. O parame- tro para o método escritor deverd ter o nome value, ¢ seu tipo deverd ser o da propriedade que ele repre- senta, Veja um exemplo: TAlgunaClasse = class(Tobject) private FAlguncanpo: integer; protected function GetAlguncanpo: integer; procedure SetAlguaCanpo( Valor: Integer): public property AlgunCanpo: Integer read GetAlgunCanpo write SetAlgunCanpo; ends Propriedades Nomeagdo/formatagao ‘As propriedades que servem como acessos para campos privados terdo nomes iguais aos campos que elas representam, sem 0 indicador (Os nomes de propriedade devergo ser substantivos, e no verbos. As propriedades representam da- dos; os métodos representam agdes. (Os nomes de propriedade de array deverdo estar no plural. Os nomes de propriedade normais deve- ro estar no singular. Uso de métodos de acesso Embora néo seja obrigatério, encoraja-se 0 uso de no minimo um método de acesso de escrita para as propriedades que representam um campo privado. Arquivos Arquivos de projeto Nomeacao 5 arquivos de projeto deverdo ter nomes descritivos. Por exemplo, 0 Delphi 5 Developer's Guide Bug ‘Manager recebeu o nome de projeto voctugs. dpe. Um programa de informagées do sistema poderd ter um 4g Nome como infosis.dpr. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 01967 so10a2020 PDFs viewer Arquivos de formulario Nomeacao Um arquivo de formulario deveré ter um nome descritivo da finalidade do formulérrio, finalizado com os caracteres Fre. Por exemplo, 0 formuldrio Sobre teria o nome de arquivo sobreFrn.cpr, e um formulério Principal teria o nome de arquivo Principalrrn.cpr. Arquivos de médulo de dados Nomeacao Um médulo de dados devera receber um nome que descreva a finalidade desse modulo. O nome devera ser finalizado com os caracteres on. Por exemplo, um médulo de dados Clientes teré o nome de arquivo Clienteson.¢fe. Arquivos remotos de médulo de dados Nomeacao Um médulo de dados remoto devera receber um nome que descreva a finalidade do modulo de dados re- moto. O nome deveré ser finalizado com os caracteres nox. Por exemplo, um médulo de dados remoto Clientes teria o nome de arquivo clientesso".¢fm. Arquivos de unidade Estrutura geral da unidade Nome da unidade Os arquivos de unidade receberao nomes descritivos. Por exemplo, a unidade contendo o formulério principal de ume aplicagéo poderia ser chamada nainrre.pas. A clausula uses Uma cléusula uses na sego interface devera conter apenas unidades exigidas pelo cddigo na segao inter- face. Remova quaisquer nomes de unidade desnecessdrios, que possam ter sido inseridos automatica- mente pelo Delphi. Uma cléusula uses na $2¢80 inpleventation devera conter apenas as unidades exigidas pelo codigo na s0¢40 inplenentation. Remove quaisquer nomes de unidade desnecessarios. A secao interface A sego interface deverd conter declaragées apenas para os tipos, varidveis, declaracdes de encaminha- mento de procedimento/funcao e outros que precisarem ser acessivels a unidadas externas. Caso contra- Tio, essas declaragdes deverdo entrar na seg80 inplenentation A secao implementation ‘A s2080 inplenentation deverd conter quaisquer declaragdes de tipos, varidvels, procedimentos/fungéies outros que sejam privados a unidade que a contém. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 67 so10a2020 PDFs viewer A secao inicialization Néo inclua cédigo demorado na sepgo inicialization de uma unidade. Isso faré com que a aplicacéo pare~ ga ser lenta logo na partida A secdo finalization Néo se esqueca de desalocar quaisquer itens que tenham sido alocados na seco inicialization Unidades de formulario Nomeacao Um arquivo de unidade para um formulério devera receber 0 mesmo nome do seu arquivo de formulério correspondente. Por exemplo, um formulério Sobre teria o nome de unidade sobre=rn.as, eum formuld- rio Principal teria o nome de arquivo de unidade orincipalrn.pas. Unidades de médulo de dados Nomeagao Os arquivos de unidade ou médulos de dados deverdo receber os mesmos nomes de seus arquivos de for- mulério correspondentes. Por exemplo, uma unidade de médulo de dados Clientes teria o nome de uni- dade clientesom.pas. Unidades de uso geral Nomeagao Uma unidade de uso geral receberé um nome indicativo da finalidade da unidede. Por exemplo, uma uni- dade de utilitarios receberia o nome sugutilitérios.pas, e uma unidade contendo varidveis globais recebe- Tia 0 nome clienteclobais.pas Lembre-se de que os nomes de unidade precisam ser exclusivos em todos os pacotes usados por um projeto. Nomes de unidade genéricos ou comuns néo so recomendados. Unidades de componentes Nomeagao ‘As unidades de componentes deverdo ser incluides em um diretério separado para distingui-las como unidades definindo componentes ou conjuntos de componentes. Elas nunca deverao ser colocadas no mesmo diret6rio do projeto. O nome de unidade deverd indicar o seu contetdo NOTA Consulte a segao “Componentes definidos pelo usuério" para obter mais informagdes sobre padroes de nomeagao de componentes, Cabecalhos de arquivo © uso de cabegalhos de arquivo informativos é encorajado para todos os arquivos de cédigo-fonte, ar- quivos de projeto, unidades etc. Um cabecalho de arquivo apropriado deveré incluir a seguinte infor- magao Copyright © ANO by AUTORES 2) doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 21067 so10a2020 PDFs viewer Formularios e mddulos de dados Formularios Padrao de nomeacao de tipo de formulario Os tipos de formulério deverdo ter nomes que descrevam a finalidade do formulério. A definig&o de tipo deverd ter o prefixo r, e um nome descritivo deverd aparecer apés 0 prefixo. Finalmente, rron deverd ser inserido no final do nome descritivo. Por exemplo, o nome de tipo para um formuladrio Sobre seria: TsobreForm = class(TFora) A definigo de um formulario principal seria: TPrincialForm - class(TForm) © formulario de entrada de clientes teria um nome como: Tentradaclientestorw ~ class(TFora) Padrao de nomeagao de instancia de formulario As insténcias de formulério deverdo ter o mesmo nome de seus tipos correspondentes, porém sem o pre- fixo 1. Por exemplo, pata os tipos de formuldrio anteriores, os nomes de instancia s40 0s seguintes: ‘Nome do tipo Nome da insténcia Tsebrerorw sebrerorm erincipalrorn Principalrorm TentradaClientesForm EntradaClientesForm Criagado automatica de formularios Somente 0 formulério principal devera ser criado automaticamente, a menos que haja um bom motivo para se fazer de outra forma. Todos os outros formularios deverdo ser removidos da lista Autocreate na caixa de didlogo Project Options (opgdes do projeto). Veja mais informagdes na préxima seco, Funcées de instanclacao de formulario modal Todas as unidades de formulério deverdo conter uma fungéo de instanciagéo de formulario que cria, configura e exibe o formulario de forma modal, além de liberar o formulario. Essa funcdo devera retor- nar o resultado modal ratornado pelo formulério. Os parémetros passados a essa funoao deverao seguir 0 padréo de passagem de parémetros, especificado neste documento. Essa funcionalidade deverd estar en- capsulada dessa maneira para facilitar a reutilizagto e a manutencao do cédigo. A varivel de formulério deverd ser removida da unidade e declarada localmente na fungo de ins- tanciagdo de formuldrio. (Observe que isso exige que o formuldrio seja removido da lista Autocreate na caixa de didlogo Project Options. Ver *Criagéio automatica de formularios”, anteriormente neste docu- mento.) Por exemplo, a unidade a seguir ilustra tal fungo para um formulério cetuserdata: unit UserDataFras interface doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 121087 so10a2020 PDFs viewer hindows, essages, sysutils, Classes, Graphics, controls, Foras, Dialogs, stdctelss type Tuserbataform ~ class(TFana) edtusernane: Tedit; edtuseriD: Tedits private { decloracées privadas } public { dectaracées piblicas } function Getuseroata(var auserviame: String; var auserto: Integer): word; inplenentation (88°08) function Getuserdata(var aUseriame: String; var ausertO: Integer): words UserataForm: TUserataForns begin UserdataFora try Useroatarorm.caption := “Getting user pata’; Result 1 Useroatafone.shaviodal; if ( Result = nrok ) then begin aUserilane := UserDataForn.edtuseriane, Texts TuserDataForm, Create (Application); aUserI0 := StrTornt(UserDataForm.edtUserTD. Text) 5 ends Finally Userdatarorn. Frees ends ends end. Médulos de dados Padrao de nomeagao de médulo de dados Um tipo oataiodule receberé um nome descritivo da finalidade do médulo de dados. A definigéo de tipo tera um prefixo 1, e um nome descritivo devera acompenhar o prefixo. Finalmente, o nome seré finalizado com a palavra oataredule. Por exemplo, 0 nome do tipo para um médulo de dados Cliente seria algo assim: Iiédulovadoscliente Lass(Toatahodule) De modo semelhante, o médulo de dados de Pedidos poderia ter 0 seguinte nome: TiéduloDadosPedidos Lass(TDatatodule) Padrao de nomeacao de instancia do médulo de dados As instncias do médulo de dados terao nomes iguais aos seus tipos correspondentes, porém sem o prefi- 440. Por exemplo, para os tipos de formulario anteriores, os nomes de insténcia s4o 08 seguintes: doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed saio87 so10a2020 PDFs viewer Nome do tipo Nome da insténcia TWéduloDadosCliente Nédulovadoscliente “TédulobadasPocidos NédulovadosPedides Pacotes Uso de pacotes de runtime ou projeto s pacotes de runtime terao apenas as unidades/componentes exigidos por outros componentes nese pacote. Outras unidades contendo editores de propriedade/componente e outro cédigo apenas de proje- to devera ser colocado em um pacote de projeto. Unidades de registro também deverdo ser colocadas em um pacote de projeto. Padrées de nomeacao de arquivo Os pacotes teréo nomes de acordo com os seguintes modelos: ‘© idéLibwy.dpk (pacote de projeto) + {fistévy.dple(Pacote de runtime) Aqui, os caracteres ii significarn um prefixo de identificagdo de trés caracteres. Esse prefixo pode- ra ser usado para identificar uma empresa, pessoa ou qualquer outra entidade de identificagéo. (Os caracteres wy significam uma verséo para o pacote correspondente a versdo do Delphi para a qual © pacote é visado. (Observe que o nome do pacote contém 1:b ou std para representé-lo como um pacote de runtime ou em tempo de projeto. Em casos em que existem pacotes tem tempo de projeto e runtime, os arquivos terdo nomes seme- Ihantes. Por exemplo, os pacotas para o Guia do Programador Delphi 5 tm os seguintes nomes: ‘+ bdguibso.dpk (pacote de projeto) ‘© dgstaso.dpk (pacote de runtime) Componentes Componentes definidos pelo usuario Padrées de nomeacao de tipo de componente (Os componentes teréo nomes semelhantes ds classes definidas na segdo “Classes”, com a excepo de que 0s componentes recebem um prefixo de identificagao de trés caracteres. Esse prefixo poderd ser usado para identificar uma empresa, pessoa ou qualquer outra entidade. Por exemplo, um componente de clock escrito para o Guia do Programador Delphi 5 seria definido da seguinte forma TédgClock = class(Tcomponent) Observe que 0 prefixo de trés caracteres esta em letras minusculas. Unidades de componentes ‘As unidades de componentes deverdo conter apenas um componente principal. Um componente princi- pal é qualquer componente que apareca na Component Palette (palheta de componentes). Quaisquer componentes/objetos auxiliares também poderdo residir na mesma unidede do componente principal. 45 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 161967 so10a2020 PDFs viewer 6 Uso de unidades de registro O procedimento de registro para os componentes devera ser removido da unidade de componentes € co- locado em uma unidade separada, Essa unidade de registro sera usada para registrar quaisquer compo- nentes, editores de propriedade, editores de componentes, experts e assim por diante. registro de componentes deverd ser feito apenas nos pacotes de projeto; portanto, a unidade de registro deverd estar contida no pacote de projeto e néo no pacote de runtime, Sugere-se que as unidades de registro tenham o seguinte nome: >eoeg. pas Aqui, x00 & um prefixo de trés caracteres usado para identificar uma empresa, pessoa ou qualquer outra entidade. Por exemplo, a unidade de registro para os componentes do Guia do Programador Del- phi 5 se chamariam pdeteg-pas Convencées de nomeacao de instancia de componente Todos os componentes deverdo ter nomes descritivos. Nenhum componente ficaré sem os nomes padrao atribuidos a eles pelo Delphi. Os componentes seréo nomeados por meio de uma variacdo da convencéo de nomeago hungara. De acordo com esse padrao, o nome do componente consistira em duas partes: um prefixo de tipo de componente e um nome qualificador. Prefixos de tipo de componente prefixo de tipo de componente ¢ um conjunto de letras mindsculas que representam o tipo de componen- te. Por exemplo, a seguir vemos prefixos de tipo de componente validos para os componentes especificados TButton bin TEdit edt ‘TspeedButton spdbtn TListBox Istbx Como vimos, 0 prefixo de tipo de componente é criado modificando-se o nome do tipo de campo- nente (por exemplo, TButton, TEdit) para um prefixo. As regras.a seguir ilustram como definir um prefi- x0 de tipo de componente 1. Remova quaisquer prefixos “T" do tipo de nome de componente. Por exemplo, “TButton” tor- na-se “Button”. 2. Remova quaisquer vogais do nome formado na etapa 1, exceto quando a vogal inicia o nome. Por exemplo, “Button” torna-se “bttn” e “Edit” torna-se “edt”. 3. Suprima consoantes duples. Por exemplo, “bttn” torna-se “btn”. 4. Se ocorrer um conflito de nome, comece incluindo vogais ao prefix para um dos componentes. Por exemplo, se um novo componente “TBatton” for inclutdo, ele entrara em conflito com “TBut- ton”. portanto, o prefixo para “TBatton” poderia ser “batn" Nome de qualificador de componente Onome do quelificador de componente deveré descrever a finalidade do componente. Por exemplo, um componente TButton com a finalidede de fechar um formulério teria o nome “btnFechar”. Um compo- ente TEdit usado para editar o nome de uma pessoa teria o nome “edtNome” doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 161967 so10a2020 POF js viewer Controles ActiveX CAPITULO com Delphi © que é um controle Activex? = Quando um controle ActiveXdeve ser utilizado * Incluindo um controle ActiveX na Component Palette «© wrapper de componentes do Delphi + Usando controles ActiveX em suas aplicagSes « Distribuindo aplicagées equipadas com controle Activex «Registro do controle Activex + BlackJack: um exemplo de aplicagéo OCX = Resumo oczz.com.bridoc!46131/delph-5-—guia-do-desenvolvedor_capitulos-do-cd wiser so10a2020 PDFs viewer © Delphi oferece a grande vantagem de integrar com facilidade os controles ActiveX padréo da industria (anteriormente conhecidos como controles OCX ou OLE) em suas aplicagdes. Ao contrario dos préprios componentes personalizados do Delphi, os controles ActiveX séo projetados para serem independentes de qualquer ferramenta de desenvolvimento em particular. Isso significa que vocé pode contar com mui- tos fornecedores para obter uma grande variedade de solugSes ActiveX que abrem um grande leque de recursos e funcionalidade. © suporte para controle ActiveX no Delphi de 32 bits funciona de modo semelhante ao suporte para VBX no Delphi 1 de 16 bits. Voce seleciona uma opedo para incluir novos controles ActiveX a par- tir do menu principal do IDE do Delphi ou do editor de pacotes, e 0 Delphi cria um wrapper do Object Pascal para o controle ActiveX, que entéo compilado em um pacote e inclufdo na Component Palette do Delphi. Estando lé, 0 controle ActiveX é integrado de modo transparente a Component Palette, junto com os seus outros componentes da VCL e ActiveX. A partir desse ponto, vocé esta a apenas um clique e um arrasto da inclusdo do controle ActiveX em qualquer uma de suas eplicagbes. Este capitulo discute a integragdo de controles ActiveX no Delphi, o uso de um controle ActiveX na sua aplicaggo e a distribui- 0 de aplicagées equipadas com ActiveX. NOTA (© Delphi 4 foia titima verso do Delphi a dar suporte para controles VBX (Visual Basic Extension). Se voos ti- ver um projeto do Delphi 1 que se baseie em um ou mais controles VBX, verifique com os fornecedores de VEX para saber se eles fornecem uma solugao ActiveX compativelpara usar em suas aplicagoes Delphi de 32 bits. O que é um controle ActiveX? Controles ActiveX so controles personalizados para aplicagées de 16 bits ¢ 32 bits do Windows, que tiram proveito das tecnologias OLE e ActiveX baseadas em COM. Ao contrario dos controles VBX, que 820 projetados para o Visual Basic de 16 bits (e, portanto, compartilham as limitagdes do Visual Basic), 08 controles ActiveX foram projetados desde 0 inicio visando & independéncia de aplicativo. Resumidamente, vocé pode pensar nos controles ActiveX como uma mistura da tecnologia VBX de fé- cil utilizag8o com o padréo ActiveX aberto. Para fins deste capitulo, vacé pode pensar no OLE ¢ no ActiveX camo a mesma coisa. Se vocs estiver procurando maiores distingdes entre esses termos, dé uma olhada no Capitulo 23. Debaixo da superficie, um controle ActiveX é na realidade um servidor ActiveX que, em um paco- te, pode oferecer todo o poder do ActiveX — incluindo todas as funges e servicos do OLE, edigao visual, arrastar e soltar e OLE Automation. Assim como todos os servidores ActiveX, os controles ActiveX s€0 registrados no Registro do Sistema. Os controles ActiveX podem ser desenvolvidos através de diversos produtos, incluindo Delphi, Borland C++Builder, Visual C++ e Visual Basic. ‘A Microsoft esté promovendo ativamente os controles ActiveX como 0 meio escolhido para os con- troles personalizados independentes do aplicativo; a Microsoft afirmou que a tecnologia VBX nao seré diretamente aceita nos sisternas operacionais Win32 em diante. Por esse motivo, os pragramadores deve- rao utilizar controles Activex em vez de controles VBX quando desenvolverem aplicagées de 32 bits NOTA Para obter uma descricao mais completa sobre tecnologia de controle ActiveX, consulte o Capitulo 25, Quando um controle ActiveX deve ser utilizado Geralmente existem dois motivos para vooé usar um controle ActiveX em vez de um controle nativo do ‘18 Delphi. O primeiro deles é que nenhum componente do Delphi disponivel atende sua necessidade em. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 181987 so10a2020 PDFs viewer particular. Como o mercado de controle ActiveX é maior do que o de controles da VCL, vocé provavel- mente encontraré uma maior variedade de controles de “peso industrial” e com todos os recursos, como processadores de textos, browsers da World Wide Web e planilhas, sob @ forma de controles ActiveX. O segundo motivo para vocé usar um controle ActiveX em vez de um controle nativo do Delphi é se vooé desenvolve em varias linguagens de programagao e deseja aproveitar seu trabalho com determinado con trole ou controles entre as varias plataformas de desenvolvimento. Embora 0s controles ActiveX sejam integrados de modo transparente no IDE do Delphi, lembre-se de algumas desvantagens inerentes eo uso de controles ActiveX nas suas aplicagSes. © aspecto mais ob- Vio é que, embora os componentes do Delphi sejam montados diretamente no executavel de uma aplica- (80, 05 controles ActiveX geralmente exigem um ou mais arquivos de runtime adicionals, que precisam ser distribufdos junto com o executavel. Outro problema é que os controles ActiveX se comunicam com as aplicagdes por meio da camada COM, enquanto os componentes do Delphi se comunicam diretamen- te com as aplicagdes e outros componentes. Isso significa que um componente do Delphi bem escrito funciona melhor do que um controle ActiveX bem escrito. Uma desvantagem mais sutil dos controles ActiveX € que eles S80 uma solugo do tipo “denominador comum', de modo que néo explorardo todos 05 recursos da ferramenta de desenvolvimento em que séo utilizados. Inclusao de um controle ActiveX na Component Palette ‘A primeira etapa no uso de um controle ActiveX em particular na sua aplicago do Delphi é a incluséo desse controle na Component Palette do IDE do Delphi. Isso coloca um icone para o controle ActiveX na Component Palette, entre seus outros controles do Delphi e Activex. Depois de incluir um controle ActiveX qualquer na Component Palette, vocé podera colocé-lo em qualquer formulario e usd-lo como faria com qualquer outro controle do Delphi. Para incluir um controle ActiveX na Component Pelette, siga estas etapas: 1. Escolha Component, Import ActiveX Control (importer controle ActiveX) a partir do menu princi- pal. A caixa de diélogo Import ActiveX (importar ActiveX) aparece (ver Figura 7.1) eee | ote Freee — al ieoaon, [rarer al FIGURA 7.1 A caixa de diélogo Import Activex. 2. Acaixade didlogo Import ActiveX é dividida em duas partes: a parte superior contém uma caixa de listagem com controles ActiveX registrados e oferece botdes Add (adicionar) e Remove (remover) que Ihe permitem registrar ou retirar os controles do registro. A parte inferior da caixa de didlogo Ihe permite especificar parémetros para a criago de um componente e unidade do Delphi que en- capsule 0 controle. Se 0 nome do controle ActiveX que vooé deseja usar estiver listado na parte superior da caixa de dialogo, prossiga para etapa 4, Caso contrério, dé um clique no boto Add para registrar um novo | doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 91967 so10a2020 PDFs viewer controle com o sistema, Um clique no botto Add faz surgir a caixa de didlogo Register OLE Control (registrar controle OLE; ver Figura 7.2). Selecione o nome do arquivo OCX ou DLL que representa © controle ActiveX que vocé deseja incluir no sistema e dé um clique no bot&o Open. Isso registra o controle ActiveX selecionado com 0 Registro do Sistema e fecha a caixa de dilogo Register OLE Control Na parte superior da caixa de didlogo Import Activex, selecione o nome do controle ActiveX que vooé deseja incluir na Component Palette. A parte inferior da caixa de didlogo contem controles de edigdo para o nome do diretorio da unidade, a pagina da palheta eo caminho de consulta, além de um controle memo que lista as classes contidas dentro do arquivo OCX. O nome do caminho mos- trado na caixa de edio&0 Unit Dir Name (nome do diretérlo da unidade) ¢ o camino do companen- te de wrapper do Delphi criado para realizar a interface com o controle ActiveX. O nome do arqui- Vo usa como padrao 0 nome do arquivo OCX (com uma extensao pas); 0 caminho usa como padrao © subdiret6rio \oelphis\tmports. Embora o padrao seja indicado para uso, vocé pode editar o cami- nho do diretério como desejer. | ten [ocs__ S10) i el seal oe Fessipe [Recor a] __ tae | | FIGURA 7.2 Acaixa de didlogo Register OLE Control. 1» controle de edigdo Palette Page (pagina da palheta) na caixa de didlogo Import ActiveX contém o nome da pagina na Component Palette onde vooé deseja que esse controle resida, O padrao ¢ @ pa- gina ActiveX. Vooé pode escolher outra pagina existente; como alternativa, se vocé criar um nome ovo, uma pagina correspondente seré criada na Component Palette. controle de memo Class Names (nomes de classe) na caixa de didlogo Import ActiveX contém os nomes dos novos objetos criados nesse controle. Vooé normalmente deverd deixar esses nomes de- finidos com 0 padréo, a menos que tenha um motivo especifico para fazer de outra forma. Por exemplo, um motivo seria se o nome da classe padrao entrar em conflito com outro componente ja instalado no IDE. Nesse ponto, vocé podera dar um clique no botao Install (instalar) ou Create Unit (criar unidade) da caixa de dialogo Import Activex. O botéo Create Unit geraré 0 eddigo-fonte da unidade para o Wrapper do componente de controle ActiveX. © botdo Install gerard o e6digo do wrapper e depois chamaré a caixa de dialogo Install, que Ihe permite escolher um pacote em que o componente pode- r4 ser instalado (ver Figura 7.3). Na caixa de didlogo Install, voo8 poder@ incluir o controle em um pacote existente ou criar um novo pacote que sera instalado na Component Palette. D8 um clique em OK nessa caixa de dialogo e 0 Componente sera instalado na palheta, Agora o seu controle ActiveX est4 na Component Palette e pronto para cumprir seu papel doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 2or967 so10a2020 PDFs viewer mot on | np Tara Fone ttaniawmibanstien =] [ Bowe | region edema FIGURA 7.3 A caixa de didlogo Install O wrapper de componentes do Delphi ‘Agora é uma boa ocasiéo para examinarmos o wrapper do Object Pascal criado para encepsular 0 contro- le ActiveX. Iss0 podera ajudar a esclarecer como funciona o suporte 40 ActiveX no Delphi, de modo que voce entenda os recursos e as limitagdes inerentes aos controles ActiveX. A Listagem 7.1 mostraa unida- de card_t18.pas gerada pelo Delphi; essa unidade encapsula 0 controle ActiveX axcard.cex. NOTA axcard.ocx & um controle ActiveX desenvolvido no Capitulo 25. Listagem 7.1 A unidade do wrapper de componentes do Delphi para axcard.ocx. unit axcard_T18; |] stteesseeeestaceseaceseaeeseaseatanesesceneatesenteaesensenansenas // 4 avIs0 “ 1/ 0s tipos declarados neste arquivo Foran gerados a partir de dados // Lidos en una biblioteca de tipos. se essa biblioteca de tipos for // novanente Inportada, explicita ou indiretanente (por meio de outra 1/ biblioteca de tipos referindo-se a esta biblioteca de tips), ou se 0 {1 conando ‘Refresh? do Type Library Editor for ativado enquanto edita // a biblioteca de tipos, o conteido deste arquiva sera gerado novanente J/ © todas as modificacies manuais serio perdides. {1 PASTLNTR : $Revision: 1.98 $ 11 arquivo gerado om 24/2/99 19 M1 pela Type Library descrita a seguir [| ateenenenecenennanennanenneneananeananennanennamentennnnemennsa/ | 11 nota // 0s itens guardados por $IFDEF_LIVE_SERVER_AT_OESIGN_TIME so usados // pelas propriedades que retornan objetos que poden exigir cria¢ao // explicit por meio de una chamada de func3o antes de qualquer acesso 11 atravas da propriedade. esses itens foran desativados para evitar 0 1/ uso acidental dentro do object Inspector. {/ Noc® poder ativi-los deFinindo LIVE_SERVER_AT_DESTSN_TIME ou J] renovendo-os seletivenente a partir de blocos $1FDEF. No entanto, // tais itens ainda precisam ser criados programaticanente por meio de {1 wm método da CoClass apropriada antes que possam ser usados. // Type Lib: C:\work\d5dg\code\chas\Axcard\axcard.tIb (1) n doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 21967 ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao // Tap\LcI0: (78330340-982C-1102-AE5C-946408¢10000)\0 // Helpfile: // Depndtst: JJ (2) v2.0 stdole, (Ce\WINOOUs\S¥STEM\STOOLE2.TLA) J1 (2) v4.0 StdVCL,_ (Ce\WINDDMS\SYSTEMSTOVCLAB.DLL) jj stittesetenaasscesessesessesssseaseseatecentensateneateaeateaeates // {STYPEDADDRESS OFF} //) Unidade precisa ser conpilada sen ponteiros 11 con tipo verificade. interface uses Windows, Activex, Classes, Graphics, OleServer, Olectrls, stavcl; /] Moeneeeenianencrnenianesnaneneneananeansnennanennanennninnnnenensa// 1/ GuIDS declarados na TypeLibrary. 0s seguintes prefixes s3o usados: J/ Bibliotecas de tipo: L1B1D_woxx J) CoClasses Lass om 1) prspinterfaces IID 000% 1) Interfaces ndo-DIsP —: 110 2000 const Ii TypeLibrary - versies principal e secundéria axcardtajorversion = 13 axcardtinorversion = 0} L1BID_Axcard: T6UID = *{78330940-0A2C-1102-AESC-046400C10000} 5 ID_ICardx: TcUID = “{78330941-042c-1102-AE5C-046408C10000)? DIID_ICardxEvents: TGUID = {78330943-942C-1202-A€5c-046408¢10000}" (CLASS _CardK: TOUIO = ‘{78330945-0A2C-1102-AESC-04640810000}" 5 |] Sethsnananeanenenaninaneanentananeananeansnennanenntnensnnengs// // Declaracdo de enuneracdes definidas na biblioteca de tipos [] Mosnaeenianencanennaneananeanencanannananeanannananennanennenenna// 1/ Constantes para enum TsDraghode type Txbragtode = Toletnun; const dinanual = $ee000000; dinautonatic = $o0000001; // Constantes para enum Txcardsuit type Txcardsuit = Toleénun; const esClub = $00080000; csbianond = $90080001; csheart = $00000002; csSpade = $00000003; JJ Constantes para enum TrCardValue type TxCardvelue = Toleénuny const cvace = $0000s000; evTvo = $00008001 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao evthree = $0000002; cvFour = $ee0aa0e3; cvFive = $e00e0000; cvsix = $00009005; evseven = $0000005; cvEight = $e000007; cunine = se0e000085 evTen = 300000009; cevlack = $0e0900085 evqueen = $e0a00008; evking = seeesa0ec; 1/ Constantes para enum TstlouseButton type ‘Totlousebutton const nbLeft ~ soseao0e0; bright = $0e00001; ribniddle = se0008002; oleenun; {1 Constantes para enum TxAlignment type Txtlignment = Toleénun; const taLeftzustify = soee00000; taRightaustify = se00v00e1; ‘taCenter = $09000002; // Constantes para enum TxBiDiNode type TxBiDiMode = ToLeEnuns const biLeftronight bonightToveft bdnightToLeftiioalige - so0e00002; bdnightToLeftReadingonly ~ sa0ee0003; type // Encaninha declaracéo de tipos definidos na Typatibrary jj steeesaeersntecsaeseatangasanestengateneseensataesteaeateasaeeas // acardx = interfaces scaraxDisp = dispinterfaces Icardxévents = dispinterfaces 1/ veclaracao de coclasses definidas na type Library 1/ (NOTA: Aqui napeanos cada CoClass para sua interface padrio) jj seteexentacsananennanenencennanensnceneaneneanentansnnaneneaaenense // carde = Tearex |] **sthnsnaaaaneanenensentinenannentanenneentanensnnannnenensenniing// J) Interface: 1arde doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 2 231067 ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao // Flags: (2416) oval oleautonation Dispatchable {/ cuio: —_{7#3309a1-082c-1102-a€5C-oa6498C10000) [j setebeeestneseeessteneerersesenteensensuseresstneeerestenseneeg/ Icardx = interface(IDispatch) [ «{7330041-042C-1102-A€SC-046408C10000}") function Get_SackColor: OLE_COLOR; safecalls procedure Set_SackColor(Value: OLE_COLOR); safecalls function Get_Color: OLE_COLOR; safecall; procedure Set_Colon(value: OLE _coLoR); safecall; Function Get_oragcurson: Smallint; safecall; procedure Set_oragcunson(Value: Snallint); safecalls Function Get_oraghade: TxtragHodes safecall; procedure Set_oraghode (Value: TxOragviode); safecalls function Get_Faceup: WordBool; safecall; procedure Set_Faceup(Value: wordBo01); safecall; Function Get ParentColor: Worda0ol; safecall; Procedure Set_Parentcolor(value: wordsool); safecall; function Get suit: Txcardsuit; safecall; Procedure Set_suit(value: Txcerdsuit); safecell; function Get_velue: Txcardvalue; safecall; procedure Set _Value(Velue: Txcardvalue); safecall; function Get_Doublesuffered: Wordgool; safecall; procedure set_ooublesuffered(value: wordsool); safecall; procedure Flipchildren(alllevels: Nord8ool); safecall; function DrawTextBiDiNodeFlags(Flags: Integer): Integers safecall; function DrawTextBiDiModeFlagsReadingOnly: Integers safecall; function Get_Enabled: WordBool; safecalls procedure Set_fnabled(Value: NordBool); safecalls function GetControlsAlignnent: TxALignnents safecalls procedure Initiateaction; safecall; function IskightToLeft: Wordsool; safecall; function UseRIghtToLeftaLignsent: Wordgool; safecalls Function UseRightToLeftheading: WondBe0l; safecalls Function UseRightTaLeftscrollear: Hords00l; safecalls function Get_eiDinede: TxtiDiMedes safecall; procedure Set_sipinode(Value: TxBiDiMode); safecall; function Get_Visible: word800l; safecall; procedure Set Visible(Value: NordBool); safecall; function Get_cursor: snallint; safecall; Procedure Set_Cursor(value: snallint); safecall; function ClassNanels(const Wane: widestring): Worddool; sefecall; procedure abouteox; safecall; property sackcolor: OLE_COLOR read Get_eackcolor write set_sackcolor; property color: OLE_coLOR read Get color write Set_colors property oragcursor: smallint read Get_Oragcursor write set_oragcursor; property Oragiode: TxOragHede read Get_DragHode write Set_Dragtiode; property FaceUp: Wordool read Get_Facelp write Set_FaceUp; property ParentColor: WordBool read Get_ParentColor write Set_ParentColor property Suit: TxCardsuit read Get_suit write Set_suits property Value: TxCardValue read Get _Value write Set_Value; property coubleauffered: Wordsa0l read Get_Ooublesuffered write Set_doublesutfered; property Enabled: WordBool read Get_Enabled write Set_Enableds doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 241067 ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao property eipinode: TxeiDiMede read Get_eipivode write set_eioinode; property Visible: WordBool read Get Visible write Set_visibles property Cursor: snaLlint read Get Cursor write Set_cursors ends [f sttthaasenaasensennasenesnennnnentinenteneneeneneinentanennenenenne (7 {/ Disprnt#: 1eardxpisp J/ Flags: (2416) Dual oleautonation Dispatchable // cure: —_{78330041-ana¢-1302-AESC-a46408C16090) Hcardwisp = dispinterface [ *{7330041-042c-1102-a€5C-oasanecrona0}? } Property sackcolar: OLE_cOLOR dispid a; property Color: OLE COLOR dispid -Sa1;, property oragcursor: SmalLint dispid 25 property Oraghode: Trbraghede dispid 3; Property Faceup: Word800l dispid 43 property ParentColor: Word8ool dispid 55 Property Suit: Txcardsuit dispid 6; property value: Txcandvalue dispid 73 property Ooubleauffered: Wordgool dispid 103 procedure Flipchildren(Alltevels: wordeool); dispid 115 function DrawTextBiDiModeFlags(Flags: Integer): Integer; dispid 14; function DrawTextBiDiModeFlagsReadingonly: Integer; dispid 15; property Enabled: WordBool dispid -514; function GetControlstligment: TxALignnents dispid 16; procedure Initisteaction; dispid 18; function IskightToLeft: Word8ool; dispid 195 function useRightToLeftalignnent: Wordeool; dispid 24; function useRightToLeftreading: wordBool; dispid 25; function UseRightToLeftScrollBar: WordBool; dispid 26; property sipinede: TxeiDiNede dispid 273 property visible: Wordsool dispid 23; property cursor: snallint dispid 23; function Classianets(const wane: nidestring): wordeool; dispid 23; procedure aboutsox; dispid -5525 ends // Dispinté: 1cardxevents 1] Flags: (4096) bispatchable (/ cure: —_{78330043-aA2C-1102-AeSC-a4s408c10090) [/ satneeennnaencennncennnennaceneaeneaneneanennanennntenenenenn // IcardxEvents - dispinterface [ {7330043 -042c-1102-AESC-oasaoaci0000}” J procedure onclick; dispid 1} procedure onoblclick; dispid 25 procedure Onkayeress(van Key: Smallint); displd 75 ends ]] seteenenenceennceneanennnceannnenencenennenennennanennnnenentenens // 1/ Declaracao de classe Proxy do controle OLE Ji None do controle + Teardx JJ String de ajuda + Cardx Control Wi Toterface padrdo + TCardx 1) Def. Int. DIS? : Ho s doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 251067 ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao {1 Toterface de evento: Icardxevents 11 TypeFlags (34) pode eriar controle jj ssseeesssacaasastatasearsesasaneasensatensnsnssasansssstateseacias // TcardxankeyPress = pracedure(Sender: Tobjects var key: Snallint) of objects Teardx = class(rolecontrol) private Fonclick: motifyevent; FonoblClick: Tuotifyevents FonkeyPress: TCardxOnkeyPress; Fant: Icard; function GetContrelinterface: iardxy protected procedure Createcontrol; procedure Initcontrelosta; override; public procedure Flipchildren(AllLevels: wordBoo1); function DrawTexteibinoderlags(Flags: Integer): integer function DrawText@lDiNodeFlagsReadingonly: Integers function Getcontrolsalignnent: TxaLignnent; procedure Initiatesction; function IskightToLeft: Hords001; function UseRightToLeftALignment: Word8001; function UseRightToLeftheading: WordBo01; function useRightToLeftscrollsar: Wordg0o1; function ClassNamers(const Wane: Xidestring): wordsoo!; procedure Aboutgox; property ControlInterface: ICardx read GetControlInterfaces property Defaultinterface: ICardx read GetContrelInterfaces property coublesuffered: Wordsool index 19 read cetwordacalProp write SettiondacelProp; property enabled: wordBocl index -514 read cetwordscolPrep write SettiordBcalProp; property sipinode: Toleenun index 27 read GetToleenunprop write SetToleEnunProp; property visible: Word800l index 28 read GetwordBoolPrap write Settiandacalerop; published Property Tabstep; property Align; property Parentshonsints property Popupienu; property Showtints property Taborders property onoeagorops Property onbragover; property onEndDrags property onenters Property Onexits property onstartorags property eackcoler: TColer index 1 read GettColorProp write SetTColorProp stored False; 6 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 251067 ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao property Color: TColor index -501 read GatTcolorerop write SetTColorProp stored False; property oragcursor: smallint index 2 read cetsmallintprop write SetSaallinterep stored False property Oraghode: TOleenus Index 3 read GetTolecnunProp write SetTOletnunProp stored False; property FaceUp: Word80ol index 4 read GetWord8oolProp write SettiordBoclProp stored False property Parentcolor: Wordgool index 5 read GetwordsoolProp write Settiordscolprep stored False; property Suit: TOletnun index 6 read GetToletnunProp write SetToleenunprop stored False; property Value: Toleznum index 7 read GetTOleznuProp write SetTolecnuaprop stored False property Cursor: snallint index 29 read Getsnallinterop write setsnallinterop stored False; property OnClick: TNotifyévent read FonClick write FOnClicks property OnblClick: Thotifyévent read FOnDbIClick write FOnDbIClicks Property onkeyPress: TCardxonkeyPress read FonkeyPress write Fonkeyeress; ends procedure Registers nplenentation uses combi; procedure Tcardx.Initcontroloata; const CEventDispros: array [9..2] of DWORD = ( se0neec0:, sooeae002, $00900007); Ccontroloata: Teontrolbata2 = ( Classi: *{78330945-982¢-102-AE5¢-46408¢10000}* EventI10:_§{78330943-042C-1102-AE5C-046408¢10000}" 5 Eventcount: 33 EventDisplDs: @ceventoispros; Licensexey: nil (*HR:$00900000"); Flags: soveao009; Version: 401); begin Cortrolbata :~ gcControloata; Tcontroldata2(cControlbata).FirsteventOFs t= Cardinal (@GFOnCLick) - Cardinal(self); ends procedure TCardx.createcontrol; procedure Decreate; begin Flntf := tunknaun(oleobject) as 1cardx; ends begin if FIntf = nil then Docreate; ends doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 271967 ‘30/09/2020 PDFs viewer Listagem 7.1 Continuacao function Teardx.cetcontralinterface: Icardx; begin Greatecontrol; Result := FInt; ends procedure TCardX.Flipchildren(AllLevels: KordBool); begin Defaultinterface. Flipchildran(aLlLevels); ends function TCaréx.DrawTextAibiMaderlags(Flags: Integer): Totegers begin Result := DefaultInterFace.brauTextBiDivodeFlags(Flags)3 ends function 1Cardx.brawrexteipimederLagsReadingonly begin Result := Defaultinterface, DranrextBiDivoder lagsReadingonly; ends ntegers function Tcardx.cetcontrolsalignnent: TxAlignment; begin Result := Defaultinterface.cetcontrolsalignnent; ends procedure TCardX.Initiatedctions begin DefaultInterface,Initiateaction; ends Function Tearex.rsiightTaLeft: wordeool; begin Result :~ DefaultInterface. TsnightToLeft; ends function Tcardx.useRightToLeftAlignnent: Wordecol; begin Result := Defaultinterface.UseRightToLeftalignnent; ends function Tcardx.UseRightToLeftneading: wordsool;, begin Result := Defaultinterface.useRightToLeftreadings ends function TCardX.UseRightToLeftscrollBar: begin Result := Default Interface.UseRightToLeftscrallear3 ends Wordool5 function TCardx.Classliamels(const Name: UideString): Hordool begin Result := Defaultinterface.Classtamers (Nana); ends Fy doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 281067 so10a2020 PDFs viewer Listagem 7.1 Continuacao procedure Tcardx.Abouteox; begin Default Interface: AboutBox; ends procedure Registers begin RagisterComponents ( ‘Activex? [TCardx]) ends end, Agora que voce jé viu 0 cédigo gerado pelo editor da biblioteca de tipos, vejamos um pouco mais a fundo 0 mecanismo de importacao da biblioteca de tipos. De onde vém os arquivos do wrapper? A primeira coisa que vocé poder notar ¢ que o nome do arquivo termina com_r.e. Ainda mais sutilmen- te, voce pode ter observado 0 fato de que existem varias referéncias a “library” (biblioteca) no arquivo de Cédigo gerado. Ambos sao indicaodes quanto a origem do arquivo de wrapper. A biblioteca de tipos de um controle ActiveX é uma informapgo especial vinculada ao controle como um recurso que descreve 0 diferentes elementos de um controle ActiveX. Em particular, as bibliotecas de tipos contém informacdes como as interfaces aceitas por um controle, as propriedades, os mStodos e os eventos de um controle, além dos tipos enumerados usados pelo controle. A primeira entrada no arquivo de wrapper & 0 GUID da biblioteca de tipos do controle. NOTA ‘As bibliotecas de tipos séo usadas principalmente por qualquer tipo de objeto Automation. © Capitulo 23 contém mais informagbas sobre as bibliotecas de tipo e seu uso. Enumeracées Analisando @ unidede gerada de cima para baixo, imediatamente apés o GUID da biblioteca de tipos es- a0 08 tipos enumerados usados pelo controle. Observe que as enumeragdes s4o declaradas como cons- tantes simples, em vez de verdadeiros tipos enumerados. Isso ¢ feito porque as enumeracées da biblioteca de tipos, assim como as da linguagem C, nao precisam comegar com zero, e os ntimeros ordinals do ele- mento néo precisam ser contiguos. Como esse tipo de declarago néo ¢ vélido em Object Pascal, as enu= meragdes devem ser declaradas como constantes, Interfaces de controle Apds 0 arquivo do wrapper, a interface principal do controle é declarada, Aqui, vooé encontraré todas as propriedades e métodos do controle ActiveX. As propriedades também so declaradas novamente em uma cispinterface, permitindo assim que o controle seja usado como uma interface dual. Os eventos so declarados separadamente em seguida em uma dispinterface. Vooé certamente no precisa saber a respel- to de interfaces para usar controles ActiveX nas suas aplicagdes. Além do mais, o trabalho com interfaces pode ser um tépico complicado, e por isso nao entraremos em muitos detalhes no momento. Vocé en- contraré mais informagSes sobre interfaces em geral no Capitulo 23, ¢ informagées sobre interfaces com contrales ActiveX no Capitulo 25. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 2ar967 so10a2020 PDFs viewer Descendente de TOleControl Logo apés no arquivo da unidade vem a definic&o de classe para o wrapper do controle. Por default, 0 nome do objeto wrapper do controle ActiveX é Txx, onde x é 0 nome da coclass de controle na biblioteca de tipos. Esse objeto, como todos os wrappers de controle ActiveX, descende da classe rolecontrol.. role- control é um componente transportando @ alga da janela que descende de twincontral. Tolecontrol encap- sula as complexidades do mapeamento da funcionamento de controles ActiveX para os componentes do Delphi, de modo que os controles ActiveX trabalhem de modo transparente com 0 Delphi. rolecontroi € uma classe abstrata — 0 que signiica que vocé nunca desejara criar uma instancia dele, mas usé-lo como ponto de partida para outras classes. Os métodos © primeiro procedimento mostrado é 0 procedimento initcontrolbate(_). Esse procedimento é introdu- Zido no objeto Tolecontrol ¢ ¢ modificado para todos os descendentes. Ele configura os nuimeros exclusi- vos da classe OLE e da identificagdo de evento, alem de outras informagdes especificas do controle. Em particular, esse método torna o Tolecontrol ciente de importantes detalhes do controle ActiveX, como IDs de classe flags de controle diversos e uma chave de licenga, se 0 controle for licenciado. Esse método aparece na parte protected da definigao de classe, pois ndo é util para os usuarios da classe — ele s6 tem sig nificado no interior da classe. O método rnitcontrotinterface( ) € modificado para inicializar o campo da interface privada Fintf com um ponteiro para a interface 1cardsx do controle. O controle ActiveX carax expde apenas um outro método: abouteox( ). E comum que os controles ‘ActiveX contenham um metodo chamado atouteox( ), que ativa uma caixa de didlogo About personaliza- da para o comendo. Esse método é chamado através da interface vrable, usando a propriedade control- Interface, que € lide a partir do campo Fintt NOTA ‘Além de chamadas do vrable usando a propriedade controlinterface, 08 métodos control também podem ser chamados com Automation, usando a propriedade oleobject de olecontrol. Como vooé verano Capi- tulo 23, normalmente & mais eficaz 2 chamada de métodos por meio de vrable em vez de por Automation. As propriedades Vocé pode ter notado que a classe Tcardx possui dois grupos de propriedades distintos. Um grupo néo possui valores de leitura e escrita especiicados. Estas s4o propriedades e eventos padrao de componentes do Delphi, herdados das classes ancestrais twincontrol € tconponent. O outro grupo de propriedades possui um Indice e também metodos get e set especificados. Esse grupo de propriedades inclui as propriedades do controle ActiveX sendo encapsuladas pelo tolecontrol, (Os métodos get e set especializados para as propriedades encapsulades oferecem a magica que pre- enche a lacuna entre as propriedades do controle ActiveX e as propriedades do componente do Object Pascal. Observe os métodos read e write que apanham e definem propriedades para cada tipo espectfico (Como ceteoolrrop( ), setsoolProp( }, GetstringProp( , SetstringProp( ) etc.). Embora existam métodos get @ set para cada tipo de propriedade, todos eles operam de modo semelhante. Na verdade, 0 oddigo a se- guir mostra métodos get e set genéricos para rolecontrol, que funcionariam dada uma propriedade do tipo x: Function Tolecontrol .cetxPrep(index: Integer): x3, Temp: Tvarbatas 30 begin doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 1967 so10a2020 PDFs viewer GetProperty(Index, Teng) Result := Temp. Vx; ends procedure ToleControl.SetxProp(Index: Integers Value: X)5 Temp: Tvaroata; begin Temp. Viype := vary Temp. Vx := Values setProperty(Index, Temp); ends Nesse cédigo, o Indice da propriedade (conforme indicado pela diretiva index nas propriedades do componente tcardsctri) & passado implicitamente para os procedimentos. A varidvel do tipo Xé empaco- tada em um registro de dados Tvaroata (um registro que representa uma Variant), e esses parametros s80 assados para o método cetrroperty( ) OU SetProperty( ) de Tolecontrol. Cada propriedade do controle ActiveX possui um indice exclusivo que atua como identificador. Usando esse indice e a variavel tvarbata Tenp, GetProperty( ) © setProperty( ) usam OLE Automation para obter e definir os valores de propriedade dentro do controle ActiveX. Se vooé jé trabalhou com outros pacotes de desenvolvimento antes, gostara de saber que 0 Delphi oferece acesso facilitado n&o apenas para as propriedades do proprio controle ActiveX. mas também para as propriedades e os métodos normais de Twincontrol. Isso permite usar um controle ActiveX como outros controles que transportam alca no Delphi, possibilitando 0 uso de principios orientados a objeto para modificar 0 comportamento de um controle ActiveX, criando descendentes personalizados dos controles ActiveX no ambiente Delphi. Usando controles ActiveX em suas aplicagoes Depois de vincular 0 wrapper do seu controle ActiveX a biblioteca de componentes, voos ja teré lutado a maior parte da batalha. Depois que o controle ActiveX tiver sido incluido na Component Palette, seu uso ser 0 mesmo que 0 de um componente normal do Delphi. A Figura 7.4 mostra o ambiente Delphi com um tearax focalizado no Form Designer. Observe as propriedades do rcardx listadas no Object Inspector. FIGURA 7.4 Trabalhando com um controle ActiveX no Delphi. 34 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 11967 so10a2020 PDFs viewer Alem das propriedades de um controle ActiveX sendo definides com 0 Object Inspector, alguns controles ActiveX também oferecem uma caixa de didlogo Properties que é revelada selecionando-se a ‘opgo Properties do menu de contexto no Form Designer do Delphi. © menu de contexto, também mos- trado na Figura 7.4, é reveledo por meio de um clique com 0 botdo direito sobre um determinado con- trole. A caixa de didlogo Properties na realidade se encontra dentro do controle ActiveX; sua aparéncia, s2U USO € seu contetido sao determinados inteiramente pelo projetista do controle. A Figura 7.5 mostraa caixa de didlogo Properties para o controle ActiveX rcardx. P| All 'sist- ia) [emcees] | meee Ese FIGURA 7.8 A caixe de diélogo Properties de rcaréx. Gomo voce pode imaginar, esse controle em perticular vem equipado com propriedades que permi- tem especificar 0 naipe, 0 valor, a cor ¢ @ figura do fundo da carta, além das propriedades padréo que se referem & posi¢go, ordem de tabulagdo etc. A carta na Figura 7.4 possul uma propriedade value definida ‘como 1 (2) e sua propriedade suit (naipe) definida como 3 (espadas). Distribuindo aplicagées equipadas com controle ActiveX Quando vocé estiver pronto para distribuir sua aplicagao equipada com controle ActiveX, haverd alguns aspectos de distribuigao que vocé tera de se lembrar enquanto se prepara para enviar seu controle Acti- veX e arquivos associados para seus clientes: + Vocé precisa enviar 0 arquivo OCX ou DLL que contém os controles ActiveX que esté usando na sua aplicagdo. Os arquivos OCX, sendo DLLs, nao esto ligados a0 executavel da sua aplica- ‘20. Alem disso, antes que o usuario posse usar sua aplicacdo, o controle ActiveX precisa ser re- gistrado no Registro do Sistema desse usuério. O registro do controle ActiveX é discutido na proxima seco. ‘+ Alguns controles ActiveX exigem uma ou mais DLLs externas ou outros arquivos para poderem funcionar. Verifique a documentagao dos seus controles ActiveX de terceiros para determinar se algum arquivo adicional precisa ser distribuido com o seu controle ActiveX. Veja no Capitulo 25 mais informagdes sobre quais arquivos adicionais poderiam ter que ser distribuidos junto com seus controles escritos em Delphi: ‘« Muitos controles ActiveX vém com um arquivo de licenga que é obrigatério se vocé quiser usar o controle durante o projeto. Esse arquivo vern do fornecedor do controle ActiveX, ¢ impede que seus usuarios finais criem aplicagdes com os controles ActiveX que vocé entrega junto com suas aplicagdes. Voc# n&o precisa remeter esses arquivos LIC com a sua aplicagdo, @ menos que os usuérios de sua aplicagao precisem usar 0s controle licenciados em uma ferramenta de desenval- 2 vimento @ voos tenha a licenga apropriada para redistribul-los. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 21967 so10a2020 PDFs viewer Registro do controle ActiveX Antes que 0 controle ActiveX possa ser usado em qualquer sistema (incluindo o dos clientes que execu tam suas aplicagdes), ele precise ser registrado no Registro do Sistema. Normalmente, isso é feito por meio do aplicativo Regsvr32.e%e, que vern com @ maioria das verses do Windows. Como alternative, vocé pode usar 0 utilitario de registro da linha de comandos, rxegsvr.exe, encontrado no diretério bin do Del phi. Ocasionalmente, vocé pode querer registrar o controle de modo mais transparente, pare que sua aplicagdo tenha um toque de integragao. Felizmente, nao é dificil integrar 0 registro do controle ActiveX (e @ remogo do registro) em sua aplicagéo. A Inprise oferece o cédigo-fonte do utilitério tregsvr como. um exemplo de aplicagéo, ¢ essa é uma demonstracio excelente de como registrar servidores ActiveX € bibliotecas de tipos. BlackJack: um exemplo de aplicagao OCX ‘A melhor maneira de demonstrar como usar um controle ActiveX em uma aplicagéo é mostrando como escrever uma aplicacao uitil que incorpore um controle ActiveX. Este exemplo utiliza o controle ActiveX ‘cardx; que maneira melhor de demonstrar um controle de carta do que criar um jogo de vinte-e-um? Por questo de argumento, cansidere que todos os programadores jogam alto e que nao precisam receber as regras do jogo (voce néo sabia que este livro tinha comedia, sabia?).Desse modo, vocé pode se concentrar na tarefa de programagao em méos, Como voce pode imaginar, a maior parte do cOdigo para essa aplicapao lida com a légica do jogo de vinte-e-um. Todo 0 cédigo ¢ fornecido nas listagens mais adiante neste capitulo; ne momento, a discus- s8o fica em torno das partes de codigo individuais que lidam diretamente com o gerenciamento ¢ a mani- Pulagao dos controles ActiveX. © nome desse projeto 87; para que voce tenha uma idéia de onde vem o Cédigo, a Figura 7.6 mostra um jogo de DDG BlackJack em andamento. ET FIGURA 7.6 Jogando vinte-e-um. O baralho de cartas Antes de escrever 0 jogo em si, vooé primeiro precisa escrever um objeto que encapsule um baralho de cartas do jogo. Ao contrério de um baralho de cartas real (em que as cartas s0 apanhadas do topo de um baralho misturado), esse objeto de baralho de cartas contém um conjunto néo misturado e utiliza name ros pseudo-aleatdrios para escolher uma carta aleatéria do baralho em sequiéncia. Isso é possivel porque cada carta tem nogdo de que ela foi usada ou néo. Isso também simplifica bastante o procedimento de embaralhar as cartas, pois tudo o que 0 objeto precisa fazer é definir cada uma das cartas como nao usa- da, O codigo para a unidade playcard.pas, que contém 0 objeto Tcarddeck, entcontra-se na Listagem 7.2. a doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 1967 ‘30/09/2020 PDFs viewer Listagem 7.2 A unidado playcard.pas unit Playcard; interface uses sysutils, Cards; type Ecardérror = class(Exception); // excecao de carta genérica Tlayingcard = record 17 representa uma carta Face: Teardvalue; 1/ valor da face da carta sult: Tearesuity // valor do naipe da carta ends {um array de 52 cartas representando un baralho ) Teardarray = array[1..52] of TPlayingcards { Objeto que representa um baralho de 52 cartas DIFERENTES. } (este € un baratho misturado de 52 cartas, eo objeto) {registra até que ponto no baralha o usuério apanhou ) {a carta, } Teardbeck = class private Feardarray: Teardareay; FTop: integer; procedure Tnitcardss function Getcount: integers public Property count: integer read Getcount; constructor Create; virtual; procedure Shuffle; function orau: TPlayingcard; ends { Getcardvalue retorna 0 valor nunérica de qualquer carta } function Getcardvalue(c: TPlayingcard): integer implenentation function Gotcardvalue(¢: TPlayingcard): Integers { retorna o valor nungrico de una carte } begin Result := ord(c.Face) + 25 if Result > 1@ then Result ends 105 procedure Tcanébeck.Initcardss { inicializa o baralho atribuindo una conbinacdo exclusive de } { valor/naipe 3 cada carte. } ix integers Arace: Teardvalues asvit: Teardsuity begin AFace != cvAces 11 conega com fs ASuit i= csClub; 11 comeca con paus doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed ‘967 ‘30/09/2020 Listagem 7.2 Continuacao PDFs viewer for i i= 1 to 52 do begin Feardarray[i].Face Fcardapray[1].suit If (1 mad 4 = 0) and (1 «|>> $2) than inc(aFace) 5 if aSuit <«|>> High(TCardsuit) then inc(Asuit) else asuit := Low(rcardsuit); ends ends constructor Teardbeck.craate; { construtor do abjeta Teardoack. } begin inherited Creates Initcards; shuffle; ends Function Tcarddeck.cetCount: integers { Retorna contagem de cartas ado usadas } begin Result t= 52 - FTops ends procedure TcardDeck.Shuffle; 7 para cada carta do baralho... H/ atribui face /f atribut naipe // para cada quatro cartas, 11 increnenta a face 17 sempre incrementa 0 naipe {(Mistura novanente as cartas ¢ define carta de cima como @. } is integers Randcaré: TPlayingcards Randiun: integers begin for i i= 1 to 52 do begin Randhiun := Randon(51) + 13 Randcard := FCardarray[Randiun); I escolhe nimero aleatéria If troca préxina carta por Feardarray[Randsun] := Fcardarray[i]; J/ carta alestéria no baralho Fcardarray[i] 1= Randcards ends Frop i= a3 ends function Teardeck.Oraw: TPlayingCard; { escolhe a préxima carta do baralho. } begin inc (T0p); if Frop = 53 then raise Ecardérror.create( ‘Deck is empty"); result := FCardarray[FTo9p]s ends initialization Randomize} J/ senente do gerador de niin, aleatério end, doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 8 1967 ‘30/09/2020 PDFs viewer 6 O jogo A interagao do jogo de vinte-e-um DDG BlackJack com o objeto rcarax ocorre principelmente em trés procedimentos. Um procedimento, chamado it ), 6 chamado quando o jogador escolhe aceitar outra carta. Outro procedimento, vealersit( ), 6 chamado quando o carteador deseje outra carta, Finalmente, © procedimento rreecards( ) & chamado para dispor de todas as cartas na tela para preparar-se para outra mao a ser distributda procedimento sit } funciona com o controle ActiveX tearax exclusivamente de duas maneiras. Primeiro, ele cria todos 0s controles dinamicamente, em vez de usar controles retirados da Component Palette. Alem disso, ele nunca usa uma varidvel de insténcia do tipo rcardx — em vez disso, ele aproveita uma construgdo with. .da para crlar e suar 0 objeto em uma nica etapa. O cddigo a seguir mostra o proce- dimento Hie ) procedure THainFora.nits {ver do jogader } begin Curcard i= CardDeck.Draws 11 apanha carta with Teardx.create(selF) do JI cria controle ocx da carta begin Left := NextPlayerPos; If define posicae Top = PYEOS; Suit i= Ord(Curcard.suit); ——J/ define naipe Value := ord(curcard.Face); If define face Parent i= Self 1) atribui pai Inc(WextPlayerPos, Width div 2); / acompanha posi¢3o Updates J} mostra carta ends Dblatn.enabled := False; JI desativa double down if Curcard.Face = cvAce then PAceFlag := True; // flag de As Inc(PlayerTatal, GetCardvalue(curcard)); 1/ acumula total PlayLbl.caption := IntTostr(PlayerTotal); 17 engana if PlayerTotal > 21 then 1/ verifica estouro begin shoutiessage(“Busted!”); shouFinstcard; Showtioners ends ends Neste procedimento, uma carta aleatdria, chemada curcerd, € retirada de um objeto rcardoeck cha- mado cardpeck. Um controle ActiveX tcardx é entéo criado, e os valores de propriedade sao atribuidos. nextPlayer?os € uma varivel que registra a posigao no eixo-X para a préxima carta, pyeos € uma constante que informa a posigo do eixo-¥ da mao do jogador. As propriedades suit e value recebem valores cor- respondem ao naipe (suit) ¢ 4 face (Face) de curcard. Hainforné atribuido para ser 0 Parent do controle, ea varidvel nextPlayerPos é incrementada pela metade de largura de uma carta, Depois de tudo isso, a varié- vel PlayerTotal & inerementada pelo valor da carta para registrar o escore do jogador. O procedimento oealerwit( ) funciona de modo semelhante ao procedimento wit( ). O obdigo des- se procedimento é 0 seguinte: procedure THalnFara.oealerdit(cardvisible: gootean); { carteador tem 2 vez } begin Curtand = cardbeck.Draxs 11 carteador apanha una carta with Teardx.Ccreate(Self) do 1/ cria 0 controle activex doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 61967 so10a2020 PDFs viewer begin Left := nextoealerros; If coleca carta no formulério Top := DYPos; suit := ord(curcard.suit); J/ ateibui naipe FaceUp i= Cardvisible; Value :~ ord(curcard.Face Jf atribui face Parent t= self; J/ atribui pai para controle Inc(WextoealerPos, width div 2); // define onde colocar préx. carta vpeates J mostra carta ends if Curcard.Face = cuace then OAceFlag := True; // define flag de As Inc(bealertotal, Getcardvalue(curcard))3 // continua contando DealLb1.caption :~ IntToste(DealerTotal); 17 engana if ceolertotal > 21 then // verifica estouro showiessage( “Dealer austed!?); ends Esse método aceita um parémetro Booleano chamado cardvisibie, que indica se a carta deve ser dis- tribufda virada para cima, Isso porque as regres do vinte-e-um dizem que a primeira carta do carteador deve permanecer virada para baixo até que 0 jogador tenha escolhido ficar com ela ou até que tenha fra- cassado. Observado essa regra, a primeira chamada para ocaleriit( ) resultard em False sendo pasado em cardvisible. O procedimento Freecards(_) é responsavel por remover todos os controles de tcardx no formulério principal. Como a aplicapgo néo mantém um array ou um punhado de varidveis do tipo Tcarex por perto ara gerenciar as cartas na tela, esse procedimento percorre a propriedade de array controls do formula- rio, procurando elementos do tipo Tcardx. Quando um controle desse tipo é encontrado, seu metodo Free € chamado para remové-lo da meméria. O truque aqui é certificar-se de estar percorrendo o array de tras para frente. Se vocé nao seguir esse caminho inverso, correré 0 risco de alterar a ordem dos controles No array enquanto esta atravessando 0 array, o que podera causar erros. O cédigo para o procedimento Freecords aparece em seguida: procedure THainrorn.Freecards; { Libera todas as cartas de controle Activex na tela } ii integers begin for i != Contrelcount - 1 donto @ do // retracede! if contrals[i] is Teardx then Controls[i] Frees ends Isso completa a explicagao sobre as partes principais do oédigo que manipula os controles ActiveX. A listagem completa de vin.pas, a unidade principal dessa aplicago, aparece na Listagem 7.3. Listagem 7.3 A unidade sain.pas para o projeto 8). unit mains interface Windows, Messages, sysutils, Classes, Graphics, Controls, Farms, Dialogs, Olectels, axcard_tie, Cards, Playcard, stdctrls, Extctrls, menus; a doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed sri967 ‘30/09/2020 PDFs viewer Listagem 7.3 Continuacao type TwainForn = class(TForm) Paneli: Panel; Mainvenut: THainlenus Playl: ThenuTtens Deal: ThenuTtens Hitt: Tenuttens Holda: Thenultems Doubleoownt: Taenuten; har Thenuttems Closet: THenurten; Helpa: THenuTtens About: THenurten; Panel2: TPanel} Label: TLabel; Cashlabel: Tlabel; eetlabel: TLabels itetn: Teuton; Dealetn: Teuton; Heldetn: Teuton; exitetn: Teuton; eetedit: Tedits Doletn: Tautton; cheatPanel: TPanel; DealLbl: Tlabel}, PlayLbl: Tlabel} Labela: TLabels Labelé: TLabel; Cheat: Thenulten; Na: Thenuttems procedure Forncreate(sender: Tobject); procedure Fornbestray(sender: Tobject); procedure abouticlick(Sender: Tobject); procedure CheatiClick(Sender: Tobject); procedure Exitatnclick(Sender: Tobject); procedure DblBtnclick(Sender: Tobject); procedure Dealatnclick(Sender: Tobject); procedure Hitstnclick(Sender: Tobject); procedure Holdstnclick(Sender: Tobject); private cardveck: Teardvecks Curcard: TPlayingcard; Nextplayerros: integer; Nextoealerpos: integer; Playertotal: integer; Dealertotal: integer; PaceFlag: Boolean} DiceFlag: Boolean; Palas Goolean; DSiFlags Goolean; DoFlag: Booleans Procedure Deal; procedure Dealeriit(Candvisible: @oolean); procedure Doublepewn; procedure Enablevoves(Fnable: Boolean); doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 1967 ‘30/09/2020 PDFs viewer Listagem 7.3 Continuacao procedure Freecards; procedure Hit; procedure Holds procedure ShowFirstCard; procedure Showwinners ends nalnform: THalnForms implenentation {$8 *.0FH) uses Aboutu; const PyPos = 1755 J Anicianda pos y para cartas do jogador DyPos = 10; {0 mesno para as cartas do carteacor procedure TMainFora.Foracreate(Sender: Tobject); begin cardoeck ends cardoeck.creates procedure THainForn.Forabestroy(Sender: Tobject); begin Cardeck.Frees ends procedure TalnFora.aboutaClick(sender: Tobjact); {crla e chama caixa about } begin with TAbouttex.create(sel#) do try ‘Showtodal Finally Frees end ends procedure THainFora.cheatiClick(sender: Tobject); begin heat1.checked := nat cheat checked; cheatParel. visible := cheat1.checked; ends procedure THainFora.ExitatnClick(Sender: TObject)s begin Close; ends procedure TalnFora.oblatnclick(sender: Tobjact); begin Daubledexns doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 301967 ‘30/09/2020 Listagem 7.3 Continuacao PDFs viewer ends procedure THainFora.DealstnClick(Sender: Tobject)s begin Deals ends procedure TainFora.Hitatn¢lick(Sender begin hits ends object); procedure TainFora.HoldstncLick(Senden: Tobject)s begin held ends procedure TiainFora.Deals {Joga una nova mao begin Freecards; eetedit.enabled := False etLabel.tnabled := False; if cardpeck.count begin Panel .Caption Cardeck. shuffles end else Panel Caption anal shows Panel updates NextplayerPos t= 193 NextdealerPos t= 193 Playertotal t= Dealertotal + PacoFlag DaceFlag PevFlag DevFlag vor lag hits Dealerit(False); hits Deolerit(true); Panel. Hides if (PlayerTotal PeIFlag := True; if (Dealertotal DBIFlag := True; if PBDFlag or DB)Flae then begin ShowFirstcard; Shoutessage(‘Blackjack!?); Shousinners <1 then = "Dealing. 8; False; False; False; False; = False; 0 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed Reshuffling and para carteador e jogador } J[ remove cartas da tela J] desativa ctrl edicéo de epost JI disable bet label JJ enbaralha se < 11 cartas dealing...°5 J{ mostra painel “repartindo” J/ cuida para que sej visivel Jf define posicao horiz. das cartas Jf 2era totais de cartas JI 20ra Flags II vez do jegador JI vez do carteador JI vez do jogador JI vez do carteador J] esconde painel 1) and PAceFlag then JI verifica vinte-e-um do jogador 1) and DAceFlag then JI verifica vinte-e-um do carteador J/ se howe vinte-e-un J/ viva carta do carteador Jf determina vencedor 401967 ‘30/09/2020 PDFs viewer Listagem 7.3 Continuacao end else Enablevoves(True) 5 JI permite jogo, nantén double down ends procedure THainForn.DealerHit(Cardvisible: Boolean); { Carteador tem a ver } begin Curcand = Cardbeck.Draws 1/ carteador apanha una carta uith Teardx.create(sel#) do 1/ cola o controle activex begin Left t+ NextdealerPoss 17 coloca carta no formilario Top := DvPos; suit := ord(curcard. suit); 1/ atribui naipe Faceup := cardvisible; Value := ord(curcard.Face); 7 atribui Face Parent := Self; {/ atribui pai para controle ne(llextbeslerPos, Nidth div 2)5 // define onde colocar prex. carte Updates 17 mostra carta ends if Curcard.Face = cvace then DaceFlag := True; // define flag As inc(Dealertotal, Getcardvalue(curcard)); 11 continua contando bealLbl.caption := intTostr(oealertotal) ; 1) engana if vealertotal > 21 then // verifica estouro do carteador Shoutiessage( ‘Dealer Busted!”); ends procedure THainForn.DoubleDowns { Chanada para double down na no distribuida } begin DoFlag t= True; 11 define #1ag double down para ajustar aposta hits 11 apanha una carta holds {/ deixa o carteador apanhar suas cartas ends procedure TMainFora.enablevoves(Enable: Boolean); { Ativa/desativa botdes/itens de enu de movinentos } begin itetn.cnabled holdetn. enabled + Doletn.cnabled := 11 Pressiona botéo 11 Segura botio /{ Botgo double down ita enabled 11 alcanga item do menu holdi.enablee 11 Nantém item do menu Doublesown1-enabled := Enables /{ tem de menu double down ends procedure THainForn.FreeCardss {Libera todas as cartas de controle Activex na tela } ix integers begin for i 1= ContralCount - 1 doxnto @ do // conta para trés! if controls[i] 1s Tcaréx then Controls[i].Frees ends a doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 431967 ‘30/09/2020 PDFs viewer Listagem 7.3 Continuacao procedure tainForn.Hits { vex do jogador } begin Curcard = CardDeck.Draxs J apanha carta with TcardX.Create(Self) do 1 cia controle de carta begin Left i= NextPlayerPoss Il define posicéo Top i= PYPos} suit = ord(curcard.suit); If define nalpe Value := ord(curcard.Face); _// define valor Parent 1 Self} I ateibui pai Inc(NextPlayerPos, Width div 2); // verifica posicao Updates If apresenta carta ends Dblatn.enabled := False; /1 desativa double down if Curcard.Face = cvace then PAceFlag := True; // define flag de As Inc(Playertotal, GetCardvalue(Curcard)) 5 Uf total acumulado PlayLbl.caption := intTostr(PlayerTotal); Uf engana if PlayerTotel > 21 then Uf verifica estouro begin Shontiessage( ‘Busted!?); showFirstcard; shousinners end ends procedure THainFora.Holds { Jogador segura, 0 procedinento permite que o carteador dé as cartas. } begin Enabletoves(False); showFinstcarcs // wostra carta do carteador if Playertotal <= 21 then 11 se Jogador 30 tiver estourado.. begin if DaceFlag then 11 se 0 carteador tem um AS... begin { Carteadar precisa atingic 17 } while (DealerTotal <= 7) or ((DealerTotal >= 11) and (DealerTotal < 17)) do Dealersit (True); end else I se no houver As, continua jogando até chegar a 17 hile Dealertotel < 17 do pealeriit(true) ends showstinner // vetermina vencedor ends procedure THainForn.ShowFirstcard; ix integers begin 11 cuide para que todas as cartas estejan viradas para cina for i 1= 0 to Controlcount - 2 do if controls[i] 1s Tcardx then begin Teardx(Controls[i]).Facelp += True; 2 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 421067 ‘30/09/2020 PDFs viewer Listagem 7.3 Continuacao ‘Tcanéx(controls[]) updates ends ends procedure THainFora.shoxitinner; { vetermina mio vencedora } St steings begin if pacetlag then U1 se carteador ten um As... begin if pealerrotal + 10 c= 21 then —_// descobre melhor mio inc(vealertotal, 10); ends if PACeFlag then 11 se jogador tom un As. begin if Playertotal + 10 «21 then —_// descabre melhor 30 inc(PlayerTotal, 19); end if Dealertotal > 21 then // zera 0 escore se estourou DealerTotal := 03 if Playertotal > 21 then Playertotal := 0; if Playerrotal > ealertotal then // se jogador ganha... begin S t= ‘You winl?s 4f coFlag then // paga 2:1 para double down ashLabel caption :~ IntTostr(steTornt(CashLabel caption) + StrTornt(Betedit Text) * 2) else 11 paga 1:1 normalmente CcashLabel caption := IntToStr(StrToInt(CashLabel Caption) + strToint Betedit. text); if ponrlag then 1 paga 1.5:1 se fez vinte-e-un cashtabel caption := inttostr(strtomntCashtabel ception) + strTomnt Botedit Text) div 2) ene else if bealerTotal > playertotal then // se carteador ganha... begin S t= ‘Dealer wins!?5 if oDFlag then 11 perde 2x em double down Cashlabel «Caption := IntToStr(StrToInt(CashLabel.Caption) ~ strTomt(setedit.Text) * 2) else 17 perda normal CcashLabel.caption := inttostr(strroint(cashLabel.caption) - StrTornt (Batedit Text); end else St Bushl?s // enpate, ninguén ganha IF messageblg(s + #13#10'D0 you want to play again with the sane bet??, mtconfirmation, [nbves, nbto], ®) = mrves then Deal; eetedit.enabled := True; 17 permite mdar a aposta etLabel..tnabled ends end. doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 431067 so10a2020 PDFs viewer Chamando um método do controle ActiveX Na Listagem 7.3, vocé pode ter notado que o formulério principal contém um métocio que cria e apre- senta uma caixa de didlogo About. A Figura 7.7 mostra @ aparéncia dessa caixa de didlogo About quando ela é chamada Dethis Dept Gate Blacklack Dasa Crp 7995, Toe Pc Teva FIGURA 7.7 Caixa de didlogo About do jogo de vinte-2-um. Essa caixa de didlogo About é especial porque contém um botéo que, quando selecionado, mostra uma caixa About para 0 controle ActiveX carax, chamando seu método AboutBox( ). A caixa About para o controle carax aparece na Figura 7.8. A seguir vemos 0 cddigo que realize essa tarefa, Olhando mais adiante, a mesma técnica usada para fazer chamades de vrable 205 servidores OLE Automation no Capitulo 23 tambem é usada aqui procedure Tabautfox.cardatnclick(Sendert Tebject)$ begin Card AboutBoxs ends FIGURA 7.8 A caixa de didlogo About do controle ActiveX cards: doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 481067 so10a2020 PDFs viewer Resumo Depois de ler este capitulo, vooé deverd entender todos 0s aspectos importantes do uso de controles Acti- veX no ambiente Delphi. Vocé aprendeu sobre a integracdo de um controle ActiveX no Delphi, como funciona o wrapper de controle ActiveX do Object Pascal, como distribuir uma eplicapao equipada com controle ActiveX, como registrar um controle ActiveX e como incorporar controles ActiveX em uma aplicagéo. Devido 4 sua presenga no mercado, os controles ActiveX normalmente podem oferecer uma exploséo de produtividade imediata. No entanto, visto que os controles ActiveX possuem algumas des- vantagens, lembre-se também de procurar os componentes nativos da VCL quando estiver adquirindo controles, doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 451067 so10a2020 POF js viewer Programagao grafica caPiTULO com GDI e fontes + Representacao de figuras no Delphi: Timage = Como salvar imagens » Uso de propriedades de TCanvas + Uso de métodos de TCanvas «Sistemas de coordenadas e modos de mapeamento * Criagéo de um programa de pintura « Animagdo com programacao grafica + Fontes avangadas ‘* Projeto de exemplo de criagéio de fonte + Resumo oczz.com.bridoc!46131/delph-5-—guia-do-desenvolvedor_capitulos-do-cd 461067 so10a2020 PDFs viewer Nos capitulos anteriores, vooé trabalhou com uma propriedade chamada canvas. Canvas possi uM nome apropriado, pois vocé pode pensar em uma janela como uma tela em branco de um artista, na qual varios objetos do Windows séo pintados. Cada botéo, janela, cursor etc. é nada mais do que uma colec&o de pixels em que as cores foram definidas para the dar alguma eparéncia util. De fato, vocé pode pensar em cada janela individual como ume superficie separada em que seus components separados so pinta- dos. Para levar essa analogia um pouco mais adiante, imagine que voce sea um artista que necessite de varias ferramentas para realizar sua tarefa. Voo8 precisa de uma palheta na qual poderd escolher diferen- tes cores. Provavelmente usara também diferentes estilos de pinoéis, ferramentas de desenho e técnicas especiais do artista. O Win32 utiliza ferramentas e técnicas semelhantes - no sentido de programacao — para pintar os diversos objetos com os quais os usuarios interagem. Essas ferramentas esto disponivels através da Graphics Device Interface (interface de dispositivo gréfico), mais conhecida como GDI. © Win32 utiliza a GDI para pintar ou desenhar as imagens que voos vé na tela do seu computador. Antes do Delphi, na programaco tradicional do Windows, os programadores trabalhavam diretamente com as funges e ferramentas da GDI. Agora, o objeto Tcanvas encapsula e simplifica o uso dessas fungdes, ferramentas e técnicas. Este capitulo o ensina a usar TCanvas para realizar fungdes graficas Uteis. Vocé tam- bém vera como pode criar projetos de programacdo avangados com 0 Delphi 5 ea GDI do Win32. Hlus- tramos isso criando um programa de pintura e um programa de animagéo. Representagao de figuras no Delphi: Timage © componente trrage representa uma imagem gréfica que pode ser exibida em qualquer lugar de um for mulario e esta disponivel a partir da Component Palette (palheta de componentes) do Delphi 5. Com ‘Tinage, Voo® pode carregar e exibit um arquivo de bitmap (.bup), um Windows metafile de 16 bits (wnt), um metafile avangado de 32 bits (.e2F), um arquivo de icone (.ico), um arquivo JPEG (jpg, .jpeg) OW OU- tros formatos de arquivo manipulados pelas classes adicionais de Téraphic. Os dados de imagem na reali- dade séo armazenados pela propriedade picture de Tinage, que ¢ do tipo picture. Imagens graficas: bitmaps, metafiles e icones Bitmaps 0s bitmaps do Win32 sao informagdes binérias organizadas em um padrao de bits que representa uma imagem gréfica. Mais especificamente, esses bits armazenam itens de informacdo de cor chama- dos pirels. Existem dois tipos de bitmaps: bitmaps depends de dispositivo (DDB) e bitmaps indepen- dentes de dispositivo (DIB) ‘Como programador do Win32, vooé provavelmente nao estara lidando muito com DDBs, pois esse formato foi mantido simplesmente por questao de compatibilidade. Bitmaps dependentes de dis- Positivo, como o nome indica, dependem do dispositivo em que sao criados. Os bitmaps nesse forma- to, quando salvos, nao armazenam informagdes referentes a palheta de cores que utiliza e nem ar- mazenam informagdes referentes A sua resolucao. ‘Ao contrério, 0s bitmaps independentes de dispositivo (DIBs) armazenam informages que Ihes Permitem ser exibidos em qualquer dispositivo sem alterar radicalmente sua aparéncia Na memoria, tanto DDBs quanto DiBs sao representados pelas mesmas estruturas, em sua maior parte. Uma diferenga fundamental é que os DD8s utilizam a palheta fornecida pelo sistema, enquanto 0s DIBs oferecem sua prépria palheta. Para avancar um pouco mais nessa explicacao, DDBs sao sim- plesmente armazenamento nativo, tratados pelas rotinas do driver de video @ pelo hardware de video. DIBs sao formatos de pixel padronizados, tratados pelas rotinas genéricas da GDI » armazenadas na meméria global. Algumas placas de video usam formatos de pixel de DIB como armazenamento nati- ‘vo, © com isso voc’ consegue DDB=DIB. Em geral, DIB oferece mais flexibilidade © simplicidade, as vezes com um pequeno prejuizo no desempenho, DDBs sempre sa0 mais rapidos, mas nao tao conve- nientes. a7 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 471967 so10a2020 PDFs viewer Metafiles ‘Ao contrario dos bitmaps, metafiles s8o imagens gréficas baseadas em vetor. Metafiles sao arquivos em que sao armazenadas uma série de rotinas da GDI, permitindo que voce salve chamadas de fun go da GDI em disco para poder reapresentar a imagem mais tarde, Isso também permite comparti- Ihr suas rotinas de desenho com outros programas sem ter de chamar a funcao especifica da GDI em cada programa. Outras vantagens dos metafiles s40 que eles podem ser dimensionados para dimen sées arbitrérias e ainda reterem suas linhas e arcos suaves ~ 0s bitmaps no conseguem fazer isso to bem. Na verdade, esse é um dos motivos por que o mecanismo de impresséio do Win32 ter sido criado em torno do armazenamento avancado de matafile para os trabalhos de impresséo. Existem dois formatos de metafile: metafiles padrao, normalmente armazenados em um arquivo com uma extensio wef, ¢ metafiles avancados, normalmente armazenados em um arquivo com uma extensao on Metafiles padrao sao reminisc&ncias do sistema Win16. Metafiles avangados sao mais poderosos e precisos. Use EMFs se vocé estiver produzindo metafiles para suas préprias aplicagdes. Se vocé esti- ver exportando seus metafiles para programas mais antigos, que nao possam utilizar 0 formato avan- ‘ado, use os WMFs de 16 bits. No entanto, saiba que, voltando para os WMFs de 16 bits, vocé também erdera varios primitivos da GDI que os EMFs acsitam, mas nao os WMFs, A classe TetaFile do Delphi 5 conhece os dois tipos de metafiles icones Icones so recursos do Win32 que na realidade so armazenados em um arquivo de Icones com uma extensAo ico, Eles lambém podem residir em um arquivo de recursos (.res). Existem dois tamanhos ti- picos de Icones no Windows: icones grandes, que possuem 32x32 pixels, ¢ icones pequenos, que pos- suem 16x16 pixels. Todas as aplicagées do Windows usam os dois tamanhos de icone. Os icones pe- quenos aparecem no canto superior esquerdo da janela principal da aplicagao e também no controle List view (modo de lista) do Windows. Esse controle aparece na pagina Win32 da Component Palette, (Os icones s80 compostos de dois bitmaps. Um deles, denominada imagem, 6 a imagem real do cone, conforme exibida na tela. O outro bitmap, denominado mascara, possibilta a obtencao do efei- to de transparéncia quando o icone & apresentado. Os icones s4o usados para diversas finalidades Por exemplo, os icones aparecem na barra de tarefas de uma aplicagao e nas caixas de mensagem onde os icones de ponto de interrogacao, ponto de exclamag&o ou sinal de parar s4o usados para chamar a atencao. picture 6 uma classe contéiner para a classe abstrata rcraphic. Uma classe contéiner significa que Picture pode conter uma referénciae exibir um Teitnap, tHetafile, Tzcon OU qualquer Outro tipo de Tere- rnic, sem realmente se importar com quem é quem. Vocé usa as propriedades e os métodos de rinage.Pic- ‘ture pare carregar arquivos de imagem em um componente tinage. Por exemplo, use a instruggo a seguir: yimage.Picture.Loadtronrile( ‘Nonearquivo.tnp"); Use uma instrugéo semelhante para carregar arquivos de cone ou metafiles. Por exemplo, 0 cbdigo a seguir carrega um metafile do Win32: ytnage. Picture. LoadFronFile(“Nonearquivo.enf*); Este codigo carrega um arquivo de icone do Win32: ylnage.Picture.LoadFronFile(‘Nomearquivo. ica?) No Delphi 5, reicture pode agora carregar imagens JPEG usando a mesma técnica pare carregar bit- maps: ag PY iage.Picture.LoadFronile(‘Nomeanquivo.jpe”)s doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 481067 so10a2020 PDFs viewer Como salvar imagens Para salvar uma imagem, use 0 método saveror ile: Mylnage.Picture.SaveToFile( ‘Honearquivo.bap?); A classe Taitnap encapsula o bitmap e a palheta do Win32, e oferece os métodos para carregar, arma- zenar, exibir, salvar e copiar as imagens de bitmap. rsitnap também controla a realizacio de palheta auto- maticamente. Isso significa que a tarefa cansativa de gerenciar bitmaps foi bastante simplificada com a classe t8itnap do Delphi §, o que permite focalizar 0 uso do bitmap e evita que vocé tenha de se preocupar com todos os detalhes internos da implementacéo. NOTA Bitmap no 80 tinico objeto que gerencia 2 realizagao da palheta. Componentes como Trnage, THetafile e cada um dos outros descendentes de reraphic também realizam palhetas de seus bitmaps sob pedido. Se vooé criar eomponentes que contenham um objeto TBitnap que pode ter imagens de 256 cores, terd de substitu o método cetralette( ) do su components para retomar a palheta de cores do bitmap. Para criar uma instancia de uma classe Teitzap e carregar um arquivo de bitmap, por exemplo, voos Usa 0s seguintes comandos: ypitmap := Thitmap.create; y@itmap. LoadFranrile(‘myane.aNe?) 3 ATENGAO Outro método para carregar bitmaps para uma aplicagao 6 carrega-lo a partir de um arquivo de recursos. Discutiremos sobre esse método mais adiante. Para copiar um bitmap para outro, vooé usa 0 método rsituap.assign( }, como neste exemplo: Bitmapt Assign(Bitnap2); Voce também pode copiar uma parte de um bitmap a partir de uma insténcia de reitnap para outra insténcia de reitnap, ou ainda para a tela do formulério, usando o método copytect( ): at: Trects begin with at do begin Top Left Right := Bithap2.width div 2; Bottom :~ BitMap2.Height div 25 ends laitnapt.canvas.copyRect(CllentRact, althap2.canvas, &1)3 ends doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 491967 so10a2020 PDFs viewer No cédigo anterior, voce primeiro calcula os valores apropriados em um registro rect e depois usar ‘ométodo reanvas.copytect( ) pare copiar uma perte do bitmap. Um trect é definido da seguinte forma TRect = record case integer of @: (Left, Top, Aight, sottom: Integer); 2: (TopLeft, sottomaight: tpoint); ends Essa técnica sera usada no programa de pintura, mais adiante neste capitulo. copyRect( ) estica auto- maticamente a parte copiada da tela de origem para preencher o reténgulo de destino. ATENCAO \Voo8 pracisa estar ciente de uma diferenga significativa no consumo de recursos para copiar bitmaps nos dois exemplos anteriores. A téenica CopyRect( } duplia 0 uso da meméria, pois existem duas cépias sepa- radas da imagem na meméria. A técnica assign( ) nao custa nada, pois os dois objetos de bitmap com- partiham uma referéncia & mesma imagem na meméria. Se vooé modificar um dos objetos de bitmap, a \VCL imitara a imagem usando um esquema de copiar-ao-escrever. Outro metodo que vocé pode usar para copiar o bitmap inteiro para a tela do formulério, de modo que encurte ou expanda para caber dentro dos limites da tela, & 0 método stretchoran(_ ). Veja um exemplo: canvas.stretchoraw(ai, nyBitnap); Discutiremos os métodos de rcanvas mais adiante neste capitulo. Uso de propriedades de TCanvas Classes de nivel mais alto, como descendentes de rrora € rsraphiccontrol, possuem uma propriedade can- vas. Essa tela (canvas) serve como superficie de pintura para os outros componentes do seu formulério. As ferramentas que canvas utiliza para realizar o desenho séo canetas (pens), pincsis (brushes) e fontes (fonts). Usando canetas Nesta sego, primeiro explicaremos como usar as propriedades de Tren e depois mostraremos algum cé- digo em um projeto de exemplo que utiliza essas propriedades ‘As canetas permitem desenhar linhas na tela e so acessadas por meio da propriedade canvas.pen. Voeé pode mudar o modo como as linhas 40 desenhadas modificando as propriedades da caneta: color, Width, style @ rode. A propriedade color especifica a cor de uma caneta. © Delphi 5 oferece constantes de cor predefini- das, que correspondem a varias cores comuns. Por exemplo, as constantes cited € civel low correspondem as cores vermelha e amarela. © Delphi 5 também define constantes para representarem as cores de ele- mentos de tela do sistema Win32, como clactiveCeption € clkighlightText, ue correspondem aos titulos ativos ¢ ao texto destacado do Win32. A linha a seguir atribui a cor azul a caneta da tela: canvas.Pen.coler blues Esta linha mostra como etribuir uma cor aleatéria @ propriedade pen de canvas: § —Pen.Color := Teolor(RGB(Random(255), Random(255), Randoa(25t5)))5 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 501967 so10a2020 PDFs viewer RGB() e Teolor © Win32 representa as cores como inteiros longos em que os trés bytes inferiores significa um nivel de intensidade de cor vermelha, verde @ azul. A combinagao dos trés valores compoe uma cor ‘Win32 valida. A funcao kca(R, G, 8) apanha trés parametros para os niveis de intensidade vermelho, verde e azul. Existem 255 valores possiveis para cada nivel de intensidade e aproximadamente 16 miles de cores podem ser retornadas a partir da fungao Rea( ). R68(0, 9, 8), por exemplo, retorna o valor de cor do preto, enquanto n5(255, 255, 255) retorna o valor de cor para o branco. n68(255, 0, 0), R68(@, 255, €) €RGB(0, 0, 255) retornam os valores de cor para vermelho, verde e azul, respectiva- mente. Variando os valores passados para sca(_}, vocé pode obter uma cor em qualquer local do es- pectro de cores. Tcolor & especitico da VCL, ¢ refere-se a constante definida na unidade craphics.pas. Essas cons- tantes sao mapeadas para uma cor com correspondéncia mais proxima na palheta do sistema ou para luma cor definida no Painel de Controle do Windows. Por exemplo, clsiue ¢ mapeado para a cor azul, enquanto cieuttonrace é mapeado para a cor especificada para as faces de botdes. Além dos trés bytes para representar a cor, o byte de mais alta ordem de Tcolor especifica como uma cor sera correspondi- da. Portanto, se o byte de mais alta ordem for $20, a cor representada sera a combinacao mais proxima nna palheta atualmente observada. Finalmente, uma cor de $02 combina com a cor mais préxima na palheta légica do contexto de dispositivo atual. Voo8 encontrara informacOes adicionais no arquivo de ajuda do Delphi, sob “rcclor type” (tipo Toolor). DICA Use a fungao colorroaca( ) para converter as cores do sistema do Win32, como clkindow, para uma cor RGB valida. A funcao é descrta na ajuda on-line do Delphi 5. A caneta também pode desenhar linhas com diferentes estilos de desenho, conforme especifica- do pela sua propriedade style. A Tabela 8.1 mostra os diferentes estilos que vocé pode definir para Pen.style. Tabela 8.1 Estilos de caneta Estilo Desenha psclear (Uma linha invistvel psbach (Uma linha composta de uma série de tragos psbashoot Uma linha composta de tragos e pontos alternados psbashOotdot Uma linha composta de uma série de combinagbes trago-ponto-ponto abot Uma linha composta de uma série de pontos psInsidefrane Uma linha dentro de um frame de formas fechadas que especificam um retangulo delimitador pssolid Uma linha sélida Allinha a seguir mostra como voos mudaria o estilo de desenho da caneta: canvas.Pen.style := psbashoots A Figura 8.1 mostra como os diferentes estilos de caneta aparecem quando desenhados na tela do formulério. Uma coisa a observar é que as cores “intermediérias” nas linhas pontilhadas vem da cor do pincel. Se voce quiser criar uma linha pontilhada preta cortando um quadrado vermelho, teria que defi- doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 511967 so10a2020 PDFs viewer Nir a canvas.8rush.Color Como clRed. A definig&o da cor da caneta e do pincel & o modo como voce dese- nharia, por exemplo, uma linha tracejada vermelha e ezul sobre um quadrado branco, pad = pxDashDotDot psClear plrideFrame FIGURA 8.1. Diferentes estilos de canet = Diferentes estilos de caneta mais grossas. A propriedade pen. width permite especificar a largura, em pixels, que a caneta utiliza para dese- nhar. Quando essa propriedade esta definida como uma largura maior, a caneta desenha com linhas O estilo de linha pontilhado aplica-se apenas a canetas com uma espessura igual a 1. A definigao da espessura da caneta como 2 desenharé uma linha s6lida, Isso vem da GDI de 16 bits, que o Win32 simula apenas por compatibilidade. © Windows 95/98 nao cria linhas pontilhadas grosses, mas 0 Windows NT/2000 pode fazer isso se voc usar apenas 0 conjunto estendido de recursos da GDI. Trés fatores determinam 0 modo como o Win32 desenha pixels ou linhas na superficie de uma tela: a cor da caneta, a cor da superficie ou de destino e a operacao de bits que o Win32 realiza sobre valores de duas cores. Essa operacdo & conhecida como operaggo de rastrelo (ou ROP). A propriedade pen.tode especifica a ROP a ser usada para uma determinada tela. Dezesseis modos séo predefinidos no Win32, como vemos na Tabela 8.2. Tabela 8.2 Modos de caneta do Win32 na cor de origem (0) @ destino (D) de ren.coler ‘Modo Cor do pixel resultante Operagio Boolsana pmBlack Sempre preto ° pute Sempre branco 1 pace Inalterado D pawor Inverte cor D not D pmcopy Cor especificada por O ° mot Copy Inverso de 0. not 0 on not 0 sq PMMergePenNot Combinaylo de © e inverso de D doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 521967 so10a2020 POF js viewer Tabela 8.2 Continuago ‘Modo Cor do pixel resultante Operagto Booleana maskPeniot pergenatben Combinago de cores comuns a O ¢ inverso de D Combinago de D e inverso de O 0 and not D prtasktiotPen Combinagdo de cores comuns @ D ¢ inverso de © not $ and 0 prverge Combinagio de Oe D sor pmotnerge Inverso da operacao prnerge sobre Oe D not (S oF 0) prask Combinagao de cores comuns a 0 € D s and panatnask Inverso da operagdo pritask sobre Oe D not (5 and 0) pt Combinagdo de cores em © ou D, mas nfo ambos 5 xoR 0 patctxor Inverso da operagdo pnkos sobre $ e D not (5 20R ren.node € pacopy Por default. 10 significa que a caneta desenha com a cor especificada por sua pro- priedade color. Suponha que vocé queira desenhar linhas pretas sobre um fundo branco. Se uma linha cruzar sobre uma linha desenhada anteriormente, ela deve desenhar em branco ao invés de preto. Uma forma de se fazer isso seria verificar a cor da area na qual vooé iré desenhar — se for branca, defina pen.color oma preto; se for preta, defina pen.color como branco. Embora esse método funcione, ele seria de- sajeitado e lento. Um método melhor seria definir Pen.color como cielack €Pen.tade COMO putct. ISSO resultaria nna caneta desenhando 0 inverso da operacao de mesclagem da cor da caneta e da superficie. A Figura 8.2 mostra 0 resultado dessa operagdo quando se desenha com uma ceneta preta de uma forma riscada, ee FIGURA 8.2 A saida de uma opsracéo patotHerge. A Listagem 8.1 & um exemplo do projeto do CD que ilustra 0 codigo resultante nas Figuras 8.1 ¢ 8.2. Voce encontrara essa demonstracdo no CD que acompanha este livro. Listagem 8.1 llustracdo das oporacoes de Pen interface oczz.com.bridoc!46131/delph-5-—guia-do-desenvolvedor_capitulos-do-cd 51967 ‘30/09/2020 PDFs viewer Listagem 8.1 Continuacao sysutils, Mindows, Hessages, Classes, Graphics, controls, Forms, Dialogs, Nenus, stdCtrls, auttons, Extctris; type TwainFora = class(TForm) mlain: Teinnenu; rmeipens: THenuTtens rmeistyles: Tenurtens imeipencolors: THenuTten; rmeiPersiode: THenuTtens procedure mistylesclick(sender: Tobject); procedure meipencolarsClick(Senden: Tobject)s procedure meiPenodeclick(Sender: Tobject); private { Declaragées privadas } public { Declaracdes piblicas } procedure Clearcanvass Procedure SetPentefaults; ends Nainform: THainFora; inplenentation {se *.0Fn) procedure TainFora.clearcanvas; Rr TRects begin 11 apaga 0 conteddo de canvas with canvas ¢o begin Brush.style := bssolid; erush.color := cluhite; Canvas. FillRect(ClientRect) ends ends procedure THainFora.SetPenefaultss begin with canvas.pen do begin wigth := 15 ode += pecopys style t= pssollds color := clelacks ends ends procedure THainForn.nmistylesClick(Sender: TObject); yPos: integers 4 Penstyle: Teenstyles doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 54967 ‘30/09/2020 PDFs viewer Listagem 8.1 Continuacao begin Clearcanvas; _// Prineiro apaga o contetida de canvas setPendefaults; I/ yos representa a coordenada Y YPos := 205 with Canvas do begin for Penstyle begin Pen.color := cleluas Pen.style 1~ Penstyles NoveTa(100, 90s); LineTo(Clientwidth, yPos)s inc(yPos, 20)5 ends sSolid to psinsidefrane do // Escreve titulos para os vérios estilos de caneta Textovt(1, 10, pssolid *); Textout(1, 30, ‘ psoash *); Textout(1, 50, * psoot *); Textout(1, 70, * psDashoot "); Textout(1, 90, * psbashotvot *); Textout(1, 110, © psclear ‘5 Textdut(1, 130, © pstnsideFrane *); ends ends procedure THalnFara.anipancolarsclick(Senden: Tobject)s is dnteger; begin Clearcanvas; —_// Apaga 0 contedo de canvas SetPendefaults; with canvas do begin for i := 1 to 100 do begin J/ Paga una cor de caneta aletaéria e desenha linha usando essa cor Pen.color := aGB(Randon(256) Random(256), Randon(256)); Noveto(randon(clientuidth), Random(clientheight)); Lineto(randon(clientwidth), Random(clientheight)); end ends ends procedure Tainéorn.aniPanoceclick(Sender: Tobject)s xy integers begin Clearcanvas; // apaga © conteido de canvas setrendefaults; yrs 103 onvas.Pen.width 1= 205 while y ¢ Clientieight do begin canvas.NoveTo(®, y)s a doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 581967 so10a2020 PDFs viewer Listagem 8.1 Continuacao 11 vesenha una linha © increnenta valor ¥ canvas.Lineto(Clientwidth, y)s inc(y, 30)5 ends xi 55 canvas.pen.Hode while x < Clientxidth do begin Canvas.NoveTa(x, @)5 canvas-LineTo(x, ClientHeight); inc(x, 30) ends ends end. A Listagem 8.1 mostra trés exemplos de tratamento da caneta da tela. As duas fungdes auxiliadoras, clearcanvas( ) @ Setvendefaults( ), $40 usadas para limpar 0 contetido da tela do formuldrio principal e re- tornar as propriedades de canves.Pen a0s seUs Valores default @ medida que essas propriedades séo modifi- cadas por cada um dos trés manipuladores de evento. Clearcanvas( ) é uma técnica iitil para apagar 0 contetido de qualquer componente contendo uma propriedade canvas. clearcanvas( ) utiliza um pincel branco s6lido para apagar o que estava pintado na tela, rittnect( ) & responsdvel por pintar uma area retangular conforme especificado pela estrutura de TRect, Clientaect, que & passada a ele. (O método nnistylesciick( ) mostra como exibir os varios estilos de teen, como mostra a Figura 8.1, desenhando linhas horizontais no canvas do formulério usando um estilo diferente de teen. Tanto rcan- vas.Movero( ) quanto Tcanvas.Linero( ) parmitem desenhar linhas na tela. © método mipencolorsclick( ) ilustra o desenho de linhas com uma cor diferente de tPen. Agui voo8 usa a fungo acs(_) para recuperar uma cor a ser atribuida a Teen.color. Os trés valores que vooé passa para ce(_) S80 valores aleatdrios dentro do intervalo de o a 255. A salda desse método aparece na Figura 8.3. Finalmente, 0 método mipentodeclick( ) ilustra como desenhar linhas usando um modo de caneta diferente. Aqui vocé usa o modo pmiit para realizar as agSes discutidas enteriormente, resultando na sal da que aparece na Figura 6.2 56 FIGURA 8.3 Saida do método mniPencolorsclick( doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 561967 so10a2020 PDFs viewer Usando os pixels de TCanvas A propriedade rcanvas.Pixels € um array bidimensional em que cada elemento representa o valor de rco- Jor de um pixel na superficie ou area de cliente do formulério. O canto superior esquerdo da superficie de pintura do seu formulério é indicado por: canvas.Pixels [0,0] © 0 canto inferior direito Canvas.Pixels[Larguractiente, alturactiente]s E raro voos precisar acessar pixels individuals no seu formuldrio. Em geral, vocé nao deseja usar a propriedade pixels, pois ela é lenta. © acesso a essa propriedade usa os fungdes da GDI cetrixel( )/setPi- el, que a Microsoft reconheceu serem imperfeitas, e que nunca serdo eficientes. Isso porque as duas fungdes se baseiam nos valores RGB de 24 bits. Quando ndo estiverem trabalhando com contextos de dispositivo RGB de 24 bits, essas fungbes precisam realizar uma gindstica intensa de combinagao de cores para converter o RGB para um formato de pixel de dispositivo. Para manipuler pixels repidamente, use a propriedade de array teitnap.scantine em seu lugar. Para buscar ou enviar um ou dois pixels de uma s6 vez, 0 uso de Pixels pode ser indicedo. Usando pincéis Esta seoo discute as propriedades de rerush e mostra algum cédigo em um projeto de exemplo que uttli- 2a essas propriedades Usando as propriedades de TBrush pincel de uma tela preenche éreas e formas desenhadas na tela. Isso difere do objeto teen, que permite desenhar linhas na tela. Um pincel permite preencher uma rea na tela usando varias cores, estilos e pa- drées. O objeto terush de convas possui trés propriedades importantes que especificam como o pincel pinta nasuperficie do formulario: color, style €sitnap. color especifica a cor do pincel, style especifica 0 padréo de segundo plano do pincel, ¢ sitnap especifica um bitmap que vooé pode usar para criar padrdes perso nalizados para o segundo plano do pincel. Cito opedes de pincel s4o especificadas pela propriedade style: bssolid, bsClear, bsHiorizontal, bsvertical, bstDiagonal, bsB0iagonal, bsCross € bsDiagcross. Por default, @ cor de pincel é civhite com um es tilo bssorid e nenhum bitmap. Voc8 pode mudar a cor e o estilo para preencher uma area com padrées di- ferentes. O exemplo na proxima seco ilustra 0 uso de cada uma das propriedades de Terush Exemplo de codigo de TBrush A Listagem 8.2 mostra a unidade para um projeto que ilustra o uso das propriedades de rerush que discu- timos. Voc8 pode carregar esse projeto a partir do CD que acompanha este livro. Listagem 8.2 Exemplo de rarush unit Mainras interface sysutils, hindows, messages, Classes, Graphics, controls, Forns, Dialogs, emus, extctris; type 1 orn = class(TForm) 7 doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed s7i967 ‘30/09/2020 PDFs viewer Listagem 8.2 Continuacao rmitain: THainmenu; wmigrushes: Thenurten; miPatterns: THenulten; mipitnapPat tern: THenultem; mipitnapPattern2: THenultem; procedure miPatternsClick(Sender: Tobject); procedure mniBitnapPat terniClick(Sender: TObject): procedure mnifitnapPat tern2Click(Sender: TObject); procedure Forwcreate(sender: Tobject); procedure Fornbestray(sender: Tobject); private Feitmap: Teitmaps public procedure Clearcanvas; ends ainForm: THainFora; inplenentation {$n *.0Fn) procedure tainFora.clearcanvas; Rr TRects begin JI Apaga 0 contesido de Canvas with Canvas do begin Brush.style := bssolid; erush.coler = cluhite; GetuindouRect(Handle, 8); A.Topleft :- ScreenTaclient (R.TopLeft); R.BottonRight :- ScreenTaClient(R.BottorRight)s FillRect(R); ends ends procedure TainFora.anipatternsClick(sender: Tobject); begin Clearcenvas; with canvas do begin 1/ Escreve os titulos para os virios estilos de pincel Textout(120, 101, ‘bssolid?); Textaut(18, 101, “bsClear?); Textdut (248, 101, ‘bscross’); Textdut(18, 221, ‘bsB0iagonal’)s Textdut(120, 221, ‘bstDiagonal’); Textdut(240, 221, ‘bsDiagCross?); Textout(10, 342, ‘bsHorizantal’); Textout(120, 341, ‘bsvertical’)s 1/ Desenha um retangulo con os varios estiles de pincel doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 581967 ‘30/09/2020 PDFs viewer Listagem 8.2 Continuacao erush.style := bsclear; Rectangle(1®, 19, 109, 108); Brush.Color := clBlack; Brush.style := bsSolids Rectangle(120, 18, 228, 108); {Oanonstra que o pincel ¢ transparente desenhando un retangulo colorido, sobre © qual o retangulo con estilo de pincel send desenhade. } Brush.style 1 bssolid; Brush.color :~ clReds Rectangle(220, @, 230, 90); erush.style := bscross; erush.coler := clelack; Rectangle(2e0, 10, 240, 100); erush.style := bsepiegonal; Rectangle(1e, 128, 108, 228); erush.style := bsFDizgonal; Rectangle(120, 120, 220, 220); Brush.style := bsDiagcrosss Rectangle(240, 120, 340, 220)5 Brush.style := bstorizontal; Rectangle(10, 240, 100, 348); erush.style := bsverticaly Rectangle(120, 240, 220, 340)3 ends ends procedure THainFora.nnisitaapPat terntclick(Sender: Tobject); begin Clearcanvass {i Carrega um bitmap do disco Feitnap. LoadFronrile(‘pattern.bap’) Cenvas.8rush.Bitnap := FBitmap; try { pesenha un retingulo para cobrir a drea do cliente inteira do formulério usando padrdo de bitmap como pincel para pintura. } Cenvas.Rectangle(®, 0, Clientwidth, ClientHeight); finally Convas Brush, Bitmap := nils ends ends procedure TalnFora.nnlaltaapeattarnaclick(Senden: Tobject)s begin Clearcanvasy doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 591967 so10a2020 PDFs viewer Listagem 8.2 Continuacao 11 Carrega um bitnap do disco Feitnap. LoadrronFile( ‘pattern2. bmp"); Canvas.Brush.Bitmap := FBitmap; try { besenha un retingulo para cobrir a érea do lente inteira do formulério usando 0 padr3o de bitmap cana pincel para pintura. canvas. Rectangle(@, 0, Clientwidth, Clientueight); finally Canvas.8rush.Biteap := nil; end ends procedure TainForn.FarnCreate(Sender: TObject); begin Foitnap := TRitnap.create; ends procedure TalnFara.Farabestray(sender: Tabjact); begin FBitnap.Frees ends ond. DICA (O método clearcanvas( ) que voo8 usa aqui é uma rotina prética para uma unidade ullitéria. Vooé pode defini clearcanvas(_) pata apanhar os pardmolros 1Canvas @ Taect aos quais 0 cédigo de apagamento sera aplicado: procedure ClearCanvas(Acanvas: TCanvas; Arect: Trec!); begin J] Apaga as constantes da tela with Acanvas do begin Brush Style Brush.Color FillRect(ARect}: end; end; O método mairatternsclick( ) ilustra 0 desenho com varios padrées de terush. Primeiro, vocé dese- nha os titulos e depois, usando cada um dos padrdes de pincel disponiveis, desenha reténgulos na tela do formulério. A Figura 8.4 mostra a saida desse método. Os métodos misitnapratterniclick( ) € mmiBitmapPattern2Click( ) ilustram como usar um padréo de bitmap como pincel. A propriedade tcanvas.srush contém uma propriedade teitnap & qual voc8 pode atribuir um padrao de bitmap. Esse padrao sera usado para preencher a area pintada pelo pincel em vez do padrao especificado pela propriedade rerush.styie. Entretanto, existem algumas regras para 0 uso dessa técnica, Primeiro, vooé teré de atribuir um objeto de bitmap vélido a propriedade. Em segundo lu- gar, vocé precisa atribuir nil & propriedade srush.sitnap quando tiver terminado de usé-la, pois o pincel no assume @ propriedade do objeto de bitmap quando vocs atribui um bitmap aele. As Figuras 8.5 ¢ 8.6 ck( ) € muiBitnapPatternaclick( ), respectivamente. 60 mostram a saida de waieitaapratternic doczz.com bridoc!46131Ielphi-5~guia-do-desenvolvedor_capltulos do-ed 601267

You might also like