Reputation: 597
Here is code:
procedure DisableContrlOL(const cArray : array of string; ReEnable : boolean = False);
// can be called from VKP / RAW / Generation clicks
var
AComponent: TComponent;
CompListDis, CompListEna : TStringList;
begin
CompListDis := TStringList.Create;
CompListEna := TStringList.Create;
for i := Low(cArray) to High(cArray) do begin
AComponent := FindComponent(cArray[i]);
if Assigned(AComponent) then
if (AComponent is TControl) then begin
if TControl(AComponent).Enabled then
CompListEna.Add(TControl(AComponent).Name)
else
CompListDis.Add(TControl(AComponent).Name);
ShowMessage(TControl(AComponent).Name);
if ReEnable then begin // if reenabling needed, then all whi
if not TControl(AComponent).Enabled then
TControl(AComponent).Enabled := True;
end else if (TControl(AComponent).Enabled) then
TControl(AComponent).Enabled := False;
end;
end;
end;
I think no more explanations are needed. The ShowMessage correctly shows name of each component, but nothing is added in StringLists. Why?
UPDATE: As question has gone pretty wild, I did confirm answer, which a bit helped me.
I understand that I did write things pretty unclear, but I am very limited, because these code lines is part of commercial project, and my hobby and heart thing. The main problem was found already 6h ago, but Rob just wanted to extend this whole question :D No, no offense, mate, it's OK. I am happy to receive so willing and helpful posts. Thanks again.
Upvotes: 1
Views: 2002
Reputation: 4659
Emphasizing that this is largely based on Rob's excellent suggestions, it looks as though you could simplify the code to:
procedure DisableContrlOL(const cArray : array of string;
ReEnable : boolean = False);
var
AComponent: TComponent;
begin
for i := Low(cArray) to High(cArray) do
begin
AComponent := FindComponent(cArray[i]);
if Assigned(AComponent) then
if (AComponent is TControl) then
begin
ShowMessage(TControl(AComponent).Name);
TControl(AComponent).Enabled := ReEnable;
end;
end;
end;
Not clear what the stringlists were for, since their contents were lost when execution left the scope of this procedure. If you want to return them, you should create and free them in the calling code.
Upvotes: 2
Reputation: 163357
How do you know that nothing is added to the lists? You create them in this code and the only references to them are in local variables. The objects are leaked when this function returns, so you never actually use the lists anywhere.
You've said you have code for "modular testing." Since that code isn't here, I must assume the code is not part of this function. But if you have external code that's supposed to check the contents of the lists, then the lists can't be just local variables. No other code can access them. You need to either return those lists or accept lists from outside that you then fill. Here's an example of the latter:
procedure DisableContrlOL(const cArray: array of string;
Reenable: Boolean
CompListDis, CompListEna: TStrings);
// can be called from VKP / RAW / Generation clicks
var
AComponent: TComponent;
AControl: TControl;
i: Integer;
begin
for i := Low(cArray) to High(cArray) do begin
AComponent := FindComponent(cArray[i]);
if not Assigned(AComponent) or not (AComponent is TControl) then
continue;
AControl := TControl(AComponent);
if AControl.Enabled then
CompListEna.Add(AControl.Name)
else
CompListDis.Add(AControl.Name);
ShowMessage(AControl.Name);
AControl.Enabled := Reenable;
end;
end;
The caller of this function will need to provide a TStrings
descendant for each list. They could be TStringList
, or they could be other descendants, such as TMemo.Lines
, so you can directly observe their contents in your program. (They can't be just TStrings
, though, since that's an abstract class.)
As you can see, I made some other changes to your code. All your code using the Reenable
parameter can be simplified to a single statement. That's because enabling a control that's already enabled, and disabling a control that's already disabled, are no-ops.
Also, Name
is a public property of TComponent
. You don't need to type-cast to TControl
before reading that property, but since you're type-casting so often elsewhere, it made sense to introduce a new variable to hold the type-casted TControl
value, and that can make your code easier to read. Easier-to-read code is easier-to-understand code, and that makes it easier to debug.
Upvotes: 4
Reputation: 84650
That sure looks like it ought to work. This is the sort of thing that the debugger can probably help with more than we can here.
Try breaking the problematic line down into multiple lines, like so:
if TControl(AComponent).Enabled then
CompListEna.Add(TControl(AComponent).Name)
else CompListDis.Add(TControl(AComponent).Name);
Rebuild with the "Use Debug DCUs" option on, and place a breakpoint on the if statement. Then use F7 to trace your way through the logic and see what's going on.
Upvotes: 0