Jan Doggen
Jan Doggen

Reputation: 9096

How to manage constantly changing project run-time parameters in the IDE?

In my (XE2) IDE I constantly have to switch the settings for Project Options/ Debugger / Parameters because I'm testing for different client configurations, databases etc.

The Parameters dropdown list is becoming unmanageable. Since these have no descriptions either, it's even hard to figure out which ones to remove (How can I clean the Parameters field in the Run -> Parameters menu?).

Any smart ideas on managing these?
In an ideal word I would like to give them a tag/description, reorder them, delete some...

Upvotes: 0

Views: 387

Answers (2)

Jan Doggen
Jan Doggen

Reputation: 9096

In addition to Lievens answer I'm adding an answer to my own question.

I have started using [identifier] at the beginning of the run-time parameter, and I can put in there what I want. In addition I have written a small app that lets me clean up the parameters that are stored in the registry (at HKEY_CURRENT_USER\Software\Embarcadero\BDS\9.0\History Lists\hlRunParameters).

enter image description here

Here is the code for that Win32 app. It will let you delete and sort the registry values. It is written in Delphi XE2. Just create a new VCL project and use this as the main form.

uCleanIDEParams.pas

unit uCleanIDEParams;
// https://stackoverflow.com/questions/27502689/how-to-manage-constantly-changing-project-run-time-parameters-in-the-ide
// All 32 bit stuff, the Delphi IDE is 32 bit too

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.CheckLst, Registry,
  Vcl.ExtCtrls;

type
  TFrmCleanIDEParams = class(TForm)
    PnlTop: TPanel;
    BtnLoad: TButton;
    EdtRegKey: TEdit;
    Label1: TLabel;
    ChkRedundant: TCheckBox;
    PnlBottom: TPanel;
    GBxSelection: TGroupBox;
    BtnSelectAll: TButton;
    BtnSelectNone: TButton;
    BtnStartWith: TButton;
    ChkNot: TCheckBox;
    EdtStartWith: TEdit;
    BtnInvert: TButton;
    Label2: TLabel;
    BtnWrite: TButton;
    ChkSort: TCheckBox;
    PnlCenter: TPanel;
    CLBParams: TCheckListBox;
    procedure BtnLoadClick(Sender: TObject);
    procedure BtnSelectAllClick(Sender: TObject);
    procedure BtnSelectNoneClick(Sender: TObject);
    procedure BtnInvertClick(Sender: TObject);
    procedure BtnStartWithClick(Sender: TObject);
    procedure BtnWriteClick(Sender: TObject);
  private
  public
  end;

var
  FrmCleanIDEParams: TFrmCleanIDEParams;

implementation

{$R *.dfm}

procedure TFrmCleanIDEParams.BtnInvertClick(Sender: TObject);
var i: integer;
begin
  for i := 0 to CLBParams.Items.Count-1 do CLBParams.Checked[i] := not CLBParams.Checked[i];
end;

procedure TFrmCleanIDEParams.BtnLoadClick(Sender: TObject);
var
  lReg      : TRegistry;
  lValue,
  lItem,
  lKey      : String;
  i,
  lNrRegVals: Integer;
begin
  lKey := Trim(EdtRegKey.Text);
  if lKey = '' then Exit;
  if lKey[1] = '\' then lKey := Copy(lKey,2);

  lReg := TRegistry.Create(KEY_READ);
  lReg.RootKey := HKEY_CURRENT_USER;

  if not lReg.OpenKey(lKey,false) then
    begin
      MessageDlg('Key not found', mtError, mbOKCancel, 0);
      Exit;
    end;
  if not lReg.ValueExists('Count') then
    begin
      MessageDlg('Value ''Count'' not found', mtError, mbOKCancel, 0);
      Exit;
    end;
  lNrRegVals := lReg.ReadInteger('Count');
  for i := 0 to lNrRegVals-1 do
  begin
     lValue := 'Item' + IntToStr(i);
     if lReg.ValueExists(lValue) then
     begin
       lItem := lReg.ReadString(lValue);
       if ChkRedundant.Checked then
         lItem := Trim(StringReplace(lItem,'  ',' ',[rfReplaceAll]));
       CLBParams.Items.Add(lItem);
     end;
  end;
