Following on from my question Inno Setup disable component selection when a specific component is selected, both solutions exhibit a problem whereby the component list does
The problem is in the way the ItemEnabled setter invalidates the item. Instead of invalidating the whole item rectangle it calls the InvalidateCheck method which invalidates only the check box portion of the item. See this code (commented by me):
procedure TNewCheckListBox.InvalidateCheck(Index: Integer);
var
IRect: TRect;
begin
// store the full item rectangle into the IRect variable
IRect := ItemRect(Index);
// offset this stored rectangle's left position by the item level
Inc(IRect.Left, (FCheckWidth + 2 * Offset) * (ItemLevel[Index]));
// set its right position to the left edge + width of the check image + margin offsets,
// but with no item text consideration, because this method was intended to invalidate
// just the check box portion of the item which is not enough for enabled state change
IRect.Right := IRect.Left + (FCheckWidth + 2 * Offset);
// flip the rectangle for RTL reading and ask the control to invalidate that rectangle
FlipRect(IRect, ClientRect, FUseRightToLeft);
InvalidateRect(Handle, @IRect, FThemeData <> 0);
end;
The enabled state setter would need to have something like this (pseudo-code):
procedure TNewCheckListBox.SetItemEnabled(Index: Integer; const AEnabled: Boolean);
begin
if ItemStates[Index].Enabled <> AEnabled then
begin
ItemStates[Index].Enabled := AEnabled;
// invalidate the check portion of the item
InvalidateCheck(Index);
// and invalidate also the text portion of the item
InvalidateText(Index);
end;
end;
So this is a bug in the TNewCheckListBox
control. Because there is no access to the item rectangles, you can ask the whole control to invalidate by calling Invalidate
when you finish updating the enabled state of the item(s):
procedure UpdateComponents;
begin
with WizardForm.ComponentsList do
begin
...
ItemEnabled[CompIndexSync] := not IsComponentSelected('Client');
ItemEnabled[CompIndexSyncClient] := not IsComponentSelected('Client');
ItemEnabled[CompIndexSyncServer] := not IsComponentSelected('Client');
...
Invalidate;
end;
end;