我的代码如下:
//-------------- 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;interfaceuses
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;interfaceuses
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这段代码,但在主窗体退出时会报地址错误,如果不要那段代码,子窗体只能最小化,不能关闭,请问各位高手,怎样才能既关闭子窗体,又能不报错呢?
解决方案 »
- Delphi2007里面 怎样添加socket控件?
- 问一个奇怪的问题。
- 急~~~~从字符串中取整数的问题~~~~各位帮帮忙~
- 一个简单的语法问题,谢谢!
- Delphi中如何制作系统托盘程序?
- winexec()运行一段DOS程序,如何怎样让它执行完再继续往下执行?
- 如何使image中的图片淡入淡出?如何使用trackbar拖到指定位置播放?
- 关于录音软件的开发问题
- 急socket 10060求救
- fastreport4.9编译的DLL无法在win7下运行
- 关于topgrid下拉筐属性的cell,如何动态导入数据???
- ⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙新手必看⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙⊙
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScreen;
FreeAndNil(TheForm); //问题应该在这里,在你的子窗体OnClose中加上TheForm=nil SendMessage(Application.Handle, WM_CLOSE, 0, 0);
FreeLibrary(Application.Handle);
end;
end;