Edo082297
asked on
Interface / Pointer GUI Association
Hello All
I would like to know the best way to store an interface reference in an assocaited pointer.
For example, in a listbox containing cats, with each item representing an ICat reference, I would like to store the ICat reference in the Objects property of the list item. Another example is using a TTreeView (cats in a tree?) and the Node's Data property.
I have accomplished this in the past using records (one sole member of type ICat and using the record pointer), and also by bypassing reference counting by typecasting the interface to a void pointer. The first method is tedious, and the second one is dangerous.
Is there some elegant construct or alternate method out there that I do not know about? Sure, one can use TInterfaceList to maintain a list of references, but there is still no way of directly associating that reference with the Objects or Data properties, so this discussion is not further advanced by such an observation.
What do you do?
Regards,
Edo
I would like to know the best way to store an interface reference in an assocaited pointer.
For example, in a listbox containing cats, with each item representing an ICat reference, I would like to store the ICat reference in the Objects property of the list item. Another example is using a TTreeView (cats in a tree?) and the Node's Data property.
I have accomplished this in the past using records (one sole member of type ICat and using the record pointer), and also by bypassing reference counting by typecasting the interface to a void pointer. The first method is tedious, and the second one is dangerous.
Is there some elegant construct or alternate method out there that I do not know about? Sure, one can use TInterfaceList to maintain a list of references, but there is still no way of directly associating that reference with the Objects or Data properties, so this discussion is not further advanced by such an observation.
What do you do?
Regards,
Edo
The type of obj doesn't really matter, it just has to be a 4-byte type. You can also use integer/cardinal/pchar/poi nter/whatE ver instead of TObject.
ASKER
Madshi,
Please re-read my question.
Wouldn't this be nice:
var
ACat: ICat;
ANode: TTreeNode;
begin
ACat := CoCat.Create;
ICat(ANode.Data) := ACat;
end;
Sorry, left side can't be assigned to.
Or:
AListBox.Items.AddObject(A Cat.Name, IUnknown(ACat));
Of course, the compiler will swallow casting ACat to a void pointer, but that is dangerous!
We are back at square one.
Edo
Please re-read my question.
Wouldn't this be nice:
var
ACat: ICat;
ANode: TTreeNode;
begin
ACat := CoCat.Create;
ICat(ANode.Data) := ACat;
end;
Sorry, left side can't be assigned to.
Or:
AListBox.Items.AddObject(A
Of course, the compiler will swallow casting ACat to a void pointer, but that is dangerous!
We are back at square one.
Edo
I thought this one would be possible:
var
ACat: ICat;
ANode: TTreeNode;
begin
ACat := CoCat.Create;
ICat(ANode.Data) := ACat;
end;
Okay, let's change it like this:
var
ACat: ICat;
APtr: pointer;
ANode: TTreeNode;
begin
ACat := CoCat.Create;
ICat(APtr) := ACat;
ICat(ANode.Data) := APtrt;
end;
To free it, do this:
APtr := ANode.Data;
ANode.Free;
ICat(APtr) := nil;
Regards, Madshi.
var
ACat: ICat;
ANode: TTreeNode;
begin
ACat := CoCat.Create;
ICat(ANode.Data) := ACat;
end;
Okay, let's change it like this:
var
ACat: ICat;
APtr: pointer;
ANode: TTreeNode;
begin
ACat := CoCat.Create;
ICat(APtr) := ACat;
ICat(ANode.Data) := APtrt;
end;
To free it, do this:
APtr := ANode.Data;
ANode.Free;
ICat(APtr) := nil;
Regards, Madshi.
ASKER
ICat(ANode.Data) := APtr;
....left side cannot be assigned to
However, I can get the compiler to take the following:
ACat := CoCat.Create;
ICat(APtr) := ACat;
ANode.Data := APtr;
However, I'm not sure if ACat is reference counted properly in this last case; using the void pointer bothers me (should it?). I'll give you full points if you check that, or once I get around to checking it and see that it does indeed correctly increment the reference count on ACat (which could be in a couple of weeks at this point).
Thanks, Madshi
Edo
....left side cannot be assigned to
However, I can get the compiler to take the following:
ACat := CoCat.Create;
ICat(APtr) := ACat;
ANode.Data := APtr;
However, I'm not sure if ACat is reference counted properly in this last case; using the void pointer bothers me (should it?). I'll give you full points if you check that, or once I get around to checking it and see that it does indeed correctly increment the reference count on ACat (which could be in a couple of weeks at this point).
Thanks, Madshi
Edo
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
var obj : TObject;
cat : ICat;
begin
ICat(obj) := cat;
ICat(obj) := nil;
This will work perfectly, even with incrementing and decrementing the reference count. Of course you have to assign "nil" to all objects before freeing them, because otherwise the reference count is never decremented.
Regards, Madshi.