f3ka Цитата: почему
Просто скопировал с примера, работает или нет не проверял.
[more=Пример]
Код: unit DLLMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids, DBGrids, Db, MemDS, StdCtrls, ExtCtrls, DBCtrls, DBAccess,
MSAccess;
type
TfmDllMain = class(TForm)
MSQuery: TMSQuery;
DBGrid: TDBGrid;
DataSource: TDataSource;
pnToolBar: TPanel;
btOpen: TButton;
btClose: TButton;
DBNavigator: TDBNavigator;
procedure btOpenClick(Sender: TObject);
procedure btCloseClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure AssignConnection(MSConnection: TMSConnection); cdecl;
procedure ShowForm; cdecl;
procedure HideForms; cdecl;
implementation
{$R *.DFM}
var
ExternalMSConnection: TMSConnection;
FormList: TList;
FormCount: integer;
procedure AssignConnection(MSConnection: TMSConnection); cdecl;
begin
ExternalMSConnection:= MSConnection;
end;
procedure ShowForm; cdecl;
begin
with TfmDllMain.Create(Application) do begin
Inc(FormCount);
Caption:= IntToStr(FormCount) + '. ' + Caption;
MSQuery.Connection := ExternalMSConnection;
MSQuery.Active := True;
Show;
end;
end;
procedure HideForms; cdecl;
begin
while FormList.Count > 0 do begin
TForm(FormList[0]).Free;
FormList.Delete(0);
end;
end;
procedure TfmDllMain.FormShow(Sender: TObject);
begin
FormList.Add(Self);
end;
procedure TfmDllMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FormList.Remove(Self);
Action := caFree;
end;
procedure TfmDllMain.btOpenClick(Sender: TObject);
begin
MSQuery.Open;
end;
procedure TfmDllMain.btCloseClick(Sender: TObject);
begin
MSQuery.Close;
end;
initialization
FormCount:= 0;
FormList:= TList.Create;
finalization
HideForms;
FormList.Free;
end.
unit ExeMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Grids, DBGrids, Db, MemDS, DBCtrls, DBAccess, SdacVcl,
MSAccess;
type
TfmExeMain = class(TForm)
MSConnection: TMSConnection;
MSConnectDialog: TMSConnectDialog;
pnToolBar: TPanel;
btLoadDLL: TButton;
btFreeDLL: TButton;
DBGrid: TDBGrid;
btConnect: TButton;
btDisconnect: TButton;
btOpen: TButton;
btClose: TButton;
MSQuery: TMSQuery;
DBNavigator: TDBNavigator;
DataSource: TDataSource;
btShowForm: TButton;
btHideForms: TButton;
procedure btLoadDLLClick(Sender: TObject);
procedure btFreeDLLClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btConnectClick(Sender: TObject);
procedure btDisconnectClick(Sender: TObject);
procedure btOpenClick(Sender: TObject);
procedure btCloseClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btShowFormClick(Sender: TObject);
procedure btHideFormsClick(Sender: TObject);
private
hDLL:HModule;
public
end;
TAssignMSConnection = procedure (MSConnection: TMSConnection); cdecl;
TShowForm = procedure; cdecl;
THideForms = procedure; cdecl;
var
fmExeMain: TfmExeMain;
implementation
{$R *.DFM}
procedure TfmExeMain.btLoadDLLClick(Sender: TObject);
var
AssignMSConnection: TAssignMSConnection;
begin
if hDLL = 0 then begin
hDLL := LoadLibrary('MS_DLL.dll');
if hDLL <> 0 then begin
@AssignMSConnection := GetProcAddress(hDLL, 'AssignConnection');
if @AssignMSConnection <> nil then
AssignMSConnection(MSConnection);
MessageDlg('DLL is loaded', mtInformation, [mbOk], 0);
end
else
MessageDlg('Cannot load DLL', mtError, [mbOk], 0);
end;
end;
procedure TfmExeMain.btShowFormClick(Sender: TObject);
var
ShowForm: TShowForm;
begin
if hDLL <> 0 then begin
@ShowForm := GetProcAddress(hDLL, 'ShowForm');
if @ShowForm <> nil then
ShowForm;
SetFocus;
end
else
MessageDlg('DLL is not loaded', mtError, [mbOk], 0);
end;
procedure TfmExeMain.btHideFormsClick(Sender: TObject);
var
HideForms: THideForms;
begin
if hDLL <> 0 then begin
@HideForms := GetProcAddress(hDLL, 'HideForms');
if @HideForms <> nil then
HideForms;
end
else
MessageDlg('DLL is not loaded', mtError, [mbOk], 0);
end;
procedure TfmExeMain.btFreeDLLClick(Sender: TObject);
begin
if hDLL <> 0 then begin
FreeLibrary(hDLL);
hDLL:= 0;
end
else
MessageDlg('DLL is not loaded', mtError, [mbOk], 0);
end;
procedure TfmExeMain.FormCreate(Sender: TObject);
begin
hDLL:= 0;
end;
procedure TfmExeMain.btConnectClick(Sender: TObject);
begin
MSConnection.Connect;
end;
procedure TfmExeMain.btDisconnectClick(Sender: TObject);
begin
MSConnection.Disconnect;
end;
procedure TfmExeMain.btOpenClick(Sender: TObject);
begin
MSQuery.Open;
end;
procedure TfmExeMain.btCloseClick(Sender: TObject);
begin
MSQuery.Close;
end;
procedure TfmExeMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if hDLL <> 0 then
FreeLibrary(hDLL);
end;
end.
library MS_DLL;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
ShareMem,
SysUtils,
Classes,
DLLMain in 'DLLMain.pas' {fmDllMain};
exports
AssignConnection,
ShowForm,
HideForms;
var
SaveExit: pointer;
procedure DllExit;
begin
ExitProc := SaveExit;
end;
begin
// SaveExit := ExitProc;
// ExitProc := @DllExit;
end.
program MS_Exe;
uses
ShareMem,
Forms,
ExeMain in 'ExeMain.pas' {fmExeMain};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TfmExeMain, fmExeMain);
Application.Run;
end.