Link to home
Start Free TrialLog in
Avatar of Edo082297
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
Avatar of Madshi
Madshi

You can do this:

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.
The type of obj doesn't really matter, it just has to be a 4-byte type. You can also use integer/cardinal/pchar/pointer/whatEver instead of TObject.
Avatar of Edo082297

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(ACat.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
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.
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
ASKER CERTIFIED SOLUTION
Avatar of Madshi
Madshi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial