0

I created two Delphi 6 applications: A host application and a frame in DLL. Everything works fine except following TabSheet's client size in alClient style: the frame simply doesn't resize. I thought that calling ShowWindow with SW_SHOWMAXIMIZED will do the task, but it resizes the frame only once.

Here is a host application's main form:

unit Form1Unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls;

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    procedure TabSheet1Show(Sender: TObject);
    procedure TabSheet2Show(Sender: TObject);
    procedure TabSheet3Show(Sender: TObject);
  private
    _dllHandle1: LongWord;
    function getDllHandle1(): LongWord;
    property DllHandle1: LongWord read getDllHandle1;
  protected
    procedure DoDestroy(); override;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TInitFrameFunc = function(const ApplicationHandle, parentHandle: LongWord):LongWord; stdcall;


procedure TForm1.DoDestroy();
begin
  inherited;
  if _dllHandle1 <> 0 then begin
    FreeLibrary(_dllHandle1);
    _dllHandle1 := 0;
  end;
end;

function TForm1.getDllHandle1(): LongWord;
begin
  if _dllHandle1 = 0 then _dllHandle1 := LoadLibrary('FrameInDLL\DllFrame1.dll');
  Result := _dllHandle1;
end;

procedure TForm1.TabSheet1Show(Sender: TObject);
begin
  //ShowMessage('Tab 1 Show');
end;

procedure TForm1.TabSheet2Show(Sender: TObject);
var initFrameFunc: TInitFrameFunc;
begin
  if DllHandle1 <> 0 then begin
    @initFrameFunc := GetProcAddress(DllHandle1, 'InitFrame');
    if Assigned(initFrameFunc) then initFrameFunc(Application.Handle, TabSheet2.Handle)
    else
      ShowMessage('"InitFrame" function not found');
  end
  else begin
    ShowMessage('DLL not found / not loaded');
  end;
end;

procedure TForm1.TabSheet3Show(Sender: TObject);
begin
  //ShowMessage('Tab 3 Show');
end;

end.

DLL project file:

library DllFrame1;

uses Windows, Controls, SysUtils, Classes, Forms, Unit1 in 'Unit1.pas' {Frame1: TFrame};

{$R *.res}

function InitFrame(const ApplicationHandle, parentHandle: LongWord): LongWord; stdcall; export;
var
  Frame1: TFrame1;
  AppHandle: THandle;
begin
  AppHandle := Application.Handle;
  Application.Handle := ApplicationHandle;
  Frame1 := TFrame1.Create(Application);
  Frame1.ParentWindow := ParentHandle;
  SetParent(Frame1.Handle, ParentHandle);
  Frame1.Align := alClient;
  Frame1.Visible := True;
  ShowWindow(Frame1.Handle, SW_SHOWMAXIMIZED);
  Application.Handle := AppHandle;
  Result := Frame1.Handle;
end;

exports InitFrame;

begin
end.

A frame in DLL:

unit Unit1;

interface

uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TFrame1 = class(TFrame)
  private
  public
  end;

implementation

{$R *.dfm}

end.
Paul
  • 25,812
  • 38
  • 124
  • 247
  • 3
    When you don't use packages, executable and the library have distinct copies of VCL. Problems are expected. F.i. a class in one is not assignment compatible to the same class in the other. – Sertac Akyuz Dec 23 '16 at 21:08
  • 1
    This has been discussed very many times here. This is why packages exist. – David Heffernan Dec 23 '16 at 21:34
  • @David Heffernan: I want restrict developers in using packages because they are currently misused and the project became a messed heap. Secondly, I want the main app to detect DLL "plugins" automatically without recompiling. – Paul Dec 24 '16 at 17:34
  • @David Heffernan: Thirdly, I want to allow developers to make "plugins" in other programming languages too. – Paul Dec 24 '16 at 17:42
  • Then you'll need to develop a plugin framework. You can't do it this way. – David Heffernan Dec 24 '16 at 18:39

0 Answers0