git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1451 8e941d3f-bd1b-0410-a28a-d453659cc2b4
		
			
				
	
	
		
			447 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			447 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
program DfmToLfm;
 | 
						|
 | 
						|
{
 | 
						|
  Converts Delphi form design file to a Lazarus form file by
 | 
						|
   deleting properties that are not supported by LCL and 
 | 
						|
   optionally making changes to font properties. (The resulting
 | 
						|
   Lazarus form file can then be converted to a Lazarus resource
 | 
						|
   file with LazRes, although this second step is only needed
 | 
						|
   now with Lazarus 0.9.28 and earlier.)
 | 
						|
 | 
						|
  Note that the Delphi form file must be a text file.
 | 
						|
 | 
						|
  List of properties to delete and other configuration settings
 | 
						|
   are read from dfmtolfm.ini.
 | 
						|
 | 
						|
  This utility (and Lazarus LazRes, if needed) can be used whenever 
 | 
						|
   design changes are made to the form in Delphi. 
 | 
						|
 | 
						|
  Note: You can use MakePasX to make the form's code file
 | 
						|
   cross-platform (a one-time conversion).
 | 
						|
 | 
						|
  Author:    Phil Hess.
 | 
						|
  Copyright: Copyright (C) 2007-2011 Phil Hess. All rights reserved.
 | 
						|
  License:   Modified LGPL.
 | 
						|
}
 | 
						|
 | 
						|
(*
 | 
						|
  Note: This converter can also convert a Lazarus form file to
 | 
						|
   another Lazarus form file (.lfm -->.lfm). This can be useful
 | 
						|
   if you need to conditionally include a different form depending 
 | 
						|
   on widgetset target. Example:
 | 
						|
 | 
						|
  {$IFNDEF LCLCarbon}
 | 
						|
   {$R *.lfm}  //include generic form with Windows and Linux
 | 
						|
  {$ELSE}
 | 
						|
   {$R *.mac.lfm}  //include prettied form with Mac (-m -s switches)
 | 
						|
  {$ENDIF}
 | 
						|
  
 | 
						|
  In this case, you would make changes in Lazarus only to the 
 | 
						|
   generic form file, then convert it to use with Mac:
 | 
						|
     dfmtolfm myform.lfm myform.mac.lfm -m -s
 | 
						|
*)
 | 
						|
 | 
						|
 | 
						|
{$IFDEF FPC}
 | 
						|
 {$MODE Delphi}
 | 
						|
{$ELSE}
 | 
						|
 {$APPTYPE CONSOLE}
 | 
						|
{$ENDIF} 
 | 
						|
{$R+,Q+}
 | 
						|
 | 
						|
uses
 | 
						|
  SysUtils,
 | 
						|
  IniFiles;
 | 
						|
 | 
						|
const
 | 
						|
  ProgramName    = 'DfmToLfm';
 | 
						|
  ProgramVersion = '0.04';
 | 
						|
  
 | 
						|
  DfmFileExt     = '.dfm';  {Delphi form file extension}
 | 
						|
  LfmFileExt     = '.lfm';  {Lazarus form file extension}
 | 
						|
  CfgFileExt     = '.ini';  {Extension for file with same name as program
 | 
						|
                              containing configuration settings}
 | 
						|
 | 
						|
  NoFontChanges  = 0;       {No font switch on command line}
 | 
						|
  UseParentFont  = 1;       {-p font switch on command line}
 | 
						|
  DeleteFontName = 2;       {-d font switch on command line}
 | 
						|
  SubstFontName  = 3;       {-s font switch on command line}
 | 
						|
  
 | 
						|
  MaxNestedObjs  = 20;      {Maximum depth of nested controls on form}
 | 
						|
  MaxFontProps   = 5;       {Maximum font properties that can be saved}          
 | 
						|
  
 | 
						|
type
 | 
						|
  TStackRec   = record      {Info about form objects}
 | 
						|
    ClassName   : string;
 | 
						|
    FontPropCnt : Integer;
 | 
						|
    FontAdded   : Boolean;
 | 
						|
    FontProps   : array [1..MaxFontProps] of string;
 | 
						|
    end;
 | 
						|
 | 
						|
