Inno Setup ComponentsList OnClick event

谁都会走 提交于 2019-12-18 05:23:07

问题


I have a list of components for my Inno Setup installer, 19 different options, I want to set the OnClick event for ONE of the components. Is there a way to do this? Or is there a way to check which component triggered the OnClick event if it's set for all components?

Currently, the OnClick event is set like so:

Wizardform.ComponentsList.OnClick := @CheckChange;

I would like to do something like:

Wizardform.ComponentsList.Items[x].OnClick := @DbCheckChange;

The WizardForm.ComponentList is declared as a: TNewCheckListBox


回答1:


You do not want to use OnClick, use OnClickCheck instead.

The OnClick is called for clicks which do not change checked state (like clicks outside of any item; or clicks on fixed items; or selection change using keyboard), but mainly it is not called for checks using keyboard.

The OnClickCheck is called only, when the checked state changes, and both for keyboard and mouse.

To tell which item was checked by user, use ItemIndex property. The user can check only the selected item.

Though if you have a components hierarchy, or setup types, the items checked automatically by the installer due to a change in child/parent items or change in the setup type, won't trigger the OnClickCheck (nor the OnClick). So to tell all changes, all you can do is to remember the previous state and compare it against the current state, when the WizardForm.ComponentsList.OnClickCheck or WizardForm.TypesCombo.OnChange are called.

const
  TheItem = 2; { the item you are interested in }

var
  PrevItemChecked: Boolean;
  TypesComboOnChangePrev: TNotifyEvent;

procedure ComponentsListCheckChanges;
var
  Item: string;
begin
  if PrevItemChecked <> WizardForm.ComponentsList.Checked[TheItem] then
  begin
    Item := WizardForm.ComponentsList.ItemCaption[TheItem];
    if WizardForm.ComponentsList.Checked[TheItem] then
    begin
      Log(Format('"%s" checked', [Item]));
    end
      else
    begin
      Log(Format('"%s" unchecked', [Item]));
    end;

    PrevItemChecked := WizardForm.ComponentsList.Checked[TheItem];
  end;
end;

procedure ComponentsListClickCheck(Sender: TObject);
begin
  ComponentsListCheckChanges;
end;

procedure TypesComboOnChange(Sender: TObject);
begin
  { First let Inno Setup update the components selection }
  TypesComboOnChangePrev(Sender);
  { And then check for changes }
  ComponentsListCheckChanges;
end;

procedure InitializeWizard();
begin
  WizardForm.ComponentsList.OnClickCheck := @ComponentsListClickCheck;

  { The Inno Setup itself relies on the WizardForm.TypesCombo.OnChange, }
  { so we have to preserve its handler. }
  TypesComboOnChangePrev := WizardForm.TypesCombo.OnChange;
  WizardForm.TypesCombo.OnChange := @TypesComboOnChange;

  { Remember the initial state }
  { (by now the components are already selected according to }
  { the defaults or the previous installation) }
  PrevItemChecked := WizardForm.ComponentsList.Checked[TheItem];
end;

For a more generic solution, see Inno Setup Detect changed task/item in TasksList.OnClickCheck event. Though with components, one has to trigger the check on the WizardForm.TypesCombo.OnChange call too.




回答2:


Or is there a way to check which component triggered the onclick event if it's set for all components?

Most component events have a Sender parameter to point at the component object that is firing the event. However, in this case, the Sender will likely be the ComponentsList itself. Depending on what ComponentsList is actually declared as (TListBox, etc), it may have a property to specify which item is currently being selected/clicked (ItemIndex, etc). Or it might even have a separate event to report per-item clicks. You did not say what ComponentsList is declared as, so nobody here can tell you exactly what to look for in it.



来源:https://stackoverflow.com/questions/36989349/inno-setup-componentslist-onclick-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!