Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional to the caption property of a popupmenu item

I have a popupmenu with a item named "Ativar", but i can not understand why this code don't work:

procedure TForm6.Ativar1Click(Sender: TObject);
begin
  if ativar1.Caption='Ativar' then
  begin
    showmessage('Initialize procedure');
    ativar1.Caption:='Desativar';
  end else
  if ativar1.Caption='Desativar' then
  begin
    showmessage('Initialize procedure');
    ativar1.Caption:='Ativar';
  end;
end;

I imagine that writing code should do the verification of the caption property of the object to activate if it is equal to Enable show the message and change the caption property to Disable, yet when the caption property is equal to Disable show the message and change the property again to Enable. What is wrong?

like image 291
V.Salles Avatar asked Dec 12 '25 08:12

V.Salles


2 Answers

You should not keep state in the caption of a UI component. What if it ever gets translated? Or if you change your mind and make the caption longer in the object inspector? Then your logic will fail.

It is better to do something like this:

  • move the state away from the Caption into a separate form field (I prefer enumerated types over booleans, so the statefield is FAtivarState and the type is TAtivarState)
  • to make sure you can translate your application, move your initial Ativar value Caption for Ativar1 from the Object Inspector to a resourcestring, and one for the desactivar state (note I kept the A keyboard shortcut for both)
    if you do not need to translate, then you can replace resourcestring with const
  • separate the assignment of the caption and the business logic into two methods (SetAtivarCaption and HandleAtivarChange)
  • call these methods from the FormCreate event method (bind it to the OnCreate event of TForm6) and Ativar1Click event method

A structured approach like the above looks like a lot of extra work, but it isn't: it saves you a lot of time solving problems like you had in your question.

Example code:

// unit name, interface clause, uses list, etc ...

type
  TAtivarState = (asAtivar, asDesativar);
  TForm6 = class(TForm);
    procedure Ativar1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FAtivarState: TAtivarState;
    procedure SetAtivarCaption(); virtual; 
    procedure HandleAtivarChange(); virtual; 

// implementation clause, uses list, etc ...

resourcestring
  AtivarCaption = '&Ativar';
  DestivarCaption = 'Des&ativar';

procedure TForm6.Ativar1Click(Sender: TObject);
begin
  HandleAtivarChange();
end;

procedure TForm6.FormCreate(Sender: TObject);
begin
  SetActivar1Caption();
end;

procedure TForm6.SetAtivarCaption();
begin
  if FAtivarState = asAtivar then
    Ativar1.Caption := AtivarCaption
  else
    Ativar1.Caption := DesativarCaption;
end;

procedure TForm6.HandleAtivarChange();
begin
  if FAtivarState = asAtivar then
  begin
    ShowMessage('Initialize procedure');
    FAtivarState := asDesativar;
  end
  else
  begin
    ShowMessage('Initialize procedure');
    FAtivarState := asAtivar;
  end;
  SetActivar1Caption();
end;
like image 153
Jeroen Wiert Pluimers Avatar answered Dec 15 '25 16:12

Jeroen Wiert Pluimers


Use StripHotKey vom Menues to replace the accelerator.

begin
  if StripHotKey(TMenuItem(Sender).Caption) = 'Ativar' then
  begin
    ShowMessage('Initialize procedure');
    TMenuItem(Sender).Caption := 'Desativar';
  end
  else if StripHotKey(TMenuItem(Sender).Caption) = 'Desativar' then
  begin
    ShowMessage('Initialize procedure');
    TMenuItem(Sender).Caption := 'Ativar';
  end;
end;
like image 40
bummi Avatar answered Dec 15 '25 15:12

bummi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!