Delphi 如何处理.dpr使用部分中的ifdef
无论何时向项目添加新单元,Delphi都会重建.dpr文件,uses部分中的所有ifdef都会消失 为了解决这个问题,我通常使用记事本创建新的.pas文件,并手动将其添加到.dpr中。如果我需要一个表单,我使用File->New->form,然后将.dpr文件恢复到以前的版本。如果你问我的话,我觉得不太好;-)Delphi 如何处理.dpr使用部分中的ifdef,delphi,Delphi,无论何时向项目添加新单元,Delphi都会重建.dpr文件,uses部分中的所有ifdef都会消失 为了解决这个问题,我通常使用记事本创建新的.pas文件,并手动将其添加到.dpr中。如果我需要一个表单,我使用File->New->form,然后将.dpr文件恢复到以前的版本。如果你问我的话,我觉得不太好;-) 你是怎么处理的?有没有办法在IDE中添加一个单元,同时保留IFDEF?您可以从IDE中手动添加它。(在项目上使用“查看源”选项) 通常,dpr是“隐藏的”。你不需要改变那里的任何东西。
你是怎么处理的?有没有办法在IDE中添加一个单元,同时保留IFDEF?您可以从IDE中手动添加它。(在项目上使用“查看源”选项) 通常,dpr是“隐藏的”。你不需要改变那里的任何东西。
如果您这样做,您最好确保所有更改都是手动的,否则您会丢失一些信息。有时我会专门创建一个单元,用于放置所有IFDEF和其他IDE在dpr中可能会弄糟的东西。该单元通常位于dpr的uses子句的顶部。这个技巧并不能适应所有的场景,但有时它可以节省很多繁琐的工作。我花了很长时间试图解决这个问题 我最终得到了每个构建类型的项目文件(.dpr), 使用项目|项目选项|目录/条件中的条件 只有我想要的单位加入到项目中 这样做的缺点是,如果在.dpr中有自定义代码,则在其更改时必须手动将其复制到其他项目文件中 正如Rob Kennedy所指出的,这可以通过将自定义代码放入自己的单元来处理,该单元由单个过程调用。从而将要进行的.dpr代码大小/更改降至最低
此外,您还可以获得另一个好处,即如果您将所有.dpr文件添加到项目组中,则只需单击/cmd行即可生成所有不同的版本。我不会将任何ifdef放入dpr文件中。如果我想在一个项目中使用不同的单位/形式,根据某些条件,我会将项目一分为二。(Delphi 7) 我也试过了。 请看第一个代码版本和我的以下评论:
program Project1;
{$IFDEF TESTIFDEF}
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$ELSE}
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$ENDIF TESTIFDEF}
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
此时,我刚刚插入了第二个表单,并注意到相应的单元(Unit2.pas)被插入到IFDEF的第一部分中,即标记为part的“TESTIFDEF”中,因此没有覆盖第二个块(在{$ELSE}之后)
因此,您的解决方案应该是:
program Project1;
{$DEFINE MYCONFIG1} // THIS ONE IS NOW ACTIVE
{$IFDEF DELPHIBASISCONFIGURATION}
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2},
Unit3 in 'Unit3.pas' {Form3};
{$ELSE}
// THIS IS A "COMMON TO ALL CONFIG" PART
uses
Forms,
// FIRST CONFIGURATION
{$IFDEF MYCONFIG1}
Unit1 in 'Unit1.pas' {Form1},
Unit3 in 'Unit3.pas' {Form3}
{$ENDIF MYCONFIG1}
// SECOND CONFIGURATION
{$IFDEF MYCONFIG2}
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2}
{$ENDIF MYCONFIG2}
// THIS IS THE "COMMON TO ALL CONFIG" END :)
;
{$ENDIF TESTIFDEF}
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
//Application.CreateForm(TForm3, Form3);
//Application.CreateForm(TForm2, Form2);
Application.Run;
end.
如您所见,我已经放弃了对Form2和Form3的Application.CreateForm(…)的调用
依我看,通常最好在您真正需要的时候动态创建补充表单,即程序开始时不是所有表单…对于表单、数据模块和其他包含单个类的单元,功能将被替换,解决方案相当简单。只是不要将自定义单位直接添加到产品中,而是将它们保存在搜索路径中的某个位置(或者修改项目搜索路径以包含它们的位置) 1) 创建一个新单元,它包含所有其他类的父类,或者它们都将实现的接口(我通常更喜欢后者,因为它允许更容易的定制)[例如,这被称为uSpecialParent.pas] 2) 添加一个类变量,在需要创建新功能时将引用该类变量。例如,如果您只想显示一组表单,因此不关心任何其他方法,那么您可以有一个如下所示的变量:
TYPE
TMySpecialFormClass : class of TForm;
VAR
TMySpecialForm : TMySpecialFormClass;
Unit uRegisterSpecialForms;
interface
uses
{$IFDF SPECIAL1}
uSpecial1,
{$ENDIF}
{$IFDEF SPECIAL2}
uSpecial2,
{$ENDIF}
uSpecialParent;
implementation
// no code needed.
initialization
{$IFDEF SPECIAL1}
TMySpecialForm := uSpecial1.TSpecialForm1;
{$ENDIF}
{$IFDEF SPECIAL2}
TMySpecialForm := uSpecial2.TSPecialForm2;
{$ENDIF}
end.
var
frm : TForm;
begin
frm := TMySpecialForm.Create(nil);
try
frm.showmodal;
finally
frm.free;
end;
end;
3) 创建另一个包含所有IFDEF的单元。它可能看起来如下所示:
TYPE
TMySpecialFormClass : class of TForm;
VAR
TMySpecialForm : TMySpecialFormClass;
Unit uRegisterSpecialForms;
interface
uses
{$IFDF SPECIAL1}
uSpecial1,
{$ENDIF}
{$IFDEF SPECIAL2}
uSpecial2,
{$ENDIF}
uSpecialParent;
implementation
// no code needed.
initialization
{$IFDEF SPECIAL1}
TMySpecialForm := uSpecial1.TSpecialForm1;
{$ENDIF}
{$IFDEF SPECIAL2}
TMySpecialForm := uSpecial2.TSPecialForm2;
{$ENDIF}
end.
var
frm : TForm;
begin
frm := TMySpecialForm.Create(nil);
try
frm.showmodal;
finally
frm.free;
end;
end;
4) 要在代码中引用此项,您只需将USPECIALPART添加到将请求特殊表单的单元中,然后动态创建它,例如,为了显示此模式,您可以调用以下命令:
TYPE
TMySpecialFormClass : class of TForm;
VAR
TMySpecialForm : TMySpecialFormClass;
Unit uRegisterSpecialForms;
interface
uses
{$IFDF SPECIAL1}
uSpecial1,
{$ENDIF}
{$IFDEF SPECIAL2}
uSpecial2,
{$ENDIF}
uSpecialParent;
implementation
// no code needed.
initialization
{$IFDEF SPECIAL1}
TMySpecialForm := uSpecial1.TSpecialForm1;
{$ENDIF}
{$IFDEF SPECIAL2}
TMySpecialForm := uSpecial2.TSPecialForm2;
{$ENDIF}
end.
var
frm : TForm;
begin
frm := TMySpecialForm.Create(nil);
try
frm.showmodal;
finally
frm.free;
end;
end;
为了完整性起见,这里是lo-tech方法: IDE再次打乱uses子句后:
+1.我不记得曾经使用过单位的条件包含。为什么要这样做?@mghie:跨编译器和RTL版本的可移植性。跨编译器(Delphi vs C++ Builder)的可移植性,避免了依赖于构建配置的单元(例如,在发布版本中,您可能不希望堆栈转储支持,因为没有调试符号)。首先,这不会导致有条件包含的单元成为项目的一部分(因此可以通过项目管理器访问)@mghie:Memory managers必须是链接器看到的第一个单元,这只能通过.dpr文件实现。这就是我所指的用例(我也在使用FastMM,除了在一些应用程序中遇到bug,并且必须在.dpr文件中维护ifdef以测试各种版本)是的,我这样做是因为我在dpr中加入了IFDEF,德尔福对此感到困惑。你能解释一下为什么有时候你只想让一个单位成为你项目的一员吗?我不明白它的目的。在我们的项目中,我们使用Delphi附带的FastMM进行发布构建,但是ext