Propriety vs Proprietary

  • Propriety: Behavior or actions that are socially acceptable, proper, or in line with established norms or standards.

    For example, “She always behaves with propriety in formal settings.”

  • Proprietary: Commonly used in the context of ownership or rights to something, especially intellectual property. It refers to something that is privately owned or exclusive to a particular entity.

    For example, “The company has a proprietary software solution that they developed in-house.”

Delphi: Excel Row and Column Count

How to get correct row and column numbers of any Excel file (XLS or XLSX):

var
  Excel, Book, Sheet: OleVariant;
  RowNumber: integer;
  ColNumber: integer;
const
  xlCellTypeLastCell = $0000000B; // ExcelXP
begin
  ...

  Book := Excel.Workbooks.Open(ExcelFilename,
                               False,   // ConfirmConversions
                               True );  // ReadOnly

  Sheet := Book.Worksheets[1];

  //RowNumber := Sheet.UsedRange.EntireRow.Count;    // May be wrong!
  //ColNumber := Sheet.UsedRange.EntireColumn.Count; // May be wrong!
  RowNumber := Sheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row;
  ColNumber := Sheet.UsedRange.SpecialCells(xlCellTypeLastCell).Column;
end;

Read more: https://stackoverflow.com/questions/11886284/usedrange-count-counting-wrong

Example software:
XLS to CSV Converter
CSV to VCF Converter

Delphi: Pos Functions

Pos function (case-sensitive)

  • The Pos function returns the position of a substring within a string. If the substring is found, Pos returns the 1-based index of the first occurrence of the substring; otherwise, it returns 0.
  • PosEx is equivalent to System.Pos.
  • You should ideally use AnsiPos instead of Pos since the former supports wide character sets!
var
  MainStr, SubStr: string;
  Position: Integer;
begin
  MainStr := 'Hello World';
  SubStr := 'World';
  Position := Pos(SubStr, MainStr);
  if Position > 0 then
    ShowMessage('Substring found at position: ' + IntToStr(Position))
  else
    ShowMessage('Substring not found');
end;

AnsiPos function (case-sensitive)

var
  MainStr, SubStr: string;
  Position: Integer;
begin
  MainStr := 'Hello World';
  SubStr := 'World';
  Position := AnsiPos(SubStr, MainStr);
  if Position > 0 then
    ShowMessage('Substring found at position: ' + IntToStr(Position))
  else
    ShowMessage('Substring not found');
end;

StrPos function (case-sensitive)

var
  MainStr, SubStr: string;
  Position: Integer;
begin
  MainStr := 'Hello World';
  SubStr := 'World';
  if StrPos(PChar(MainStr), PChar(SubStr)) <> nil then
    ShowMessage('Substring found')
  else
    ShowMessage('Substring not found');
end;

AnsiStrPos function (case-sensitive)

Unlike the StrPos function, AnsiStrPos works with multi-byte characters sets (MBCS).

var
  MainStr, SubStr: string;
  Position: Integer;
begin
  MainStr := 'Hello World';
  SubStr := 'World';
  if AnsiStrPos(PChar(MainStr), PChar(SubStr)) <> nil then
    ShowMessage('Substring found')
  else
    ShowMessage('Substring not found');
end;

TextPos function (case-insensitive)

var
  MainStr, SubStr: string;
  Position: Integer;
begin
  MainStr := 'Hello World';
  SubStr := 'World';
  if TextPos(PChar(MainStr), PChar(SubStr)) <> nil then
    ShowMessage('Substring found')
  else
    ShowMessage('Substring not found');
end;

Other Useful Functions

.ContainsCase-Sensitive
.StartsWithCase-Sensitive
.EndsWithCase-Sensitive
AnsiContainsStrCase-Sensitive
AnsiStartsStrCase-Sensitive
AnsiEndsStrCase-Sensitive
AnsiContainsTextCase-Insensitive
AnsiStrings.ContainsTextCase-Insensitive
StrUtils.ContainsTextCase-Insensitive

Delphi: Run DOS Commands

ShellExecute

Results can’t be read easily!

https://engineertips.wordpress.com/2021/02/22/delphi-shellexecute-alternatives/

TDOSCommand Component

https://github.com/TurboPack/DOSCommand

Results can be read by using OnNewLine event!

https://engineertips.wordpress.com/2022/04/21/delphi-tdoscommand-eassertionfailed-error/

GetDosOutput Procedure

Results can be read by using a Memo or RichEdit!

procedure GetDosOutput(CommandLine, WorkDir: string; aMemo: TMemo);
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of AnsiChar;
  BytesRead: Cardinal;
  Handle: Boolean;
begin
  //AMemo.Lines.Add('Commencing processing...');
  with SA do begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
  try
    with SI do
    begin
      FillChar(SI, SizeOf(SI), 0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;
    Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
                            nil, nil, True, 0, nil,
                            PChar(WorkDir), SI, PI);
    CloseHandle(StdOutPipeWrite);
    if Handle then
      try
        repeat
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
          if BytesRead > 0 then
          begin
            Buffer[BytesRead] := #0;
            AMemo.Text := AMemo.Text + String(Buffer);
          end;
        until not WasOK or (BytesRead = 0);
        WaitForSingleObject(PI.hProcess, INFINITE);
      finally
        CloseHandle(PI.hThread);
        CloseHandle(PI.hProcess);
      end;
  finally
    CloseHandle(StdOutPipeRead);
    //AMemo.Lines.Add('Processing completed successfully.');
    //AMemo.Lines.Add('**********************************');
    //AMemo.Lines.Add('');
  end;
end;

Delphi: TStringGrid Tips

Fix “horizontal scroll requires releasing mouse button”

StringGrid1.Options := StringGrid1.Options + [goThumbTracking];

Go to top and select first cell

StringGrid1.Selection := TGridRect(Rect(1, 1, 1, 1));
StringGrid1.TopRow := 1;
StringGrid1.LeftCol := 1;

Example Software: Container Loading Calculator

Other StringGrid Tips

Delphi: TrackBar MouseEnter and MouseLeave

TTrackBar doesn’t have built-in MouseEnter, MouseLeave, MouseMove, MouseDown events.

  private
    { Private declarations }
    FTrackEnter: Boolean;
    procedure CMMouseEnter( var Message : TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave( var Message : TMessage); message CM_MOUSELEAVE;

procedure TForm1.CMMouseEnter( var Message : TMessage);
var
  ptWork: TPoint;
begin
  GetCursorPos(ptWork);
  if WindowFromPoint(ptWork) = TrackBar1.Handle then //Mouse is over TrackBar1
  begin
    FTrackEnter := True;
  end;
end;

procedure TForm1.CMMouseLeave( var Message : TMessage);
var
  ptWork: TPoint;
begin
  GetCursorPos(ptWork);
  if (WindowFromPoint(ptWork) <> TrackBar1.Handle) and
     (FTrackEnter) then //Mouse leaves TrackBar1
  begin
    FTrackEnter := False;
  end;
end;