Board index » delphi » Calling a function in main app from a DLL

Calling a function in main app from a DLL

I need to write a DLL that will show a modeless form with a listbox, and
trigger a function in the calling application when each time an item in
the listbox is selected. I know how to set up the modeless form and how
to query which item is selected through a function exported from the DLL
- but I cant see how to get the next step - i.e. triggering a function
in the calling application each time the selected item is changed. I
don't know whether it can even be done, but I'd be grateful for any
advice. (The DLL would be for use with a non-Delphi application -
actually one written in Mapbasic).

Happy New Year!

Alan Hale

 

Re:Calling a function in main app from a DLL


It is possible.
Basically you just call a procedure in your DLL, passing the address in a
pointer as a parameter to your call-back function.
Now the DLL knows what adress to call and can do so when needed.

Look in the help under "pointers, procedure and method".

Finn Tolderlund

Alan Hale <adh...@clara.net> skrev i en
nyhedsmeddelelse:386E6C85.A8FDE...@clara.net...

Quote
> I need to write a DLL that will show a modeless form with a listbox, and
> trigger a function in the calling application when each time an item in
> the listbox is selected. I know how to set up the modeless form and how
> to query which item is selected through a function exported from the DLL
> - but I cant see how to get the next step - i.e. triggering a function
> in the calling application each time the selected item is changed. I
> don't know whether it can even be done, but I'd be grateful for any
> advice. (The DLL would be for use with a non-Delphi application -
> actually one written in Mapbasic).

> Happy New Year!

> Alan Hale

Re:Calling a function in main app from a DLL


Finn

Many thanks for your reply on this. However, I still have problems
understanding what to do. I have looked at the Help file you suggest and also
looked at an example on callbacks in Delphi Developer's Guide, but this
example does not use a form in the DLL.

I can see (I think!)  how one would pass a pointer as a parameter in the
function I use to create the form. How can you refer to this from the OnClick
event of a Listbox in the form however?

This is new territory for me so any further help you (ora nynoe) can offer
would be most welcome.

Many thanks.

Alan Hale

Quote
Finn Tolderlund wrote:
> It is possible.
> Basically you just call a procedure in your DLL, passing the address in a
> pointer as a parameter to your call-back function.
> Now the DLL knows what adress to call and can do so when needed.

> Look in the help under "pointers, procedure and method".

> Finn Tolderlund

> Alan Hale <adh...@clara.net> skrev i en
> nyhedsmeddelelse:386E6C85.A8FDE...@clara.net...
> > I need to write a DLL that will show a modeless form with a listbox, and
> > trigger a function in the calling application when each time an item in
> > the listbox is selected. I know how to set up the modeless form and how
> > to query which item is selected through a function exported from the DLL
> > - but I cant see how to get the next step - i.e. triggering a function
> > in the calling application each time the selected item is changed. I
> > don't know whether it can even be done, but I'd be grateful for any
> > advice. (The DLL would be for use with a non-Delphi application -
> > actually one written in Mapbasic).

> > Happy New Year!

> > Alan Hale

Re:Calling a function in main app from a DLL


Alan Hale <adh...@clara.net> skrev i en
nyhedsmeddelelse:386F92FA.520F6...@clara.net...

Quote
> Many thanks for your reply on this. However, I still have problems
> understanding what to do. I have looked at the Help file you suggest and
also
> looked at an example on callbacks in Delphi Developer's Guide, but this
> example does not use a form in the DLL.

Doing it from a DLL is no different from doing it from anywhere else.
Anyway, I have cooked up a simple example for you using a form in a DLL.

Have fun with it.

Finn Tolderlund

Project1:
=====Project1.dpr=====
program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas';

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
==========

=====Unit1.pas=====
unit Unit1;

interface

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

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

var
  Form1: TForm1;

procedure Callback(Number: Integer);

implementation

{$R *.DFM}

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetCallbackProcedure(@Callback);
  VisDllFormModal;
end;

procedure Callback(Number: Integer);
begin
  Form1.Edit1.Text := IntToStr(Number);
end;

end.
==========

