I am doing my A2 computing project in Delphi and have encountered a problem when it comes to adding additional parameters to an event procedure.
I am creating a number of Labels (TLabel object) and storing them in an array under my main form, "form1".
This is what I have currently:
**The declaration of the array of labels and the corresponding ClickEvent procedure with the standard (Sender: TObject) parameter passed.
public
InventoryLabel : array [0..23] of TLabel;
procedure InventoryLabelClick(Sender: TObject);
**This is the procedure of the ClickEvent matching the one declared above. (The contents of the procedure is very messy but is relevant to the question and is what I am using to get by currently.)
Procedure TForm1.InventoryLabelClick(Sender: TObject);
begin
if sender = InventoryLabel[0] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[0]].cardpic);
if sender = InventoryLabel[1] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[1]].cardpic);
if sender = InventoryLabel[2] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[2]].cardpic);
if sender = InventoryLabel[3] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[3]].cardpic);
if sender = InventoryLabel[4] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[4]].cardpic);
if sender = InventoryLabel[5] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[5]].cardpic);
if sender = InventoryLabel[6] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[6]].cardpic);
if sender = InventoryLabel[7] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[7]].cardpic);
if sender = InventoryLabel[8] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[8]].cardpic);
if sender = InventoryLabel[9] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[9]].cardpic);
if sender = InventoryLabel[10] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[10]].cardpic);
if sender = InventoryLabel[11] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[11]].cardpic);
if sender = InventoryLabel[12] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[12]].cardpic);
if sender = InventoryLabel[13] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[13]].cardpic);
if sender = InventoryLabel[14] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[14]].cardpic);
if sender = InventoryLabel[15] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[15]].cardpic);
if sender = InventoryLabel[16] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[16]].cardpic);
if sender = InventoryLabel[17] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[17]].cardpic);
if sender = InventoryLabel[18] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[18]].cardpic);
if sender = InventoryLabel[19] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[19]].cardpic);
if sender = InventoryLabel[20] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[20]].cardpic);
if sender = InventoryLabel[21] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[21]].cardpic);
if sender = InventoryLabel[22] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[22]].cardpic);
if sender = InventoryLabel[23] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[23]].cardpic);
end;
**This is the bit of code that creates the labels and gives them their attributes.
for I := 0 to 23 do
begin
InventoryLabel[i] := TLabel.Create(nil);
with InventoryLabel[i] do
begin
Parent := Inventory;
left := 8;
OnClick := InventoryLabelClick;
visible := false;
end;
end;
This is all very well and works(ish) however I want to pass a parameter when I call the "InventoryLabelClick" procedure in this case the variable "I" which will be the reference of which label is pressed. This will allow me to remove all of the "if sender = inventorylabel[x]" (x being any of the numbers above) and instead replace with just the second bit "imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[I]].cardpic);" but with the parameter "I" instead of the number "x" (same as above).
I tried the following edits to see if it would work.
**Change it in the declaration
Public
procedure InventoryLabelClick(Sender: TObject; I: Integer);
**Change it for the procedure in the implementation
Procedure TForm1. InventoryLabelClick(Sender: TObject; I: Integer);
**Then when the event it assigned to the object
for I := 0 to 23 do
begin
InventoryLabel[i] := TLabel.Create(nil);
with InventoryLabel[i] do
begin
Parent := Inventory;
left := 8;
OnClick := InventoryLabelClick;
visible := false;
end;
end;
**the sender parameter is default so there is no need to declare it in the first case. However when there are multiple parameters it asks for both.
When run, this returns the error message "
E2010 Incompatible types:'TNotifyEvent' and 'procedure, untyped pointer or untyped parameter'
" I take this to mean that I have declared the parameters wrong.
Is anybody able to help me solve this problem? If it turns out that it is impossible to pass an additional parameter like I have attempted to do above, can anybody suggest a way of making the code a bit neater?
Thanks in advance.
Save the "i" value in the TLabel's Tag property.
for I := 0 to 23 do begin
InventoryLabel[i] := TLabel.Create(nil);
with InventoryLabel[i] do begin
Parent := Inventory;
Tag := i;
left := 8;
OnClick := InventoryLabelClick;
visible := false;
end;
end;
Then, in your OnClick event, type cast Sender to TLabel and read off the Tag value to get the label clicked on:
Procedure TForm1.InventoryLabelClick(Sender: TObject);
begin
imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[TLabel(Sender).Tag]].cardpic);
end;
Why don't you do it like this?
Procedure TForm1.InventoryLabelClick(Sender: TObject);
var i : integer;
begin
for i := 0 to 23 do
if sender = InventoryLabel[i] then imgInvItem.Picture.LoadFromFile(redcarddeck[redcardpositionsofinventory[i]].cardpic);
end;
Of course, the best way would be to make InventoryLabel not TLabel, but a custom class that capsulates a TLabel and a LoadPicture method, so you can do:
Procedure TForm1.InventoryLabelClick(Sender: TObject);
begin
Sender.LoadPicture;
end;
But this will be a bit more work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With