标签: delphi-2007

Delphi接口是否在子类中继承

如果我在基类上实现一个接口,它将由它的子类继承,我知道函数/过程将是,但我更感兴趣的是我是否能够将子类强制转换为接口然后返回到它原班.

我希望我能做的是将不同基类的对象传递给一个函数,然后在函数确定中输入并根据需要使用它们.

这是可能的,这是正确的方法吗?

更新

为了帮助消除任何混乱(或创造更多),我想做的事情(条纹下到核心).

接口

    IMyInterFace = interface
   ['{B7203E50-F5CB-4755-9DB1-FB41B7B192C5}'] 
     function MyFunction: Boolean;
   end;
Run Code Online (Sandbox Code Playgroud)

基类

   type TMyObject = class(TInterfacedObject,IMyInterFace)
Run Code Online (Sandbox Code Playgroud)

子类

  type TSubMyObject = class(TMyObject)
Run Code Online (Sandbox Code Playgroud)

另一类

  type TMyOtherObject = class(TInterfacedObject,IMyInterFace)
Run Code Online (Sandbox Code Playgroud)

然后用法

 procedure foo();
   var obj:TSubMyObject;
 begin
      obj := TSubMyObject.Create();
      SendInterfaceObject(obj);
 end;

 procedure bar();
   var obj:TMyOtherObject;
 begin
      obj := TMyOtherObject.Create();
      SendInterfaceObject(obj);
 end;



 procedure SendInterfaceObject(iobj:IMyInterFace);
 begin
     if (iobj is TSubMyObject) then
     begin
        //code here
     end
     else if (iobj is TMyOtherObject) then
     begin
       //code here
     end;
 end;
Run Code Online (Sandbox Code Playgroud)

更新2

我更新了代码abit,以便更好地展示我的意思.

//这里代码部分与传递给它的对象几乎没有关系,例如,如果这个类是TAccounts并且它被传递了一个TEmployee对象,那么它可以支付每周付费,但是如果它是TInvoice那么它会检查到看看是否需要支付,只在日期是死线前2天支付.

TEmployee/TInvoice甚至可能来自要求付款的外派. …

delphi oop delphi-2007

4
推荐指数
1
解决办法
2245
查看次数

为什么在使用readbuffer时使用string [1]而不是string

我有这样的记录

  TEmf_SrectchDIBits = packed record
    rEMF_STRETCHDI_BITS: TEMRStretchDIBits;
    rBitmapInfo: TBitmapInfo;
    ImageSource: string;
  end;
  ---
  ---
  RecordData: TEmf_SrectchDIBits;
Run Code Online (Sandbox Code Playgroud)

如果我正在使用TStream将数据读入其中,则会发生异常

SetLength(RecordData.ImageSource, pRecordSize);

EMFStream.ReadBuffer(RecordData.ImageSource,pRecordSize) 
Run Code Online (Sandbox Code Playgroud)

但如果我使用下面的代码,它正常工作

SetLength(RecordData.ImageSource, pRecordSize);

EMFStream.ReadBuffer(RecordData.ImageSource[1], pRecordSize);
Run Code Online (Sandbox Code Playgroud)

那么使用String和String有什么区别[1]

delphi delphi-2007 delphi-2006

4
推荐指数
2
解决办法
926
查看次数

从Delphi中的richedit获取richtext

有没有办法从richedit获取RTF数据而不使用savetostream

strStream := TStringStream.Create('') ;
try
  RichEdit.Lines.SaveToStream(strStream);
  Text := strStream.DataString;
  strStream.CleanupInstance;
finally
  strStream.Free
Run Code Online (Sandbox Code Playgroud)

delphi richedit delphi-2007

4
推荐指数
1
解决办法
7745
查看次数

Delphi - 从类和接口继承(适配器模式)?

我正在尝试执行GoF适配器模式,并且在C#示例中,我遵循Adapter类继承原始类和适配接口.在Delphi(2007)中,据我所知,这是不可能的,或者是这样吗?如果一个类继承了一个接口,它需要从TInterfacedObject继承,因为Delphi不允许多个类继承,这就是故事的结尾.我无法同时从自定义类和接口继承.

我对么?

谢谢.

我在http://delphipatterns.blog.com/2011/02/22/decorator-5/上实现了这种模式

delphi inheritance interface delphi-2007

4
推荐指数
1
解决办法
2493
查看次数

bpl delphi专家和dll delphi专家之间的区别是什么

我在delphi IDE专家工作,现在为了避免依赖性问题,我正在考虑重建这个专家作为dll专家,正如在这些答案中提出的那样,现在我的专家(编译为bpl)访问ScreenApplication全局变量(实例) Delphi IDE),所以我想知道如果我编译我的专家作为一个DLL我仍然可以访问这些变量,我也想知道which are the main differences between a bpl delphi expert and a dll delphi expert?

ide delphi delphi-2007 toolsapi

4
推荐指数
1
解决办法
577
查看次数

如何在Windows 7中获取域名

我写了一个运行Excel加载项的dll(几年前).

我使用此代码检索域名,并在Windows XP中正常工作,但在Windows 7中失败.
只有我以管理员身份运行才能正常工作.
但是,我不想以管理员身份运行,因为此代码是Excel加载项DLL的一部分,如果以管理员身份运行,Excel无法找到用户的文件.

MyReg:= TRegistry.Create;

MyReg.RootKey:= HKEY_LOCAL_MACHINE;
MyReg.OpenKey(RegKeyWin7,false);
NetworkID2:= lowercase(trim(MyReg.ReadString(RegValWin7)));
MyReg.CloseKey;

FreeAndNil(MyReg);

FNetworkOK:= (NetworkID2 = OKRes4);
//Temp check to pinpoint the problem.
if FNetWorkOK = false then ShowMessage('Error wrong domain: '+NetworkID2)
else ShowMessage('all ok');
Run Code Online (Sandbox Code Playgroud)

如何在正常权限下使用Delphi检索Windows 7中的域名?

delphi dns dll delphi-2007 windows-7

4
推荐指数
1
解决办法
1467
查看次数

如何记录源代码行导致异常并添加自定义信息?

我们的应用程序使用JCL记录导致异常的源代码行,并且它运行良好.我用的是D2007.我有一个执行实际日志记录的TApplicationEvents.OnException事件.考虑一下:

function MyFunc: String;
begin
  // Codelines that may raise exception.
  // Call functions that also may raise exception  
end;

procedure ComplexFunc(aVariable: String);
begin
  // also here can it be exceptions....
  // Code here that is the cause of exception
end;

procedure foo;
var
  myVar: String;
begin
  myvar := MyFunc;
  ComplexFunc(myvar);  
end;

procedure TMainForm.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
  LogLastException(E, 'Unhandled Exception (%s)', [E.Message], 20);
end;
Run Code Online (Sandbox Code Playgroud)

我有3个方法和我的onException事件.LogLastException在发生异常时记录callstack.问题是我无法在没有松散导致异常的源代码的情况下向E.Message添加信息.假设它是ComplexFunc中引发异常的第二行.我还想记录myvar变量的值.所以我将代码更改为:

function MyFunc: String;
begin
  // Codelines that may raise exception.
  // Call functions that …
Run Code Online (Sandbox Code Playgroud)

delphi exception-handling delphi-2007

4
推荐指数
1
解决办法
1229
查看次数

为什么在关闭时不执行包中任何单元定型部分的代码?

我有一个应用程序,它使用静态链接的运行时包以及使用它们的设计时包.由于某种原因,任何单元定型部分中的代码都没有在运行时运行(我无法分辨何时开始发生).

finalization
  ShowMessage('Goodbye');
end.
Run Code Online (Sandbox Code Playgroud)

关闭Delphi会显示消息,但不会在我的应用程序关闭时显示.如果我在ShowMessage上设置一个断点,它会在那里中断,但不执行该行,这更令人讨厌.如果最终化中有多行,则调试器在第一行停止,不执行它然后跳转到结尾.

procedure ProcOne;
begin
  SomeObject.Free; // Debugger does not enter or stop here
  SomeObject := nil;
end;

finalization
  ProcOne; // Debugger stops here, doesn't execute, jumps to "end."
  ProcTwo; // Every line has a blue dot
  ShowMessage('Bye');
end.
Run Code Online (Sandbox Code Playgroud)

ProcOne断点上的调用堆栈显示@ Halt0 => FinalizeUnits => MyPackage.MyUnit.Finalization.

如果我将该单元包含在不使用包的应用程序中,则一切都正常执行.

有谁知道可能导致这种情况的原因是什么?

编辑:

感谢Allen Bauer的评论指向了正确的方向,我已经设法解决了这个问题.如果使用运行时包构建应用程序,然后动态加载另一个也引用该包和单元的包,则似乎会出现问题.

我创建了一个演示问题的测试项目:TestFinalization

有谁知道这个和/或解决方法的原因?在您注意到外部资源未被清除之前,您通常可能不会注意到您的终结未运行.

delphi finalization package delphi-2007

4
推荐指数
1
解决办法
1373
查看次数

如何覆盖委托方法实现?

在Delphi 2007中,我使用一个类来实现第二类支持的接口之一.这很有效.德尔福帮助指出:

默认情况下,使用implements关键字委托所有接口方法.但是,您可以在类中使用方法解析子句或声明方法来实现某些接口方法来覆盖此默认行为.

但是,当我在我的第二个类中声明一个具有其中一个接口方法的匹配签名的方法时,它不会被调用.

我想知道这是不是因为我在创建它时通过另一个界面访问该类.

下面是一个演示我的问题的测试程序:

program Project1;

{$APPTYPE CONSOLE}

type
  IInterface1 = interface
  ['{15400E71-A39B-4503-BE58-B6D19409CF90}']
    procedure AProc;
  end;

  IInterface2 = interface
  ['{1E41CDBF-3C80-4E3E-8F27-CB18718E8FA3}']
  end;

  TDelegate = class(TObject)
  protected
    procedure AProc;
  end;

  TMyClass = class(TInterfacedObject, IInterface1, IInterface2)
  strict private
    FDelegate: TDelegate;
    property Delegate: TDelegate read FDelegate implements IInterface1;
  public
    constructor Create;
    destructor Destroy; override;
    procedure AProc;
  end;

procedure TDelegate.AProc;

begin
  writeln('TClassDelegate.AProc');
end;

constructor TMyClass.Create;
begin
  inherited;
  FDelegate := TDelegate.Create;
end;

destructor TMyClass.Destroy;
begin
  FDelegate.Free;
  inherited;
end;

procedure TMyClass.AProc;

begin
  writeln('TMyClass.AProc');
end;

var …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-2007

4
推荐指数
1
解决办法
1267
查看次数

如何终止具有单独消息循环的线程?

我正在为SetWindowsHookExAPI 编写一个实用程序单元.

要使用它,我想要一个这样的界面:

var
  Thread: TKeyboardHookThread;
begin
  Thread := TKeyboardHookThread.Create(SomeForm.Handle, SomeMessageNumber);
  try
    Thread.Resume;
    SomeForm.ShowModal;
  finally
    Thread.Free; // <-- Application hangs here
  end;
end;
Run Code Online (Sandbox Code Playgroud)

在我当前的实现中,TKeyboardHookThread我无法正确退出线程.

代码是:

  TKeyboardHookThread = class(TThread)
  private
    class var
      FCreated                 : Boolean;
      FKeyReceiverWindowHandle : HWND;
      FMessage                 : Cardinal;
      FHiddenWindow            : TForm;
  public
    constructor Create(AKeyReceiverWindowHandle: HWND; AMessage: Cardinal);
    destructor Destroy; override;
    procedure Execute; override;
  end;

function HookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
  S: KBDLLHOOKSTRUCT;
begin
  if nCode < 0 then begin
    Result …
Run Code Online (Sandbox Code Playgroud)

delphi multithreading delphi-2007 message-loop

4
推荐指数
1
解决办法
1173
查看次数