Paulo Nobre Postado Abril 11, 2006 Denunciar Share Postado Abril 11, 2006 Alguém poderia dizer para que serve a propriedade TAG? Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 11, 2006 Denunciar Share Postado Abril 11, 2006 Tag é uma propriedade integer(4 bytes) que os componentes disponibilizam para armazenar informações. É uma propriedade segura que eles nunca a utilizam; então você pode colocar nela qualquer informação de 32 bits. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Paulo Nobre Postado Abril 12, 2006 Autor Denunciar Share Postado Abril 12, 2006 S3c, não entendi muito bem.Você poderia dar um exemplo prático de utilização, com um código mínimo se possível. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Progr'amador Postado Abril 12, 2006 Denunciar Share Postado Abril 12, 2006 Exemplo:eu tenho um form pra imprimir Relatório, esse form pode ser aberto de vários forms, um unico button eu imprimo 6 relatórios diferente, pra isso eu estou usando o TAG desse form: cada relatório representa um número diferente nessa tag, de cada lugar que eu abro esse form o TAG recebe um valor diferente.tipo:FormRelat := TFormRelat.Create(Self);FormRelat.Tag := 1;FormRelat.ShowModal;FormRelat.Free;ai no button de imprimir eu coloco um if:IF tag = 1 then beginbla;bla;bla..end else if tag = 2 then begin......etc...end;Foi uma forma que eu achei de fazer isso.Uso para outras coisas tambem.Eu acho num tem uma finalidade em si, cada um usa de acordo com a necessidade.Abs. Progr'amador. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Paulo Nobre Postado Abril 12, 2006 Autor Denunciar Share Postado Abril 12, 2006 Valeu Progr'mador obrigado por sua atenção e exemplo.Serviu para ter uma idéia.Abraços. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 12, 2006 Denunciar Share Postado Abril 12, 2006 Vale lembrar que não necessariamente se coloca números em Tag; você também pode colocar ponteiros para referenciar objetos. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Paulo Nobre Postado Abril 13, 2006 Autor Denunciar Share Postado Abril 13, 2006 Mas, s3c, o que são na realidade ponteiros? Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 13, 2006 Denunciar Share Postado Abril 13, 2006 Ponteiros são referências a endereços de memória; por ex, quando você instancia um objeto, na realidade o nome desse objeto é um ponteiro ou um endereço de memória. Os Windows 98/Me/2000/2003/XP são sistemas de 32 bits, então os endereços de memória também são 32 bits e é por isso que você pode armazenar ponteiros nas propriedades Tag dos componentes:procedure TForm1.Button1Click(Sender: TObject); var SL:TStringList; begin SL := TStringList.Create; Form1.Tag := Integer(SL); end; procedure TForm1.FormDestroy(Sender: TObject); begin if Form1.Tag <> 0 then TStringList(Form1.Tag).Free; end;Nesse exemplo Form1.Tag armazena o endereço de um objeto. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 tiagojacomini Postado Abril 13, 2006 Denunciar Share Postado Abril 13, 2006 interessante, eu uso a propriedade TAG de um TAction para definir níveis de acesso no programa, tipo, quando cadastra um usuario, defino o nivel de acesso dele, ae nas chamadas de forms, no Action eu defino as tags se o usuário tiver acesso entra beleza, se a tag for diferende já manda um showmessage que ele não tem acesso nessa area...p**** vivendo e aprendendo, algum tempo eu achava q tags não era nada..hauahuafalou Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Paulo Nobre Postado Abril 14, 2006 Autor Denunciar Share Postado Abril 14, 2006 É , s3c, acho que estou começando a aprender um pouco de delphi, embora saiba que esta idéia de ponteiros não pertence a uma linguagem específica.A um tempo atrás estava aprendendo um pouco(muito pouco) de C, e vi que que no final da apostila se falava em ponteiros. Não cheguei lá e fiquei sem saber.Tenho esperança que até antes de morrer esteja fazendo cada vez menos CTRL + C & CTRL + V (no sentido de copiar sem entender-mesmo sabendo que em certas ocasiões, como para terminar um programa, isto é necessário) porisso peço desculpas por insistir em perguntas que são teóricas e que muitas pessoas usam diretamente.Inclusive acho, que deveríamos ter um tópico lá em cima "PINADO", cujo título poderia ser diga não ao CTRL + C & CTRL + V. Lá as pessoas poderiam não colocar dicas, como no tópico de dicas, mas sim explicações teóricas sobre tópicos normalmente não encontrados normalmente por aí.Veja o nosso colega Tiago, que já usava TAGS, e ficou surpreso com o exemplo.Eu particularmente nunca usei TAG, pelo menos em DELPHI. A muito tempo atrás, quando estava estudando VB, fiz um exemplo pelo livro que usava, mas sem entender o porque.Obrigado a todos vocês Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 14, 2006 Denunciar Share Postado Abril 14, 2006 A um tempo atrás estava aprendendo um pouco(muito pouco) de C, e vi que que no final da apostila se falava em ponteiros.Acredito que "ponteiros" nessa parte da apostila se referia aos endereços de memória de variáveis e não objetos(embora sejam ponteiros também). Por ex, teoricamente você não pode alterar o valor de uma constprocedure TForm1.Button1Click(Sender: TObject); Const Fim_do_Mes_12:Byte = 31; begin Fim_do_Mes_12 := 32; // Gera erro de compilação end; Mas se fizer assim:procedure TForm1.Button1Click(Sender: TObject); Const Fim_do_Mes_12:Byte = 31; var p:PChar; b32:Byte; begin p := @Fim_do_Mes_12; b32 := 32; Move(b32, p^, 1); ShowMessage(IntToStr(Fim_do_Mes_12)); end;você alterou o valor de uma const sem o Delphi saber, utilizando o endereço de memória(ponteiro) da constante. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Paulo Nobre Postado Abril 14, 2006 Autor Denunciar Share Postado Abril 14, 2006 Acredito que "ponteiros" nessa parte da apostila se referia aos endereços de memória de variáveis e não objetos(embora sejam ponteiros também). Por ex, teoricamente você não pode alterar o valor de uma constRealmente depois que li isto fui rever a apostila, já que hoje estou com bastante tempo, é lá está se falando a respeito de memória de variável.você alterou o valor de uma const sem o Delphi saber, utilizando o endereço de memória(ponteiro) da constante.Interessante este exemplo seu."Dá até para dar uma enganada no DELPHI". Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Micheus Postado Abril 16, 2006 Denunciar Share Postado Abril 16, 2006 Fiquei intrigado com a colocação do s3c, com relação da utilização da contante tipada, pois já utilizei deste artifícil antes. Aqui onde estou, só tenho o velho D3 instalado(o D7 só em casa) e testei a alteração explícita da constante no código (como no exemplo), sendo que não obtive qualquer problema (funciona perfeitamente). A menos que nas versões do Delphi isto não seja mais permitido, talvez seja uma questão de configuração - sei lá.Também, para o exemplo citado, acho que não há necessidade de utilização de tipos intermediários. Uma vez que você saiba o tipo de dados que pretende mover, basta criar um ponteiro para o mesmo. Nesta configuração poderíamos colocar o ex. desta maneira:procedure TForm1.Button1Click(Sender: TObject); Const Fim_do_Mes_12 :Byte = 31; var b32 :^Byte; begin b32 := @Fim_do_Mes_12; b32^ := 32; sendo que b32 será um ponteiro para uma área de memórea que conterá Byte e b32^ apontará para o conteúdo desta área. Como neste caso é byte, você lerá byte. Uma aplicação interessante de ponteiros é quando da utilização de buffers onde são armazenados tipos de dados de tamanhos conhecidos. você pode utilizá-los como indexador para o buffer: procedure qualquer_coisa; type PInfo = ^TInfo; TInfo = record Nome :string[20]; // ** observe tamanho fixo Idade :Byte; Sexo :Byte; end; var StrMsg :String; StrBuf :array[1..512] of char; InfoBuf :Pointer; PtrInfo :PInfo; PtrIdx, PtrEnd :PChar; begin FillChar(StrBuf, SizeOf(StrBuf), #0); // preenche todo o StrBuf com zeros // populando o StrBuf para o teste StrPCopy(@StrBuf, 'Testando o uso de ponteiros.'#13'Com quebra de texto.'); StrMsg := ''; PtrIdx := @StrBuf; // início da área de memória PtrEnd := PtrIdx +SizeOf(StrBuf); // Final - máximo esperado while PtrIdx <= PtrEnd do begin case PtrIdx^ of #0 : Break; // caso o StrBuf não tenha sido preenchido totalmente haverão zeros #13 : StrMsg := StrMsg + #10'Nova linha: '; else StrMsg := StrMsg + PtrIdx^; end; Inc(PtrIdx); end; ShowMessage(StrMsg); GetMem(InfoBuf, SizeOf(TInfo) *2); // aloca espaço para dois registros PtrInfo := InfoBuf; // inicializa apontador PtrInfo^.Nome := 'Nome 1'; Inc(PtrInfo); PtrInfo^.Nome := 'Nome 2'; StrMsg := ''; PtrInfo := InfoBuf; StrMsg := 'Nome: '+ PtrInfo^.Nome +#10; Inc(PtrInfo); StrMsg := StrMsg +'Nome: '+ PtrInfo^.Nome; FreeMem(InfoBuf); ShowMessage(StrMsg); end; O indexador será inbrementado automaticamente pelo número de byte que contém a estrutura apontada por ele. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 17, 2006 Denunciar Share Postado Abril 17, 2006 procedure TForm1.Button1Click(Sender: TObject); Const Fim_do_Mes_12 :Byte = 31; var b32 :^Byte; begin b32 := @Fim_do_Mes_12; b32^ := 32; Sim, é a mesma coisa; só declarei um PChar para melhor entendimento.GetMem(InfoBuf, SizeOf(TInfo) *2); // aloca espaço para dois registros PtrInfo := InfoBuf; // inicializa apontador PtrInfo^.Nome := 'Nome 1'; Inc(PtrInfo); PtrInfo^.Nome := 'Nome 2'; StrMsg := ''; PtrInfo := InfoBuf; StrMsg := 'Nome: '+ PtrInfo^.Nome +#10; Inc(PtrInfo); StrMsg := StrMsg +'Nome: '+ PtrInfo^.Nome; FreeMem(InfoBuf); ShowMessage(StrMsg); Neste caso, acho que InfoBuf é desnecessário, podendo-se alocar memória diretamente em PtrIfo:GetMem(PtrInfo, SizeOf(TInfo) *2); // aloca espaço para dois registros PtrInfo^.Nome := 'Nome 1'; StrMsg := 'Nome: '+ PtrInfo^.Nome +#10; Inc(PtrInfo); PtrInfo^.Nome := 'Nome 2'; StrMsg := StrMsg +'Nome: '+ PtrInfo^.Nome; Dec(PtrInfo); FreeMem(PtrInfo); ShowMessage(StrMsg);Quanto a ponteiros para estrturas, são muito úteis na passagem de parâmetros onde não é necessária a cópia de toda a estrutura, mas somente o ponteiro dela(4bytes) e com isso o parãmetro se torna var naturalmente. Já a utilização de ponteiros de type record dentro de um método são úteis quando a estrutura não é conhecida e tem que ser preenchida através de um array de informações dos tipos de campos; neste caso é melhor declarar um type packed record onde a utilização de memória se dá exatamente conforme os tipos dos campos. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Micheus Postado Abril 17, 2006 Denunciar Share Postado Abril 17, 2006 Neste caso, acho que InfoBuf é desnecessário, podendo-se alocar memória diretamente em PtrIfo:Observe que na forma de utilização proposta (indexador), a cada incremento, o endereço se modifica. Se não for mantido o endereço inicial do buffer alocado, ao final, você não conseguirá liberar corretamente esta área de memória, visto que este será o endereço que você passará para o Freemem. falou?!O exemplo é meio idiota, eu sei, mas o objetivo é mostrar que pode-se utilizar ponteiros para "navegar" através de uma área de memória. Pode ser útil ao utilizar Stream para ler conteúdo de um arquivo que contenha registros ou similares e você leia blocos grandes de dados para o buffer do Stream. Utilizei isto quando resolvi criar uma classe descendente de TFileStream que implementasse o Writeln e Readln. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 17, 2006 Denunciar Share Postado Abril 17, 2006 Se não for mantido o endereço inicial do buffer alocado, ao final, você não conseguirá liberar corretamente esta área de memória, visto que este será o endereço que você passará para o Freemem.você pode notar que foi dado um Inc após a alocação de memória e antes do FreeMem é dado um Dec, restaurando assim o ponteiro original. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 Micheus Postado Abril 17, 2006 Denunciar Share Postado Abril 17, 2006 Isto só é verdade porque, como eu disse antes, o meu exemplo é meio idiota. Se o buffer tivesse muitos registros NÂO apenas 2 (dois) e estivessemos varrendo o buffer num loop, ao final o ponteiro (indexador) estaria apontando para o último registro, ou seja, final da memória alocada (posição 3, 100, 1000 - sei lá) e não na inicial. Citar Link para o comentário Compartilhar em outros sites More sharing options...
0 s3c Postado Abril 17, 2006 Denunciar Share Postado Abril 17, 2006 Neste caso o ponteiro inicial deve ser mantido e utilizado um indexador auxiliar. Citar Link para o comentário Compartilhar em outros sites More sharing options...
Pergunta
Paulo Nobre
Alguém poderia dizer para que serve a propriedade TAG?
Link para o comentário
Compartilhar em outros sites
17 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.