当我们在我上一家公司创建构建过程时,我们想要做完全相同的事情。我们使用Subversion,并拥有一个包含所有共享组件的项目,其中包含一个(Finalbuilder)项目来构建所有共享包。
然后,我将使用类似于Marjan的(MyLib)变量的技术。并从批处理文件中启动Delphi以获取最新的组件集。
最终,我们发现这是不必要的。我们主框架的发布属性很少更改,因此我们只使用一个已安装的软件包集,例如
c:\ BDS \ Components \ D12 \ Bpl(这可能因开发人员而异)
但是,位于
c:\ BDS \ MyProject \ Shared
始终在编译时链接,因为它在构建项目时的相对搜索路径上
c:\ BDS \ MyProjectExperimental
在构建时也会使用正确分支的代码。
我们实际上通过使用CodeSmith(代码生成器)解决了存储库问题,以生成框架,其额外好处是它们将放置在正确的文件夹中,并具有正确的命名约定(以及任何特定于分支的更改)。我们之所以这样做是为了节省时间,但我们(偶然)完全避免了这个问题。
CodeSmith模板在第一帧设置需要花费一些时间,但之后我们很容易就能够适应它来创建其他子类,而不需要过多的脑力(例如dataModules)。
cfEditFrame.dfm.cst
<%@ CodeTemplate Language="C#" TargetLanguage="Delphi" Src="" Inherits="" Debug="False" Description="cfEditFrames.dfm 模板" ResponseEncoding="ASCII" %>
<%@ Property Name="TypeName" Type="System.String" Default="TypeName" Optional="False" Category="Strings" Description="类型名称。例如:账户;月龄" %>
继承自 cf<%=TypeName%>EditFrame 的 Tcf<%=TypeName%>EditFrame:
宽度 = 425
高度 = 63
end
cfEditFrame.cst - 我们必须调用的一个脚本,用于生成新的子类化框架
<%@ CodeTemplate Language="C#" TargetLanguage="Delphi" Src="" Inherits="" Debug="False" Description="cfSDMEditComp Template." ResponseEncoding="ASCII" %>
<%@ Property Name="OutputFolder" Type="System.String" Default="..\\SharedNonInstalled" Optional="False" Category="Strings" Description="" %>
<%@ Property Name="TypeName" Type="System.String" Default="TypeName" Optional="False" Category="Strings" Description="Type 的名称,例如 Account;AgeMonths。" %>
<%@ Register Name="EditFramesPasTemplate" Template="cfEditFrames.pas.cst" %>
<%@ Register Name="EditFramesDfmTemplate" Template="cfEditFrames.dfm.cst" %>
<%@ Import NameSpace="System.IO" %>
<script runat="template">
public override void Render(TextWriter writer)
{
EditFramesPasTemplate cfEditFramesPasTemplate = new EditFramesPasTemplate();
this.CopyPropertiesTo(cfEditFramesPasTemplate);
cfEditFramesPasTemplate.RenderToFile(String.Format("{0}\\Edit\\cf{1}EditFrames.pas", OutputFolder, TypeName), true);
EditFramesDfmTemplate cfEditFramesDfmTemplate = new EditFramesDfmTemplate();
this.CopyPropertiesTo(cfEditFramesDfmTemplate);
cfEditFramesDfmTemplate.RenderToFile(String.Format("{0}\\Edit\\cf{1}EditFrames.dfm", OutputFolder, TypeName), true);
}
</script>
可能会有其他源代码生成器做得同样好,甚至更好。我们有CodeSmith,因此使用它。希望上述文件格式正确。我是一个 SO 新手,希望 html 代码的呈现是正确的。
关于在这些框架上同时拥有属性和组件,你需要做一件奇怪的事情。你需要分两步来完成。首先,在第一个类中添加框架属性,然后在其子类中添加组件。
例如,我们在 cfBaseEditFrames.TcfBaseEditFrame 中添加自定义属性。
然后,我们将其作为 TcfBaseEditFrame 的子类,如 cfEditFrames.TcfEditFrame = class(TcfBaseEditFrame)。
这是我们添加组件的地方(在我们的例子中是 TActionList 和 TImageList)。
在将它们注册为包时,我们添加了:
RegisterCustomModule(TcfBaseEditFrame, TWinControlCustomModule);
然后,我们确保这个包在我们的项目组中,并且没有问题打开新的子类化框架。
最后一点,记住,从记忆中看来,重要的是后代框架(TcfEditFrame)是添加组件的那个,不能在 TcfBaseEditFrame 添加组件而在 TcfEditFrame 添加属性。
BaseEditFrames.pas
单位 BaseEditFrames;
接口
使用
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,
对话框;
类型
TBaseEditFrame = 类(TFrame)
private
{私有声明}
FNewFormProperty: string;
published
{发布声明}
property NewFormProperty: string read FNewFormProperty write FNewFormProperty;
end;
实现
{$R *.dfm}
结束。
BaseEditFrames.dfm
对象 BaseEditFrame: TBaseEditFrame
左 = 0
上 = 0
宽度 = 320
高度 = 240
TabOrder = 0
end
EditFrames.pas
单元编辑框架;
接口
使用
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActnList, BaseEditFrames;
类型
TEditFrame = class(TBaseEditFrame)
ActionList: TActionList;
private
{ 私有声明 }
public
{ 公共声明 }
end;
实现
{$R *.dfm}
结束。
EditFrames.dfm
对象 EditFrame:TEditFrame
左 = 0
上 = 0
宽度 = 320
高度 = 240
TabOrder = 0
对象 ActionList:TActionList
左 = 72
上 = 16
结束
结束
FramePackage.dpk
包FramePackage;
{$R * .res}
{$ ALIGN 8}
{$ ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO OFF}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST OFF}
{$MINENUMSIZE 1}
{$IMAGEBASE $ 400000}
{$ DESCRIPTION'可继承的框架'}
{$ IMPLICITBUILD ON}
要求
rtl,
vcl,
designide;
包含
在'RegisterFramePackage.pas'中注册帧包,
在“BaseEditFrames.pas”中的BaseEditFrame:TFrame,
在'EditFrames.pas'中的EditFrame:TFrame。
结束。
单位RegisterFramePackage;
接口
过程登记;
实施
使用类,DesignIntf,WCtlForm,BaseEditFrames;
过程登记;
开始
RegisterCustomModule(TBaseEditFrame,TWinControlCustomModule);
结束;
结束。
你需要安装此设计时包。然后你可以在另一个项目中拥有一个如下的框架。
EditFrameDescendants.pas
单元 EditFrameDescendants;
接口
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, EditFrames, ActnList;
type
TEditFrameDescendant = class(TEditFrame)
Action1: TAction;
private
{ Private declarations }
public
{ Public declarations }
end;
实现
{$R *.dfm}
end.
EditFrameDescendants.dfm
继承自TEditFrameDescendant的EditFrameDescendant:
ParentFont = False
继承自TActionList的ActionList:
object Action1: TAction
Caption = 'Action1'
end
end
end
您应该能够打开EditFrameDescendant,编辑其惊人的“NewFormProperty”,并将操作添加到其操作列表中。对我来说很有效...祝好运