Multimedia development 02-19-2016

February 20, 2016

Fix the TStringList of Delphi7

We came on an annoying bug with the TStringList of delphi7.

At the end of the list, there’s always a linebreak (#10#13) added. We found 2 different solutions to this problem. Either we had to patch the component itself, or we just had to remove the last character after each time we called the .Text function.

Solution 1 (Patch component) :

// Fix TStringList

type
  TCustomStringList = class(TStringList)
  protected
    function GetTextStr: string; override;
  end;

function TCustomStringList.GetTextStr: string;
var
  I, L, Size, Count: Integer;
  P: PChar;
  S, LB: string;
begin
  Count := GetCount;
  Size := 0;
  LB := sLineBreak;
  for I := 0 to Count - 1 do begin
    if (I < (Count - 1)) then
      Inc(Size, Length(Get(I)) + Length(LB))
    else
      Inc(Size, Length(Get(I)))
  end;
  SetString(Result, nil, Size);
  P := Pointer(Result);
  for I := 0 to Count - 1 do
  begin
    S := Get(I);
    L := Length(S);
    if L <> 0 then
    begin
      System.Move(Pointer(S)^, P^, L);
      Inc(P, L);
    end;
    L := Length(LB);
    if (L <> 0) and (I < ( Count - 1 )) then
    begin
      System.Move(Pointer(LB)^, P^, L);
      Inc(P, L);
    end;
  end;
end;

Solution 2 (Remove character) :

myText : string;
myText := MyStringList.Text;
// Remove the last linebreak
myText := copy(myText, 0, length(myText) - length(sLineBreak));

Dark or light

We programmed a function which detects if a color is dark or light.

Function IsDarkColor(color : TColor):Boolean;
var a: Single;
begin
a := 1 - ( 0.299 * GetRValue(color) + 0.587 * GetGValue(color) + 0.114 * GetBValue(color)) / 255;
Result := (a > 0.5);
end;

How many lines?

While creating the functionality to render subtitle files for Multimedia, we came across a hard problem. We had to find a way to detect the total height of text written on a TPanel. This text had also the possibility to wordwrap. So we couldn’t just base ourself on (# of the caption lines.count * TextHeight).

Here’s how we did it.

function GetNumberOfLinesInCaption(APanel: TPanel): Integer;
var
  r: TRect;
  h: Integer;
begin
  h := APanel.Canvas.TextHeight(APanel.Caption);
  if h = 0 then begin
    Result := 0;
    Exit;
  end; //empty caption

  FillChar(r, SizeOf(TRect), 0);
  R.Top := APanel.Top;
  R.Bottom := APanel.Height;
  R.Left := APanel.Left;
  R.Right := APanel.Width;
  
  if 0 = DrawText(APanel.Canvas.Handle, PChar(APanel.Caption), Length(APanel.Caption), r, DT_EDITCONTROL or DT_WORDBREAK or DT_CALCRECT) then
  begin
    Result := -1;
    Exit;
  end; //function call has failed

  Result := (R.Bottom - R.Top) div h;
end;

Thank you for reading. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *