求助调用DLL子窗体装入PAGECONTROL中的问题

海木漄 2011-01-25 10:44:34
library UDllFrom; //DLL庫封裝之處

{ 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
SysUtils,
Classes,
forms,
RzTabs,
UChildForm in 'UChildForm.pas' {Form1};

{$R *.res}
procedure AddTabSheet(FormClass: TFormClass;tbs:TRZTabSheet; rzpgc:TRZPagecontrol);
var
Form:TForm;
begin
rzpgc.ActivePage := tbs; //加上这一步算是双向指定了,指定激活页
Form := FormClass.Create(tbs); //创建Form(用TabSheet)实例
Form.Parent := tbs; //指定Form的父窗体
tbs.Caption := Form.Caption; //标题
tbs.TabVisible:=True;
Form.Show; //显示
end;
function run_form(hs:THandle;tbs:TRZTabSheet;rzpgc:TRZPagecontrol):integer;stdcall;
var
TForm1:TFormclass;
begin
Application.Handle:=hs;
AddTabSheet(TForm1,tbs,rzpgc);
end;
exports
run_form;
begin
end.
-----------------------------調用DLL窗體,將子窗体装入主窗体中
unit UTestForm;

interface

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

type
TTestForm = class(TForm)
rzpgc: TRzPageControl;
tbs: TRzTabSheet;
BitBtn1: TBitBtn;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
function rum_Form(hs:THandle;tbs:TRZTabSheet;rzpgc:TRZPagecontrol):Integer;stdcall;external 'UDllFrom.dll';
var
TestForm: TTestForm;

implementation

{$R *.dfm}

procedure TTestForm.BitBtn1Click(Sender: TObject);
begin
rum_Form(Application.Handle,tbs,rzpgc);
end;

end.
----------------------------
提示錯誤,無法找到程序的輸入點
...全文
201 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
vga 2012-06-06
  • 打赏
  • 举报
回复
即使是这样,在delphi 2010 等版本还是有错误。

在 delphi 2007 运行后 报 有 7 个字节的 内存泄露.....

用 ReportMemoryLeaksOnShutdown := DebugHook = 1;
测试。
海木漄 2011-01-25
  • 打赏
  • 举报
回复
哥哥,你有没有真正实践成功过呢?
iamduo 2011-01-25
  • 打赏
  • 举报
回复
exe 调用 dll 里的东西。
请将实例留在 dll 中。
Form2 在 dll 中创建,在 dll 中释放。
用简单的两个函数对应这两个动作,由exe调用执行。
海木漄 2011-01-25
  • 打赏
  • 举报
回复
那個貼子已給分了,但是還是沒有解決的,靜態調用DLL子窗體時,關閉主主窗体就会报错。
海木漄 2011-01-25
  • 打赏
  • 举报
回复
楼主,我试了一个可以显示出来,可是关闭掉主窗体时就会报错
海木漄 2011-01-25
  • 打赏
  • 举报
回复
在关闭主窗体时会报错,为什么呢?
Runtime Error216 at 004F509E
bdmh 2011-01-25
  • 打赏
  • 举报
回复
dll文件,TForm2为随便一个窗体

library Project1;

uses
SysUtils,
Classes,
Controls,
Forms,
Windows,
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}
procedure ShowForm(app:TApplication; parent:TWinControl);stdcall;
var
frm : TForm2;
begin
frm := TForm2.Create(Application);
frm.ParentWindow := parent.Handle;
frm.Show;
frm.Align := alClient;
end;

exports
ShowForm name 'ShowForm';

begin

end.


程序调用

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ExtCtrls,ShellAPI;

type
TForm1 = class(TForm)
PageControl1: TPageControl;
Button1: TButton;
TabSheet1: TTabSheet;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

procedure ShowForm(app:TApplication; parent:TWinControl);stdcall;external 'Project1.dll';

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowForm(Application,PageControl1.Pages[0]);
end;

end.
海木漄 2011-01-25
  • 打赏
  • 举报
回复
主DLL:
---------
library UDllFrom;

{ 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
SysUtils,
Classes,
forms,
Dialogs,
controls,
windows,
UChildForm in 'UChildForm.pas' {childForm};
var
DllApp : TApplication;
DLLScr: TScreen;

{$R *.res}
procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;
procedure ShowForm(app:TApplication; parent:TWinControl);stdcall;
var
childForm: TchildForm;
begin
Application := app;
childForm := TchildForm.Create(Application);
childForm.ParentWindow := parent.Handle;
childForm.Show;
childForm.Align := alClient;
end;
exports
ShowForm name 'rums';
begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL; // DLLProc 在SysInit单元中

end.
---------------------这里是照抄的,
海木漄 2011-01-25
  • 打赏
  • 举报
回复
后来改成这样了:
implementation
procedure rums(app:THandle;parent:TWinControl);stdcall;external 'UDllFrom.dll';
{$R *.dfm}

procedure TTestForm.test1Click(Sender: TObject);
begin
rums(Application.Handle,tbs);
end;

end.
提示的是:rtl140.bpl错误。。。。。好多异常。。。。。。。。。。。。。。
海木漄 2011-01-25
  • 打赏
  • 举报
回复
其實,我后来也有加进去的:
library UDllFrom;

{ 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
SysUtils,
Classes,
forms,
Dialogs,
controls,
windows,
UChildForm in 'UChildForm.pas' {childForm};
var
DllApp : TApplication;
DLLScr: TScreen;

{$R *.res}
procedure ExitDLL(Reason: Integer);
begin
if Reason = DLL_PROCESS_DETACH then
begin
Application := DLLApp;
Screen := DLLScr;
end;
end;
procedure run_form(parent:THandle);stdcall;
var
childForm: TchildForm;
begin

childForm:=TchildForm.Create(Application);
childForm.ParentWindow:=parent;
childForm.Show;
childForm.Align:=alclient;
end;
exports
run_form name 'rums';
begin
DLLApp := Application;
DLLScr := Screen;
DLLProc := @ExitDLL; // DLLProc 在SysInit单元中

end.
----------------調用,
unit UTestForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, RzTabs, StdCtrls, Buttons, Menus, ExtCtrls;

type
TShowDLLForm = procedure(aHandle: THandle); stdcall; //定義一個函数指针
EDLLError = class(Exception);
TTestForm = class(TForm)
rzpgc: TRzPageControl;
tbs: TRzTabSheet;
MainMenu1: TMainMenu;
test1: TMenuItem;
procedure test1Click(Sender: TObject);

private
DLLHandle: THandle;
{ Private declarations }
public
{ Public declarations }
end;

var
TestForm: TTestForm;

implementation
procedure rums(parent:THandle);stdcall;external 'UDllFrom.dll';
{$R *.dfm}

procedure TTestForm.test1Click(Sender: TObject);
begin
rums(tbs.Handle);
end;

end.
-------------------------問題依舊在,也是出刺那个错误
bdmh 2011-01-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sukeman 的回复:]
哥哥,说一个完整的不行吗?你到底有没有真正实践过啊
[/Quote]
看着,把dll文件改成如下

library Project1;

uses
SysUtils,
Classes,
Controls,
Forms,
Windows,
Unit2 in 'Unit2.pas' {Form2};

{$R *.res}
var
DllApp:TApplication;
procedure ShowForm(app:TApplication; parent:TWinControl);stdcall;
var
frm : TForm2;
begin
Application := app;
frm := TForm2.Create(Application);
frm.ParentWindow := parent.Handle;
frm.Show;
frm.Align := alClient;
end;

procedure DLLMain(Reason: Integer); register;
begin
{DLL取消调用时,发送DLL_PROCESS_DETACH消息,此时将DLL的Application返回为本身}
if Reason = DLL_PROCESS_DETACH then Application:=DLLApp;
end;

exports
ShowForm name 'ShowForm';

begin
DllApp := Application;
DLLProc := @DLLMain;
end.

海木漄 2011-01-25
  • 打赏
  • 举报
回复
哥哥,说一个完整的不行吗?你到底有没有真正实践过啊
bdmh 2011-01-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sukeman 的回复:]
楼主,我试了一个可以显示出来,可是关闭掉主窗体时就会报错
[/Quote]
报错是因为application的指向问题,你需要保留一个dll的application.handle,然后在关闭时,把dll的application.handle恢复
wei_wu49036233 2011-01-25
  • 打赏
  • 举报
回复
先释放子窗体,再释放主窗体~!

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