我偶然发现了一件非常奇怪的事情。请参阅此屏幕截图:
为什么在可用表单列表中显示$R *.res
?这个项目只有两个表单和一个附加单元,这是项目的主文件源:
program MyProgram;
uses
Forms,
uMain in 'uMain.pas' {fMain},
uEmail in 'uEmail.pas' {frmEmail},
Vcl.Themes,
Vcl.Styles,
Other.Unit in 'Other.Unit.pas';
{$R *.res}
begin
Application.Initialize;
TStyleManager.TrySetStyle('Iceberg Classico');
Application.Title := 'My Program Title';
Application.CreateForm(TfMain, fMain);
Application.Run;
end.
PS - 这是稍微修改过的代码,唯一改变的是程序名称,程序标题和其中一个单位(Other.Unit.pas
)的名称,我知道这是一个不好的例子,因为{{1是一个保留字。但原始单元名称具有名称空间前缀,例如此名称。
更新
我按照建议将此RES引用移到uses子句之前。在此之后(并清除所有临时文件,重新启动IDE等),它仍然显示在列表中。但令我惊讶的是,IDE实际上已经添加了这个RES参考!
所以现在IDE已经把它变成了:
Unit
(UpdateUnit是我给它的新名称所以我不会提供内部信息)
所以,我打开了DPROJ文件并搜索了UpdateUnit in 'UpdateUnit.pas' {$R *.res};
,确实找到了这个:
*.res
答案 0 :(得分:10)
如上所述,我无法重现这一点......但是,如果我在'Other.unit.pas'“行中的”Other.Unit“之后删除了尾随的分号(”;“),则”$ R * .res “显示在项目选项中。
据我所知,这不是一个错误。由于您的评论表明所呈现的代码与您使用的代码不同,因此很难诊断。我会尝试解释发生的事情;如果您查看uMain和uEmail单元,则每个单元旁边都会有一个注释,即表单的名称。由于这些单元实际上可能未在IDE中打开,因此无法知道是否存在与该单元关联的表单。 uMain.dfm的存在并不能保证uMain.pas实际上有一个形式(它可能是遗留下来的)。 IDE将此简单注释放在该单元的uses子句中,以告诉项目经理该单元具有表单。
通过删除“;”,解析器将下一个注释标记视为{$ R * .res}。然后得出结论,Other.Unit.pas必须包含名为“$ R * .res”的表单。它没有验证名称,甚至没有尝试打开单位。它只需要该注释的原始内容并假定它是一个表单名称。
您可以安全地在uses子句之前移动{$ R * .res},以便项目解析器不会将该指令注释混淆为表单。
编辑:从上面的评论:
可能发生的是这个;在某些时候,您可能已经编辑了.dpr文件,使得解析器认为“$ R * .res”是表单名称。然后,您在该状态下保存它,该状态也将该信息注入.dproj文件。 IDE会尝试将这两个内容保持同步,有时会将.dproj文件作为“主”并更新.dpr文件以进行匹配。您应该能够安全地从dproj文件中删除$ R * .res。
答案 1 :(得分:4)
这不能用Delphi XE2 Update 4重现(见下文) 更准确地说:您发布的代码无法重现。
但是您在评论中描述的方案确实如果:.dproj
被清除,IDE会将不正确的信息重新添加到.dpr
。请参阅下文以获得进一步说明。
在这个答案的最后一个编辑,显示你在客户端发生的事情:Delphi XE2可能会以某种方式混淆内部状态出错,并且它回写错误的.dproj
和{{1}文件。
如果您发布的代码与失败的代码不同,请使用失败的代码更正您的问题(并在我的回答中发表评论,以便我收到通知并更新QC条目;在当前表单中您的QC条目将被标记为“无法重现”,然后关闭)。
我看到IDE在AV之后在各个地方(包括项目选项)混淆,或者.pas或.dpr文件中的行结尾不是CRLF,或者手动编辑.DPR文件时。
重新启动IDE时,这些问题通常会消失。有时您甚至需要清理一些文件(扩展名为.DCU,.local等)。
最糟糕的情况是,IDE非常混乱,以至于.DPR和.DPROJ都包含错误信息(因此我的评论),在您的情况下似乎是这种情况(感谢您编辑过的问题)。您可以手动编辑.DPROJ和.DPR文件来解决此问题。确保备份,因为很容易破坏.DPROJ文件的XML格式
如果我在分号之前移动RES声明,我可以重现它:这是IDE期望的格式,因此它可以解析Forms,DataModule和Frames(以及可能的其他设计表面)的.DPR:
.dpr
基本上,您不应该编辑.DPR文件:IDE拥有它并将重写它,例如当您向项目添加新单元,更改程序图标,更改应用程序标题等时。
不重现的主程序:
Unit1 in 'Unit1.pas' {DataModule1: TDataModule},
Unit2 in 'Unit2.pas' {Frame2: TFrame};
Unit3 in 'Unit3.pas' {Form3};
选项对话框:
重现的主程序(注意RES所在的位置):
program MyProgram;
uses
Vcl.Forms,
uMain in 'uMain.pas' {fMain},
uEMail in 'uEMail.pas' {frmEmail},
Vcl.Themes,
Vcl.Styles,
Other.Module in 'Other.Module.pas';
{$R *.res}
begin
Application.Initialize;
TStyleManager.TrySetStyle('Iceberg Classico');
Application.Title := 'My Program Title';
Application.CreateForm(TfMain, fMain);
Application.Run;
end.
编辑20130616
在下面的客户端进入此区域是program MyProgram;
uses
Vcl.Forms,
uMain in 'uMain.pas' {fMain},
uEMail in 'uEMail.pas' {frmEmail},
Vcl.Themes,
Vcl.Styles,
Other.Module in 'Other.Module.pas' {$R *.res};
begin
Application.Initialize;
TStyleManager.TrySetStyle('Iceberg Classico');
Application.Title := 'My Program Title';
Application.CreateForm(TfMain, fMain);
Application.Run;
end.
和.dpr
之前/之后的差异(某些名称已被匿名化)。
Delphi XE2以某种方式感到困惑:它不是.dpr中的编辑导致了这个问题。
我怀疑有两件事:
我已将所有.dpr代码重构为一个单独的模块。希望这是原因,这不会再发生。
旧的.dpr片段:
.dproj
新的.dpr片段:
program Server;
uses
ShareMem,
SysUtils,
Forms,
SvcMgr,
WebReq,
uMain in 'uMain.pas' {fMain},
//...
uDBOrm in 'uDBOrm.pas',
uWinProxySettings in '..\..\..\Server\trunk\Server\uWinProxySettings.pas',
GpStuff in 'GpStuff.pas',
DSiWin32 in 'DSiWin32.pas';
{$R *.res}
function IsServiceApp: Boolean;
begin
//...
end;
begin
if IsServiceApp = True then
begin
//...
end else
begin // GUI Interface
if Assigned(Application) then
FreeAndNil(Application);
Forms.Application.Initialize;
Forms.Application.MainFormOnTaskbar := True;
ReportMemoryLeaksOnShutdown := True;
Forms.Application.CreateForm(TfMain, fMain);
Forms.Application.Run;
end;
end.
旧的.dproj片段:
program Server;
uses
ShareMem,
SysUtils,
Forms,
SvcMgr,
WebReq,
uMain in 'uMain.pas' {fMain},
//...
uDBOrm in 'uDBOrm.pas' {$R *.res},
uWinProxySettings in '..\..\..\Server\trunk\Server\uWinProxySettings.pas',
GpStuff in 'GpStuff.pas',
DSiWin32 in 'DSiWin32.pas';
{$R *.res}
function IsServiceApp: Boolean;
begin
//...
end;
begin
if IsServiceApp = True then
begin
//...
end else
begin // GUI Interface
if Assigned(Application) then
FreeAndNil(Application);
Forms.Application.Initialize;
Forms.Application.MainFormOnTaskbar := True;
ReportMemoryLeaksOnShutdown := True;
Forms.Application.CreateForm(TfMain, fMain);
Forms.Application.Run;
end;
end.
新的.dproj片段:
<DCCReference Include="uDBOrm.pas"/>
<DCCReference Include="..\..\..\Server\trunk\Server\uWinProxySettings.pas"/>