delphi dll 封装mdi 窗体+逻辑(100分)

  • 主题发起人 主题发起人 mzwang123
  • 开始时间 开始时间
M

mzwang123

Unregistered / Unconfirmed
GUEST, unregistred user!
http://www.delphibbs.com/delphibbs/dispq.asp?lid=534762
无意间找到这个5年前的帖子,不知像阿朱 程云这样的高手是否还从事软件开发工作。如今我也遇到相同的问题。以dll的形式封装mdi ,将窗体+逻辑做成dll,主程序只是一个调用框架,假如主程序有一个主菜单A B C D四项,单击任一项都会出现子窗体,但相同类型的子窗体只能存大一个,比如单击了A项出现了子窗体A,单击了B项出现了子窗体B,此时又单击了A项,此时已存在的子窗体A被激活而不会再次被创建。在下遇到的难题是主框架窗体不识别子窗体,即mdichildcount一直为0。还有就是在给DLL传递参数的时候是传apllicatin好呢,还是application.handle好呢?5年前 程云也遇到了相同的问题可是没有在帖子上回答。真的很遗憾。不知5年后的今天哪位高手愿意指点在下,能把源代码发出来最好。在下QQ358590376,欲加在下只须写上大富翁即可。mzwang123@163.com在下的e-mail.
 
                 哎
             哎        哎
 
在此声明: 本例子是看见各位DFW 问得比较多的问题而写的。
只经过粗略的测试, 还请各位多多指教! 谢谢。

1.主EXE内容:
unit Unit2;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus;

type
TLoadFrm = procedure(App: TApplication; Scr: TScreen ); StdCall;
TForm2 = class(TForm)
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure N2Click(Sender: TObject);
private
DllHandle: Cardinal;
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if DllHandle <> 0 then FreeLibrary(DllHandle);
end;

procedure TForm2.N2Click(Sender: TObject);
var
LoadFrm: TLoadFrm;
begin
DllHandle := LoadLibrary(Pchar('F:/Component/Dllfrm/Order/prDll.dll'));
if DllHandle <= 0 then Exit;
LoadFrm := GetProcAddress(DllHandle, PChar('LoadFrm'));
if @LoadFrm = nil then Exit;
LoadFrm(Application, Screen);
end;

end.

2.DLL部分:
library prDll;

uses
SysUtils,
Classes,
Forms,
Windows,
Unit3 in 'Unit3.pas' {Form3},
Unit4 in 'Unit4.pas';

{$R *.RES}
Exports
LoadFrm;
var
GApplication: TApplication ;
GScreen: TScreen;
procedure InitDll(dWseason: DWORD);
begin
case dWseason of
DLL_PROCESS_ATTACH: begin
GApplication := Application;
GScreen := Screen;
end;
DLL_PROCESS_DETACH: begin
Application := GApplication;
Screen := GScreen;
end;
end;
end;
begin
DllProc := @InitDll;
InitDll(DLL_PROCESS_ATTACH);
end.
DLL 包含的窗体:
unit Unit3;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm3 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form3: TForm3;

implementation

{$R *.DFM}

procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Form3 := nil;
end;
end.
DLL 包含的公共单元(主要是函数书写):
unit Unit4;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Unit3;

procedure LoadFrm(App: TApplication; Scr: TScreen); StdCall;
implementation
procedure LoadFrm(App: TApplication; Scr: TScreen );
var
LPtr: PLongint;
begin
if Form3 <> nil then Exit;
Application := App;
Screen := Scr;
LPtr := @Application.MainForm;
LPtr^ := Longint(App.MainForm);
Form3 := TForm3.Create(App.MainForm);
Form3.Show;
end;
end.

不知道对你有没有用!
 
kk2000,非常感谢你能参与,可是你的框架程序.exe无法识别它的子窗体,当创建一个子窗体后,再次单击菜单的时候你怎样判断它是否存在????依你的程序还是会再创建一个子窗体而不是将存在的子窗体激活。哎,这是困难点,我在单步调试的时候发现主框架的mdichildcount一直为0,不管是在主框架中判断,还是将application传入dll后再判断。你说呢???还有刚开始我写这个程序的时候,程序能创建子窗体,但是当我关闭主程序的时候,出现了错误,我觉得问题出在dll释放的时候,不知kk2000是否遇到类似的错误,请指教一下。
 
垦请各位高手积极参与,总不至于delphi不可能实现这个功能吧!真诚的等待中ing
 
procedure LoadFrm(App: TApplication; Scr: TScreen );
var
LPtr: PLongint;
begin
if Form3 <> nil then Exit;
Application := App;
Screen := Scr;
LPtr := @Application.MainForm;
LPtr^ := Longint(App.MainForm);
Form3 := TForm3.Create(App.MainForm);
Form3.Show;
end;
从我的LoadFrm 来看并不会创建已经存在的窗口
if Form3 <> nil then Exit; 这句代码就可以保证
但你想激活存在的子窗体 可以使用showwindow(form.handle, sw_show)
 
但是你想管理更多的窗口的话! 我想你通过修改
procedure LoadFrm(App: TApplication; Scr: TScreen ); 这个函数
procedure LoadFrm(App: TApplication; Scr: TScreen; FormClass: PChar );
然后通过类名去查找窗口是否实例化了! 当然你得建立一个记录结构,使用来保存
你的必要信息, 使用一个指针容器(如Tlist)把这些信息保存起来. 然后通过窗口
类名和指针容器去查找你需要的信息,就可以知道你的子窗口是否已经创建,没有创建
就创建,创建了就激活存在的子窗体.OK
 
kk2000,非常感谢你的帮助,眼下也只好这样了。若能实现定会通知你的。358590376,在下QQ,十分想交个朋友。
 
在下分数也不多,不要见怪。
 
兄弟,我的问题和你类似,请看http://www.delphibbs.com/delphibbs/dispq.asp?lid=3542871。其他问题通过d5 d6指南和阿朱程云的资料我全部通过。
 
带vcl;rtl两个包编译,
Dll也一样.
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部