问题
Related to this question: Should "Library path" point to the source files of packages?
Fabricio Araujo suggested that is not necessary to set the 'search path' for each new project by creating a 'Default Project Option'. How can this be done in Delphi XE7?
回答1:
How this can be done in Delphi XE7?
It cannot. This functionality was removed I'm not sure exactly when, but it has not been present for some considerable time.
What you can do is:
- Create a new project.
- Change its settings however you please.
- Save this modified project template to some central location.
- Whenever you make a new project, do so by copying this project template.
You can integrate this process into the IDE by saving your modified project template into the Object Repository. Add a project to the repository with Project | Add to Repository.
回答2:
Prompted by your q, and more for amusement than anything else, I decided to try writing an IDE-plugin that would provide a way to store some preferred project settings somewhere and allow you to apply them to the current project.
To use, prepare and save a sample .Ini file containing your preferred settings in the format shown below (it's important to get the project option names right, see below for how to do find them out), then compile the unit below into a new package and install it in the IDE. Its gui will pop up when you subsequently open a project.
The settings in the .Ini are loaded into a ValueList editor and pressing the [Return] key in one of the values will apply it to the project.
Interestingly, the names the IDE uses for the Project seetings are the same in XE7
as they are in D7. Iow, the XE7 IDE uses these internally rather than the names
which appear in the .DProj XML file. You can get a full list of them by clicking the GetOptions
button.
As usual when working with the IDE OTA services, the code has to include a fair amount of "baggage".
Tested in D7 and XE7.
Sample Ini File:
[settings]
OutputDir=Somewhere
UnitOutputDir=Somewhere else
UnitDir=$(DELPHI)
ObjDir=$(DELPHI)
SrcDir=$(DELPHI)
ResDir=$(DELPHI)
Code:
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.
来源:https://stackoverflow.com/questions/33215008/how-to-create-a-default-project-under-delphi-xe7