另一个简单问题,调试通过立刻给分---如何在主单元中调用其动态创建的Form2里的一个函数? ( 积分: 100 )

  • 主题发起人 主题发起人 cnh
  • 开始时间 开始时间
C

cnh

Unregistered / Unconfirmed
GUEST, unregistred user!
File>>New>>Application,Unit1(Form1),然后File>>New>>Form,Unit2(Form2)。
Unit1(Form1)是主单元,动态创建Form2( aa:= TForm2.Create( self ); )。现在要在Unit1里面得到其动态创建的实例aa的函数aerty的地址,并且调用这个函数,请问该怎么写,调试通过立刻给分,谢谢!

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
aa: TForm2;
p: pointer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
aa:= TForm2.Create( self );
aa.BorderStyle:= bsNone;
aa.WindowState:= wsMaximized;
aa.Position:= poScreenCenter;
aa.Visible:=true ;
aa.BringToFront ;
aa.Show ;
p:= @aa.aerty; // 我想得到实例aa的函数aerty的地址
 aa.aerty; // 并且运行实例aa的函数aerty
end;
end.

下面是Unit2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
self.Close;
end;
procedure TForm2.aerty;
begin
showmessage('OK');
end;
end.
请问我在Unit2里面该怎样声明或处理函数aerty?谢谢!
 
File>>New>>Application,Unit1(Form1),然后File>>New>>Form,Unit2(Form2)。
Unit1(Form1)是主单元,动态创建Form2( aa:= TForm2.Create( self ); )。现在要在Unit1里面得到其动态创建的实例aa的函数aerty的地址,并且调用这个函数,请问该怎么写,调试通过立刻给分,谢谢!

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
aa: TForm2;
p: pointer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
aa:= TForm2.Create( self );
aa.BorderStyle:= bsNone;
aa.WindowState:= wsMaximized;
aa.Position:= poScreenCenter;
aa.Visible:=true ;
aa.BringToFront ;
aa.Show ;
p:= @aa.aerty; // 我想得到实例aa的函数aerty的地址
 aa.aerty; // 并且运行实例aa的函数aerty
end;
end.

下面是Unit2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm2 = class(TForm)
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
self.Close;
end;
procedure TForm2.aerty;
begin
showmessage('OK');
end;
end.
请问我在Unit2里面该怎样声明或处理函数aerty?谢谢!
 
TForm2 = class(TForm)
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure aerty;//在这里,如果不想给外部调用,则在private部分
end;

另外,在Unit1 中,最好也是这样声明:
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
form2: TForm2; //在这里声明被TForm1调用的对象 ,因为form2在本单元只为TForm1调用,它应该为TForm1的私有成员
public
{ Public declarations }
end;
下列代码:
var
Form1: TForm1;
aa: TForm2;
p: pointer;
在单元中随便声明变量是严重的不良习惯
Delphi自身的这种做法( Form1: TForm1;)是倍受争议的
 
谢谢张鸿林。
但我需要的是动态创建的Form2在内存中的实例中的函数aerty的地址!
有个相似的例子:比如我们动态加载DLL,xpab.dll,DLL有一个输出函数Dfkk 。
Type TDfkk = function : BOOL; stdcall;
var LibHandle: Thandle;
Dfkk: TDfkk;
p: pointer;

LibHandle:= Loadlibrary('xpab.dll');
@Dfkk:= GetProcAddress( LibHandle, 'Dfkk' );
Dfkk;  // 运行函数Dfkk
p:= @Dfkk;   // 函数Dfkk的地址赋给指针p
freelibrary(LibHandle);

最后指针p的值就是DLL的输出函数Dfkk的地址。
 
TObject.methodaddress('<MethodName>')
 
Delphi 里面的RTTI只针对Published的函数和过程,所以使用TMethod动态设置函数地址的话也只能设置Published的内容

参考
http://www.delphibbs.com/delphibbs/dispq.asp?lid=095126
标题是: TMethod.Data指向哪?

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1058202
标题是: Delphi中如何能够动态地获取一个类的方法列表,并动态地访问该类的方法?
 
谢谢各位!
现在的问题是,使用methodaddress无法传递参数。为简略起见,不动态创建Form2,只用主单元,请看下面:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Unit2;
type
TProck = procedure ( d: integer ); // 定义函数类型。
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure akkp( a:integer );
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
p: pointer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
p:= MethodAddress('akkp'); //取得函数地址
TProck( p )( 123 ); //运行函数
end;
procedure TForm1.akkp( a:integer );
begin
Form1.Label1.Caption:= 'Now---'+inttostr(a);
end;
end.
运行以后显示的不是123,而是一个奇怪的数字4518772,methodaddress没有正确传递参数,请问是怎么回事呢?
 
这样就可以了

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TProck = procedure ( d: integer ) of object; // 定义函数类型。
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;

procedure Button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
published
procedure akkp( a:integer );
end;
var
Form1: TForm1;
p: TProck;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
TMethod(p).Code:= MethodAddress('akkp'); //取得函数地址
TProck(p)( 123 ); //运行函数
end;
procedure TForm1.akkp( a:integer );
begin
Form1.Label1.Caption:= 'Now---'+inttostr(a);
end;
end.
 
通过!!谢谢各位啦。先给分!
再请问一下,TProck = procedure ( d: integer ) of object;是个什么类型?这属于哪方面的知识点,我是初学者,请点拔,谢谢!
 
对象方法,表示这个方法属于对象,在Delphi的帮助里面有说明的,另外TMethod在帮助里面也有说明,就是只针对Published方法,具体看我的代码
 
为什么原来那样就不能正确传递参数呢?原因何在?
 

Similar threads

I
回复
0
查看
698
import
I
I
回复
0
查看
577
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部