RAD Studio
ContentsIndex
PreviousUpNext
How Delphi Adds Properties

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:

property Caption: TCaption read Get_Caption write Set_Caption;

Delphi adds the following declarations to the wrapper class:

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

 

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

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

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

 

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:

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

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

 

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.

Copyright(C) 2008 CodeGear(TM). All Rights Reserved.
What do you think about this topic? Send feedback!