RAD Studio |  |

How Delphi Adds Properties
See Also
Collapse All

The ActiveX wrapper class implements properties in its interface using read and write access methods. That is, the wrapper class has COM properties, which appear on an interface as getter and/or setter methods. Unlike VCL properties, you do not see a "property" declaration on the interface for COM properties. Rather, you see methods that are flagged as property access methods. When you add a property to the ActiveX control's default interface, the wrapper class definition (which appears in the _TLB unit that is updated by the Type Library editor) gains one or two new methods (a getter and/or setter) that you must implement, just as when you add a method to the interface, the wrapper class gains a corresponding method for you to implement. Thus, adding properties to the wrapper class's interface is essentially the same as adding methods: the wrapper class definition gains new skeletal method implementations for you to complete.

Note: For details on what appears in the generated _TLB unit, see Code generated when you import type library information.
For example, consider a Caption property, of type TCaption in the underlying VCL object. To Add this property to the object's interface, you enter the following when you add a property to the interface via the type library editor:
Copy Code

    property Caption: TCaption read Get_Caption write Set_Caption;

Delphi adds the following declarations to the wrapper class:

Copy Code

    function Get_Caption: WideString; safecall;
    procedure Set_Caption(const Value: WideString); safecall;

Copy Code

    STDMETHOD(get_Caption(BSTR* Value));
    STDMETHOD(set_Caption(BSTR Value));

In addition, it adds skeletal method implementations for you to complete:

Copy Code

    function TButtonX.Get_Caption: WideString;
    begin
    end;
    procedure TButtonX.Set_Caption(Value: WideString);
    begin
    end;

Copy Code

    STDMETHODIMP TButtonXImpl::get_Caption(BSTR* Value)
    {
      try
      {
      }
      catch(Exception &e)
      {
        return Error(e.Message.c_str(), IID_IButtonX);
      }
      return S_OK;
    };
    STDMETHODIMP TButtonXImpl::set_Caption(BSTR Value)
    {
      try
      {
      }
      catch(Exception &e)
      {
        return Error(e.Message.c_str(), IID_IButtonX);
      }
      return S_OK;
    };

Typically, you can implement these methods by simply delegating to the associated VCL control, which can be accessed using the FDelphiControl member of the wrapper class:

Copy Code

    function TButtonX.Get_Caption: WideString;
    begin
       Result := WideString(FDelphiControl.Caption);
    end;

    procedure TButtonX.Set_Caption(const Value: WideString);
    begin
       FDelphiControl.Caption := TCaption(Value);
    end;

Copy Code

    STDMETHODIMP TButtonXImpl::get_Caption(BSTR* Value)
    {
    try
    {
    *Value = WideString(m_VclCtl->Caption).Copy();
    }
    catch(Exception &e)
    {
    return Error(e.Message.c_str(), IID_IButtonX);
    }
    return S_OK;
    };
    STDMETHODIMP TButtonXImpl::set_Caption(BSTR Value)
    {
      try
      {
        m_VclCtl->Caption = AnsiString(Value);
      }
      catch(Exception &e)
      {
        return Error(e.Message.c_str(), IID_IButtonX);
      }
      return S_OK;
    };

In some cases, you may need to add code to convert the COM data types to native Delphi types. The preceding example manages this with typecasting.

Note: Because the Automation interface methods are declaredsafecall, you do not have to implement COM exception code for these methods—the Delphi compiler handles this for you by generating code around the body of safecall methods to catch Delphi exceptions and to convert them into COM error info structures and return codes.
See Also

Code Generated When You Import Type Library Information

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!