=====Unit2.pas=====
unit Unit2;

interface

uses
  Windows, Forms;

const
  DLLname = 'DLL1.dll';

procedure VisDllFormModal;
procedure SetCallbackProcedure(Address: pointer);

type
  TVisForm = procedure ; stdcall;
  TSetCallbackProcedure = procedure (CallbackAddress: pointer); stdcall;

var
  DllHandle: THandle;

implementation

procedure VisDllFormModal;
var
  VisForm: TVisForm;
begin
  if DllHandle = 0 then
    DllHandle := LoadLibrary(Dllname);
  if DllHandle <> 0 then
  begin
    @VisForm := GetProcAddress(DllHandle, 'VisFormModal');
    if @VisForm <> nil then
      VisForm;
//    FreeLibrary(DllHandle);
//    DllHandle := 0;
  end;
end;

procedure SetCallbackProcedure(Address: pointer);
var
  SetCallbackProcedure: TSetCallbackProcedure;
begin
  if DllHandle = 0 then
    DllHandle := LoadLibrary(Dllname);
  if DllHandle <> 0 then
  begin
    @SetCallbackProcedure := GetProcAddress(DllHandle,
'SetCallbackProcedure');
    if @SetCallbackProcedure <> nil then
      SetCallbackProcedure(Address);
  end;
end;

initialization
  DllHandle := 0;
finalization
  if DllHandle <> 0 then
    FreeLibrary(DllHandle);
end.
==========

DLL:
=====DLL1.dpr=====
library DLL1;

uses
  SysUtils,
  Classes,
  DllUnit1 in 'DllUnit1.pas' {DllForm1};

{$R *.RES}

begin
end.
==========

=====DllUnit1.pas=====
unit DllUnit1;

interface

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

type
  TDllForm1 = class(TForm)
    Edit1: TEdit;
    Callback_Button: TButton;
    procedure Callback_ButtonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ModalForm: TDLLForm1;
  CallbackProcedure: procedure(Number: Integer);

procedure VisFormModal; stdcall;
procedure SetCallbackProcedure(CallbackAddress: pointer); stdcall;

exports
  VisFormModal,
  SetCallbackProcedure;

implementation

{$R *.DFM}

procedure VisFormModal; stdcall;
begin
  try
    ModalForm := TDllForm1.Create(Application);
    try
      ModalForm.ShowModal;
    finally
      FreeAndNil(ModalForm);
    end;
  except
    on E: Exception do
      Application.HandleException(E);
  end;
end;

procedure TDllForm1.Callback_ButtonClick(Sender: TObject);
begin
  if Assigned(CallbackProcedure) then
    CallbackProcedure(StrToIntDef(Edit1.Text, 0));
end;

procedure SetCallbackProcedure(CallbackAddress: pointer); stdcall;
begin
  CallbackProcedure := CallbackAddress;
end;

initialization
  CallbackProcedure := nil;
finalization
end.
==========

Re:Calling a function in main app from a DLL


Im Artikel <386E6C85.A8FDE...@clara.net>, Alan Hale <adh...@clara.net>
schreibt:

Quote
>The DLL would be for use with a non-Delphi application -
>actually one written in Mapbasic

If that language supports callback functions, then pass an appropriate callback
function to the DLL. If not ... :-(

DoDi

Re:Calling a function in main app from a DLL


The most reliable way is to place the procedure to be called back to
in a com object within the app then anything can call it.
But it took a few weeks of screaming and tearing my hair out to
work it all out.
It does work perfectly though.
Nick
Quote
Alan Hale wrote:

> I need to write a DLL that will show a modeless form with a listbox, and
> trigger a function in the calling application when each time an item in
> the listbox is selected. I know how to set up the modeless form and how
> to query which item is selected through a function exported from the DLL
> - but I cant see how to get the next step - i.e. triggering a function
> in the calling application each time the selected item is changed. I
> don't know whether it can even be done, but I'd be grateful for any
> advice. (The DLL would be for use with a non-Delphi application -
> actually one written in Mapbasic).

> Happy New Year!

> Alan Hale

Other Threads