【问题标题】:How to create a default project under Delphi XE7?Delphi XE7下如何创建默认项目?
【发布时间】:2015-10-19 12:56:01
【问题描述】:

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

Fabricio Araujo 建议不必通过创建“默认项目选项”来为每个新项目设置“搜索路径”。在 Delphi XE7 中如何做到这一点?

【问题讨论】:

    标签: delphi delphi-xe7


    【解决方案1】:

    在你的 q 提示下,我决定尝试一下 编写一个 IDE 插件,提供一种存储一些首选项目的方法 在某处设置并允许您将它们应用到当前项目。

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

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

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

    像往常一样使用 IDE OTA 服务时,代码必须包含 相当数量的“行李”。

    在 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.
    

    【讨论】:

      【解决方案2】:

      如何在 Delphi XE7 中做到这一点?

      它不能。此功能已被删除,我不确定确切的时间,但它已经有一段时间没有出现了。

      你可以做的是:

      1. 创建一个新项目。
      2. 随意更改其设置。
      3. 将此修改后的项目模板保存到某个中心位置。
      4. 每当您创建新项目时,请复制此项目模板。

      您可以通过将修改后的项目模板保存到 Object Repository 来将此过程集成到 IDE 中。使用Project | Add to Repository 将项目添加到存储库。

      【讨论】:

      • 嗨,大卫。我知道那已经不存在了。但我希望它可以以某种方式进行更改/编辑。我的意思是德尔福必须从某个地方加载它。对吗?
      • Emba 决定默认项目不应该是用户可以弄乱的东西。大概是因为它引起了很多混乱。当用户想知道为什么某些设置是奇怪和不寻常的值时。
      • Embarcadero 的大智慧:) :)
      • 我实际上认为他们做对了。我喜欢一个新项目从一台机器到另一台机器的可预测状态。并不是没有其他方法可以实现您想要的。
      • 他们可以做很多事情。您是否发现自己经常创建新项目?我知道我没有。我还使用了共享选项集,以便我可以以协调的方式在多个项目中应用设置。我认为这比必须以特定方式配置每台开发机器要强大得多。
      猜你喜欢
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多