How to invoke a procedure created inside the New Component during the implementation

160 views Asked by At

I have created and implemented a New Component and inside this created component, there is a procedure InitCombo that needs to be invoked in the implementation.

How will I do that?

Here's the procedure InitCombo inside the New Component:

procedure TNewComponent.InitCombo;       //TComboBox ancestor
begin
  FStoredItems.OnChange := nil;
  StoredItems.Assign(Items);
  AutoComplete := False;
  FStoredItems.OnChange := StoredItemsChange;
  doFilter := True;
  StoredItemIndex := -1;
end;

Here's my attempt to invoke but returns an error message:

procedure TfrmMain.FormActivate(Sender: TObject);
begin
  TNewComponent.InitCombo;
end;

Error Messages
[dcc32 Error] makeasale_u_v1.pas(84): E2076 This form of method call only allowed for class methods or constructor

Please note that compiling, building, the installation went well and it is working. Except only on how to invoke the procedure inside the component?

1

There are 1 answers

1
Ken White On BEST ANSWER

Based only on the following portion of the first paragraph of your question

there is a procedure InitCombo that needs to be invoked in the implementation.

It appears you're confused about at least a couple of things about writing components.

First, you initialize the component properties either in its constructor to initialize things, or in an overridden Loaded method, which is called after the component is streamed in from the .dfm file where the component was used. Note that Loaded changes should not touch properties or events that the user can set in the Object Inspector, because doing so will prevent the user's settings from being used.

constructor TNewComponent.Create(AOwner: TComponent);
begin
  inherited;
  // Do your stuff here
end;

procedure TNewComponent.Loaded;
begin
  // Do your stuff here
end;

Second, events that are published (that can be seen in the Events tab of the Object Inspector) belong to the programmer that is using the component, not the component author. Never do anything to those event handlers. Your component should never touch those events except to call them if the end user has assigned a handler. So the code below is absolutely incorrect, because the OnChange event belongs to the user of your component, not your component code:

procedure TNewComponent.InitCombo;       //TComboBox ancestor
begin
  FStoredItems.OnChange := nil;
  ...
  FStoredItems.OnChange := StoredItemsChange;
end;

If you absolutely must do this, you need to do it properly by saving any event handler the end user has assigned, and restore it afterward:

procedure TNewComponent.InitCombo;
var
  OldOnChange: TNotifyEvent;
begin
  OldOnChange := Self.OnChange;
  // Do your stuff here
  Self.OnChange := OldOnChange;
end;

Third, unless you're using a class procedure or class function, you cannot call a method on a class itself (in other words, you cannot use TNewComponent.DoSomething). You call methods or access properties on an instance of the component itself. In your component code, that would be done by using Self, which refers to the current implemented component, as in Self.DoSomething.