Search code examples
delphicomponentsruntimesynedit

Creating a component from a DLL, runtime


Decided to migrate from Delphi 2007 to Delphi 11 Alexandria. I had DLLs made with component creation from them. In the program, I dynamically load the DLL, a component is created in the DLL. Code that worked without issue on Delphi 2007 does not work on Delphi 11 Alexandria. Errors are constantly different, if I solve one error, another error appears. I can't find a solution. Please tell me how to create a component from a DLL.

My old code:

DLL:

library PascalHighlighter;

uses
  Forms,
  SynEditHighlighter, SynHighlighterPas, SynMemo;

{$R *.res}

var Component:TSynPasSyn;

type TSynPasSynClass = class of TSynPasSyn;

procedure PascalHighlighter_Create(Form:TForm; ComponentNum:Word);
begin
if Component=nil then begin
 Component := TSynPasSynClass.Create(Form);
 Component.Name:='SynPasSyn1';
end;
TSynmemo(Form.Components[ComponentNum]).Highlighter:=Component;
Component.CommentAttri.Foreground:=$00007F00;
Component.KeyAttri.Foreground:=$00A40000;
Component.StringAttri.Foreground:=$00FE0000;
end;

exports PascalHighlighter_Create;


begin
end.

Load DLL:

type

TDLLComponent = function(Form:TForm; ComponentNum: Word): Word;

var

PascalHighlighter_Create: TDLLComponent;
dll_PascalHighlighter: Thandle;

procedure TForm1.ButtinClick(Sender: TObject);
begin
if Fileexists(dirplugins+'PascalHighlighter.dll') then begin
 dll_PascalHighlighter:= LoadLibrary(PChar(dirplugins+'PascalHighlighter.dll'));
 @PascalHighlighter_Create:= GetProcAddress(dll_PascalHighlighter, 'PascalHighlighter_Create');
end;
if Assigned(PascalHighlighter_Create) then begin
 PascalHighlighter_Create(Form1,(Form1.Findcomponent('Synmemo1') as TSynmemo).ComponentIndex);
end;

end;

I tried to create an ordinary Memo from a DLL. Another error, but it doesn't work either.

I need to understand how to create a SynPasSyn1 component from a DLL and connect it to SynMemo. Or at least using the example of any other component, I can figure it out myself further.

Here is an example of creating a Memo. Why does it give an error " cannot assign a TFont to a TFont" and how to solve it?

library Mymemo;

uses
  Vcl.Forms, Vcl.StdCtrls;

{$R *.res}

var Component:TMemo;

procedure Mymemo_Create(Form:TForm); stdcall;
begin
 Component := TMemo.Create(Form);
 Component.Name:='Memo1';
with Component do begin
  Left := 100;
  Top := 100;
  Width := 400;
  Height := 300;
  Visible := True;
  Parent := Form; //Any container: form, panel, ...
end;

end;

exports Mymemo_Create;


begin
end.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

type
 TDLLComponent = procedure(Form:TForm{; ComponentNum: Word}); stdcall;//: Word;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 Mymemo_Create :TDLLComponent;
 dll_Mymemo :THandle;
 dirplugins :String;
begin
dirplugins:='E:\_Downloads\vk\Mymemo\';
 if Fileexists(dirplugins+'Mymemo.dll') then begin
   dll_Mymemo:= LoadLibrary(PChar(dirplugins+'Mymemo.dll'));
   if dll_Mymemo <> 0 Then begin
    edit1.Text:='load';
   end;
   //@
   Mymemo_Create:= GetProcAddress(dll_Mymemo, 'Mymemo_Create');
  if Assigned(Mymemo_Create) = True then begin
  edit1.Text:='load & create';
   Mymemo_Create(Form1);
  end;
 end;
end;

end.

How to create a component from a DLL?


Solution

  • I found a solution with DLL connection.Unit FastMM5. In the DPR file, in the Uses add "FastMM5", necessarily in the first place. It is added to the DLL and to the program where the library will be called from. Seems, no crashes, no hanging processes.