end;

procedure TFrmCleanIDEParams.BtnSelectAllClick(Sender: TObject);
var i: integer;
begin
  for i := 0 to CLBParams.Items.Count-1 do CLBParams.Checked[i] := true;
end;

procedure TFrmCleanIDEParams.BtnSelectNoneClick(Sender: TObject);
var i: integer;
begin
  for i := 0 to CLBParams.Items.Count-1 do CLBParams.Checked[i] := true;
end;

procedure TFrmCleanIDEParams.BtnStartWithClick(Sender: TObject);
var
  i     : integer;
  lStart,
  lItem : string;
begin
  lStart := Lowercase(Trim(EdtStartWith.Text));
  if lStart = '' then Exit;
  for i := 0 to CLBParams.Items.Count-1 do
  begin
    lItem := lowercase(CLBParams.Items[i]);
    if (not ChkNot.Checked) and (Pos(lStart,lItem) = 1)
    or (ChkNot.Checked) and (Pos(lStart,lItem) <> 1) then
      CLBParams.Checked[i] := true;
  end;
end;

procedure TFrmCleanIDEParams.BtnWriteClick(Sender: TObject);
var
  lReg      : TRegistry;
  lValue,
  lKey      : String;
  i,
  lNrToWrite,
  lNrRegVals: Integer;
begin
  for i := CLBParams.Items.Count-1 downto 0 do
    if not CLBParams.Checked[i] then
      CLBParams.Items.Delete(i);
  if CLBParams.Items.Count = 0 then
    begin
      MessageDlg('Nothing to do', mtInformation, mbOKCancel, 0);
      Exit;
    end;
  if ChkSort.Checked then
    CLBParams.Sorted := true;

  // Now writing back

  lKey := Trim(EdtRegKey.Text);
  if lKey = '' then Exit;
  if lKey[1] = '\' then lKey := Copy(lKey,2);

  lReg := TRegistry.Create(KEY_READ or KEY_WRITE);
  lReg.RootKey := HKEY_CURRENT_USER;
  if not lReg.OpenKey(lKey,false) then
    begin
      MessageDlg('Key not found', mtError, mbOKCancel, 0);
      Exit;
    end;
  if not lReg.ValueExists('Count') then
    begin
      MessageDlg('Value ''Count'' not found', mtError, mbOKCancel, 0);
      Exit;
    end;
  lNrRegVals := lReg.ReadInteger('Count');

  lNrToWrite := CLBParams.Items.Count;
  lReg.WriteInteger('Count',lNrToWrite);
  // Write TCheckListBox items:
  for i := 0 to lNrToWrite-1 do
  begin
    lValue := 'Item' + IntToStr(i);
    lReg.WriteString(lValue,CLBParams.Items[i]);
  end;
  // Remove the rest:
  for i := lNrToWrite to lNrRegVals-1 do
    lReg.DeleteValue('Item' + IntToStr(i));
end;

end.

uCleanIDEParams.dfm

