TButton size?? lazarus / 31-LCL ---------------------------------------------------------------------- garlar27 · 2011-05-12 20:00 I'm clueless and hope someone could help me with this one:    I Have a form which has a public method which receives a string and an array of string. The method creates as many buttons as elements array have. Everything works fine.    Then I wanted have all buttons with the same width: the width of the button with the longest caption.    So I did this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {_________________________________________________________________ ButtonClick }procedure TFormMensaje.ButtonClick(Sender: TObject);var   Msj: string;begin   if Sender is TButton then begin      FResponse := (Sender as TButton).Caption; // property FResponse: string;   end;end; {<--- ButtonClick } function TFormMessage.ShowMsg(const Mssg: string; const BtnLst: array of string): string;var   i, TheLonger: Integer;   B: TButton;begin   Result := '';   TheLonger := 0;   SetLength(FBtnLst, High(BtnLst+1)); // property: FBtnLst Array of TButton    for i := 0 to High(BtnLst) do begin      B := TButton.Create(Self);      FBtnLst[i] := B;      { Here I set properties like parent, position, etc. }      B.OnClick := @ButtonClick;      B.Autosize := True;      B.Caption := BtnLst[i];    TheLonger := Max(TheLonger, B.With);   end;    for i := 0 to High(FBtnLst) do begin      FBtnLst[i].AutoSize := FALSE;      FBtnLst[i].Width := TheLongest;   end;    ShowModal;    Result := FResponse;end;     The problem with that code is that it always set the width to 75 and not the "real" button's width.    I did a workaround by doing this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    //.....   TheLongest := Max(TheLongest, Canvas.TextExtent(B.Caption).cx);   //...    //...      FBtnLst[i].Width := TheLongest + AN_ARBITRARY_MARGIN_CONSTANT;   //...     It works but I don't like it because different OS / Themes might have or need different margins.    So here comes my question: Does anybody knows a better way to do it? ---------------------------------------------------------------------- Blaazen · 2011-05-12 21:52 I can't see TheLongest declared. Code: [Select] for i := 0 to High(BtnLst) do begin        B := TButton.Create(Self);        FBtnLst := B;        { Here I set properties like parent, position, etc. }        B.OnClick := @ButtonClick;        B.Autosize := True;        B.Caption := BtnLst;        TheLonger := Max(TheLonger, B.With);     end;       for i := 0 to High(FBtnLst) do begin        FBtnLst.AutoSize := FALSE;        FBtnLst.Width := TheLongest;     end;    and probably you had to change [ ] to < > because of this forum. Otherwise code seems good to me, maybe this problem is widgetset related. I tried to make TButton with AutoSize=True and to give it very long Caption and its size was immediately changed. Oh, maybe I found problem now. You change buttons but the form is invisible. You call ShowModal at the end. IMO it is the reason. ---------------------------------------------------------------------- garlar27 · 2011-05-13 12:20 Quote from: Blaazen on May 12, 2011, 11:52:18 pmI can't see TheLongest declared. Code: [Select] for i := 0 to High(BtnLst) do begin        B := TButton.Create(Self);        FBtnLst := B;        { Here I set properties like parent, position, etc. }        B.OnClick := @ButtonClick;        B.Autosize := True;        B.Caption := BtnLst;        TheLonger := Max(TheLonger, B.With);     end;       for i := 0 to High(FBtnLst) do begin        FBtnLst.AutoSize := FALSE;        FBtnLst.Width := TheLongest;     end;    and probably you had to change [ ] to < > because of this forum. Yep, I have to watch my hands from typo "Longer" should be "Longest". And I forgot about that bracket thing... Quote from: Blaazen on May 12, 2011, 11:52:18 pmOh, maybe I found problem now. You change buttons but the form is invisible. You call ShowModal at the end. IMO it is the reason. Exactly!! I realized that very quickly and placing the resizing code in FormShow didn't help. afterwards I tried to access properties and methods to get the size the button will have when painted tried with almost any thing that came to my head but I couldn't make it. If possible I would like to adjust size before showing the form. My work around is working but it might get me in trouble when using another theming or OS. ---------------------------------------------------------------------- Blaazen · 2011-05-13 13:48 I think I got it. You need this: Code: [Select]procedure GetPreferredSize(var PreferredWidth, PreferredHeight: integer;                                Raw: boolean = false;                                WithThemeSpace: boolean = true); virtual;Simply: Code: [Select]var w, h: Longint; begin ... Button.GetPreferredSize(w, h, false, true); ...and you will have the right width in variable "w" even if the button is invisible and its size is not changed yet. ---------------------------------------------------------------------- garlar27 · 2011-05-16 15:21 I couldn't make it work maybe it's due to my old (Lazarus 0.9.28.2) or my OS (Ubuntu 9.10). Code: [Select]... Button := TButton.Create(Self); Button.Parent := Self; Button.Autosize := True; Button.Top := 0; Button.Left := 0; Button.Caption  := ACaption; Button.GetPreferredSize(w, h, false, true); // Here "w" and "h" values are zero ---------------------------------------------------------------------- Blaazen · 2011-05-16 15:34 This works (Laz. 0.9.31 + Qt): Code: [Select]var w, h: LongInt;    Butt: TButton; begin   Butt:=TButton.Create(self);   with Butt do     begin       Butt.Parent:=self;       Butt.Visible:=False;       Butt.AutoSize:=False;  //regardless if it is False; or True;       Butt.Caption:='Butt++++++++++++++++++++++';       Butt.GetPreferredSize(w, h, false, true);       Form1.Caption:=inttostr(Butt.Width)+' '+inttostr(w);       Free;     end;Form title is: "75 186" 75 is the default width, 186 ---------------------------------------------------------------------- garlar27 · 2011-05-16 16:44 Thank you Blaazen. I will try to test it on 0.9.30 + gtk. I think I won't have problems.