Goal
I'm helping out a friend make an installer using Inno Setup in Conjunction with VCL-Styles plugin. I currently trying to access an index which is supposedly linked to each choice in a combo box and for that I use the TNewComboBox.ItemIndex
.
Error
For some reason, accessing / returning the property doesn't work for us and we recieve this error:
Code
Here is the code
Source: "C:\Program Files (x86)\The Road To Delphi\VCL Styles Inno\VclStylesinno.dll"; DestDir: "{app}";
var
cb: TNewComboBox;
procedure DropDownChange(Sender : TObject );
begin
case cb.ItemIndex of // <------- Error line 76 "Could not Call proc"
0:
begin
Delete(cfgStr, Pos(cvar, cfgStr) + Length(cvar), 1);
Insert('0', cfgStr, Pos(cvar, cfgStr) + Length(cvar));
end;
1:
begin
Delete(cfgStr, Pos(cvar, cfgStr) + Length(cvar), 1);
Insert('1', cfgStr, Pos(cvar, cfgStr) + Length(cvar));
end;
2:
begin
Delete(cfgStr, Pos(cvar, cfgStr) + Length(cvar), 1);
Insert('2', cfgStr, Pos(cvar, cfgStr) + Length(cvar));
end;
3:
begin
Delete(cfgStr, Pos(cvar, cfgStr) + Length(cvar), 1);
Insert('3', cfgStr, Pos(cvar, cfgStr) + Length(cvar));
end;
4:
begin
Delete(cfgStr, Pos(cvar, cfgStr) + Length(cvar), 1);
Insert('4', cfgStr, Pos(cvar, cfgStr) + Length(cvar));
end;
5:
begin
Delete(cfgStr, Pos(cvar, cfgStr) + Length(cvar), 1);
Insert('0', cfgStr, Pos(cvar, cfgStr) + Length(cvar));
end;
end
end;
procedure CreateDropDown(page: TWizardPage; caption: String; cb: TNewComboBox; cvar: String; index: Integer; item0, item1, item2, item3, item4, item5 : String);
var
newLabel: TLabel;
begin
newLabel:= TLabel.Create(page);
newLabel.Parent:= page.Surface;
newLabel.Caption:= caption;
case page of
SettingsPageA:
begin
newLabel.Left:= curWidthA;
newLabel.Top:= curHeightA;
case curWidthA of
0:
begin
curWidthA:= curWidthA + 264;
end;
264:
begin
curWidthA:= curWidthA + 264;
end;
528:
begin
curWidthA:= 0;
curHeightA:= curHeightA + 66;
end;
end;
end;
SettingsPageB:
begin
newLabel.Left:= curWidthB;
newLabel.Top:= curHeightB;
case curWidthB of
0:
begin
curWidthB:= curWidthB + 264;
end;
264:
begin
curWidthB:= curWidthB + 264;
end;
528:
begin
curWidthB:= 0;
curHeightB:= curHeightB + 66;
end;
end;
end;
SettingsPageC:
begin
newLabel.Left:= curWidthC;
newLabel.Top:= curHeightC;
case curWidthC of
0:
begin
curWidthC:= curWidthC + 264;
end;
264:
begin
curWidthC:= curWidthC + 264;
end;
528:
begin
curWidthC:= 0;
curHeightC:= curHeightC + 66;
end;
end;
end;
end;
newLabel.Width:= 247;
newLabel.Height:= 25;
newLabel.Transparent:= True;
cb:= TNewComboBox.Create(page);
cb.Parent:= page.Surface;
cb.Left:= newLabel.Left;
cb.Top:= newLabel.Top + newLabel.Height + 4;
cb.Width:= newLabel.Width;
cb.Height:= newLabel.Height;
cb.Style:= csDropDownList;
cb.Items.Add(item0);
if Length(item1) > 0 then
begin
cb.Items.Add(item1);
if Length(item2) > 0 then
begin
cb.Items.Add(item2);
if Length(item3) > 0 then
begin
cb.Items.Add(item3);
if Length(item4) > 0 then
begin
cb.Items.Add(item4);
if Length(item5) > 0 then
begin
cb.Items.Add(item5);
end;
end;
end;
end;
end;
cb.ItemIndex := index;
cb.OnChange:= @DropDownChange; <---------------
end;
This is just a piece of the code which performs an .OnChange
whenever the combo box changes of choice / Index. Thanks!
I've been requested for a minimal example of reproducible code shown below
procedure DropDownChanged(Sender: TObject);
begin
Log(IntToStr(cb.ItemIndex);
end;
procedure CreateDropDown(page: TWizardPage; caption: String; cb: TNewComboBox; cvar: String; index: Integer; item0, item1 : String);
var
newLabel: TLabel;
begin
newLabel:= TLabel.Create(page);
newLabel.Parent:= page.Surface;
newLabel.Caption:= caption;
newLabel.Left:= curWidth;
newLabel.Top:= curHeight;
newLabel.Width:= 247;
newLabel.Height:= 25;
newLabel.Transparent:= True;
cb:= TNewComboBox.Create(page);
cb.Parent:= page.Surface;
cb.Left:= newLabel.Left;
cb.Top:= newLabel.Top + newLabel.Height + 4;
cb.Width:= newLabel.Width;
cb.Height:= newLabel.Height;
cb.Style:= csDropDownList;
cb.Items.Add(item0);
cb.Items.Add(item1);
cb.ItemIndex:= index;
cb.OnChange:= DropDownChanged;
end;
And to execute it:
CreateDropDown(wpReady, 'Caption', 'ComboBox', 0, 'First Item', 'Second Item');
Edit 2
This is the original author of this little project. I've watered down the code necessary to recreate the issue, like this:
[Code]
var
ExamplePage: TWizardPage;
cb: TNewComboBox;
procedure DropDownChanged(Sender: TObject);
begin
Log(IntToStr(cb.ItemIndex));
end;
procedure CreateDropDown(page: TWizardPage; cb: TNewComboBox; index: Integer; item0, item1 : String);
begin
cb:= TNewComboBox.Create(page);
cb.Parent:= page.Surface;
cb.Style:= csDropDownList;
cb.Items.Add(item0);
cb.Items.Add(item1);
cb.ItemIndex:= index;
cb.OnChange:= @DropDownChanged;
end;
procedure CreateExamplePage;
var
ExampleComboBox: TNewComboBox;
begin
ExamplePage:= CreateCustomPage(wpWelcome, 'Example Page', 'This is an example');
CreateDropDown(ExamplePage, ExampleComboBox, 0, 'First Item', 'Second Item');
end;
procedure InitializeWizard;
begin
CreateExamplePage;
end;
This is the minimum required to reproduce the error upon selecting an item in the drop-down. I hope this helps clear out the issue!
You have name conflict between the global cb
variable and local cb
parameter of CreateDropDown
function. You assign the local parameter (what makes little sense), while the global variable is never assigned. Plus, it's not really clear, what is the purpose of ExampleComboBox
.
Maybe you wanted something like this?
[Code]
var
ExamplePage: TWizardPage;
ExampleComboBox: TNewComboBox;
procedure DropDownChanged(Sender: TObject);
begin
Log(IntToStr(ExampleComboBox.ItemIndex));
end;
function CreateDropDown(
page: TWizardPage; index: Integer; item0, item1: String): TNewComboBox;
begin
Result := TNewComboBox.Create(page);
Result.Parent:= page.Surface;
Result.Style:= csDropDownList;
Result.Items.Add(item0);
Result.Items.Add(item1);
Result.ItemIndex:= index;
Result.OnChange:= @DropDownChanged;
end;
procedure CreateExamplePage;
begin
ExamplePage :=
CreateCustomPage(wpWelcome, 'Example Page', 'This is an example');
ExampleComboBox :=
CreateDropDown(ExamplePage, 0, 'First Item', 'Second Item');
end;
procedure InitializeWizard;
begin
CreateExamplePage;
end;
The DropDownChanged
does not have to rely on the global variable. If you want it to work for other comboboxes, rely on the Sender
parameter instead
Log(IntToStr(TNewComboBox(Sender).ItemIndex));