Knowledge Base Alert September, 2016







TPlanner:

How to create programatically a plannerItem and start an ItemEditor



Example:

var
  plit: TPlannerItem;
begin
  plit := planner1.CreateItem;
  plit.itembegin := 4;
  plit.itemend := 6;
  plit.itempos := 0;
  plIt.Edit;
end;


TAdvStringGrid:

Using the new OnHoverButtonsShow event to configure different hover buttons for different columns



To do this, enable HoverButtons and implement the OnHoverButtonsRow event that is triggered when the mouse hovers a cell. Here it is possible to control whether hover buttons are shown with the Allow event parameter and from this event, the grid.HoverButtons property can be used to customize hover buttons per cell.

The code to show different hover buttons only for column 4 and 6 is therefore:

procedure TForm1.AdvStringGrid1HoverButtonsShow(Sender: TObject; X, Y: Integer;
  var Allow: Boolean);
var
  c,r: integer;
begin
  AdvStringGrid1.MouseToCell(x,y,c,r);

 if c = 4 then
  begin
    // configure hover buttons here for column 4
    AdvStringGrid1.HoverButtons.Buttons[0].Caption := 'A';
    AdvStringGrid1.HoverButtons.Buttons[1].Caption := 'B';
    AdvStringGrid1.HoverButtons.Column := 4;
  end
  else
  if c = 6 then
  begin
    // configure hover buttons here for column 6
    AdvStringGrid1.HoverButtons.Buttons[0].Caption := 'C';
    AdvStringGrid1.HoverButtons.Buttons[1].Caption := 'D';
    AdvStringGrid1.HoverButtons.Column := 6;
  end
  else
    Allow := false;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AdvStringGrid1.HoverButtons.Enabled := true;
  AdvStringGrid1.HoverButtons.Buttons.Clear;
  AdvStringGrid1.HoverButtons.Buttons.Add.Caption := '0';
  AdvStringGrid1.HoverButtons.Buttons.Add.Caption := '1';
  AdvStringGrid1.AutoNumberRow(0);
  AdvStringGrid1.LinearFill(false);
end;
Result:



TAdvStringGrid:

Changing the font color of a part of the text in a grid cell using rich text



Example:

begin
  AdvStringGrid1.Cells[1,1] := 'Hello world';
  AdvStringGrid1.CellToRich(1,1, AdvStringGrid1.RichEdit);

  AdvStringGrid1.RichEdit.SelStart := 6;
  AdvStringGrid1.RichEdit.SelLength := 5;
  AdvStringGrid1.RichEdit.SelAttributes.Color := clRed;

  AdvStringGrid1.RichToCell(1,1, AdvStringGrid1.RichEdit);
end;


TAdvCheckedTreeView:

Using the DataObject



The DataObject can hold any object you like, but you are responsible for cleaning up any references to avoid memory leaks.
A typical use:

type
  TPerson = class
    FName: string;
    FBirthDay: TDateTime;
  public
    constructor Create(AName: string; ABirthDay: TDateTime);
    property Name: string read FName;
    property BirthDay: TDateTime read FBirthDay;
  end;

...

implementation

...

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  n: TAdvCheckedTreeViewNode;
begin
  FPersons := TObjectList<TPerson>.Create;
  FPersons.Add(TPerson.Create('Tom Jones', EncodeDate(2016, 1, 1)));
  FPersons.Add(TPerson.Create('John Appleseed', EncodeDate(2016, 1, 2)));

  AdvCheckedTreeView1.Nodes.Clear;
  AdvCheckedTreeView1.Columns[0].Text := 'Name';
  AdvCheckedTreeView1.Columns.Add.Text := 'Birthday';
  for I := 0 to FPersons.Count - 1 do
  begin
    n := TAdvCheckedTreeViewNode(AdvCheckedTreeView1.Nodes.Add);
    n.Text[0] := FPersons[I].Name;
    n.Text[1] := DateToStr(FPersons[I].Birthday);
    n.CheckTypes[0] := tvntCheckBox;
    n.DataObject := FPersons[I];
  end;
end;

{ TPerson }

constructor TPerson.Create(AName: string; ABirthDay: TDateTime);
begin
  FName := AName;
  FBirthday := ABirthDay;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FPersons.Free;
end;
Now when selecting, editing, expanding a node, you can always directly use the DataObject and cast it to TPerson:

procedure TForm1.AdvCheckedTreeView1AfterCheckNode(Sender: TObject;
  ANode: TAdvTreeViewVirtualNode; AColumn: Integer);
var
  p: TPerson;
begin
  if Assigned(ANode.Node) and Assigned(ANode.Node.DataObject) then
    p := TPerson(ANode.Node.DataObject);
end;


TAdvCheckedTreeView:

Multi-column checked listbox via TAdvCheckedTreeView





procedure TForm1.FormCreate(Sender: TObject);
var
  c: TAdvTreeViewColumn;
  n: TAdvTreeViewNode;
  I: Integer;
