能否在DLL调用模块中动态创建构件(100分)

  • 主题发起人 主题发起人 so-cool
  • 开始时间 开始时间
S

so-cool

Unregistered / Unconfirmed
GUEST, unregistred user!
主叫模块能将其构件或自身当做参数传递给调用的DLL,
并且DLL中的过程能更改其构件参数的属性,那么能利用
DLL中的过程在构件中创建新的构件吗(即DLL在调用模块
中动态创建构件)?
 
能,自己先做一下。
 
当然做过

主程序和单元文件:
program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
puProc:procedure(self:Tobject);

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
aLib:THandle;
proc:procedure(sender:Tobject);
begin
aLib:=LoadLibrary('project2');
if aLib>=32 then begin
proc:=GetProcAddress(aLib,'MyMsg');
//button1.Click:=proc;
puproc:=proc;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
// showmessage(button1.Caption);
puProc(form1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
aLib:Thandle;
crProc:procedure(bt:TButton);
begin
aLib:=LoadLibrary('DLLDemo');
if aLib>=32 then begin
crProc:=GetprocAddress(aLib,'CreaButn');
crProc(button1);
end;
end;

end.

库项目及单元文件
library Project2;

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

exports
CreaButn,MyMsg;

{$R *.res}

begin
end.

unit Unit2;

interface

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

type
TForm2 = class(TForm)
Button1: TButton;
private
{ Private declarations }
public
{ Public declarations }

end;

var
Form2: TForm2;


procedure MyMsg(frm:TForm);
procedure CreaButn(bt:TButton);cdecl;

implementation

{$R *.dfm}

procedure MyMsg(frm:TForm);
var
bt:TButton;
begin
bt:=TButton.Create(frm);
bt.Caption:='试验';
bt.Left:=300;
bt.Top:=300;
bt.Parent:=frm;
end;

procedure CreaButn(bt:TButton);
begin
showmessage(bt.Caption);
end;
end.

但编译后内存出错
 
如果主调是delphi,当然可以
如果不是,component还要可见的话,就困难了
注意不要造成内存泄露
 
这样写一定会出错的呀,你在 procedure MyMsg(frm:TForm) 中没有创建TFORM 就在上面
创建TBUTTON怎么可以呢,
procedure MyMsg();
var frm :TFORM;
bt:TButton;
begin
frm := tform.create(nil);
bt:=TButton.Create(frm);
bt.Caption:='试验';
bt.Left:=300;
bt.Top:=300;
bt.Parent:=frm;

end;
再试一下,我没试不知道行否 :)
 
TO菜妹妹:或许这样可以,但这时创建的button1肯定不是我想要的
我想要的是在当参数传递过来的那个窗体上创建
 
因为你的代码中没有写创建窗体参数 ,你只要保证调用此函数时,
窗体参数已经被创建,然后 if not Assigned(frm) then exit;
做一判断就不会出错了
 
Project1中的Application.CreateForm(TForm1, Form1)算不算?
 
逻辑有问题。
 
能不能具体点!
 
你是想在工程文件中动态创建button,在DLL中创建button是DLL的私有变量怎么可能
在工程文件中显示呢,你应该在动态链接库的接口函数中返回TButton的变量才行。
 
多人接受答案了。
 
后退
顶部