{Interface - is actually abstract class}
TAbstractPrinter = class
protected
{"abstract" means "no implementation" - to avoid dummy implementation stubs}
function GetResolution:Integer;virtual;abstract;
public
function Print(ABitmap:TBitmap):Boolean;virtual;abstract;
{Read only property implemented via getter method}
property Resolution:Integer read GetResolution;
end;
{Actual implementation}
TMyPrinter = class(TAbstractPrinter)
protected
function GetResolution:Integer;override;
public
function Print(ABitmap:TBitmap):Boolean;override;
end;
function TMyPrinter.GetResolution:Integer;
begin
{Real implementation here}
end;
function TMyPrinter.Print(ABitmap:TBitmap):Boolean;
begin
{Real implementation here}
end;
{Example of usage}
{MyPrinter.drv DLL file}
function CreatePrinter:TAbstractPrinter;
begin
{100% valid syntax! That's, where polymorphism magic happens!}
Result := TMyPrinter.Create;
end;
{OS code}
TCreatePrinter = function:TAbstractPrinter;
function Print(ADriverName:String;ABitmap:TBitmap):Boolean;
var
Printer:TAbstractPrinter;
Driver:Handle;
CreatePrinter:TCreatePrinter;
begin
Driver := LoadLibrary(DriverName);
CreatePrinter := TCreatePrinter(GetProcAddress(Driver, 'CreatePrinter'));
Printer := CreatePrinter^;
Result := Printer.Print(Bitmap);
end;