📄 delphidata.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: DelphiData.pas, released on 2004-03-29.
The Initial Developer of the Original Code is Andreas Hausladen
(Andreas dott Hausladen att gmx dott de)
Portions created by Andreas Hausladen are Copyright (C) 2004 Andreas Hausladen.
All Rights Reserved.
Contributor(s): -
You may retrieve the latest version of this file at the Project JEDI's JVCL
home page, located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: DelphiData.pas,v 1.17 2005/01/27 13:10:17 ahuser Exp $
unit DelphiData;
{$I jvcl.inc}
{$I windowsonly.inc}
interface
uses
Windows, SysUtils, Classes, Contnrs, Registry, ShlObj;
const
BDSVersions: array[1..3] of record
Name: string;
VersionStr: string;
Version: Integer;
CIV: string; // coreide version
ProjectDirResId: Integer;
Supported: Boolean;
end = (
(Name: 'C#Builder'; VersionStr: '1.0'; Version: 1; CIV: '71'; ProjectDirResId: 64507; Supported: False),
(Name: 'Delphi'; VersionStr: '8'; Version: 8; CIV: '71'; ProjectDirResId: 64460; Supported: False),
(Name: 'Delphi'; VersionStr: '2005'; Version: 9; CIV: '90'; ProjectDirResId: 64431; Supported: True)
);
type
TCompileTarget = class;
TCompileTargetList = class;
TDelphiPackage = class;
TDelphiPackageList = class;
TCompileTargetList = class(TObjectList)
private
function GetItems(Index: Integer): TCompileTarget;
procedure LoadTargets(const SubKey, HKCUSubKey: string);
function IsBDSSupported(const IDEVersionStr: string): Boolean;
public
constructor Create;
property Items[Index: Integer]: TCompileTarget read GetItems; default;
end;
TCompileTarget = class(TObject)
private
FName: string;
FIDEName: string;
FLatestRTLPatch: Integer;
FLatestUpdate: Integer;
FIDEVersion: Integer;
FIDEVersionStr: string;
FVersion: Integer;
FVersionStr: string;
FExecutable: string;
FEdition: string;
FRootDir: string;
FBDSProjectsDir: string;
FBrowsingPaths: TStringList;
FDCPOutputDir: string;
FBPLOutputDir: string;
FPackageSearchPaths: TStringList;
FSearchPaths: TStringList;
FDisabledPackages: TDelphiPackageList;
FKnownPackages: TDelphiPackageList;
FKnownIDEPackages: TDelphiPackageList;
FHKLMRegistryKey: string;
FRegistryKey: string;
FDebugDcuPaths: TStringList;
procedure LoadFromRegistry;
function ReadBDSProjectsDir: string;
procedure LoadPackagesFromRegistry(APackageList: TDelphiPackageList;
const SubKey: string);
procedure SavePackagesToRegistry(APackageList: TDelphiPackageList;
const SubKey: string);
function GetHomepage: string;
procedure GetBDSVersion(out Name: string; out Version: Integer; out VersionStr: string);
function GetMake: string;
function GetBplDir: string;
function GetDcpDir: string;
public
constructor Create(const AName, AVersion, ARegSubKey: string);
destructor Destroy; override;
function IsBCB: Boolean;
function IsBDS: Boolean;
function IsPersonal: Boolean;
function DisplayName: string;
function VersionedDCP(const Filename: string): string;
{ returns the filename + version + extension for Delphi 5 and BCB 5
else it returns the Filename. }
function FindPackage(const PackageName: string): TDelphiPackage;
function FindPackageEx(const PackageNameStart: string): TDelphiPackage;
function ExpandDirMacros(const Dir: string): string;
function InsertDirMacros(const Dir: string): string;
procedure SavePaths;
{ writes BrowsingPaths and SearchPaths to the registry }
procedure SavePackagesLists;
{ writes KnownPackages and DisabledPackages to the registry }
property Homepage: string read GetHomepage;
property RegistryKey: string read FRegistryKey;
property HKLMRegistryKey: string read FHKLMRegistryKey;
property Make: string read GetMake;
property Name: string read FName;
property Version: Integer read FVersion;
property VersionStr: string read FVersionStr;
property IDEName: string read FIDEName;
property IDEVersion: Integer read FIDEVersion;
property IDEVersionStr: string read FIDEVersionStr;
property Executable: string read FExecutable; // [Reg->App] x:\path\Delphi.exe
property RootDir: string read FRootDir; // [Reg->RootDir] x:\path
property Edition: string read FEdition; // [Reg->Version] PER/PRO/CSS
property LatestUpdate: Integer read FLatestUpdate;
property LatestRTLPatch: Integer read FLatestRTLPatch;
property BrowsingPaths: TStringList read FBrowsingPaths; // with macros
property DCPOutputDir: string read FDCPOutputDir; // with macros
property BPLOutputDir: string read FBPLOutputDir; // with macros
property PackageSearchPathList: TStringList read FPackageSearchPaths; // with macros
property SearchPaths: TStringList read FSearchPaths; // with macros
property DebugDcuPaths: TStringList read FDebugDcuPaths; // with macros
property BDSProjectsDir: string read FBDSProjectsDir;
property BplDir: string read GetBplDir; // macros are expanded
property DcpDir: string read GetDcpDir; // macros are expanded
property KnownIDEPackages: TDelphiPackageList read FKnownIDEPackages;
property KnownPackages: TDelphiPackageList read FKnownPackages;
property DisabledPackages: TDelphiPackageList read FDisabledPackages;
end;
TDelphiPackageList = class(TObjectList)
private
function GetItems(Index: Integer): TDelphiPackage;
public
function IndexOfFilename(const Filename: string): Integer;
procedure Add(const Filename, Description: string);
property Items[Index: Integer]: TDelphiPackage read GetItems; default;
end;
TDelphiPackage = class(TObject)
private
FFilename: string;
FDescription: string;
function GetName: string;
public
constructor Create(const AFilename, ADescription: string);
property Name: string read GetName;
property Filename: string read FFilename;
property Description: string read FDescription;
end;
procedure ConvertPathList(const Paths: string; List: TStrings); overload;
function ConvertPathList(List: TStrings): string; overload;
{$IFDEF COMPILER5}
function AnsiStartsText(const SubStr, Text: string): Boolean;
function ExcludeTrailingPathDelimiter(const Path: string): string;
{$ENDIF COMPIELR5}
implementation
uses
{$IFDEF COMPILER6_UP}
StrUtils,
{$ENDIF COMPILER6_UP}
CmdLineUtils,
JvConsts;
{$IFDEF COMPILER5}
function AnsiStartsText(const SubStr, Text: string): Boolean;
begin
Result := AnsiStrLIComp(PChar(SubStr), PChar(Text), Length(SubStr)) = 0;
end;
function ExcludeTrailingPathDelimiter(const Path: string): string;
begin
if (Path <> '') and (Path[Length(Path)] = '\') then // Delphi 5 only knows Windows
Result := Copy(Path, 1, Length(Path) - 1)
else
Result := Path;
end;
function GetEnvironmentVariable(const Name: string): string;
begin
SetLength(Result, 8 * 1024);
SetLength(Result, Windows.GetEnvironmentVariable(PChar(Name), PChar(Result), Length(Result)));
end;
{$ENDIF COMPIELR5}
const
KeyBorland = '\SOFTWARE\Borland\'; // do not localize
function SubStr(const Text: string; StartIndex, EndIndex: Integer): string;
begin
Result := Copy(Text, StartIndex, EndIndex - StartIndex + 1);
end;
procedure ConvertPathList(const Paths: string; List: TStrings); overload;
var
F, P: PChar;
S: string;
begin
List.Clear;
P := PChar(Paths);
while (P[0] <> #0) do
begin
// trim
while (P[0] = ' ') do
Inc(P);
if P[0] = #0 then
Break;
F := P;
while not (P[0] in [#0, ';']) do
Inc(P);
SetString(S, F, P - F);
List.Add(ExcludeTrailingPathDelimiter(S));
if P[0] = #0 then
Break;
Inc(P);
end;
end;
function ConvertPathList(List: TStrings): string; overload;
var
I: Integer;
begin
Result := '';
for I := 0 to List.Count - 1 do
Result := Result + List[I] + ';';
SetLength(Result, Length(Result) - 1);
end;
{ TCompileTargetList }
constructor TCompileTargetList.Create;
begin
inherited Create;
if CmdOptions.RegistryKeyDelphi = '' then
CmdOptions.RegistryKeyDelphi := 'Delphi'; // do not localize
if CmdOptions.RegistryKeyBCB = '' then
CmdOptions.RegistryKeyBCB := 'C++Builder'; // do not localize
if CmdOptions.RegistryKeyBDS = '' then
CmdOptions.RegistryKeyBDS := 'BDS'; // do not localize
if not CmdOptions.IgnoreDelphi then
LoadTargets('Delphi', CmdOptions.RegistryKeyDelphi); // do not localize
if not CmdOptions.IgnoreBCB then
LoadTargets('C++Builder', CmdOptions.RegistryKeyBCB); // do not localize
if not CmdOptions.IgnoreDelphi then
LoadTargets('BDS', CmdOptions.RegistryKeyBDS); // do not localize
end;
function TCompileTargetList.GetItems(Index: Integer): TCompileTarget;
begin
Result := TCompileTarget(inherited Items[Index]);
end;
procedure TCompileTargetList.LoadTargets(const SubKey, HKCUSubKey: string);
var
Reg, HKCUReg: TRegistry;
List: TStrings;
i: Integer;
begin
Reg := TRegistry.Create;
HKCUReg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
HKCUReg.RootKey := HKEY_CURRENT_USER;
if Reg.OpenKeyReadOnly(KeyBorland + SubKey) then
begin
List := TStringList.Create;
try
Reg.GetKeyNames(List);
for i := 0 to List.Count - 1 do
if List[i][1] in ['1'..'9'] then // only version numbers (not "BDS\DBExpress")
if (SubKey <> 'BDS') or IsBDSSupported(List[i]) then
begin
if HKCUReg.KeyExists(KeyBorland + HKCUSubKey + '\' + List[i]) then
Add(TCompileTarget.Create(SubKey, List[i], HKCUSubKey));
end;
finally
List.Free;
end;
end;
finally
HKCUReg.Free;
Reg.Free;
end;
end;
function TCompileTargetList.IsBDSSupported(const IDEVersionStr: string): Boolean;
var
IDEVersion: Integer;
begin
Result := False;
IDEVersion := StrToInt(IDEVersionStr[1]);
if (IDEVersion >= Low(BDSVersions)) and (IDEVersion <= High(BDSVersions)) then
Result := BDSVersions[IDEVersion].Supported;
end;
{ TCompileTarget }
constructor TCompileTarget.Create(const AName, AVersion, ARegSubKey: string);
begin
inherited Create;
FIDEName := AName;
FIDEVersionStr := AVersion;
FIDEVersion := StrToIntDef(Copy(FIDEVersionStr, 1, Pos('.', FIDEVersionStr) - 1), 0);
if not IsBDS then
begin
FName := FIDEName;
FVersion := FIDEVersion;
FVersionStr := FIDEVersionStr;
end
else
GetBDSVersion(FName, FVersion, FVersionStr);
FHKLMRegistryKey := KeyBorland + IDEName + '\' + IDEVersionStr;
FRegistryKey := KeyBorland + ARegSubKey + '\' + IDEVersionStr;
FBrowsingPaths := TStringList.Create;
FPackageSearchPaths := TStringList.Create;
FSearchPaths := TStringList.Create;
FDebugDcuPaths := TStringList.Create;
FBrowsingPaths.Duplicates := dupIgnore;
FPackageSearchPaths.Duplicates := dupIgnore;
FSearchPaths.Duplicates := dupIgnore;
FDebugDcuPaths.Duplicates := dupIgnore;
FDisabledPackages := TDelphiPackageList.Create;
FKnownIDEPackages := TDelphiPackageList.Create;
FKnownPackages := TDelphiPackageList.Create;
LoadFromRegistry;
end;
destructor TCompileTarget.Destroy;
begin
FBrowsingPaths.Free;
FPackageSearchPaths.Free;
FSearchPaths.Free;
FDebugDcuPaths.Free;
FDisabledPackages.Free;
FKnownIDEPackages.Free;
FKnownPackages.Free;
inherited Destroy;
end;
function TCompileTarget.DisplayName: string;
begin
Result := Format('%s %s (%s)', [Name, VersionStr, Edition]); // do not localize
end;
function TCompileTarget.ExpandDirMacros(const Dir: string): string;
var
I, EndPs: Integer;
S, NewS: string;
begin
Result := Dir;
I := 1;
while I < Length(Result) do
begin
if (Result[I] = '$') and (Result[I + 1] = '(') then
begin
EndPs := I + 2;
while (EndPs <= Length(Result)) and (Result[EndPs] <> ')') do
Inc(EndPs);
S := AnsiLowerCase(SubStr(Result, I + 2, EndPs - 1));
NewS := S;
// available macros
if (S = 'delphi') or (S = 'bcb') or (S = 'bds') then // do not localize
NewS := FRootDir
else if IsBDS and (S = 'bdsprojectsdir') then
NewS := BDSProjectsDir
else
NewS := GetEnvironmentVariable(S);
if NewS <> S then
begin
Delete(Result, i, EndPs - I + 1);
Insert(NewS, Result, I);
Inc(I, Length(NewS) - 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -