DelphiXE7下如何创建默认工程?

How to create a default project under Delphi XE7?

与此问题相关:Should "Library path" point to the source files of packages?

Fabricio Araujo 建议不必通过创建 'Default Project Option' 为每个新项目设置 'search path'。如何在 Delphi XE7 中完成此操作?

How this can be done in Delphi XE7?

不能。此功能已删除我不确定确切时间,但它已经有相当长的时间不存在了。

您可以做的是:

  1. 创建一个新项目。
  2. 随意更改其设置。
  3. 将修改后的项目模板保存到某个中心位置。
  4. 无论何时创建新项目,都可以通过复制此项目模板来完成。

您可以将修改后的项目模板保存到 Object Repository. Add a project to the repository with Project | Add to Repository 中,从而将此过程集成到 IDE 中。

在你的q提示下,更多的是娱乐而不是其他,我决定尝试一下 编写一个 IDE-plugin 来提供一种存储一些首选项目的方法 在某处设置并允许您将它们应用到当前项目。

要使用、准备和保存包含您首选设置的示例 .ini 文件,格式如下所示(正确设置项目选项名称很重要,请参阅下文了解如何找到它们),然后编译将下面的单元放入一个新包并将其安装在 IDE 中。当你随后打开一个项目时,它的gui会弹出。

.Ini 中的设置被加载到 ValueList 编辑器中并按下 [Return] 键入其中一个值会将其应用于项目。

有趣的是,IDE 用于项目设置的名称在 XE7 中是相同的 就像他们在 D7 中一样。 Iow,XE7 IDE 在内部使用这些而不是名称 出现在 .DProj XML 文件中。您可以通过单击 GetOptions 按钮获得它们的完整列表。

像往常一样使用 IDE OTA 服务时,代码必须包括 相当数量的 "baggage".

在 D7 和 XE7 中测试。

示例 Ini 文件:

[settings]
OutputDir=Somewhere
UnitOutputDir=Somewhere else
UnitDir=$(DELPHI)
ObjDir=$(DELPHI)
SrcDir=$(DELPHI)
ResDir=$(DELPHI)

代码:

unit ProjectOptionsXE7u;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ToolsAPI, Grids, ValEdit, IniFiles;

type
  TProjectOptionsForm = class(TForm)
    Panel1: TPanel;
    Memo1: TMemo;
    ValueListEditor1: TValueListEditor;
    btnGetOptions: TButton;
    procedure btnGetOptionsClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ValueListEditor1KeyPress(Sender: TObject; var Key: Char);
  private
    function GetCurrentProject: IOTAProject;
    procedure GetOptionsFromIni;
    procedure UpdateOptionValue;
  public
    Services: IOTAServices;
    ProjectGroup : IOTAProjectGroup;
    Project: IOTAProject;
    Options : IOTAProjectOptions;
    ModServices: IOTAModuleServices;
    Module: IOTAModule;
    NotifierIndex: Integer;
    Ini : TMemIniFile;
    IsSetUp : Boolean;
    SetUpCount : Integer;
    procedure GetProjectOptions;
    procedure SetUp;
  end;

var
  ProjectOptionsForm: TProjectOptionsForm;

procedure Register;

implementation

{$R *.dfm}

type
  TIdeNotifier = class(TNotifierObject, IOTANotifier, IOTAIDENotifier)
  protected
    procedure AfterCompile(Succeeded: Boolean);
    procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
    procedure FileNotification(NotifyCode: TOTAFileNotification;
      const FileName: string; var Cancel: Boolean);
  end;

procedure Register;
begin
  ProjectOptionsForm:= TProjectOptionsForm.Create(Nil);
  ProjectOptionsForm.Services := BorlandIDEServices as IOTAServices;
  ProjectOptionsForm.NotifierIndex := ProjectOptionsForm.Services.AddNotifier(TIdeNotifier.Create);
end;

procedure CloseDown;
begin
  ProjectOptionsForm.Services.RemoveNotifier(ProjectOptionsForm.NotifierIndex);
  ProjectOptionsForm.Close;
  ProjectOptionsForm.Free;
end;

procedure TIdeNotifier.AfterCompile(Succeeded: Boolean);
begin
end;

procedure TIdeNotifier.BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
begin
end;

procedure TIdeNotifier.FileNotification(NotifyCode: TOTAFileNotification;
  const FileName: string; var Cancel: Boolean);
begin
  if NotifyCode in [ofnProjectDesktopLoad, ofnActiveProjectChanged]  then begin
    ProjectOptionsForm.Show;
//    ProjectOptionsForm.Memo1.Lines.Add('Got notification');
    ProjectOptionsForm.SetUp;
//    ProjectOptionsForm.Memo1.Lines.Add('after GetProjectOptions');
  end;
end;

procedure TProjectOptionsForm.btnGetOptionsClick(Sender: TObject);
var
  KeyName,
  Value,
  S : String;
  V : Variant;
  i : Integer;
begin
  GetProjectOptions;
  ValueListEditor1.Strings.Clear;
  for i := Low(Options.GetOptionNames) to High(Options.GetOptionNames) do begin
    try
      KeyName := Options.GetOptionNames[i].Name;
      if CompareText(KeyName, 'HeapSize') = 0 then
        NoOp;
      V := Options.Values[KeyName];
      if not VarIsEmpty(V) then
        Value := VarToStr(V)
      else
        Value := '';
      ValueListEditor1.InsertRow(KeyName, Value, True);
    except
      //  Reading some CPP-related settings cause exceptions
      S := '***Error   ' + KeyName; // + ': ' + IntToStr(Options.Values[KeyName].Kind);
      Memo1.Lines.Add(S);
    end;
  end;
end;

procedure TProjectOptionsForm.FormDestroy(Sender: TObject);
begin
  Ini.Free;
end;

procedure TProjectOptionsForm.GetOptionsFromIni;
var
  i : Integer;
  KeyName : String;
  TL : TStringList;
begin
  ValueListEditor1.Strings.Clear;
  TL := TStringList.Create;
  try
    Ini.ReadSection('Settings', TL);
    Assert(TL.Count > 0);
    for i := 0 to TL.Count - 1 do begin
      KeyName := TL[i];
      ValueListEditor1.InsertRow(KeyName, Ini.ReadString('Settings', KeyName, ''), True);
    end;
  finally
    TL.Free;
  end;
end;

procedure TProjectOptionsForm.FormCreate(Sender: TObject);
var
  IniFileName : String;
begin
  IniFileName := 'd:\aaad7\ota\ProjectOptions.Ini'; //  <beware of hard-code path
  Ini := TMemIniFile.Create(IniFileName);
  GetOptionsFromIni;
end;

function TProjectOptionsForm.GetCurrentProject: IOTAProject;
var
  i: Integer;
begin
  Result := nil;
  ModServices := BorlandIDEServices as IOTAModuleServices;
  for i := 0 to ModServices.ModuleCount - 1 do
  begin
    Module := ModServices.Modules[i];
    if Supports(Module, IOTAProjectGroup, ProjectGroup) then begin
      Result := ProjectGroup.ActiveProject;
      Options := Result.ProjectOptions;
      Exit;
    end
    else if Supports(Module, IOTAProject, Project) then
    begin // In the case of unbound packages, return the 1st
      if Result = nil then begin
        Result := Project;
        Options := Result.ProjectOptions;
      end;
    end;
  end;
end;

procedure TProjectOptionsForm.GetProjectOptions;
begin
  Assert(Project <> Nil, 'Project');
  Options := Project.ProjectOptions;
end;

procedure TProjectOptionsForm.SetUp;
begin
  Project := GetCurrentProject;
  GetProjectOptions;
  Inc(SetUpCount);
  Caption := 'Setup done ' + IntToStr(SetUpCount);
  IsSetUp := True;
end;

procedure TProjectOptionsForm.UpdateOptionValue;
var
  Rect : TGridRect;
  S : String;
  KeyName,
  Value : String;
  Row,
  Col : Integer;
begin
  if Options = Nil then
    Exit;
  Rect := ValueListEditor1.Selection;
//  S := 'left: %d top: %d right: %d, bottom: %d';
//  S := Format(S, [Rect.Left, Rect.Top, Rect.Right, Rect.Bottom]);
//  Memo1.Lines.Add(S);
  Row := Rect.Bottom;
  Col := Rect.Left - 1;
  KeyName := ValueListEditor1.Cells[Col, Row];
  Value := ValueListEditor1.Values[KeyName];

  Options.SetOptionValue(KeyName, Value);
  Options.ModifiedState := True;

  Module.Save(False, False);
end;

procedure TProjectOptionsForm.ValueListEditor1KeyPress(Sender: TObject; var
    Key: Char);
begin
  if Key = #13 then
    UpdateOptionValue;
end;

initialization

finalization
  CloseDown;
end.