Lazarus

Programming => General => Topic started by: Medhome on December 01, 2024, 07:08:41 pm

Title: storing string
Post by: Medhome on December 01, 2024, 07:08:41 pm
Hi All
How to store a  string into tag propertie of an object for example   in TButton.tag
Regards
Med
Title: Re: storing string
Post by: cdbc on December 01, 2024, 07:18:32 pm
Hi
Code: Pascal  [Select][+][-]
  1. TButton.tag:= ptrint(strnew('yourstringhere'));
Regards Benny
Title: Re: storing string
Post by: Medhome on December 01, 2024, 07:22:46 pm
Thanks. But How to retrieve ?
Med
Title: Re: storing string
Post by: cdbc on December 01, 2024, 07:27:04 pm
Hi
Code: Pascal  [Select][+][-]
  1. var p: pchar;
  2. begin
  3.   p:= pchar(TButton.Tag);
  4.   Caption:= string(p);
  5.   strDispose(p);
  6. end;
  7.  
Regards Benny
Title: Re: storing string
Post by: Remy Lebeau on December 02, 2024, 04:41:09 pm
Here is a slightly cleaner way without resorting to StrNew()/StrDispose():

Code: Pascal  [Select][+][-]
  1. // to store a new string...
  2. var tag: Pointer;
  3. tag := nil;
  4. string(tag) := 'yourstringhere';
  5. TButton.Tag := PtrInt(tag);

Code: Pascal  [Select][+][-]
  1. // to retrieve the stored string...
  2. var tag: Pointer;
  3. tag := Pointer(TButton.Tag);
  4. Somestring := string(tag);

Code: Pascal  [Select][+][-]
  1. // to update the stored string...
  2. var tag: Pointer;
  3. tag := Pointer(TButton.Tag);
  4. string(tag) := 'yourstringhere';
  5. TButton.Tag := PtrInt(tag);

Code: Pascal  [Select][+][-]
  1. // to release the stored string when done using the Tag...
  2. var tag: Pointer;
  3. tag := Pointer(TButton.Tag);
  4. string(tag) := '';
  5. TButton.Tag := 0;
Title: Re: storing string
Post by: Fibonacci on December 02, 2024, 05:21:17 pm
There is a cleaner way:

Code: Pascal  [Select][+][-]
  1. var tag: PtrInt;
  2. string(tag) := 'yourstringhere';
  3. TButton.Tag := tag;


Project project1 raised exception class 'External: ACCESS VIOLATION' with message:
Access violation writing to address $00000001001596D4.

 In file 'x86_64.inc' at line 1255:
decl       {$ifdef win64} (%rcx) {$else} (%rdi) {$endif}
Title: Re: storing string
Post by: Thaddy on December 02, 2024, 05:45:07 pm
Maybe:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$modeswitch typehelpers}{$H+}{$M+}
  2. uses classes;
  3.  
  4. type
  5.   TTagString = type helper for PtrInt // tag is ptrint.
  6.   strict private
  7.     function  GetString:String;inline;
  8.     procedure SetString(const value:string);inline;
  9.   published
  10.     property AsString:String read GetString write SetString;
  11.   end;
  12.  
  13.  function  TTagString.GetString:String;inline;
  14.  begin
  15.    Result := string(self);
  16.  end;
  17.    
  18.  procedure TTagString.SetString(const value:string);inline;
  19.  begin
  20.    string(self) := value;
  21.  end;
  22.  
  23. var
  24.   a:TComponent;  
  25. begin
  26.   a:= TComponent.Create(nil); // anything with a tag
  27.   a.tag.AsString := 'Hello, tag';
  28.   writeln(a.tag.AsString);
  29.   a.free;
  30. end.
More Pascal code, once, less fuss.  8-) (the generated assembler code is minimal!)
Anyway, it is not wise to use the tag as a permanent solution in production code.
But this code doesn't crash...and does the job...
Title: Re: storing string
Post by: domasz on December 02, 2024, 07:04:49 pm
How about?
Code: Pascal  [Select][+][-]
  1. type TButton = class(StdCtrls.TButton)
  2. public
  3.   Str: String;
  4. end;
  5.  

and then:
Code: Pascal  [Select][+][-]
  1. Button1.Str := 'My String';
Title: Re: storing string
Post by: Thaddy on December 02, 2024, 07:12:38 pm
- doesn't set caption.
- doesn't cover all components.
- doesn't exist.
Title: Re: storing string
Post by: domasz on December 02, 2024, 07:23:10 pm
- doesn't set caption.
- doesn't cover all components.
- doesn't exist.
1) It's not supposed to set Caption. Instead of Tag it uses Str, so Tag can be used for integers, like intended.
2)
Code: Pascal  [Select][+][-]
  1.  TComponent = class(Classes.TComponent)
  2.  public
  3.    Str: String;
  4.  end;

