我在delphi中遇到这个错误,我从不同的形式(总共3个)中进行了预测,当我创建最后一个孩子时,它会创建每个组件3次。它的dll项目和dll使用不同的形式。我有一个用于测试dll的启动器。在调用创建所需表单的函数时,它会在一个窗口中创建所有3个(下面的屏幕)。我试过给我的组件命名相同。它没有显示编译dll时的任何错误,但是在从启动器调用该函数时它表示该组件或该组件已经存在,因此我必须为所有组件提供不同的名称。 (如果不清楚,请向我提问,我不知道如何更清楚地解释它)
以下是我的表单定义:
TFrmReserve007 = class(TfrmRsrvExtended)
private
{ Private declarations }
[...]
protected
{ Protected declarations }
[...]
public
{ Public declarations }
[...]
end;
TfrmRsrvExtended = class(TfrmRsrv)
Act_Browse2: TAction;
Act_SaveAs2: TAction;
Act_LoadDefault2: TAction;
ImageListToolbar2: TImageList;
PSCMandatoryObjects2: TPSCMandatoryObjects;
ImageListMouvement2: TImageList;
[...More components...]
TopPanel2: TPSCTopPanel;
procedure Act_BrowseExecute(Sender: TObject);
procedure Act_LoadDefaultExecute(Sender: TObject);
procedure Act_loadSenderExecute(Sender: TObject);
procedure bbtn_Browse2Click(Sender: TObject);
private
{ Private declarations }
[...]
protected
[...]
public
{ Public declarations }
[...]
end;
TFrmRsrv = class(TForm)
PSCButtonPanel1: TPSCButtonPanel;
PageControl: TPageControl;
TabSheeta: TTabSheet;
[.. More components...]
Act_LoadKeyWord1: TAction;
Act_LoadStorage1: TAction;
Mandatory1: TPSCMandatoryObjects;
PSCHint: TPSCHint;
{$ENDREGION}
private
{ Private declarations }
protected
{ Protected declarations }
[...]
public
{ Public declarations }
[...]
end;
这意味着那里有功能和程序。
这是我使用TFrmReserve007.Create(nil)
LAUNCHER
procedure setLXCom;
begin
if lxPom59Svc = nil then
begin
ClassID := ContractIDToClassID('pom59PumaToRio@dtad');
IU := CreateLynxObject( ClassID);
if IU = Nil then begin
raise Exception.Create( 'CreateLynxObject failed');
end;
IU.QueryInterface( Ipom59Svc, lxPom59Svc);
if lxPom59Svc = nil then
begin
raise Exception.Create( 'QueryInterface ILynxRio failed');
end;
end;
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
setLxCom;
lxPom59Svc.RioSvcGui007V2(
LxPom59Svc.RioGetDataPCE007V2('9051','2010010281',false),lgFRENCH)
end;
DLL
function tl_pom59Svc.RioSvcGui007V2(
Info: IInfoNotisReservation;For007:boolean;Extension:string; ParentWindow: HWND)
: IInfoNotisReservation;
var
Ok : Boolean;
untKey: String;
canSave : Boolean;
begin
Ok := False;
GetRioDB(fRegister);
untKey := RioN.GetRegisterByID(RioN.RegisterID, FLAG_IGNORE_SECURITY).Data.UnitID.Value;
canSave := RioN.GetPieceAccess(info.pieceID).Edit;
While Not(Ok) do
begin
Ok := true;
case LoadFRM_ReservationMod007(Info,
fRegister, UntKey, canSave, For007, Extension,Parentwindow) of
TR_Ok :
begin
Result := Info;
end;
TR_Cancel :
begin
Result := Nil;
end;
else
Result := Nil;
end;
end;
end;
Function LoadFrm_ReservationMod007(var InfoReservation : IInfoNotisReservation;
Reg_Key,Unt_Key:string;CanSave:Boolean;For007:boolean;Extension:string; ParentWindow: HWND):TTrilean;
var
Frm_ReservMod007: TFrmReserve007;
begin
Frm_ReservMod007 := TFrmReserve007.Create(nil);
FRM_ReservMod007.ShowModal;
if Frm_ReservMod007.ModalResult <> Mrcancel then
begin
InfoReservation.Assign(Frm_ReservMod007.InfoReserv);
Result := TR_Ok;
end
else
begin
InfoReservation := Nil;
Result := TR_Cancel;
end;
end;
答案 0 :(得分:2)
听起来这就是你所做的 - 让我猜测重现这个问题的步骤:
TForm1
TForm1
TForm2
.pas
的{{1}}文件,使其继承自TForm2
(即:TForm1
TForm2 = class(TForm1)
未包含TForm2
中的任何控件,即使您“继承了”TForm1
。TForm1
设计器复制并粘贴到TForm1
设计师。这是使用可视化设计器创建继承表单的错误方法。
要创建包含设计时编辑的继承表单,您必须选择
档案 - &gt;新 - &gt;其他...
从那里,(这取决于Delphi版本,但对于任何合理的现代......),你选择
Delphi项目 - &gt;可继承的项目 - &gt; Form1中
TForm2
是您希望继承的基本表单。这应该生成一个新单元,其表单继承了基本表单的类代码以及 Form1
。如果你看一下创建错误方式的表单中的DFM
文件(作为文本 - 推送.dfm
),你会看到顶部:
Alt+F12
如果你正确地继承(如上所述),你会看到 object Form2: TForm2
...[etc]
文件的开头为:
.dfm
或者,您可以创建常规表单并修改类型声明以从基本表单继承:
inherited Form2: TForm2
...[etc]
但您还必须确保将 TForm2 = class(TForm1)
...[etc]
文件从.dfm
修改为object
。这可以确保表单设计者正确导入属于祖先表单的控件。
这里的教训是,设计时表单包含两个关键代码。
inherited
文件.pas
文件这里的错误是您只继承了类代码(功能),但没有继承设计和布局信息(内容)。