*** Delphi 零件:***
我有一个包含该事件的类,需要从该事件调用一个过程,将接口对象传递给它。它在 Delphi 中运行良好,但在Pascal Script中声明时出现问题。
对于后台-IGPGraphics
接口是Delphi GDI+ library
的一部分,没有方法的定义如下:
type
IGdiplusBase = interface
['{24A5D3F5-4A9B-42A2-9F60-20825E2740F5}']
IGPGraphics = interface(IGdiPlusBase)
['{57F85BA4-CB01-4466-8441-948D03588F54}']
下面是一个简化的 Delphi 伪代码,我需要用Pascal脚本来完成:
type
TRenderEvent = procedure(Sender: TObject; const GPGraphics: IGPGraphics) of object;
TRenderClass = class(TGraphicControl)
private
FOnRender: TRenderEvent;
public
property OnRender: TRenderEvent read FOnRender write FOnRender;
end;
// when the TRenderClass object instance fires its OnRender event I want to call
// the RenderObject procedure passing the IGPGraphics interfaced object to it; I
// hope I'm doing it right, I'm just a newbie to this stuff - but it works so far
// in Delphi (since I didn't get it to work in Pascal Script)
procedure TForm1.RenderClass1Render(Sender: TObject; const GPGraphics: IGPGraphics);
begin
RenderObject(GPGraphics, 10, 10);
end;
// what I need in Pascal Script is between these two lines; just pass the interface
// object from the event fired by component to the procedure called from inside it
procedure RenderObject(const GPGraphics: IGPGraphics; X, Y);
begin
// and here to work with the interfaced object somehow
end;
Pascal脚本编译部分:
我的目标是在Pascal Script中使用带有事件的类,并且需要像上面一样将接口对象传递给该过程,所以我首先尝试在编译时声明如下(但我甚至不确定这样做是否正确):
// the interface
PS.AddInterface(Cl.FindInterface('IUnknown'), StringToGuid('{57F85BA4-CB01-4466-8441-948D03588F54}'), 'IGPGraphics');
// the type for the event
PS.AddTypeS('TRenderEvent', 'procedure(Sender: TObject; const GPGraphics: IGPGraphics)');
// and the class with the event itself
with PS.AddClassN(PS.FindClass('TGraphicControl'), 'TRenderClass') do
begin
RegisterProperty('OnRender', 'TRenderEvent', iptrw);
end;
型
Pascal脚本运行时部分:
运行时部分是我最困惑的地方,我不知道如何从调用堆栈中获取接口对象并将其传递给RenderObject过程:
function RenderClassProc(Caller: TPSExec; Proc: TPSExternalProcRec; Global,
Stack: TPSStack): Boolean;
var
PStart: Cardinal;
begin
PStart := Stack.Count-1;
Result := True;
if Proc.Name = 'RENDEROBJECT' then
begin
// how do I get the interfaced object from Stack (or whatever else) and pass
// it to the RenderObject proc here ? I can't find anything related about it
// except functions that has no parameter index
RenderObject(Stack.Get ?, Stack.GetInt(PStart-2), Stack.GetInt(PStart-3));
end;
end;
问题是
有人能建议我如何正确定义这种情况下的编译和运行时部分,或者纠正我传递接口对象的方式吗?
P.S.对不起,InnoSetup标签,但也许有人 * 从那里 * 试图定制InnoSetup这种方式。
多谢了!
3条答案
按热度按时间ryoqjall1#
如果我理解你的问题,你想把接口作为参数传递给方法。不幸的是,我没有确切的答案,但我知道如何为PascalScript的全局变量赋值接口。下面是我在卡斯特利亚中的做法:
在PSScript OnCompile事件中,使用PS.Comp.AddInterface添加接口,然后添加每个必要的方法,之后添加接口类型的变量,如下所示,例如:
然后,在OnExecute事件中,将以前创建的变量绑定到示例:
完成此操作后,脚本就可以通过变量访问接口对象,因此在本示例中,脚本可以包含对Clipboard.getText的调用,它的工作方式与您预期的一样。
这是经过测试和工作。
现在,我推测您可能能够使用TPSScript.ExecuteFunction,从上面传入PIFVariant,以更接近您想要的结果。
祝你好运!
wwwo4jvm2#
很难相信,但我找到了怎么做
这基本上是应该做的。
这对于类是有效的,但对于接口应该没有太大的不同,只需对参数变量使用TPSVariantInterface类型而不是TPSVariantClass;其他的一切都应该是一样的
我希望这可能会对某人有所帮助。
uoifb46i3#
PS中的接口只需要在编译时声明(无RI寄存器):