Recent

Author Topic: Variable number of buttons in function "QuestionDlg" with message type "mtCustom  (Read 849 times)

MaxCuriosus

  • Full Member
  • ***
  • Posts: 140
How can I set a variable number of custom buttons to use as follows:

Code: Pascal  [Select][+][-]
  1. Var
  2.   N:Integer;
  3.   LI:LongInt;
  4.   App:String;
  5.   SL:TStringList;  
  6.  
  7. {...}
  8.  
  9.         SL:=TstringList.create;
  10.         SL.LoadFromFile('AppList');
  11.         N:=SL.Count-1;
  12.  
  13.         LI:=QuestionDlg('Caption','Message',mtCustom,
  14.                   [
  15.                   N,SL[N],
  16.                   {...}
  17.                   1,SL[1],
  18.                   0,SL[0],'IsDefault'],'');
  19.  
  20.         App:=SL[LI];
  21.         WriteLn(App);
  22.         SL.Free;                                                  
  23.  

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
Code: Pascal  [Select][+][-]
  1. var
  2.   b: array of TVarRec;
  3.   s, s2: String;
  4. begin
  5.   s := 'abc';
  6.   s2 := 'foo';
  7.   SetLength(b, 4);
  8.   b[0].VType := vtInteger;
  9.   b[0].VInteger := 1;
  10.   b[1].VType := vtAnsiString;
  11.   b[1].VAnsiString := pointer(s);
  12.  
  13.   b[2].VType := vtInteger;
  14.   b[2].VInteger := 2;
  15.   b[3].VType := vtAnsiString;
  16.   b[3].VAnsiString := pointer(s2);
  17.   QuestionDlg('a','b', mtConfirmation, b,0);
  18. end;
  19.  

You can change the length of b as needed, to add as many pairs as you want.


Mind, that you pass the string as pointer. It will therefore not be refcounted.

So you must keep the original string for the duration of the call, and you must NOT modify it in any way.

E.g. if above you did "s:= s +'bar';" after setting b[1], then you risk seeing trash or getting a crash.
The danger is, that it may work at random. But it will sometimes break.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
If you need that many choices, maybe better use TTaskDialog?

There are quick helper methods named:   TaskDlg();

They can offer items in a list with radio buttons.

ASerge

  • Hero Member
  • *****
  • Posts: 2438
Example:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.btnTestClick(Sender: TObject);
  2. var
  3.   SL: TStringList;
  4.   VA: array of TVarRec;
  5.   iL, iV: SizeInt;
  6. begin
  7.   SL := TStringList.Create;
  8.   try
  9.     SL.Append('One');
  10.     SL.Append('Two');
  11.     SL.Append('Three');
  12.     // Make array of TVarRec
  13.     SetLength(VA, SL.Count * 2 + 1);
  14.     iV := 0;
  15.     for iL := SL.Count - 1 downto 0 do
  16.     begin
  17.       with VA[iV] do
  18.       begin
  19.         VType := vtInteger;
  20.         VInteger := iL;
  21.       end;
  22.       Inc(iV);
  23.       with VA[iV] do
  24.       begin
  25.         VType := vtAnsiString;
  26.         VAnsiString := Pointer(SL[iL]);
  27.       end;
  28.       Inc(iV);
  29.     end;
  30.     with VA[iV] do
  31.     begin
  32.       VType := vtAnsiString;
  33.       VAnsiString := Pointer(string('IsDefault'));
  34.     end;
  35.     QuestionDlg('Caption', 'Message', mtCustom, VA, '');
  36.   finally
  37.     SL.Free;
  38.   end;
  39. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 17396
  • Ceterum censeo Trump esse delendam
Mind, that you pass the string as pointer. It will therefore not be refcounted.

So you must keep the original string for the duration of the call, and you must NOT modify it in any way.
You can avoid that if you call UniqueString ? Although that is not strictly fully immutable, it is less of a risk.
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • Debugger - SynEdit - and more
    • wiki
Mind, that you pass the string as pointer. It will therefore not be refcounted.

So you must keep the original string for the duration of the call, and you must NOT modify it in any way.
You can avoid that if you call UniqueString ? Although that is not strictly fully immutable, it is less of a risk.

No need. Nothing says it must be Unique.

And, you can make a copy of it. As long as it goes to another variable.

Technically, you can even re-assign the original var, if you have another var that holds the original string (but I wouldn't recommend that, unless you have a very good understanding of how string ref counting and const work)

MaxCuriosus

  • Full Member
  • ***
  • Posts: 140
Martin_fr @ Reply #1,
ASerge @ Reply #3,
Thank you for your examples, they fully solve my case.

Martin_fr @ Reply #2,
For good measure I've tried the TTaskDialog. With the use of radio buttons the layout is more compact and pleasant.

Fibonacci

  • Hero Member
  • *****
  • Posts: 786
  • Internal Error Hunter
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   QuestionDlg('title', 'text', mtConfirmation, [
  4.     0, 'no icon',
  5.     1, 'i1',
  6.     2, 'i2',
  7.     3, 'i3',
  8.     4, 'i4',
  9.     5, 'i5',
  10.     6, 'i6',
  11.     7, 'i7',
  12.     8, 'i8'
  13.   ], 0);
  14. end;

ASerge

  • Hero Member
  • *****
  • Posts: 2438
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   QuestionDlg('title', 'text', mtConfirmation, [
  4.     0, 'no icon',
  5.     1, 'i1',
  6.     2, 'i2',
  7.     3, 'i3',
  8.     4, 'i4',
  9.     5, 'i5',
  10.     6, 'i6',
  11.     7, 'i7',
  12.     8, 'i8'
  13.   ], 0);
  14. end;
Have you read the original question?

Fibonacci

  • Hero Member
  • *****
  • Posts: 786
  • Internal Error Hunter
Have you read the original question?

Lol not really :D Just read yours and Martin code and thought it could maybe be written a bit shorter :D
« Last Edit: June 24, 2025, 05:30:48 am by Fibonacci »

 

TinyPortal © 2005-2018