使用包(Package)技术实现动态加载MDI子窗口,不同于一般的DLL技术(存在很大的限制和隐患),开题换分(7分)

  • 主题发起人 主题发起人 LiChaoHui
  • 开始时间 开始时间
ninglng@163.com

看的开心啦,给你加倍的分
 
不错,给你加分,但我应该如何把分加给你,我不会操作,你可以给个提示我吗
 
你开一个帖子,然后把地址回复到下面就行了
 
to LiChaoHui:
给我一个txyqbf_Gxx@163.com
其实没什么可以保留的,我就贴一个我写得吧(SDI):
exe 调用dll 中窗体的例子,sdi 和 mdi 基本上一样:
DLL 部分:

{****************************************************************}
{ }
{ Project: UDllTest               }
{ Copyright(c) 2003, 2005                 }
{ Unit for UDllTest                   }
{ Create : 2003-01-05 by 林红卫             }
{ }
{****************************************************************}

library UDllTest;

uses
SysUtils,
Forms,
Messages,
Windows,
Classes,
UFrmTestForm1 in 'UFrmTestForm1.pas' {Form1},
UFrmTestForm2 in 'UFrmTestForm2.pas' {Form2};

var
DLLApp: TApplication;
DLLScreen: TScreen;
TheForm: TForm;
theClass: TPersistentClass;

procedure RunDLL(DLLName, FormName, FormCaption: string;
APP: TApplication; SC: TScreen) stdcall;

begin
Application := App;
Screen := sc;
RegisterClasses([TForm1, TForm2]);

theClass := GetClass('T' + FormName);

if theClass.InheritsFrom(TForm) and (theClass <> nil) then
begin
TheForm := TForm(theClass.Create).Create(Application);
TheForm.Caption := FormCaption;
TheForm.Show;
end;
end;

procedure DLLUnloadProc(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp; //恢复
Screen := DLLScreen;
FreeAndNil(TheForm);
FreeAndNil(theClass); // 卸载时释放资源
end;
end;

exports
RunDLL;

begin
DLLApp := Application; //保存 DLL 中初始的 Application 对象
DLLScreen := Screen;
DLLProc := @DLLUnloadProc; //保证 DLL 卸载时恢复原来的 Application
end.
这是dpr 你加入form1,form2 就行啦!

exe 的dll 调用部分:

{****************************************************************}
{ }
{ Project: DllDebug             }
{ Copyright(c) 2003, 2005                 }
{ Unit for UCommonUnit                   }
{ Create : 2003-01-05 by 林红卫             }
{ }
{****************************************************************}

unit UCommonUnit;

interface

uses
Windows,
SysUtils,
Forms;

type
TRunDLL = procedure(DLLName, FormName, FormCaption: string;
Application: TApplication; Screen: TScreen) stdcall;

procedure RunDLLForm(DLLName, FormName, FormCaption: string;
APP: TApplication; SC: TScreen) stdcall;

implementation

procedure RunDLLForm(DLLName, FormName, FormCaption: string;
APP: TApplication; SC: TScreen) stdcall;
var
GetDllHWND: HWND;
RunDLL: TRunDLL;
begin
GetDllHWND := LoadLibrary(PChar(DllName));
if GetDllHWND < 32 then
begin
MessageBox(0, '没有找到附带DLL文件,请确认程序是否完整!',
'加载DLL失败', MB_OK);
Exit;
end;

@RunDLL := GetProcAddress(GetDllHWND, 'RunDLL');
if @RunDLL <> nil then
begin
try
RunDLL(UpperCase(Trim(DLLName)), UpperCase(Trim(FormName)),
FormCaption, APP, SC);
except
raise Exception.Create('T' + FormName + '不存在');
end;
end;
end;
end.
dll 的Form Name 可以从Exe 传入。

 
你的这种方法不是很难,但不理想
http://www2.borland.com.tw/tw/reference9.html
 
怎么不理想??有什么隐患,我真的看不出来。
 
我看了你的程序,自己按照你的程序试了一下,
程序退出的时候出错,这是为什么呢?
即使调试也找不出错在哪里,这就是最大的隐患

你的程序中会有两个Application 和 Screen对象
其中一份根本就没有用
其他的全局对象也可能存在两份,某些操作可能会出错,
我以前也尝试过类似的方法,但觉得不理想

用包来做,就不存在这样的问题,
而且程序也简单
 
多人接受答案了。
 
我正在用学这东东,去拿分吧,我要一个学习学习。
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1634400
 
楼上的把你的帖子结掉吧,很抱歉以前没有你的回复
 
后退
顶部