Search code examples
delphi-10.2-tokyodfm

Delphi how to remove deleted properties from dfm in exe


I have many dfms. I am using delete unwanted properties exe from this site Delphi DFM properties remover, to remove deleted properties which are no longer required. Following code works fine except for some properties like if I want to delete property with name Prop then it deletes another property with name SecondProp along with Prop. mPropList contains each property on new line like Prop1 Prop2 SecondProp Propn

I doubt following code:

 if StrIPos(mPropList.Lines[K] + ' =', S) = 0 then
      begin
        LResult.Add(LSource[J]);
        continue;
      end;

How to skip SecondProp in such case?

I tried this

if mPropList.Lines[K] = S then
      begin
        LResult.Add(LSource[J]);
        continue;
      end;

To match exact strings, but it didn't work.

This is delete button code

procedure TfrmDeleteProp_MainForm.Button2Click(Sender: TObject);
var
      LFile, LSource, LResult: TStringList;
      I, J, K, Processed, WasError, Removed: Integer;
      SkipPropData: Boolean;
      FLOpt: TFileListOptions;
      S: String;
begin
      LFile := TStringList.Create;
      LSource := TStringList.Create;
      LResult := TStringList.Create;
  try
    if chbxSubFolders.Checked then
      FLOpt := [flFullNames, flRecursive]
    else
      FLOpt := [flFullNames];

    if not AdvBuildFileList(IncludeTrailingBackslash(edPath.Text) + '*.DFM', faAnyFile, LFile, FLOpt) then
    begin
      MessageBox(Handle,
        'Invalid path specified. Can not process.',
        'Warning',
        MB_OK or MB_ICONEXCLAMATION);
      exit;
    end;

    Processed := 0;
    WasError := 0;

    for I := 0 to LFile.Count - 1 do
    begin
      LSource.LoadFromFile(LFile[I]);
      Removed := 0;

      for K := 0 to mPropList.Lines.Count - 1 do
      begin
        if K > 0 then
          LSource.Assign(LResult);

        if Trim(mPropList.Lines[K]) = '' then
          continue;

        LResult.Clear;
        SkipPropData := False;

        for J := 0 to LSource.Count - 1 do
        begin
          S := Trim(LSource[J]);

          if SkipPropData then
          begin
            if (S > '') and (S[Length(S)] in [')', '}']) then
              SkipPropData := False;
            continue;
          end;

          if StrIPos(mPropList.Lines[K] + ' =', S) = 0 then
          begin
            LResult.Add(LSource[J]);
            continue;
          end;

          if (S > '') and (S[Length(S)] in ['(', '{']) then
            SkipPropData := True;

          Removed := Removed + 1;
        end;
      end;

      if Removed > 0 then
      begin
        if RenameFile(LFile[I], ChangeFileExt(LFile[I], '.BAK')) then
        begin
          LResult.SaveToFile(LFile[I]);
          Processed := Processed + 1;
        end else
        begin
          MessageBox(Handle,
            PChar('Can not create back up copy for file: ' + LFile[I] + #13#10'File is not processed.'),
            'Warning',
            MB_OK or MB_ICONEXCLAMATION);
          WasError := WasError + 1;
        end;
      end;
    end;

    MessageBox(Handle,
      PChar(Format('Total files found: %d'#13#10'Properties were removed from: %d'#13#10'Error files: %d',
        [LFile.Count, Processed, WasError])),
      'Statistics',
      MB_OK or MB_ICONINFORMATION);
  finally
    LFile.Free;
    LSource.Free;
    LResult.Free;
  end;
end;

Solution

  • We established that:

    • Your mPropList.Lines each contain something like Prop =[...] or SecondProp =[...], and the property name always starts the line.
    • LResult holds the lines that should be kept. So, you don't want to add to that if the strings match, but you do if they don't.

    Putting these together, you want to do LResult.Add() only if StrIPos(...) <> 1. That way, you add

    • lines that don't contain the property name (StrIPos() == 0, i.e. < 1) and
    • lines that contain it as a substring but not at the start, i.e. only within another property name (StrIPos > 1).

    The fixed code will thus look like:

    if StrIPos(mPropList.Lines[K] + ' =', S) <> 1 then
      begin
        LResult.Add(LSource[J]);
        continue;
      end;