关于动态调用dll 中的非模式窗体的问题?
----DLL 工程文件--
library BOMI01;uses
SysUtils,
Forms,
Windows,
Messages,
Classes,
uBOMI01 in 'uBOMI01.pas' {frmBom};{$R *.res}
var
DLLApp: TApplication;
DLLScr: TScreen;function CreateForm(App: TApplication; Scr: TScreen):TForm;
begin
Application := App;
Screen := Scr;
Application.CreateForm(TfrmBom, frmBom);
result:=frmBom;
end;procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;exports
CreateForm;begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL;
end.
--- dll 中的 窗体单元---
unit uBOMI01;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;type
TfrmBom = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;var
frmBom: TfrmBom;implementation{$R *.dfm}end.
--调用的主窗体单元
unit uMainFrm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin;type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TfrmMain = class(TForm)
StatusBar1: TStatusBar;
CoolBar1: TCoolBar;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
procedure ToolButton1Click(Sender: TObject);
private
procedure LoadDllForm(DllName: string);
public
{ Public declarations }
end;var
frmMain: TfrmMain;
DLLForm: TForm;
implementation{$R *.dfm}
procedure TfrmMain.LoadDllForm(DllName: string);
var
dllhandle: THandle;
Dllsub: InvokeDLLForm;
begin
dllhandle := loadlibrary('BOMI01.dll');
if dllhandle <> 0 then
begin
@dllsub := GetProcAddress(dllhandle,'CreateForm');
if Assigned(Dllsub) then
DLLForm := Dllsub(application,screen) ;
//dllform.Show;-- 问题点???
end;
end;procedure TfrmMain.ToolButton1Click(Sender: TObject);
begin
LoadDllForm('BOMI01.dll')
end;
end.问题: 因为是初学DLL ,所以上属代码是简单的抄别人的代码,不知为何别的人代码在调用时不需要在调用的地主加上dllform.show ,就能正常运行,而我的不加dllform.show 就不法显示dll 中的窗体,而且我加上dllform.show 后,dll 中的窗体能显示出来,
但在关闭了dll 中的窗体后,再关闭调用的主程序,会报内存地址错误!
--别人的代码如下:
library prjDLL;uses
SysUtils,
Forms,
Windows,
Messages,
Classes,
DLLFormUnit in 'DLLFormUnit.pas' {frmDLLFrm};{$R *.res}var
DLLApp: TApplication;
DLLScr: TScreen;
function CreateDLLForm(App: TApplication; Scr: TScreen):TForm;
begin
Application := App;
Screen := Scr;
Application.CreateForm(TfrmDLLFrm, frmDLLFrm);
result:=frmDLLFrm;
end;procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;
exports
CreateDLLForm;begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL;
end.
------------
unit MainUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, DB, ADODB, Grids, StdCtrls;type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
M_Invoke: TMenuItem;
mi_inDLL: TMenuItem;
mi_inGeneral: TMenuItem;
m_Windows: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
procedure mi_inDLLClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
frmMain: TfrmMain;
DLLForm: TForm;
implementationuses GeneralFormUnit, AboutUnit;{$R *.dfm}procedure TfrmMain.mi_inDLLClick(Sender: TObject);
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
begin
DLLHandle := LoadLibrary('prjDLL.dll');
if DLLHandle <> 0 then
begin
@DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
if Assigned(DLLSub) then
begin
DLLForm := DLLSub(Application, Screen);
end;
end;
end;end.
----DLL 工程文件--
library BOMI01;uses
SysUtils,
Forms,
Windows,
Messages,
Classes,
uBOMI01 in 'uBOMI01.pas' {frmBom};{$R *.res}
var
DLLApp: TApplication;
DLLScr: TScreen;function CreateForm(App: TApplication; Scr: TScreen):TForm;
begin
Application := App;
Screen := Scr;
Application.CreateForm(TfrmBom, frmBom);
result:=frmBom;
end;procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;exports
CreateForm;begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL;
end.
--- dll 中的 窗体单元---
unit uBOMI01;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;type
TfrmBom = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;var
frmBom: TfrmBom;implementation{$R *.dfm}end.
--调用的主窗体单元
unit uMainFrm;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, ToolWin;type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TfrmMain = class(TForm)
StatusBar1: TStatusBar;
CoolBar1: TCoolBar;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
procedure ToolButton1Click(Sender: TObject);
private
procedure LoadDllForm(DllName: string);
public
{ Public declarations }
end;var
frmMain: TfrmMain;
DLLForm: TForm;
implementation{$R *.dfm}
procedure TfrmMain.LoadDllForm(DllName: string);
var
dllhandle: THandle;
Dllsub: InvokeDLLForm;
begin
dllhandle := loadlibrary('BOMI01.dll');
if dllhandle <> 0 then
begin
@dllsub := GetProcAddress(dllhandle,'CreateForm');
if Assigned(Dllsub) then
DLLForm := Dllsub(application,screen) ;
//dllform.Show;-- 问题点???
end;
end;procedure TfrmMain.ToolButton1Click(Sender: TObject);
begin
LoadDllForm('BOMI01.dll')
end;
end.问题: 因为是初学DLL ,所以上属代码是简单的抄别人的代码,不知为何别的人代码在调用时不需要在调用的地主加上dllform.show ,就能正常运行,而我的不加dllform.show 就不法显示dll 中的窗体,而且我加上dllform.show 后,dll 中的窗体能显示出来,
但在关闭了dll 中的窗体后,再关闭调用的主程序,会报内存地址错误!
--别人的代码如下:
library prjDLL;uses
SysUtils,
Forms,
Windows,
Messages,
Classes,
DLLFormUnit in 'DLLFormUnit.pas' {frmDLLFrm};{$R *.res}var
DLLApp: TApplication;
DLLScr: TScreen;
function CreateDLLForm(App: TApplication; Scr: TScreen):TForm;
begin
Application := App;
Screen := Scr;
Application.CreateForm(TfrmDLLFrm, frmDLLFrm);
result:=frmDLLFrm;
end;procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;
exports
CreateDLLForm;begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL;
end.
------------
unit MainUnit;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, DB, ADODB, Grids, StdCtrls;type
InvokeDLLForm = function(App: TApplication; Scr: TScreen): TForm;
TfrmMain = class(TForm)
MainMenu1: TMainMenu;
M_Invoke: TMenuItem;
mi_inDLL: TMenuItem;
mi_inGeneral: TMenuItem;
m_Windows: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
procedure mi_inDLLClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
frmMain: TfrmMain;
DLLForm: TForm;
implementationuses GeneralFormUnit, AboutUnit;{$R *.dfm}procedure TfrmMain.mi_inDLLClick(Sender: TObject);
var
DLLHandle: THandle;
DLLSub: InvokeDLLForm;
begin
DLLHandle := LoadLibrary('prjDLL.dll');
if DLLHandle <> 0 then
begin
@DLLSub := GetProcAddress(DLLHandle, 'CreateDLLForm');
if Assigned(DLLSub) then
begin
DLLForm := DLLSub(Application, Screen);
end;
end;
end;end.
解决方案 »
- 如何在线程中调用dll中的函数??
- 如何把OleVariant数据保存到文件中???
- 告诉大家一个学习delphi非常好的地方
- 讨论:几个关于midas 的话题
- 关于NetMeeting控件的方法
- 又能上CSDN了,又送控件又送分呢 (之二),
- TDBRADIOGROUP的Items都是竖向排列,如何可以横向排列?
- 怎样逼迫edit1中输入数据是整型的?
- 如何让MEDIAPLAYER播放LISTBOX中的列表文件?
- 怎么样提取一个EXE里面的所有资源保存为res!
- 在用Delphi+DBGRID来做数据库时,在前台如何来及时发映在后台的数据变化。先给50分,解后再给150分。
- 哪里可以找到传奇真正的源代码?
TfrmDLLFrm 的 onCreate 和 onClose 事件中做了什么
接受者:aiirii 重要性:重要性:1 非常不重要重要性:2 不重要重要性:3 一般重要性:4 重要重要性:5 非常重要
内容 http://community.csdn.net/Expert/topic/4372/4372786.xml?temp=.6672785
朋友 ,你好,我看了'DLLFormUnit.pas' ,在onCreate 和 onClose 事件中没做了什么?
如果没有,那
Application.CreateForm(TfrmBom, frmBom);应该是第一个create 的窗体,只有主窗体,才会自动显示,感觉,但你的代码,又是在一个窗体的button click 中调用的,我就不明白
从上面的代码看,肯定会出问题的