object FrmCleanIDEParams: TFrmCleanIDEParams
  Left = 0
  Top = 0
  Caption = 'Clean Delphi IDE runtime parameters'
  ClientHeight = 560
  ClientWidth = 549
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  PixelsPerInch = 96
  TextHeight = 13
  object PnlTop: TPanel
    Left = 0
    Top = 0
    Width = 549
    Height = 58
    Align = alTop
    BevelOuter = bvNone
    TabOrder = 0
    object Label1: TLabel
      Left = 19
      Top = 11
      Width = 308
      Height = 13
      Caption = 'HKEY_CURRENT_USER registry key for IDE runtime parameters:'
    end
    object BtnLoad: TButton
      Left = 496
      Top = 30
      Width = 40
      Height = 25
      Caption = 'Load'
      TabOrder = 0
      OnClick = BtnLoadClick
    end
    object EdtRegKey: TEdit
      Left = 16
      Top = 32
      Width = 473
      Height = 21
      TabOrder = 1
      Text = '\Software\Embarcadero\BDS\9.0\History Lists\hlRunParameters'
    end
    object ChkRedundant: TCheckBox
      Left = 388
      Top = 10
      Width = 151
      Height = 17
      Hint = 'Removes leading, trailing, and duplicate spaces'
      Caption = 'Remove redundant spaces'
      Checked = True
      State = cbChecked
      TabOrder = 2
    end
  end
  object PnlBottom: TPanel
    Left = 0
    Top = 471
    Width = 549
    Height = 89
    Align = alBottom
    BevelOuter = bvNone
    TabOrder = 1
    object Label2: TLabel
      Left = 74
      Top = 62
      Width = 287
      Height = 13
      Caption = 'Click button to write the selected items back to the registry:'
    end
    object GBxSelection: TGroupBox
      Left = 16
      Top = -3
      Width = 520
      Height = 51
      Caption = ' Select '
      TabOrder = 0
      object BtnSelectAll: TButton
        Left = 348
        Top = 18
        Width = 50
        Height = 25
        Caption = 'All'
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'Tahoma'
        Font.Style = []
        ParentFont = False
        TabOrder = 0
        OnClick = BtnSelectAllClick
      end
      object BtnSelectNone: TButton
        Left = 404
        Top = 18
        Width = 50
        Height = 25
        Caption = 'None'
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'Tahoma'
        Font.Style = []
        ParentFont = False
        TabOrder = 1
        OnClick = BtnSelectNoneClick
      end
      object BtnStartWith: TButton
        Left = 51
        Top = 18
        Width = 79
        Height = 25
        Hint = 'Selection is additive'
        Caption = 'starting with:'
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'Tahoma'
        Font.Style = []
        ParentFont = False
        ParentShowHint = False
        ShowHint = True
        TabOrder = 2
        OnClick = BtnStartWithClick
      end
      object ChkNot: TCheckBox
        Left = 11
        Top = 22
        Width = 40
        Height = 17
        Caption = 'NOT'
        TabOrder = 3
      end
      object EdtStartWith: TEdit
        Left = 136
        Top = 20
        Width = 121
        Height = 21
        Hint = 'Case insensitive match'
        ParentShowHint = False
        ShowHint = True
        TabOrder = 4
        Text = '['
      end
      object BtnInvert: TButton
        Left = 460
        Top = 18
        Width = 50
        Height = 25
        Caption = 'Invert'
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWindowText
        Font.Height = -11
        Font.Name = 'Tahoma'
        Font.Style = []
        ParentFont = False
        TabOrder = 5
        OnClick = BtnInvertClick
      end
    end
    object BtnWrite: TButton
      Left = 364
      Top = 58
      Width = 89
      Height = 25
      Hint = 'Write the selected items back to the registry'
      Caption = 'Write back'
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = [fsBold]
      ParentFont = False
      ParentShowHint = False
      ShowHint = True
      TabOrder = 1
      OnClick = BtnWriteClick
    end
    object ChkSort: TCheckBox
      Left = 459
      Top = 62
      Width = 57
      Height = 17
      Caption = '(sorted)'
      Checked = True
      State = cbChecked
      TabOrder = 2
    end
  end
  object PnlCenter: TPanel
    Left = 0
    Top = 58
    Width = 549
    Height = 413
    Align = alClient
    BevelOuter = bvNone
    TabOrder = 2
    object CLBParams: TCheckListBox
      AlignWithMargins = True
      Left = 15
      Top = 10
      Width = 522
      Height = 393
      Margins.Left = 15
      Margins.Top = 10
      Margins.Right = 12
      Margins.Bottom = 10
      Align = alClient
      ItemHeight = 13
      TabOrder = 0
    end
  end
end

Notes:

  1. Do not forget to change the version number in the key if you are using anything other than XE2. For old Delphi versions you may even have to change Embarcadero to Borland.

  2. Do not run this app from within the IDE. When it closes, Delphi will overwrite any changes you made to that registry key, and it looks like your program does not work ;=)

Upvotes: 1

Lieven Keersmaekers
Lieven Keersmaekers

Reputation: 58451

Not ideal but a workaround would be to add a redundant tag parameter as first parameter.

That way at least, when you use the dropdown list, you'll have some indication on what parameter combination you are using.

Upvotes: 1

Related Questions