Delphi界面助手/解决方法

时间:2014-07-17 01:56:17

标签: delphi interface delphi-xe5 spring4d

我意识到Delphi不支持接口助手,但在阅读了几个SO主题和Spring4D的来源之后,我想知道有没有办法实现以下目的?源代码注释几乎总结了我正在尝试做的事情,所以这里是:

program IHelper;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Spring,
  System.SysUtils;

type

  IMyThing = interface
  ['{01E799A5-9141-4C5E-AA85-B7C9792024D9}']
    procedure BasicThing;
  end;

  TMyThing = class(TInterfacedObject, IMyThing)
  strict private
    procedure BasicThing;
  end;

  IMyThingHelper = record
  private
    FOutage: IMyThing;
  public
    class operator Implicit(const Value: IMyThing): IMyThingHelper;
    procedure HelpfulThing;
  end;

  TMyThingHelper = class helper for TMyThing
  public
    class procedure ObjectThing;
  end;

{ TOutage }

procedure TMyThing.BasicThing;
begin
  Writeln('Basic Thing');
end;


{ IOutageHelper }

procedure IMyThingHelper.HelpfulThing;
begin
  Writeln('Helpful thing');
end;

class operator IMyThingHelper.Implicit(const Value: IMyThing): IMyThingHelper;
begin
  Result.FOutage := Value;
end;

{ TMyThingHelper }

class procedure TMyThingHelper.ObjectThing;
begin
  Writeln('Object thing');
end;

var
  LThing: IMyThing;

begin
  try
    LThing := TMyThing.Create;
    LThing.BasicThing;
    //LThing.HelpfulThing;               // <--- **** prefer this syntax but obviously does not compile
    IMyThingHelper(LThing).HelpfulThing; // <--- this works ok but prefer not to have to cast it here

    //LThing.ObjectThing;                // <--- obviously does not compile
    (LThing as TMyThing).ObjectThing;    // <--- class helpers work ok but no good for interfaces

    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

有关如何使用****显示此代码的任何想法或建议? 我理解答案可能是彻头彻尾的“不”,但似乎有一些非常聪明的解决方法正在完成,也许比我聪明的人知道怎么做? (Delphi XE5)

另一个例子

var
   dataObject: IDataObject;

//Get clipboard IDataObject
OleGetClipboard({out}dataObject);

//Check if they want us to move or copy what's on the clipboard
preferredDropEffect: DWORD := dataObject.GetPreferredDropEffect;

//...do the stuff with the clipboard

//Tell them what we did
dataObject.SetPerformedDropEffect(DROPEFFECT_NONE); //we moved the underlying data; sender need not do anything
dataObject.SetPasteSucceeded(DROPEFFECT_MOVE); //Paste complete

带着帮手:

TDataObjectHelper = interface helper for IDataObject
public
   function GetPreferredDropEffect(DefaultPreferredDropEffect: DWORD=DROPEFFECT_NONE): DWORD;
end;

function TDataObjectHelper.GetPreferredDropEffect(DefaultPreferredDropEffect: DWORD=DROPEFFECT_NONE): DWORD;
begin
{
    DROPEFFECT_NONE   = 0;  //Drop target cannot accept the data.
    DROPEFFECT_COPY   = 1;  //Drop results in a copy. The original data is untouched by the drag source.
    DROPEFFECT_MOVE   = 2;  //Drag source should remove the data.
    DROPEFFECT_LINK   = 4;  //Drag source should create a link to the original data.
    DROPEFFECT_SCROLL = 0x80000000 //Scrolling is about to start or is currently occurring in the target. This value is used in addition to the other values.
}
    if TDataObjectHelper.ContainsFormat(Source, CF_PreferredDropEffect) then
        Result := TDataObjectHelper.GetUInt32(Source, CF_PREFERREDDROPEFFECT)
    else
        Result := DefaultDropEffect;
end;

3 个答案:

答案 0 :(得分:4)

为什么不使用其他界面?

program IHelper;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Spring,
  System.SysUtils;

type

  IMyThing = interface
  ['{01E799A5-9141-4C5E-AA85-B7C9792024D9}']
    procedure BasicThing;
  end;

  IMyThingHelper = interface
  ['{...}']
    procedure HelpfulThing;
  end;

  TMyThing = class(TInterfacedObject, IMyThing, IMyThingHelper)
  strict private
    procedure BasicThing;
    procedure HelpfulThing;
  end;

{ TOutage }

procedure TMyThing.BasicThing;
begin
  Writeln('Basic Thing');
end;

{ IOutageHelper }

procedure TMyThing.HelpfulThing;
begin
  Writeln('Helpful thing');
end;

var
  LThing: IMyThing;
  LHelper: IMyThingHelper;
begin
  try
    LThing := TMyThing.Create;
    LThing.BasicThing;
    if Supports(LThing, IMyThingHelper, LHelper) then
      LHelper.HelpfulThing;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

答案 1 :(得分:2)

有两种方法可以实现这一目标:

  • 其中一个变量为IMyThingHelper,并为其分配接口,然后调用&#34;扩展方法&#34;在记录变量上。

  • 另一种方法是使用absolute


var
  LThing: IMyThing;
  LHelper: IMyThingHelper absolute LThing;
begin
  LThing := TMyThing.Create;
  LHelper.HelpfulThing;

前段时间,我在博客上发表了这篇文章issue。不幸的是,在我的情况下,&#34;助手记录&#34; Enumerable<T>有很多通用的方法,编译器得到了极大的减速。

答案 2 :(得分:1)

另一种实现此目的的方法是说服Idera实现此功能。您可以通过upvote此功能请求来帮助它 https://quality.embarcadero.com/browse/RSP-16763