var
 | 
						|
  CfgFileName : string;
 | 
						|
{$IFNDEF FPC}
 | 
						|
  MatchFound  : TFilenameCaseMatch;
 | 
						|
{$ENDIF}
 | 
						|
  FontSwitch  : Integer;
 | 
						|
  MacSwitch   : Boolean;
 | 
						|
  CfgFileObj  : TMemIniFile;
 | 
						|
  InFileName  : string;
 | 
						|
  IsDfmInFile : Boolean;
 | 
						|
  OutFileName : string;
 | 
						|
  InFileVar   : TextFile;
 | 
						|
  OutFileVar  : TextFile;
 | 
						|
  StackLevel  : Integer;
 | 
						|
  StackRec    : array [1..MaxNestedObjs] of TStackRec;
 | 
						|
  DeleteLine  : Boolean;
 | 
						|
  InStr       : string;
 | 
						|
  StripStr    : string;
 | 
						|
  SkipStr     : string;
 | 
						|
  ParentLevel : Integer;
 | 
						|
  FontPropNum : Integer;
 | 
						|
 | 
						|
begin
 | 
						|
 | 
						|
   {Base configuration file name on program file location and program name}
 | 
						|
  CfgFileName := 
 | 
						|
   ExtractFilePath(ParamStr(0)) + LowerCase(ProgramName) + CfgFileExt;
 | 
						|
{$IFNDEF FPC}
 | 
						|
  CfgFileName := ExpandFileNameCase(CfgFileName, MatchFound);
 | 
						|
{$ENDIF}
 | 
						|
 | 
						|
  if ParamCount = 0 then  {List program syntax and exit?}
 | 
						|
    begin
 | 
						|
    WriteLn(ProgramName, ', version ', ProgramVersion);
 | 
						|
    WriteLn('Converts a Delphi (or Lazarus) form file to a Lazarus form file.');
 | 
						|
    WriteLn;
 | 
						|
    WriteLn('Usage: ', LowerCase(ProgramName), ' infile[', DfmFileExt, '|',
 | 
						|
            LfmFileExt, '] [outfile.lfm] [-p|-d|-s][-m]');
 | 
						|
    WriteLn;
 | 
						|
    WriteLn('Switches:');
 | 
						|
    WriteLn('  -p  Add parent''s font to controls with no font ',
 | 
						|
            '(useful with Windows).');
 | 
						|
    WriteLn('  -d  Delete font name from controls ',
 | 
						|
            '(useful with GTK and GTK2).');
 | 
						|
    WriteLn('  -s  Substitute font names (useful with non-Windows targets).');
 | 
						|
    WriteLn('  -m  Mac prettifier.');
 | 
						|
    WriteLn;
 | 
						|
    WriteLn('Example:');
 | 
						|
    WriteLn('  ', LowerCase(ProgramName),
 | 
						|
            ' MainForm.dfm -s -m  (Creates MainForm.lfm, substituting fonts');
 | 
						|
    WriteLn('    and prettying form for use on Mac.)');
 | 
						|
    WriteLn;
 | 
						|
    WriteLn('Notes:');
 | 
						|
    WriteLn('  ', ProgramName, ' will look for its configuration data here:');
 | 
						|
    WriteLn('    ', CfgFileName);
 | 
						|
    WriteLn;
 | 
						|
    WriteLn('  See also the comments at top of ', LowerCase(ProgramName), 
 | 
						|
            '.pas.');
 | 
						|
    Halt;
 | 
						|
    end;
 | 
						|
 | 
						|
   {Check for command line switches}
 | 
						|
  FontSwitch := NoFontChanges;
 | 
						|
  if FindCmdLineSwitch('p', ['-'], True) then
 | 
						|
    FontSwitch := UseParentFont
 | 
						|
  else if FindCmdLineSwitch('d', ['-'], True) then
 | 
						|
    FontSwitch := DeleteFontName
 | 
						|
  else if FindCmdLineSwitch('s', ['-'], True) then
 | 
						|
    FontSwitch := SubstFontName;
 | 
						|
  MacSwitch := FindCmdLineSwitch('m', ['-'], True);
 | 
						|
 | 
						|
   {Load configuration file}
 | 
						|
  if not FileExists(CfgFileName) then
 | 
						|
    begin
 | 
						|
    WriteLn('Can''t load program configuration file ', CfgFileName);
 | 
						|
    Halt;
 | 
						|
    end;
 | 
						|
  CfgFileObj := TMemIniFile.Create(CfgFileName);
 | 
						|
  
 | 
						|
   {Get name of input form file from command line}
 | 
						|
  InFileName := ParamStr(1);
 | 
						|
  if ExtractFileExt(InFileName) = '' then  {No extension?}
 | 
						|
    InFileName := InFileName + DfmFileExt;  {Assume it's a Delphi form file}
 | 
						|
{$IFNDEF FPC}
 | 
						|
  InFileName := ExpandFileNameCase(InFileName, MatchFound);
 | 
						|
{$ELSE}
 | 
						|
  InFileName := ExpandFileName(InFileName);
 | 
						|
{$ENDIF}
 | 
						|
  IsDfmInFile := SameText(ExtractFileExt(InFileName), DfmFileExt);
 | 
						|
 | 
						|
   {Get name of output form file from command line or generate it}
 | 
						|
  OutFileName := '';
 | 
						|
  if (ParamStr(2) <> '') and (Copy(ParamStr(2), 1, 1) <> '-') then
 | 
						|
    OutFileName := ParamStr(2)  {Output file specified}
 | 
						|
  else if IsDfmInFile then
 | 
						|
    OutFileName := ChangeFileExt(InFileName, LfmFileExt);
 | 
						|
     {Base Lazarus form file name on Delphi form file name}
 | 
						|
  if OutFileName = '' then
 | 
						|
    begin
 | 
						|
    WriteLn('No output file specified');
 | 
						|
    Halt;  {If converting a Lazarus form file, have to specify output file}
 | 
						|
    end;
 | 
						|
 | 
						|
{$IFNDEF FPC}
 | 
						|
  OutFileName := ExpandFileNameCase(OutFileName, MatchFound);
 | 
						|
{$ELSE}
 | 
						|
  OutFileName := ExpandFileName(OutFileName);
 | 
						|
{$ENDIF}
 | 
						|
 | 
						|
  if SameText(InFileName, OutFileName) then
 | 
						|
    begin
 | 
						|
    WriteLn('Output file is same as input file');
 | 
						|
    Halt;
 | 
						|
    end;
 | 
						|
 | 
						|
   {Open input form file}
 | 
						|
  AssignFile(InFileVar, InFileName);
 | 
						|
  try
 | 
						|
    Reset(InFileVar);
 | 
						|
  except
 | 
						|
    on EInOutError do
 | 
						|
      begin
 | 
						|
      WriteLn('Can''t open input form file ', InFileName);
 | 
						|
      Halt;
 | 
						|
      end;
 | 
						|
    end;
 | 
						|
 | 
						|
   {Create output form file}
 | 
						|
  AssignFile(OutFileVar, OutFileName);
 | 
						|
  try 
 | 
						|
    Rewrite(OutFileVar);
 | 
						|
  except
 | 
						|
    on EInOutError do
 | 
						|
      begin
 | 
						|
      WriteLn('Can''t create output form file ', OutFileName);
 | 
						|
      Halt;
 | 
						|
      end;
 | 
						|
    end;
 | 
						|
 | 
						|
  StackLevel := 0;
 | 
						|
  while not Eof(InFileVar) do  {Read and process input form file}
 | 
						|
    begin
 | 
						|
    DeleteLine := False;
 | 
						|
    ReadLn(InFileVar, InStr);  {Read property from form file}
 | 
						|
    StripStr := StringReplace(InStr, ' ', '', [rfReplaceAll]); {Strip spaces}
 | 
						|
 | 
						|
    if (SameText('object ', Copy(Trim(InStr), 1, 7)) or
 | 
						|
        SameText('end', StripStr)) and  {End of object's props reached?}
 | 
						|
       (StackLevel > 1) and  {Object is nested?} 
 | 
						|
       (not CfgFileObj.ValueExists(
 | 
						|
             'NoFont', StackRec[StackLevel].ClassName)) and  {Class has font?}
 | 
						|
       (StackRec[StackLevel].FontPropCnt = 0) and  {Object has no font?}
 | 
						|
       (FontSwitch = UseParentFont) and  {Okay to insert parent font in object?}
 | 
						|
       (not StackRec[StackLevel].FontAdded) then  {Font not inserted yet?}
 | 
						|
      begin
 | 
						|
      ParentLevel := StackLevel;
 | 
						|
      repeat
 | 
						|
        Dec(ParentLevel);
 | 
						|
      until (ParentLevel = 0) or
 | 
						|
            (StackRec[ParentLevel].FontPropCnt > 0);
 | 
						|
      if ParentLevel > 0 then  {A parent has font?}
 | 
						|
        begin  {Add font properties to current object}
 | 
						|
        for FontPropNum := 1 to StackRec[ParentLevel].FontPropCnt do
 | 
						|
          begin
 | 
						|
          WriteLn(OutFileVar, StringOfChar(' ', (StackLevel-ParentLevel)*2), 
 | 
						|
                  StackRec[ParentLevel].FontProps[FontPropNum]);
 | 
						|
          end;
 | 
						|
        end;
 | 
						|
      StackRec[StackLevel].FontAdded := True;
 | 
						|
      end;
 | 
						|
 | 
						|
    if SameText('object ', Copy(Trim(InStr), 1, 7)) then
 | 
						|
      begin  {Push object's class name on stack}
 | 
						|
      Inc(StackLevel);
 | 
						|
      if Pos(': ', InStr) > 0 then  {Named control?}
 | 
						|
        StackRec[StackLevel].ClassName :=
 | 
						|
         Trim(Copy(InStr, Pos(': ', InStr)+2, MaxInt))
 | 
						|
      else  {Unnamed control}
 | 
						|
        StackRec[StackLevel].ClassName := Trim(Copy(Trim(InStr), 7, MaxInt));
 | 
						|
      StackRec[StackLevel].FontPropCnt := 0;
 | 
						|
      StackRec[StackLevel].FontAdded := False;
 | 
						|
      end
 | 
						|
 | 
						|
    else if SameText('end', StripStr) then
 | 
						|
      begin  {Pop current class from stack}
 | 
						|
      Dec(StackLevel);
 | 
						|
      end
 | 
						|
 | 
						|
    else if SameText('font.', Copy(Trim(InStr), 1, 5)) then
 | 
						|
      begin  {Font property}
 | 
						|
      if FontSwitch = UseParentFont then
 | 
						|
        begin  {Save font property in case need it for child objects}
 | 
						|
        if StackRec[StackLevel].FontPropCnt < MaxFontProps then
 | 
						|
          begin
 | 
						|
          Inc(StackRec[StackLevel].FontPropCnt);
 | 
						|
          StackRec[StackLevel].FontProps[StackRec[StackLevel].FontPropCnt] :=
 | 
						|
          InStr;
 | 
						|
          end;
 | 
						|
        end
 | 
						|
      else if FontSwitch = DeleteFontName then
 | 
						|
        begin
 | 
						|
        if SameText('font.name', Copy(Trim(InStr), 1, 9)) then
 | 
						|
          DeleteLine := True;
 | 
						|
        end;
 | 
						|
       {Check if font property should be deleted from current object}
 | 
						|
      if IsDfmInFile and
 | 
						|
         CfgFileObj.ValueExists('DeleteProps',
 | 
						|
                                StackRec[StackLevel].ClassName + '.' +
 | 
						|
                                Copy(StripStr, 1, Pos('=', StripStr)-1)) then
 | 
						|
        DeleteLine := True;
 | 
						|
      end
 | 
						|
 | 
						|
    else if Copy(StripStr, Length(StripStr), 1) = '<' then  {Skip to end>?}
 | 
						|
      begin
 | 
						|
      repeat
 | 
						|
        WriteLn(OutFileVar, InStr);
 | 
						|
        ReadLn(InFileVar, InStr);
 | 
						|
      until Trim(InStr) = 'end>';
 | 
						|
      end
 | 
						|
 | 
						|
    else if Pos('=', StripStr) > 0 then  {Other property?}
 | 
						|
      begin  {Check if property should be deleted from current object}
 | 
						|
      if IsDfmInFile and
 | 
						|
         (CfgFileObj.ValueExists('DeleteProps', 
 | 
						|
                                 Copy(StripStr, 1, Pos('=', StripStr)-1)) or
 | 
						|
          CfgFileObj.ValueExists('DeleteProps',
 | 
						|
                                 StackRec[StackLevel].ClassName + '.' +
 | 
						|
                                 Copy(StripStr, 1, Pos('=', StripStr)-1))) then
 | 
						|
        begin  {Property or class.property in list of props to delete?} 
 | 
						|
        DeleteLine := True;
 | 
						|
        if Copy(StripStr, Length(StripStr), 1) = '(' then  {Delete > 1 line?}
 | 
						|
          begin
 | 
						|
          repeat
 | 
						|
            ReadLn(InFileVar, SkipStr);
 | 
						|
            SkipStr := Trim(SkipStr);
 | 
						|
          until Copy(SkipStr, Length(SkipStr), 1) = ')';
 | 
						|
          end;
 | 
						|
        end;
 | 
						|
      end;  
 | 
						|
 | 
						|
    if not DeleteLine then  {Include line in output form file?}
 | 
						|
      begin
 | 
						|
      try
 | 
						|
         {If Delphi form file does have Height and Width, reduce
 | 
						|
           to size of its ClientHeight or ClientWidth.}
 | 
						|
        if IsDfmInFile and (StackLevel = 1) and
 | 
						|
           SameText('Height=', Copy(StripStr, 1, 7)) then
 | 
						|
          WriteLn(OutFileVar,
 | 
						|
                  '  Height = ', 
 | 
						|
                  IntToStr(StrToInt(Copy(StripStr, 8, MaxInt)) - 34))
 | 
						|
        else if IsDfmInFile and (StackLevel = 1) and
 | 
						|
                SameText('Width=', Copy(StripStr, 1, 6)) then
 | 
						|
          WriteLn(OutFileVar,
 | 
						|
                  '  Width = ', 
 | 
						|
                  IntToStr(StrToInt(Copy(StripStr, 7, MaxInt)) - 8))
 | 
						|
 | 
						|
         {LCL TGroupBox child controls' Top measures from a lower position
 | 
						|
           within group box than with VCL, so reduce Top value}
 | 
						|
        else if IsDfmInFile and (StackLevel > 1) and
 | 
						|
                SameText('Top=', Copy(StripStr, 1, 4)) and
 | 
						|
                SameText('TGroupBox', StackRec[Pred(StackLevel)].ClassName) then
 | 
						|
          WriteLn(OutFileVar,
 | 
						|
                  Copy(InStr, 1, Succ(Pos('=', InStr))),
 | 
						|
                  IntToStr(StrToInt(Copy(StripStr, 5, MaxInt)) - 16))
 | 
						|
 | 
						|
(*  This incorrect swapping has been fixed in FPC 2.2 based Lazarus releases.
 | 
						|
         {Lazarus IDE appears to swap Top and Left properties for non-visual
 | 
						|
           controls, so swap them for Orpheus table cell controls.}
 | 
						|
        else if ((CompareText('Top=', Copy(StripStr, 1, 4)) = 0) or
 | 
						|
                 (CompareText('Left=', Copy(StripStr, 1, 5)) = 0)) and
 | 
						|
                ((CompareText('TOvcTC', 
 | 
						|
                              Copy(StackRec[StackLevel].ClassName, 1, 6)) = 0) or
 | 
						|
                 (CompareText('TO32TC', 
 | 
						|
                              Copy(StackRec[StackLevel].ClassName, 1, 6)) = 0) or
 | 
						|
                 (CompareText('TOvcController', 
 | 
						|
                              StackRec[StackLevel].ClassName) = 0)) then
 | 
						|
          begin
 | 
						|
          if CompareText('Top=', Copy(StripStr, 1, 4)) = 0 then
 | 
						|
            WriteLn(OutFileVar, 
 | 
						|
                    StringReplace(InStr, 'Top', 'Left', [rfIgnoreCase]))
 | 
						|
          else
 | 
						|
            WriteLn(OutFileVar,
 | 
						|
                    StringReplace(InStr, 'Left', 'Top', [rfIgnoreCase]));
 | 
						|
          end
 | 
						|
*)
 | 
						|
  
 | 
						|
        else if (FontSwitch = SubstFontName) and
 | 
						|
                SameText('font.name', Copy(StripStr, 1, 9)) then
 | 
						|
          begin
 | 
						|
          StripStr := Copy(InStr, Pos('=', InStr)+3, MaxInt); {Name after quote}
 | 
						|
          Delete(StripStr, Length(StripStr), 1);  {Delete closing quote}
 | 
						|
          if MacSwitch and
 | 
						|
             CfgFileObj.ValueExists('MacFontSubstitutes', StripStr) then
 | 
						|
            WriteLn(OutFileVar,
 | 
						|
                    Copy(InStr, 1, Succ(Pos('=', InStr))), '''',
 | 
						|
                    CfgFileObj.ReadString('MacFontSubstitutes', StripStr, ''), 
 | 
						|
                    '''')
 | 
						|
          else if CfgFileObj.ValueExists('FontSubstitutes', StripStr) then
 | 
						|
            WriteLn(OutFileVar,
 | 
						|
                    Copy(InStr, 1, Succ(Pos('=', InStr))), '''',
 | 
						|
                    CfgFileObj.ReadString('FontSubstitutes', StripStr, ''), 
 | 
						|
                    '''')
 | 
						|
          else
 | 
						|
            WriteLn(OutFileVar, InStr);
 | 
						|
          end
 | 
						|
 | 
						|
        else if MacSwitch and
 | 
						|
                (StackLevel > 1) and
 | 
						|
                (SameText('TButton', StackRec[StackLevel].ClassName) or
 | 
						|
                 SameText('TBitBtn', StackRec[StackLevel].ClassName)) and
 | 
						|
                SameText('Height=', Copy(StripStr, 1, 7)) and
 | 
						|
                (StrToInt(Copy(StripStr, 8, MaxInt)) > 22) then
 | 
						|
          WriteLn(OutFileVar,
 | 
						|
                  Copy(InStr, 1, Succ(Pos('=', InStr))), '22')
 | 
						|
           {Reduce button height so it's displayed as oval on Mac.
 | 
						|
            TODO: TSpeedButton too?}
 | 
						|
           
 | 
						|
        else if MacSwitch and
 | 
						|
                (StackLevel > 1) and
 | 
						|
                SameText('TabOrder=', Copy(StripStr, 1, 9)) and
 | 
						|
                CfgFileObj.ValueExists('MacNoFocus',
 | 
						|
                                       StackRec[StackLevel].ClassName) then
 | 
						|
          begin
 | 
						|
          WriteLn(OutFileVar, InStr);  {No change to TabOrder property}
 | 
						|
          WriteLn(OutFileVar,
 | 
						|
                  Copy(InStr, 1, Length(InStr)-Length(Trim(InStr))), {Spaces}
 | 
						|
                  'TabStop = False');  {Control can't receive focus}
 | 
						|
          end
 | 
						|
 | 
						|
        else  {No change to property}
 | 
						|
          WriteLn(OutFileVar, InStr);
 | 
						|
 | 
						|
         {Delphi form files don't always include Height or Width properties,
 | 
						|
           which are required by Lazarus, so add them based on ClientHeight 
 | 
						|
           and ClientWidth properties, which apparently act the same as
 | 
						|
           Height and Width in Lazarus (unlike Delphi).}
 | 
						|
        if IsDfmInFile and
 | 
						|
           (SameText('ClientHeight=', Copy(StripStr, 1, 13)) or
 | 
						|
            SameText('ClientWidth=', Copy(StripStr, 1, 12))) then
 | 
						|
          WriteLn(OutFileVar, 
 | 
						|
                  StringReplace(InStr, 'Client', '',  [rfIgnoreCase]));
 | 
						|
      except
 | 
						|
        on EInOutError do
 | 
						|
          begin
 | 
						|
          WriteLn('Can''t write to output form file ', OutFileName);
 | 
						|
          Halt;
 | 
						|
          end; 
 | 
						|
        end;
 | 
						|
      end;
 | 
						|
    end;  {while not Eof}  
 | 
						|
 | 
						|
  CloseFile(InFileVar);
 | 
						|
  try   
 | 
						|
    CloseFile(OutFileVar);
 | 
						|
  except
 | 
						|
    on EInOutError do
 | 
						|
      begin
 | 
						|
      WriteLn('Can''t close output form file ', OutFileName);
 | 
						|
      Halt;
 | 
						|
      end;
 | 
						|
    end;
 | 
						|
  CfgFileObj.Free;
 | 
						|
  WriteLn(OutFileName, ' successfully created');
 | 
						|
 | 
						|
end.
 | 
						|
 |