Difference between revisions of "Form in DLL"
From Lazarus wiki
Jump to navigationJump to search (Created page with "The following application and library demonstrate you how to show a modal form from a DLL library. Tested on win32 with Lazarus 1.7 trunk. Main application: <syntaxhighlight>...") |
|||
Line 1: | Line 1: | ||
− | The following application and library demonstrate you how to show a modal form from a DLL library. Tested on win32 with Lazarus 1.7 trunk. | + | The following application and library demonstrate you how to show a modal and a non-modal form and create a custom component on application form from a DLL library. Tested on win32 with Lazarus 1.7 trunk. |
Main application: | Main application: | ||
Line 6: | Line 6: | ||
uses | uses | ||
− | Interfaces, Classes, LCLType, StdCtrls, Forms; | + | Interfaces, Classes, LCLType, Controls, StdCtrls, Forms, ExtCtrls; |
+ | type | ||
+ | TEnableDisableFormsCallBack = procedure(var FormList: Pointer); | ||
+ | TCreateButtonCallBack = procedure(Caption: PChar; OnClick: TProcedure); | ||
+ | |||
+ | procedure DLLDialog_Init(DisableFormsCallBack, EnableFormsCallback: TEnableDisableFormsCallBack); external 'DLLDialog.dll'; | ||
+ | procedure DLLDialog_Final; external 'DLLDialog.dll'; | ||
procedure DLLDialog_ShowModal(ParentWindow: HWND); external 'DLLDialog.dll'; | procedure DLLDialog_ShowModal(ParentWindow: HWND); external 'DLLDialog.dll'; | ||
+ | procedure DLLDialog_Show(ParentWindow: HWND); external 'DLLDialog.dll'; | ||
+ | procedure DLLDialog_CreateDLLButton(ParentWindow: HWND); external 'DLLDialog.dll'; | ||
+ | procedure DLLDialog_CreateButton(CreateButtonCallBack: TCreateButtonCallBack); external 'DLLDialog.dll'; | ||
type | type | ||
TMainForm = class(TForm) | TMainForm = class(TForm) | ||
+ | private | ||
+ | PnlParent: TPanel; | ||
+ | |||
+ | procedure BtnAddDLLButtonClick(Sender: TObject); | ||
+ | procedure BtnAddButtonClick(Sender: TObject); | ||
+ | procedure ShowModalDLLDialog(Sender: TObject); | ||
+ | procedure ShowDLLDialog(Sender: TObject); | ||
public | public | ||
constructor Create(aOwner: TComponent); override; | constructor Create(aOwner: TComponent); override; | ||
− | |||
end; | end; | ||
+ | |||
+ | var | ||
+ | MainForm: TMainForm; | ||
{ TMainForm } | { TMainForm } | ||
+ | |||
+ | procedure DisableFormsCallBack(var FormList: Pointer); | ||
+ | begin | ||
+ | FormList := Screen.DisableForms(nil, TList(FormList)); | ||
+ | end; | ||
+ | |||
+ | procedure EnableFormsCallback(var FormList: Pointer); | ||
+ | begin | ||
+ | Screen.EnableForms(TList(FormList)); | ||
+ | end; | ||
constructor TMainForm.Create(aOwner: TComponent); | constructor TMainForm.Create(aOwner: TComponent); | ||
var | var | ||
− | + | BtnShow, BtnShowModal, BtnAddDLLButton, BtnAddButton: TButton; | |
begin | begin | ||
inherited CreateNew(aOwner); | inherited CreateNew(aOwner); | ||
Position := poWorkAreaCenter; | Position := poWorkAreaCenter; | ||
− | Width := | + | Width := 600; |
Height := 200; | Height := 200; | ||
− | + | BtnShow := TButton.Create(Self); | |
− | + | BtnShow.Parent := Self; | |
− | + | BtnShow.Caption := 'Show form'; | |
− | + | BtnShow.AutoSize := True; | |
− | + | BtnShow.OnClick := @ShowDLLDialog; | |
+ | |||
+ | BtnShowModal := TButton.Create(Self); | ||
+ | BtnShowModal.Parent := Self; | ||
+ | BtnShowModal.Caption := 'Show modal form'; | ||
+ | BtnShowModal.AutoSize := True; | ||
+ | BtnShowModal.OnClick := @ShowModalDLLDialog; | ||
+ | BtnShowModal.AnchorSide[akLeft].Control := BtnShow; | ||
+ | BtnShowModal.AnchorSide[akLeft].Side := asrRight; | ||
+ | BtnShowModal.BorderSpacing.Left := 10; | ||
+ | |||
+ | BtnAddDLLButton := TButton.Create(Self); | ||
+ | BtnAddDLLButton.Parent := Self; | ||
+ | BtnAddDLLButton.Caption := 'Create real DLL button'; | ||
+ | BtnAddDLLButton.AutoSize := True; | ||
+ | BtnAddDLLButton.OnClick := @BtnAddDLLButtonClick; | ||
+ | BtnAddDLLButton.AnchorSide[akLeft].Control := BtnShowModal; | ||
+ | BtnAddDLLButton.AnchorSide[akLeft].Side := asrRight; | ||
+ | BtnAddDLLButton.BorderSpacing.Left := 10; | ||
+ | |||
+ | BtnAddButton := TButton.Create(Self); | ||
+ | BtnAddButton.Parent := Self; | ||
+ | BtnAddButton.Caption := 'Create fake DLL button'; | ||
+ | BtnAddButton.AutoSize := True; | ||
+ | BtnAddButton.OnClick := @BtnAddButtonClick; | ||
+ | BtnAddButton.AnchorSide[akLeft].Control := BtnAddDLLButton; | ||
+ | BtnAddButton.AnchorSide[akLeft].Side := asrRight; | ||
+ | BtnAddButton.BorderSpacing.Left := 10; | ||
+ | |||
+ | PnlParent := TPanel.Create(Self); | ||
+ | PnlParent.Parent := Self; | ||
+ | PnlParent.AnchorSide[akTop].Control := BtnShow; | ||
+ | PnlParent.AnchorSide[akTop].Side := asrBottom; | ||
+ | PnlParent.BorderSpacing.Top := 10; | ||
+ | PnlParent.Width := 220; | ||
end; | end; | ||
− | procedure | + | procedure CreateButtonCallBack(ACaption: PChar; AOnClick: TProcedure); |
var | var | ||
− | + | Btn: TButton; | |
+ | MyMethod: TMethod; | ||
+ | begin | ||
+ | Btn := TButton.Create(MainForm); | ||
+ | Btn.Caption := ACaption; | ||
+ | Btn.Left := 100; | ||
+ | Btn.Width := 100; | ||
+ | Btn.Height := 20; | ||
+ | MyMethod.Code := AOnClick; | ||
+ | MyMethod.Data := nil; | ||
+ | Btn.OnClick := TNotifyEvent(MyMethod); | ||
+ | Btn.Parent := MainForm.PnlParent; | ||
+ | end; | ||
+ | |||
+ | procedure TMainForm.BtnAddButtonClick(Sender: TObject); | ||
+ | begin | ||
+ | DLLDialog_CreateButton(@CreateButtonCallBack); | ||
+ | end; | ||
+ | |||
+ | procedure TMainForm.BtnAddDLLButtonClick(Sender: TObject); | ||
+ | begin | ||
+ | DLLDialog_CreateDLLButton(PnlParent.Handle); | ||
+ | end; | ||
+ | |||
+ | procedure TMainForm.ShowDLLDialog(Sender: TObject); | ||
begin | begin | ||
− | + | DLLDialog_Show(0); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end; | end; | ||
− | + | procedure TMainForm.ShowModalDLLDialog(Sender: TObject); | |
− | + | begin | |
+ | DLLDialog_ShowModal(Self.Handle); | ||
+ | end; | ||
{$R *.res} | {$R *.res} | ||
Line 60: | Line 139: | ||
Application.Initialize; | Application.Initialize; | ||
Application.CreateForm(TMainForm, MainForm); | Application.CreateForm(TMainForm, MainForm); | ||
− | Application.Run; | + | DLLDialog_Init(@DisableFormsCallBack, @EnableFormsCallback); |
+ | try | ||
+ | Application.Run; | ||
+ | finally | ||
+ | DLLDialog_Final; | ||
+ | end; | ||
end. | end. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 71: | Line 155: | ||
uses | uses | ||
− | Interfaces, Classes, LCLType, StdCtrls, Forms, Dialogs; | + | Interfaces, Classes, LCLType, StdCtrls, Controls, Forms, Dialogs; |
type | type | ||
Line 83: | Line 167: | ||
ParentFormHandle: HWND; | ParentFormHandle: HWND; | ||
end; | end; | ||
+ | |||
+ | TEnableDisableFormsCallBack = procedure(var FormList: Pointer); | ||
+ | TCreateButtonCallBack = procedure(Caption: PChar; OnClick: TProcedure); | ||
+ | |||
+ | TApplicationCallback = class(TComponent) | ||
+ | private | ||
+ | DisableFormsCallBack: TEnableDisableFormsCallBack; | ||
+ | EnableFormsCallback: TEnableDisableFormsCallBack; | ||
+ | FormList: Pointer; | ||
+ | public | ||
+ | procedure DisableForms(Sender: TObject); | ||
+ | procedure EnableForms(Sender: TObject); | ||
+ | procedure BtnClick(Sender: TObject); | ||
+ | |||
+ | constructor Create(aOwner: TComponent); override; | ||
+ | destructor Destroy; override; | ||
+ | end; | ||
+ | |||
+ | var | ||
+ | ApplicationCallback: TApplicationCallback; | ||
+ | |||
+ | procedure DLLDialog_Init(DisableFormsCallBack, EnableFormsCallback: TEnableDisableFormsCallBack); | ||
+ | begin | ||
+ | ApplicationCallback := TApplicationCallback.Create(nil); | ||
+ | ApplicationCallback.DisableFormsCallBack := DisableFormsCallBack; | ||
+ | ApplicationCallback.EnableFormsCallback := EnableFormsCallback; | ||
+ | end; | ||
+ | |||
+ | procedure DLLDialog_Final; | ||
+ | begin | ||
+ | ApplicationCallback.Free; | ||
+ | end; | ||
procedure DLLDialog_ShowModal(ParentWindow: HWND); | procedure DLLDialog_ShowModal(ParentWindow: HWND); | ||
Line 88: | Line 204: | ||
DLLDialog: TDLLDialog; | DLLDialog: TDLLDialog; | ||
begin | begin | ||
− | DLLDialog := TDLLDialog.Create( | + | DLLDialog := TDLLDialog.Create(ApplicationCallback); |
try | try | ||
DLLDialog.ParentFormHandle := ParentWindow; | DLLDialog.ParentFormHandle := ParentWindow; | ||
Line 95: | Line 211: | ||
DLLDialog.Free; | DLLDialog.Free; | ||
end; | end; | ||
+ | end; | ||
+ | |||
+ | procedure DLLDialog_Show(ParentWindow: HWND); | ||
+ | var | ||
+ | DLLDialog: TDLLDialog; | ||
+ | begin | ||
+ | DLLDialog := TDLLDialog.Create(ApplicationCallback); | ||
+ | DLLDialog.ParentFormHandle := ParentWindow; | ||
+ | DLLDialog.Show; | ||
+ | end; | ||
+ | |||
+ | procedure DLLDialog_CreateDLLButton(ParentWindow: HWND); | ||
+ | var | ||
+ | Btn: TButton; | ||
+ | BtnParentForm: TForm; | ||
+ | begin | ||
+ | BtnParentForm := TForm.CreateNew(ApplicationCallback); | ||
+ | BtnParentForm.ParentWindow := ParentWindow; | ||
+ | BtnParentForm.Width := 100; | ||
+ | BtnParentForm.Height := 20; | ||
+ | BtnParentForm.BorderStyle := bsNone; | ||
+ | BtnParentForm.Visible := True; | ||
+ | |||
+ | Btn := TButton.Create(ApplicationCallback); | ||
+ | Btn.Caption := 'Real DLL Button'; | ||
+ | Btn.Width := BtnParentForm.Width; | ||
+ | Btn.Height := BtnParentForm.Height; | ||
+ | Btn.OnClick := @ApplicationCallback.BtnClick; | ||
+ | Btn.Parent := BtnParentForm; | ||
+ | end; | ||
+ | |||
+ | procedure FakeBtnClick; | ||
+ | begin | ||
+ | ShowMessage('You clicked a fake button from a DLL!'); | ||
+ | end; | ||
+ | |||
+ | procedure DLLDialog_CreateButton(CreateButtonCallBack: TCreateButtonCallBack); | ||
+ | begin | ||
+ | CreateButtonCallBack('Fake DLL Button', @FakeBtnClick); | ||
end; | end; | ||
exports | exports | ||
− | DLLDialog_ShowModal; | + | DLLDialog_Init, DLLDialog_Final, DLLDialog_ShowModal, DLLDialog_Show, |
+ | DLLDialog_CreateButton, DLLDialog_CreateDLLButton; | ||
+ | |||
+ | { TApplicationCallback } | ||
+ | |||
+ | constructor TApplicationCallback.Create(aOwner: TComponent); | ||
+ | begin | ||
+ | inherited Create(aOwner); | ||
+ | |||
+ | Application.AddOnModalBeginHandler(@DisableForms); | ||
+ | Application.AddOnModalEndHandler(@EnableForms); | ||
+ | end; | ||
+ | |||
+ | procedure TApplicationCallback.BtnClick(Sender: TObject); | ||
+ | begin | ||
+ | ShowMessage('You clicked a real button from a DLL!'); | ||
+ | end; | ||
+ | |||
+ | destructor TApplicationCallback.Destroy; | ||
+ | begin | ||
+ | Application.RemoveOnModalBeginHandler(@DisableForms); | ||
+ | Application.RemoveOnModalEndHandler(@EnableForms); | ||
+ | |||
+ | inherited Destroy; | ||
+ | end; | ||
+ | |||
+ | procedure TApplicationCallback.DisableForms(Sender: TObject); | ||
+ | begin | ||
+ | DisableFormsCallBack(FormList); | ||
+ | end; | ||
+ | |||
+ | procedure TApplicationCallback.EnableForms(Sender: TObject); | ||
+ | begin | ||
+ | EnableFormsCallback(FormList); | ||
+ | end; | ||
{ TDLLDialog } | { TDLLDialog } |
Revision as of 23:52, 10 May 2016
The following application and library demonstrate you how to show a modal and a non-modal form and create a custom component on application form from a DLL library. Tested on win32 with Lazarus 1.7 trunk.
Main application:
program MainApp;
uses
Interfaces, Classes, LCLType, Controls, StdCtrls, Forms, ExtCtrls;
type
TEnableDisableFormsCallBack = procedure(var FormList: Pointer);
TCreateButtonCallBack = procedure(Caption: PChar; OnClick: TProcedure);
procedure DLLDialog_Init(DisableFormsCallBack, EnableFormsCallback: TEnableDisableFormsCallBack); external 'DLLDialog.dll';
procedure DLLDialog_Final; external 'DLLDialog.dll';
procedure DLLDialog_ShowModal(ParentWindow: HWND); external 'DLLDialog.dll';
procedure DLLDialog_Show(ParentWindow: HWND); external 'DLLDialog.dll';
procedure DLLDialog_CreateDLLButton(ParentWindow: HWND); external 'DLLDialog.dll';
procedure DLLDialog_CreateButton(CreateButtonCallBack: TCreateButtonCallBack); external 'DLLDialog.dll';
type
TMainForm = class(TForm)
private
PnlParent: TPanel;
procedure BtnAddDLLButtonClick(Sender: TObject);
procedure BtnAddButtonClick(Sender: TObject);
procedure ShowModalDLLDialog(Sender: TObject);
procedure ShowDLLDialog(Sender: TObject);
public
constructor Create(aOwner: TComponent); override;
end;
var
MainForm: TMainForm;
{ TMainForm }
procedure DisableFormsCallBack(var FormList: Pointer);
begin
FormList := Screen.DisableForms(nil, TList(FormList));
end;
procedure EnableFormsCallback(var FormList: Pointer);
begin
Screen.EnableForms(TList(FormList));
end;
constructor TMainForm.Create(aOwner: TComponent);
var
BtnShow, BtnShowModal, BtnAddDLLButton, BtnAddButton: TButton;
begin
inherited CreateNew(aOwner);
Position := poWorkAreaCenter;
Width := 600;
Height := 200;
BtnShow := TButton.Create(Self);
BtnShow.Parent := Self;
BtnShow.Caption := 'Show form';
BtnShow.AutoSize := True;
BtnShow.OnClick := @ShowDLLDialog;
BtnShowModal := TButton.Create(Self);
BtnShowModal.Parent := Self;
BtnShowModal.Caption := 'Show modal form';
BtnShowModal.AutoSize := True;
BtnShowModal.OnClick := @ShowModalDLLDialog;
BtnShowModal.AnchorSide[akLeft].Control := BtnShow;
BtnShowModal.AnchorSide[akLeft].Side := asrRight;
BtnShowModal.BorderSpacing.Left := 10;
BtnAddDLLButton := TButton.Create(Self);
BtnAddDLLButton.Parent := Self;
BtnAddDLLButton.Caption := 'Create real DLL button';
BtnAddDLLButton.AutoSize := True;
BtnAddDLLButton.OnClick := @BtnAddDLLButtonClick;
BtnAddDLLButton.AnchorSide[akLeft].Control := BtnShowModal;
BtnAddDLLButton.AnchorSide[akLeft].Side := asrRight;
BtnAddDLLButton.BorderSpacing.Left := 10;
BtnAddButton := TButton.Create(Self);
BtnAddButton.Parent := Self;
BtnAddButton.Caption := 'Create fake DLL button';
BtnAddButton.AutoSize := True;
BtnAddButton.OnClick := @BtnAddButtonClick;
BtnAddButton.AnchorSide[akLeft].Control := BtnAddDLLButton;
BtnAddButton.AnchorSide[akLeft].Side := asrRight;
BtnAddButton.BorderSpacing.Left := 10;
PnlParent := TPanel.Create(Self);
PnlParent.Parent := Self;
PnlParent.AnchorSide[akTop].Control := BtnShow;
PnlParent.AnchorSide[akTop].Side := asrBottom;
PnlParent.BorderSpacing.Top := 10;
PnlParent.Width := 220;
end;
procedure CreateButtonCallBack(ACaption: PChar; AOnClick: TProcedure);
var
Btn: TButton;
MyMethod: TMethod;
begin
Btn := TButton.Create(MainForm);
Btn.Caption := ACaption;
Btn.Left := 100;
Btn.Width := 100;
Btn.Height := 20;
MyMethod.Code := AOnClick;
MyMethod.Data := nil;
Btn.OnClick := TNotifyEvent(MyMethod);
Btn.Parent := MainForm.PnlParent;
end;
procedure TMainForm.BtnAddButtonClick(Sender: TObject);
begin
DLLDialog_CreateButton(@CreateButtonCallBack);
end;
procedure TMainForm.BtnAddDLLButtonClick(Sender: TObject);
begin
DLLDialog_CreateDLLButton(PnlParent.Handle);
end;
procedure TMainForm.ShowDLLDialog(Sender: TObject);
begin
DLLDialog_Show(0);
end;
procedure TMainForm.ShowModalDLLDialog(Sender: TObject);
begin
DLLDialog_ShowModal(Self.Handle);
end;
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
DLLDialog_Init(@DisableFormsCallBack, @EnableFormsCallback);
try
Application.Run;
finally
DLLDialog_Final;
end;
end.
DLL with a form:
library DllDialog;
{$mode objfpc}{$H+}
uses
Interfaces, Classes, LCLType, StdCtrls, Controls, Forms, Dialogs;
type
TDLLDialog = class(TForm)
protected
procedure CreateParams(var Params: TCreateParams); override;
public
procedure BtnShowMessageClick(Sender: TObject);
constructor Create(aOwner: TComponent); override;
public
ParentFormHandle: HWND;
end;
TEnableDisableFormsCallBack = procedure(var FormList: Pointer);
TCreateButtonCallBack = procedure(Caption: PChar; OnClick: TProcedure);
TApplicationCallback = class(TComponent)
private
DisableFormsCallBack: TEnableDisableFormsCallBack;
EnableFormsCallback: TEnableDisableFormsCallBack;
FormList: Pointer;
public
procedure DisableForms(Sender: TObject);
procedure EnableForms(Sender: TObject);
procedure BtnClick(Sender: TObject);
constructor Create(aOwner: TComponent); override;
destructor Destroy; override;
end;
var
ApplicationCallback: TApplicationCallback;
procedure DLLDialog_Init(DisableFormsCallBack, EnableFormsCallback: TEnableDisableFormsCallBack);
begin
ApplicationCallback := TApplicationCallback.Create(nil);
ApplicationCallback.DisableFormsCallBack := DisableFormsCallBack;
ApplicationCallback.EnableFormsCallback := EnableFormsCallback;
end;
procedure DLLDialog_Final;
begin
ApplicationCallback.Free;
end;
procedure DLLDialog_ShowModal(ParentWindow: HWND);
var
DLLDialog: TDLLDialog;
begin
DLLDialog := TDLLDialog.Create(ApplicationCallback);
try
DLLDialog.ParentFormHandle := ParentWindow;
DLLDialog.ShowModal;
finally
DLLDialog.Free;
end;
end;
procedure DLLDialog_Show(ParentWindow: HWND);
var
DLLDialog: TDLLDialog;
begin
DLLDialog := TDLLDialog.Create(ApplicationCallback);
DLLDialog.ParentFormHandle := ParentWindow;
DLLDialog.Show;
end;
procedure DLLDialog_CreateDLLButton(ParentWindow: HWND);
var
Btn: TButton;
BtnParentForm: TForm;
begin
BtnParentForm := TForm.CreateNew(ApplicationCallback);
BtnParentForm.ParentWindow := ParentWindow;
BtnParentForm.Width := 100;
BtnParentForm.Height := 20;
BtnParentForm.BorderStyle := bsNone;
BtnParentForm.Visible := True;
Btn := TButton.Create(ApplicationCallback);
Btn.Caption := 'Real DLL Button';
Btn.Width := BtnParentForm.Width;
Btn.Height := BtnParentForm.Height;
Btn.OnClick := @ApplicationCallback.BtnClick;
Btn.Parent := BtnParentForm;
end;
procedure FakeBtnClick;
begin
ShowMessage('You clicked a fake button from a DLL!');
end;
procedure DLLDialog_CreateButton(CreateButtonCallBack: TCreateButtonCallBack);
begin
CreateButtonCallBack('Fake DLL Button', @FakeBtnClick);
end;
exports
DLLDialog_Init, DLLDialog_Final, DLLDialog_ShowModal, DLLDialog_Show,
DLLDialog_CreateButton, DLLDialog_CreateDLLButton;
{ TApplicationCallback }
constructor TApplicationCallback.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
Application.AddOnModalBeginHandler(@DisableForms);
Application.AddOnModalEndHandler(@EnableForms);
end;
procedure TApplicationCallback.BtnClick(Sender: TObject);
begin
ShowMessage('You clicked a real button from a DLL!');
end;
destructor TApplicationCallback.Destroy;
begin
Application.RemoveOnModalBeginHandler(@DisableForms);
Application.RemoveOnModalEndHandler(@EnableForms);
inherited Destroy;
end;
procedure TApplicationCallback.DisableForms(Sender: TObject);
begin
DisableFormsCallBack(FormList);
end;
procedure TApplicationCallback.EnableForms(Sender: TObject);
begin
EnableFormsCallback(FormList);
end;
{ TDLLDialog }
constructor TDLLDialog.Create(aOwner: TComponent);
var
BtnShowMessage: TButton;
begin
inherited CreateNew(aOwner);
Caption := 'This form is in a DLL !!!';
Position := poWorkAreaCenter;
Width := 200;
Height := 100;
BtnShowMessage := TButton.Create(Self);
BtnShowMessage.Parent := Self;
BtnShowMessage.Caption := 'Show message';
BtnShowMessage.AutoSize := True;
BtnShowMessage.OnClick := @BtnShowMessageClick;
end;
procedure TDLLDialog.BtnShowMessageClick(Sender: TObject);
begin
ShowMessage('Hello from DLL!');
end;
procedure TDLLDialog.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.WndParent := ParentFormHandle;
end;
begin
Application.Initialize;
end.