-- Page 4 --
Last updated: 02/18/2005

Below is a list of Delphi code tips that I have come across from personal experience and various newsgroups.  I collect bits and pieces of code that I find very useful and place them all in one unit so they are accessed easily in other Delphi projects.  You are free to download this unit here.

Download the unit containing all the source found on these Code Tips pages by clicking on the spinning disk on the left or here. You will need WinZip or Pkunzip to unzip the file.  After unzipping the unit to a directory of your choice, simply add it to your project's uses clause and you're ready to use the code.

Note: all of this code has been tested and compiled in Delphi 3, 4 & 5.  If you find ANY problems with compiling or running the code in your project, please let me know and I will do my best to help resolve your issue.  Thanks!

  1. Trimming multiple characters from a string.
  2. Trimming/replacing all instances of a character in a string.
  3. Using CreateProcess() to launch another application.
  4. Using CreateProcess() to launch another application and wait until it's finished.


This is the same as the TrimAllChar() function, but can delete a set of characters from a string. See the comment for an example of the usage. Thanks to Jeff Hamblin <[email protected]> for this code.

type
  TDelChars = set of Char;

function DeleteCharsFromString(const TempStr: string; DelChars: TDelChars): string;
{ func to delete all occurrences of each char in a set from a string. }
{ e.g. DeleteCharsFromString('$12,345.67', ['$', ',']) will return '12345.67' }
{ Thanks to Jeff Hamblin for this code. Email: [email protected] }
{ Web: http://www.qtools.com }

var
  i: integer;
begin
  Result := TempStr;
  for i := Length(result) downto 1 do
    if Result[i] in DelChars then
      Delete(result, i, 1);
end;


Sometimes you want to replace or remove all instances of a character in a string.  Say you have '000123' and you want '123'.  Call this function like this:  tmpStr := TrimAllChar('000123', '0');  You can replace the '' with any character you want.

{Removes/replaces all occurences of a character from a string}
function TrimAllChar(const S: string; const ch: Char): string;
var
  buf: string;
begin
  buf := S;
  Result := '';
  {while Pos finds a blank}
  while (Pos(ch, buf) > 0) do
    begin
      {copy the substrings before the blank in to Result}
      Result := Result + Copy(buf, 1, Pos(ch, buf) - 1);
      buf := Copy(buf, Pos(ch, buf) + 1, Length(buf) - Pos(ch, buf));
    end;
  {There will still be a remainder in buf, so copy remainder into Result}
  Result := Result + buf;
end;


A useful function to launch another executable, batch file, PIF file, etc. in Delphi on a 32-bit platform.  Simply pass the name of the executable and the Visibility type (SW_SHOWNORMAL, SW_HIDE, etc.  You can find a list of them in Win32.hlp under 'ShowWindow()'). If you want your program to wait until the launched application is finished, see WinExecAndWait32().

Added CloseHandle() calls to close the handles since they are no longer needed. Thanks to Kevin S. Gallagher for this addition.

function WinExec32(FileName: string; Visibility: integer): boolean;
var
  zAppName: array[0..512] of char;
  zCurDir : array[0..255] of char;
  WorkDir : string;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  StrPCopy(zAppName, FileName);
  GetDir(0, WorkDir);
  StrPCopy(zCurDir, WorkDir);
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  Result := CreateProcess(nil,
                          zAppName, { pointer to command line string }
                          nil,      { pointer to process security attributes }
                          nil,      { pointer to thread security attributes }
                          False,    { handle inheritance flag }
                          CREATE_NEW_CONSOLE or { creation flags }
                          NORMAL_PRIORITY_CLASS,
                          nil,      { pointer to new environment block }
                          nil,      { pointer to current directory name }
                          StartupInfo,  { pointer to STARTUPINFO }
                          ProcessInfo); { pointer to PROCESS_INF }

  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ProcessInfo.hThread);
end;


This function is the same as WinExec32(), but it allows you to tell Delphi to wait until the launching application is done before continuing on to the next line of code.  Again, the list of variables passed to Visibility is in Win32.hlp under 'ShowWindow()'.

Added CloseHandle() calls to close the handles since they are no longer needed. Thanks to Kevin S. Gallagher for this addition.

{$DEFINE Delphi3Below}
{$IFDEF VER130} //Delphi 5
  {$UNDEF Delphi3Below}
{$ELSE}
  {$IFDEF VER120} //Delphi 4
    {$UNDEF Delphi3Below}
  {$ENDIF}
{$ENDIF}

{ WinExecAndWait32 ******************************************** }
{ 32 bit routine that will launch an app and wait for it to     }
{ finish. Works on 32 bit & 16 bit exe's as well as .pifs       }
{ ************************************************************* }
function WinExecAndWait32(FileName: string; Visibility: integer): integer;
{ returns -1 if the Exec failed, otherwise returns the process' }
{ exit code when the process terminates.                        }
var
  zAppName: array[0..512] of char;
  zCurDir : array[0..255] of char;
  WorkDir : string;
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  {$IFNDEF Delphi3Below}
    CardinalResult: cardinal;
  {$ENDIF}
begin
  StrPCopy(zAppName, FileName);
  GetDir(0, WorkDir);
  StrPCopy(zCurDir, WorkDir);
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := Visibility;
  if not CreateProcess(nil,
                       zAppName, { pointer to command line string }
                       nil, { pointer to process security attributes }
                       nil, { pointer to thread security attributes }
                       false, { handle inheritance flag }
                       CREATE_NEW_CONSOLE or { creation flags }
                       NORMAL_PRIORITY_CLASS,
                       nil, { pointer to new environment block }
                       nil, { pointer to current directory name }
                       StartupInfo, { pointer to STARTUPINFO }
                       ProcessInfo) then { pointer to PROCESS_INF }
    Result := -1
  else
    begin
      WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
      {$IFNDEF Delphi3Below}
        GetExitCodeProcess(ProcessInfo.hProcess, CardinalResult);
        Result := CardinalResult;
      {$ELSE}
        GetExitCodeProcess(ProcessInfo.hProcess, Result);
      {$ENDIF}
      CloseHandle(ProcessInfo.hProcess);
      CloseHandle(ProcessInfo.hThread);
    end;
end;


-- End of Page 4 --