S
shunbing
Unregistered / Unconfirmed
GUEST, unregistred user!
我的代码如下:
//-------------- Library begin -----------------
library DLLForm;
{ 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
Windows,
SysUtils,
Classes,
Forms,
dialogs,
Messages,
Help in 'Help.pas' {FrmHelp}; //MDIChild窗体
var
DLLAPP: TApplication;
DLLScreen: TScreen;
TheForm: TForm;
TheClass: TPersistentClass;
{$R *.res}
procedure RunDLL(DLLName, FormName, FormCaption: String; APP: TApplication; SC: TScreen) stdcall;
begin
Application := App;
Screen := SC;
RegisterClasses([TFrmHelp]);
TheClass := GetClass(PChar('T' + FormName));
if (TheClass <> nil) and TheClass.InheritsFrom(TForm) then
begin
TheForm := TForm(TheClass.Create).Create(nil);
TheForm.Show;
end;
end;
procedure DLLUnLoadProc(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScreen;
FreeAndNil(TheForm);
SendMessage(Application.Handle, WM_CLOSE, 0, 0);
FreeLibrary(Application.Handle);
end;
end;
exports
RunDLL;
begin
DLLAPP := Application;
DLLScreen := Screen;
DLLProc := @DLLUnLoadProc;
end.
//---------------------- Library end ----------------
//---------------------- UNIT begin ----------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;
const
WM_WXBFREE =WM_USER+1982;
type
TDLLMainForm = class(TForm)
MainMenu1: TMainMenu;
DLL1: TMenuItem;
DLL2: TMenuItem;
procedure DLL2Click(Sender: TObject);
private
procedure wxbFreeLib(var Message: TMessage) ; message WM_WXBFREE;
{ Private declarations }
public
{ Public declarations }
end;
Type
TRunDLL = procedure(DLLName, FormName,FormCaption: String; Application: TApplication; Screen: TScreen); stdcall;
procedure RunDLLForm(DLLName, FormName,FormCaption: String; App: TApplication; SC: TScreen); stdcall;
var
GetDLLHWND: HWND;
DLLMainForm: TDLLMainForm;
implementation
{$R *.dfm}
procedure RunDLLForm(DLLName, FormName,FormCaption: String; App: TApplication; SC: TScreen); stdcall;
var
RunDLL: TRunDLL;
begin
GetDLLHWND := LoadLibrary(PChar(DLLName));
if GetDLLHWND < 32 then
begin
MessageBox(0, PChar('未找到DLL'), PChar('加载DLL失败'), MB_OK);
Exit;
end;
@RunDLL := GetProcAddress(GetDLLHWND, PChar('RunDLL'));
if @RunDLL <> nil then
begin
Try
RunDLL(PChar(UpperCase(Trim(DLLName))), PChar(UpperCase(Trim(FormName))),PChar(FormCaption), APP, SC);
Except
Raise Exception.Create('T' + FormName + '不存在');
End;
end;
end;
procedure TDLLMainForm.DLL2Click(Sender: TObject);
begin
RunDLLForm('DLLForm', 'FrmHelp', 'FrmHelp', Application, Screen)
end;
end.
//------------------ UNIT end ----------------
现在子窗体能够打开,也能够关闭,因为子窗体的onClose事件加了action := caFree这段代码,但在主窗体退出时会报地址错误,如果不要那段代码,子窗体只能最小化,不能关闭,请问各位高手,怎样才能既关闭子窗体,又能不报错呢?
//-------------- Library begin -----------------
library DLLForm;
{ 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
Windows,
SysUtils,
Classes,
Forms,
dialogs,
Messages,
Help in 'Help.pas' {FrmHelp}; //MDIChild窗体
var
DLLAPP: TApplication;
DLLScreen: TScreen;
TheForm: TForm;
TheClass: TPersistentClass;
{$R *.res}
procedure RunDLL(DLLName, FormName, FormCaption: String; APP: TApplication; SC: TScreen) stdcall;
begin
Application := App;
Screen := SC;
RegisterClasses([TFrmHelp]);
TheClass := GetClass(PChar('T' + FormName));
if (TheClass <> nil) and TheClass.InheritsFrom(TForm) then
begin
TheForm := TForm(TheClass.Create).Create(nil);
TheForm.Show;
end;
end;
procedure DLLUnLoadProc(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScreen;
FreeAndNil(TheForm);
SendMessage(Application.Handle, WM_CLOSE, 0, 0);
FreeLibrary(Application.Handle);
end;
end;
exports
RunDLL;
begin
DLLAPP := Application;
DLLScreen := Screen;
DLLProc := @DLLUnLoadProc;
end.
//---------------------- Library end ----------------
//---------------------- UNIT begin ----------------
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;
const
WM_WXBFREE =WM_USER+1982;
type
TDLLMainForm = class(TForm)
MainMenu1: TMainMenu;
DLL1: TMenuItem;
DLL2: TMenuItem;
procedure DLL2Click(Sender: TObject);
private
procedure wxbFreeLib(var Message: TMessage) ; message WM_WXBFREE;
{ Private declarations }
public
{ Public declarations }
end;
Type
TRunDLL = procedure(DLLName, FormName,FormCaption: String; Application: TApplication; Screen: TScreen); stdcall;
procedure RunDLLForm(DLLName, FormName,FormCaption: String; App: TApplication; SC: TScreen); stdcall;
var
GetDLLHWND: HWND;
DLLMainForm: TDLLMainForm;
implementation
{$R *.dfm}
procedure RunDLLForm(DLLName, FormName,FormCaption: String; App: TApplication; SC: TScreen); stdcall;
var
RunDLL: TRunDLL;
begin
GetDLLHWND := LoadLibrary(PChar(DLLName));
if GetDLLHWND < 32 then
begin
MessageBox(0, PChar('未找到DLL'), PChar('加载DLL失败'), MB_OK);
Exit;
end;
@RunDLL := GetProcAddress(GetDLLHWND, PChar('RunDLL'));
if @RunDLL <> nil then
begin
Try
RunDLL(PChar(UpperCase(Trim(DLLName))), PChar(UpperCase(Trim(FormName))),PChar(FormCaption), APP, SC);
Except
Raise Exception.Create('T' + FormName + '不存在');
End;
end;
end;
procedure TDLLMainForm.DLL2Click(Sender: TObject);
begin
RunDLLForm('DLLForm', 'FrmHelp', 'FrmHelp', Application, Screen)
end;
end.
//------------------ UNIT end ----------------
现在子窗体能够打开,也能够关闭,因为子窗体的onClose事件加了action := caFree这段代码,但在主窗体退出时会报地址错误,如果不要那段代码,子窗体只能最小化,不能关闭,请问各位高手,怎样才能既关闭子窗体,又能不报错呢?