3) No idea what you mean
Title: Re: storing string
Post by: Remy Lebeau on December 02, 2024, 09:46:56 pm
Project project1 raised exception class 'External: ACCESS VIOLATION' with message:
Access violation writing to address $00000001001596D4.

Sorry, I forgot to initialize the PtrInt to 0 before assigning the string value to it.  I have updated my earlier example.
Title: Re: storing string
Post by: egsuh on December 03, 2024, 09:13:47 am


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.   TButton = class(StdCtrls.TButton)
  12.   public
  13.      TextTag : string;
  14.   end;
  15.  
  16.  
  17.   { TForm1 }
  18.  
  19.   TForm1 = class(TForm)
  20.     Button1: TButton;
  21.     procedure Button1Click(Sender: TObject);
  22.     procedure FormCreate(Sender: TObject);
  23.   private
  24.  
  25.   public
  26.  
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.  
  32. implementation
  33.  
  34. {$R *.lfm}
  35.  
  36. { TForm1 }
  37.  
  38. procedure TForm1.FormCreate(Sender: TObject);
  39. begin
  40.    Button1.TextTag:= 'This is my text tag';
  41. end;
  42.  
  43. procedure TForm1.Button1Click(Sender: TObject);
  44. begin
  45.   showmessage(button1.TextTag);
  46. end;
  47.  
  48. end.
  49.  
Title: Re: storing string
Post by: Thaddy on December 03, 2024, 09:38:41 am
Yes, but that requires inheritance. My helper solution solves it for any component, all of them.
Without the need to modify the inheritance tree.
Title: Re: storing string
Post by: silvercoder70 on December 04, 2024, 01:00:44 pm
And back in the day I would use...

Code: Pascal  [Select][+][-]
  1. function RefString(const S: string): Pointer;
  2. var
  3.   Local: string;
  4. begin
  5.   Local := S;
  6.   Result := Pointer(Local);
  7.   Pointer(Local) := nil;
  8. end;
  9.  
  10. procedure ReleaseString(P: Pointer);
  11. var
  12.   Local: string;
  13. begin
  14.   Pointer(Local) := P;  
  15. end;
  16.  

You would have to look at "Delphi in a Nutshell" page 60 (?) for the explanation.
Title: Re: storing string
Post by: ASerge on December 04, 2024, 11:06:57 pm
I don't really like all the solutions from above.
It takes a lot of effort to figure out why it works.
And repeated conversions of types.
In some solutions, they forgot about freeing up memory, apparently they tested it only on constants.
In my opinion, there is already a container for strings, it's easy enough to use it:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, StdCtrls;
  9.  
  10. type
  11.   TForm1 = class(TForm)
  12.     Button1: TButton;
  13.     Button2: TButton;
  14.     procedure Button1Click(Sender: TObject);
  15.     procedure Button2Click(Sender: TObject);
  16.     procedure FormCreate(Sender: TObject);
  17.     procedure FormDestroy(Sender: TObject);
  18.   private
  19.     FTagHolder: TStringList;
  20.   public
  21.  
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.Button1Click(Sender: TObject);
  34. begin
  35.   Button1.Tag := FTagHolder.Add('Some string');
  36. end;
  37.  
  38. procedure TForm1.Button2Click(Sender: TObject);
  39. begin
  40.   Caption := FTagHolder[Button1.Tag];
  41. end;
  42.  
  43. procedure TForm1.FormCreate(Sender: TObject);
  44. begin
  45.   FTagHolder := TStringList.Create;
  46. end;
  47.  
  48. procedure TForm1.FormDestroy(Sender: TObject);
  49. begin
  50.   FTagHolder.Free;
  51. end;
  52.  
  53. end.
Title: Re: storing string
Post by: Wesbat on December 06, 2024, 04:51:11 am
Here is a slightly cleaner way without resorting to StrNew()/StrDispose():

Code: Pascal  [Select][+][-]
  1. var tag: Pointer;
  2. tag := nil;
  3. string(tag) := 'yourstringhere';
  4. TButton.Tag := PtrInt(tag);

Code: Pascal  [Select][+][-]
  1. var tag: Pointer;
  2. tag := Pointer(TButton.Tag);
  3. Somestring := string(tag);
  4. ...
  5. string(tag) := '';

As someone who is still learning, I find this example very instructive into how Pointers operate. Thanks for sharing.
TinyPortal © 2005-2018