Interface querying

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;