我的问题如下,
有一个MDI应用Exe,动态调用MDI子窗体DLL,这个子窗体继承某个窗体基类。
当不使用delphi IDE的可视化继承,而仅仅只是改写代码,那么主窗体可以正常装载这个DLL。
但是,使用可是化继承,即子类窗体上有了基类上的所有控件后,程序代码不变。重新编译,
那么Exe就无法装载这个DLL了。
十万火急,大虾出手主Exe
unit FormMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;type
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
ChildDLL1: TMenuItem;
Close1: TMenuItem;
procedure ChildDLL1Click(Sender: TObject);
procedure Close1Click(Sender: TObject);
private
{ Private declarations }
lib : THandle;
public
{ Public declarations }
end;var
frmMain: TfrmMain;implementation{$R *.dfm}procedure TfrmMain.ChildDLL1Click(Sender: TObject);
var
p : procedure(App : TApplication; Scr : TScreen);
begin
lib := SafeLoadLibrary('ChildDLL.dll');
if lib > 0 then
begin
@p := GetProcAddress(lib, 'ShowForm');
if @p <> nil then
p(Application, Screen);
end;
end;procedure TfrmMain.Close1Click(Sender: TObject);
begin
if lib > 0 then
begin
FreeLibrary(lib);
lib := 0;
end;
end;end.基类
unit FormBase;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;type
TfrmBase = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Edit1: TEdit;
private
{ Private declarations }
public
{ Public declarations }
end;var
frmBase: TfrmBase;implementation{$R *.dfm}end.子窗体DLL工程
library ChildDLL;uses
SysUtils,
Classes,
Windows,
Forms,
FormChild in 'FormChild.pas' {frmChild},
FormBase in 'FormBase.pas' {frmBase};{$R *.res}var
OldApp : TApplication;
OldScreen : TScreen;procedure Entry(Reason : Integer);
begin
if Reason = DLL_PROCESS_ATTACH then
begin
OldApp := Application;
OldScreen := Screen;
end;
if Reason = DLL_PROCESS_DETACH then
begin
Application := OldApp;
Screen := OldScreen;
end;
end;exports
ShowForm;
begin
DLLProc := @Entry;
Entry(DLL_PROCESS_ATTACH);
end.
unit FormChild;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FormBase;type
TfrmChild = class(TfrmBase)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
lbl : TLabel;
public
constructor Create(AOwner : TComponent); override;
end;procedure ShowForm(App : TApplication; Scr : TScreen);implementation{$R *.dfm}var
frmChild: TfrmChild;procedure ShowForm(App : TApplication; Scr : TScreen);
begin
Application := App;
Screen := Scr;
frmChild := TfrmChild.Create(App);
frmChild.Align := alClient;
frmChild.Show;
end;
constructor TfrmChild.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
lbl := TLabel.Create(self);
lbl.Parent := Panel2;
lbl.SetBounds(10, 10, 10, 10);
lbl.Caption := 'from frmChild';
end;
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Sender := nil;
end;end.
有一个MDI应用Exe,动态调用MDI子窗体DLL,这个子窗体继承某个窗体基类。
当不使用delphi IDE的可视化继承,而仅仅只是改写代码,那么主窗体可以正常装载这个DLL。
但是,使用可是化继承,即子类窗体上有了基类上的所有控件后,程序代码不变。重新编译,
那么Exe就无法装载这个DLL了。
十万火急,大虾出手主Exe
unit FormMain;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus;type
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
ChildDLL1: TMenuItem;
Close1: TMenuItem;
procedure ChildDLL1Click(Sender: TObject);
procedure Close1Click(Sender: TObject);
private
{ Private declarations }
lib : THandle;
public
{ Public declarations }
end;var
frmMain: TfrmMain;implementation{$R *.dfm}procedure TfrmMain.ChildDLL1Click(Sender: TObject);
var
p : procedure(App : TApplication; Scr : TScreen);
begin
lib := SafeLoadLibrary('ChildDLL.dll');
if lib > 0 then
begin
@p := GetProcAddress(lib, 'ShowForm');
if @p <> nil then
p(Application, Screen);
end;
end;procedure TfrmMain.Close1Click(Sender: TObject);
begin
if lib > 0 then
begin
FreeLibrary(lib);
lib := 0;
end;
end;end.基类
unit FormBase;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;type
TfrmBase = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Edit1: TEdit;
private
{ Private declarations }
public
{ Public declarations }
end;var
frmBase: TfrmBase;implementation{$R *.dfm}end.子窗体DLL工程
library ChildDLL;uses
SysUtils,
Classes,
Windows,
Forms,
FormChild in 'FormChild.pas' {frmChild},
FormBase in 'FormBase.pas' {frmBase};{$R *.res}var
OldApp : TApplication;
OldScreen : TScreen;procedure Entry(Reason : Integer);
begin
if Reason = DLL_PROCESS_ATTACH then
begin
OldApp := Application;
OldScreen := Screen;
end;
if Reason = DLL_PROCESS_DETACH then
begin
Application := OldApp;
Screen := OldScreen;
end;
end;exports
ShowForm;
begin
DLLProc := @Entry;
Entry(DLL_PROCESS_ATTACH);
end.
unit FormChild;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FormBase;type
TfrmChild = class(TfrmBase)
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
lbl : TLabel;
public
constructor Create(AOwner : TComponent); override;
end;procedure ShowForm(App : TApplication; Scr : TScreen);implementation{$R *.dfm}var
frmChild: TfrmChild;procedure ShowForm(App : TApplication; Scr : TScreen);
begin
Application := App;
Screen := Scr;
frmChild := TfrmChild.Create(App);
frmChild.Align := alClient;
frmChild.Show;
end;
constructor TfrmChild.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
lbl := TLabel.Create(self);
lbl.Parent := Panel2;
lbl.SetBounds(10, 10, 10, 10);
lbl.Caption := 'from frmChild';
end;
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Sender := nil;
end;end.
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货