begin
  AdvCheckedTreeView1.BeginUpdate;
  AdvCheckedTreeView1.Columns.Clear;
  c := AdvCheckedTreeView1.Columns.Add;
  c.Text := 'Col 1';
  c := AdvCheckedTreeView1.Columns.Add;
  c.Text := 'Col 2';
  c := AdvCheckedTreeView1.Columns.Add;
  c.Text := 'Col 3';

  AdvCheckedTreeView1.Nodes.Clear;
  AdvCheckedTreeView1.NodesAppearance.LevelIndent := 0;
  AdvCheckedTreeView1.NodesAppearance.ExpandWidth := 0;
  AdvCheckedTreeView1.NodesAppearance.ExpandHeight := 0;
  AdvCheckedTreeView1.NodesAppearance.ShowLines := False;
  AdvCheckedTreeView1.NodesAppearance.SelectionArea := tsaFull;

  for I := 0 to 9 do
  begin
    n := AdvCheckedTreeView1.Nodes.Add;
    n.CheckTypes[0] := tvntCheckBox;
    n.Text[0] := 'Item ' + inttostr(I);
    n.Text[1] := 'Item ' + inttostr(I);
    n.Text[2] := 'Item ' + inttostr(I);
  end;
  AdvCheckedTreeView1.EndUpdate;
end;


TMS WebGMaps:

Increase maximum number of allowed waypoints when using GetDirections



The number of waypoints is limited to 8. When an API key is assigned, up to 23 waypoints are allowed. This is a limitation of the Google Directions API which we have no control over.

Example:

  WebGMaps1.APIKey := 'abc';
Detailed information about Google Maps Directions API usage limits can be found here:
https://developers.google.com/maps/documentation/directions/usage-limits



TTMSFNCListBox:

Rating



procedure TForm3.FormCreate(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to TMSFNCListBox1.Items.Count - 1 do
    TMSFNCListBox1.Items[I].DataInteger := RandomRange(1, 6)
end;

procedure TForm3.TMSFNCListBox1AfterDrawItem(Sender: TObject;
  AGraphics: TTMSFNCGraphics; ARect: TRectF; AItem: TTMSFNCListBoxItem);
var
  r: Integer;
  I: Integer;
  bmp: TBitmap;
  rrt: TRectF;
begin
  r := AItem.DataInteger;
  bmp := TMSFNCBitmapContainer1.FindBitmap('rating');
  for I := 0 to r - 1 do
  begin
    rrt := RectF(Round(ARect.Right - ((bmp.Width + 4) * (I + 1))), Round(ARect.Top + (ARect.Height - bmp.Height) / 2),
      Round(ARect.Right - ((bmp.Width + 4) * I)), Round(ARect.Top + (ARect.Height - bmp.Height) / 2 + bmp.Height));

    AGraphics.DrawBitmap(rrt, bmp);
  end;
end;



TTMSFMXDirectoryTreeView:

How to display folders first followed by files as in File Explorer



You could accomplish this by using the following code.

procedure TForm1.FormCreate(Sender: TObject); 
begin
  TMSFMXDirectoryTreeView1.Filter := '';
  TMSFMXDirectoryTreeView1.LoadDirectory('E:\');
  TMSFMXDirectoryTreeView1.Sort(0, True, True, nsmDescending); 
end;

procedure TForm1.TMSFMXDirectoryTreeView1AfterExpandNode(Sender: TObject; ANode: TTMSFMXTreeViewVirtualNode);
begin
  TMSFMXDirectoryTreeView1.Sort(0, True, True, nsmDescending); 
end;

procedure TForm1.TMSFMXDirectoryTreeView1NodeCompare(Sender: TObject; Node1, Node2: TTMSFMXTreeViewNode; AColumn: Integer; var ACompareResult: Integer); var
  n1: TTMSFMXDirectoryTreeViewNode;
  n2: TTMSFMXDirectoryTreeViewNode;
begin
  n1 := TTMSFMXDirectoryTreeViewNode(Node1);
  n2 := TTMSFMXDirectoryTreeViewNode(Node2);
  ACompareResult := AnsiCompareStr(ExtractFileExt(n1.FileName), ExtractFileExt(n2.FileName));
  if ACompareResult = 0 then
    ACompareResult := AnsiCompareStr(n1.StrippedHTMLText[AColumn], n2.StrippedHTMLText[AColumn]);
    ACompareResult := ACompareResult * -1; 
end;

TMS FixInsight:

W1035 Return value of function '%s' might be undefined



Did you know that Delphi compiler warning "W1035 Return value of function '%s' might be undefined" works only with simple types like integers, but never work for managed types like strings or interfaces?

Using FixInsight's rule W521 you can handle ANY type:

function TForm1.TestInteger: Integer;
begin

end;

Delphi Compiler: W1035 Return value of function 'TForm1.TestInteger' might be undefined
FixInsight: W521 Return value of function 'TForm1.TestInteger' might be undefined

function TForm1.TestString: string;
begin

end;
Delphi Compiler: NOTHING
FixInsight: W521 Return value of function 'TForm1.TestString' might be undefined


As always, we thank all users for the numerous inputs, feedback, comments and suggestions. This is an invaluable help to steer our developments here at TMS software. We continue to look forward to all your further communications to direct our team to provide you better tools and components for your needs.

Kind regards,
TMS software team
Email: info@tmssoftware.com
Web: http://www.tmssoftware.com
Support, FAQ & Manuals: http://www.tmssoftware.com/site/support.asp


Follow latest developments at tmssoftware.com




NOTICE: If you wish to unsubscribe from the TMS software Newsletter, please click here.