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 you patch the component itself, or you just remove the last character after each time you call 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 *

%d bloggers like this: