Ir para conteúdo
Fórum Script Brasil
  • 0

Propriedade Tag


Paulo Nobre

Pergunta

17 respostass a esta questão

Posts Recomendados

  • 0

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 begin

bla;

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.

Link para o comentário
Compartilhar em outros sites

  • 0

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.

Link para o comentário
Compartilhar em outros sites

  • 0

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..

hauahua

falou

Link para o comentário
Compartilhar em outros sites

  • 0

É , 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

Link para o comentário
Compartilhar em outros sites

  • 0
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 const
procedure 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.

Link para o comentário
Compartilhar em outros sites

  • 0

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 const

Realmente 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".

Link para o comentário
Compartilhar em outros sites

  • 0

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.

Link para o comentário
Compartilhar em outros sites

  • 0
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.

Link para o comentário
Compartilhar em outros sites

  • 0
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.

Link para o comentário
Compartilhar em outros sites

  • 0
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.

Link para o comentário
Compartilhar em outros sites

  • 0

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.

Link para o comentário
Compartilhar em outros sites

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.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...