我有两个项目,A和B。A是Windows VCL应用程序,B是activeX服务器应用程序。 B公开使用COM托管的类型库。该类型库被A调用。我试图向B传递A主窗口的句柄,并让B使用该句柄作为父控件来创建VCL TFrame
。最后,我试图将这个VCL TFrame
以指针的形式返回给A。
我遇到以下异常:
项目带有消息的引发的异常类EInvalidOperation '控件'MainFrame'没有父窗口。路径:MainFrame”。
我缩小了代码行,在下面显示为MainFrame := TMainFrame.CreateParented(ParentHandle);
,这会在项目B的以下COM对象功能中引起麻烦:
function DelphiCOMServiceImplementation.GetDelphiVCLFramePointer(pointer: Pointer; width: Double; height: Double): Pointer; stdcall;
begin
ParentHandle := Cardinal(pointer);
MainFrame := TMainFrame.CreateParented(ParentHandle); // This is the line that causes the exception.
MainFrame.Width := Trunc(width);
MainFrame.Height := Trunc(height);
MainHandle := MainFrame.Handle;
MainPointer := System.Pointer(MainHandle);
Result := MainPointer;
end;
上面,TMainFrame
只是承载TFrame
的简单VCL TLabel
。
为什么会出现此错误,我该如何解决?本质上,无论有没有父控件,我都希望能够成功构造我的TFrame
控件,然后我想将TFrame
的句柄从COM对象返回给调用者
我检查了指针,传入的基数将其值保留在COM对象中。我之所以尝试执行此任务,是因为我最终想从另一种技术中调用我的COM对象,但是现在我只在Delphi领域中遇到这些问题,我必须对其进行补救。
这是我在B中设置COM对象的方式:
unit DelphiCOMServiceUnit;
interface
uses SysUtils,ComObj,ComServ,DelphiCOMService_TLB,Winapi.activeX,StdVcl,Frame,Vcl.Forms,Winapi.Windows;
type
DelphiCOMServiceImplementation = class(TComObject,IDelphiCOMService)
private
MainFrame: TMainFrame;
MainHandle: Cardinal;
ParentHandle: Cardinal;
MainPointer: Pointer;
protected
function GetDelphiVCLFramePointer(pointer: Pointer; width: Double; height: Double): Pointer; stdcall;
procedure WindowResized(width: Double; height: Double); safecall;
end;
implementation
function DelphiCOMServiceImplementation.GetDelphiVCLFramePointer(pointer: Pointer; width: Double; height: Double): Pointer; stdcall;
begin
ParentHandle := Cardinal(pointer);
MainFrame := TMainFrame.CreateParented(ParentHandle);
MainFrame.Width := Trunc(width);
MainFrame.Height := Trunc(height);
MainHandle := MainFrame.Handle;
MainPointer := System.Pointer(MainHandle);
Result := MainPointer;
end;
procedure DelphiCOMServiceImplementation.WindowResized(width: Double; height: Double); safecall;
begin
MainFrame.Width := Trunc(width);
MainFrame.Height := Trunc(height);
end;
initialization
TComObjectFactory.Create(ComServer,DelphiCOMServiceImplementation,StringToGUID('{D448873F-EAF7-4F40-8BC7-EF9853E64A0F}'),'DelphiCOMServiceImplementation','',ciMultiInstance,tmApartment);
end.
这是我如何从A调用此COM对象的方法:
procedure TForm1.Formactivate(Sender: TObject);
begin
Service := CoDelphiCOMServiceImplementation.Create();
Parent := Pointer(Handle);
Service.GetDelphiVCLFramePointer(Parent,1337,1337);
end;
A只是一个简单的VCL Windows应用程序,上面有一种形式。我已经绑定了一个Formactivate
事件,其中使用当前表单的句柄调用B。
另外,为了完成操作,这是我设置* .ridl的方法: