classobjectinno-setuppascalscripttobject

Inno Setup get TObject type/class in event handler


I have an event procedure that checks the OnKeyUp key press for two objects/controls (TNewEdit and TNewComboBox). Both objects need to be completed before a TNewButton gets enabled.

However, I cannot find a way to know how to get the type of the Sender: TObject, if that is TNewEdit or TNewComboBox.

Anyone can help?


Solution

  • You should not need to know the type/class for anything.

    Such a need is a sign of a bad design.


    If the handling of the event is different for each type/class, create a separate handler for each.

    If part of the handling is common, call the common handler from the specific handlers.

    var
      Edit: TNewEdit;
      ComboBox: TNewComboBox;
    
    procedure CommonKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);  
    begin
      Log('Common handling');
    end;
    
    procedure EditKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
      Log('Edit key up');
      CommonKeyUp(Sender, Key, Shift);
    end;
    
    procedure ComboBoxKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
      Log('Combo box key up');
      CommonKeyUp(Sender, Key, Shift);
    end;
    
    procedure InitializeWizard();
    begin
      { ... }
    
      Edit.OnKeyUp := @EditKeyUp;
      Combobox.OnKeyUp := @ComboBoxKeyUp;
    end;
    

    Though as you actually have two controls, you probably want to distinguish, what control raised the event.

    That's, what the Sender argument is for. The following code shows how to use it. But again, in general, this is not the right way to go.

    var
      Edit: TNewEdit;
      ComboBox: TNewComboBox;
    
    procedure ControlKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
      if Sender = Edit then
      begin
        Log('Edit key up');
      end
        else
      if Sender = ComboBox then
      begin
        Log('Combo box key up');
      end
        else
      begin
        Log('Other key up');
      end;
    end;
    
    procedure InitializeWizard();
    begin
      { ... }
    
      Edit.OnKeyUp := @ControlKeyUp;
      Combobox.OnKeyUp := @ControlKeyUp;
    end;
    

    Though still I do not understand, what you need this for.

    You have to check both controls every time, so why do you need to know, what control, was the one that changed?

    Also, to detect a change, do not use OnKeyUp, use OnChange. That way you capture all changes (key press, drag&drop, copy&paste, anything).

    var
      Edit: TNewEdit;
      ComboBox: TNewComboBox;
      Button: TNewButton;
    
    procedure ControlChange(Sender: TObject);
    begin
      Button.Enabled := (Edit.Text <> '') and (ComboBox.Text <> '');
    end;
    
    procedure InitializeWizard();
    begin
      { ... }
    
      Edit.OnChange := @ControlChange;
      Combobox.OnChange := @ControlChange;
    end;