How to use interface querying on forms in Delphi 3
A form is a TComponent, which provides a wrapper around a COM object
(VCLComObject/ComObject). Therefore, it does not _AddRef/_Release itself,
but the object it wraps. In D3 this means that the component (a Form)
needs
to implement a dummy object that can be used for reference counting.
In
Delphi 4, you do not need to assign a dummy object since Delphi will
only
_AddRef/_Release if the object is assigned.
The following sample queries all forms for an IShowMe interface:
procedure ExecuteShowMeOnAllForms;
var
Idx : integer;
ShowMeObject : IShowMe;
ObjectAssigned : boolean;
RefCountedObject : IUnknown;
begin
RefCountedObject := TInterfacedObject.Create;
for Idx := Screen.FormCount - 1 downto 0 do
with Screen.Forms[Idx] do begin
// Find out if we need to assign a VCLComObject.
ObjectAssigned := not Assigned (VCLComObject);
if ObjectAssigned then
VCLComObject := Pointer
(RefCountedObject);
try
// GetInterface calls ShowMeObject's
_Release & _AddRef, which is
// implemented by RefCountedObject.
if GetInterface (IShowMe,
ShowMeObject) then
ShowMeObject.ShowMe;
finally
if ObjectAssigned then begin
ShowMeObject
:= nil; // Calls VCLComObject._Release.
VCLComObject
:= nil; // Now we can safely reset VCLComObject.
end;
end;
end;
end;