Knowledge Base Alert June, 2017


How to restrict or bias the items displayed in TWebGMapsLookupEdit to a certain location.

  • Assign the desired location coordinates to the LocationBias.Latitude and Location.Longitude properties
  • Assign the radius (in meters) around the location within which to display results.
  • Set the LocationBias.BiasType to btBias to activate the Biasing based on the location and radius. Or set LocationBias.BiasType to btStrict to display only places that are strictly within the region defined by location and radius.


  WebGMapsLookupEdit1.LocationBias.Latitude := WebGMaps1.MapOptions.DefaultLatitude;
  WebGMapsLookupEdit1.LocationBias.Longitude := WebGMaps1.MapOptions.DefaultLongitude;
  WebGMapsLookupEdit1.LocationBias.Radius := 5000;
  WebGMapsLookupEdit1.LocationBias.BiasType := btStrict;

TMS Cryptography Pack:

How to encrypt a message using a key derived from a password

This example uses the the Argon2, ed25519 and AES algorithms with the TArgon2KeyDerivation, TECCEncSign and TAESEncryption components.

Alice wants to send a message to Bob, so she has his public key (he uses the ed25519 algorithm).

The password can be requested to Alice using a dialog box.

Alice can use the following function to encrypt a message to Bob :

function EncryptMessageToBob(password: string; input: string; BobPublicKey: string): string;
  aesKey: string;
  eccCipher, aesCipher : string;
  Argon2.StringSalt := '0123456789012345';
  Argon2.outputFormat := raw;
  aesKey := Argon2.GenerateKey(password);
  ECC.PublicKey := BobPublicKey;
  eccCipher := ecc.Encrypt(aesKey);
  aes.Key := aesKey;
  aesCipher := aes.Encrypt(input);
  Result := eccCipher + '+' + aesCipher;

To decrypt Alice’s message, Bob can use the following function:

function DecryptMessageFromAlice(input: string; BobPrivateKey: string): string;
  eccCipher, aesCipher: string;
  aesKey: string;
  eccCipher := input.subString(0, Pos('+', input) - 1);
  aesCipher := input.subString(Pos('+', input), input.Length);
  ECC.PrivateKey := BobPrivateKey;
  aesKey := ecc.Decrypt(eccCipher);
  aes.Key := aesKey;
  Result := aes.Decrypt(aesCipher);

In the subsequent messages, Alice and Bob can save the aesKey and not send the eccCipher string.

TMS TPlannerMonthView:

Get the date clicked on a TPlannerMonthView from the right mouse click

You can use PlannerMonthView.DateAtXY() to convert mouse coordinates to a date clicked.


procedure TForm3.PlannerMonthView1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  dt: TDateTime;
  if Button = mbRight then
    caption := DateToStr(dt);

TMS TAdvStringGrid:

Using a memo dropdown editor for the TAdvStringGrid with content in readonly memo

This requires putting the memo control on the memo dropdown editor for TAdvStringGrid in readonly mode after it was displayed. Default, this memo is not in readonly mode. To do this, the event handler for the dropdown on the dropdown editor can be assigned via:

  AdvStringGrid1.MemoDropDown.OnDropDown := MemoDropDown;

and from this MemoDropDown event handler, the memo can be set in read only mode.

The full code becomes:

  TForm1 = class(TForm)
    AdvStringGrid1: TAdvStringGrid;
    procedure FormCreate(Sender: TObject);
    { Private declarations }
    { Public declarations }
    procedure MemoDropDown(Sender: TObject; var acceptdrop: boolean);

  Form1: TForm1;


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
  AdvStringGrid1.DefaultEditor := edMemoDropDown;
  AdvStringGrid1.Options := advstringgrid1.Options + [goEditing];
  AdvStringGrid1.Cells[1,1] := 'This is a long text in a cell that can be viewed (readonly) in the dropdown editor';
  AdvStringGrid1.MemoDropDown.OnDropDown := MemoDropDown;

procedure TForm1.MemoDropDown(Sender: TObject;var acceptdrop: boolean);
  AdvStringGrid1.MemoDropDown.Memo.ReadOnly := true;

TMS TAdvStringGrid:

Moving rows with cells using objects in the grid with drag & drop

It is possible to move rows around in the grid via OLE drag & drop and the nice extra the user gets is a drag image of the rows being dragged during the drag & drop operation. This operation is enabled with the settings under grid.DragDropSettings.

To drag entire rows within the grid, this is enabled via:

  grid.DragDropSettings.OleDropTarget := true;
  grid.DragDropSettings.OleDropSource := true;
  grid.DragDropSettings.OleEntireRows := true;

To enable that rows within the grid are being moved with this drag & drop operation, these additional settings are required:

  grid.DragDropSettings.OleInsertRows := true;
  grid.DragDropSettings.OleRemoveRows := true;

As this drag & drop operation is based on OLE drag & drop and makes as such interoperability with other Windows applications possible, the default information involved in the drag & drop is the cell text. This implies that with default settings, objects associated with cells are not moved within the grid. To enable this, set grid.Navigation.AllowFmtClipboard = true. With this flag, the full cell settings, i.e. text & properties and associated object are copied via the clipboard.

The entire code to demonstrate this becomes:
// event handler to show where cell objects are used

procedure TForm1.gridGetCellColor(Sender: TObject; ARow,
  ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
  if grid.Objects[acol,arow] = TObject(1) then
    abrush.Color := clRed;

procedure TForm1.FormCreate(Sender: TObject);

  grid.Objects[1,3] := TObject(1);
  grid.Objects[1,5] := TObject(1);
  grid.Objects[1,7] := TObject(1);

  grid.DragDropSettings.OleDropTarget := true;
  grid.DragDropSettings.OleDropSource := true;
  grid.DragDropSettings.OleEntireRows := true;
  grid.DragDropSettings.OleInsertRows := true;
  grid.DragDropSettings.OleRemoveRows := true;
  grid.Navigation.AllowClipboardAlways := true;
  // enable this to see cell objects being moved with drag & drop too
  grid.Navigation.AllowFmtClipboard := true;

  grid.Options := grid.Options + [goRowSelect];

TMS TDBAdvRichEditor:

Persisting rich text from a rich editor in a binary blob field or memo field

When using TDBAdvRichEditor, this is expected to be connected to a binary blob field to persist the rich text in a database field. In this case, the data is persisted in the blob field as a binary Delphi object stream. It is thus required that it is connected to a binary blob field, otherwise, loading back the data from the blob will fail.

If it is wanted that the data is persisted in a memo (text) field, you can do this by connecting a regular TAdvRichEditor to a non-visual component TDBAdvRichEditorRTFIO. This non-visual component will convert the TAdvRichEditor content to a text RTF stream and vice versa and as such a regular DB memo text field can be used for persisting the rich editor content.


Rendering complex graphics in the PDF Library

A full sample source application can be downloaded via:


Setting up your form fast and easy with TMS FNC Blox control and selector

  1. Create a new VCL, LCL or FMX application and open the main form.
  2. Drop an instance of TTMSFNCBloxControl on the form
  3. Drop an instance of TTMSFNCBloxSelector on the form
  4. Notice the green checkmark indicating the TTMSFNCBloxSelector instance has found the TTMSFNCBloxControl instance
  5. Run the application and start designing your blox diagram.

TMS Aurelius:

Reading Text Blobs with TMS Aurelius

When reading blobs that contain text values, you might get undesired results given the confusion of what encoding to be used with the raw blob content. To make sure everything is correct, you should add the [DBTypeMemo] attribute to your mapped blob field/property:

FMyBlob: TBlob;

and then use AsUnicodeString property to read/write text:

MyBlobValue := MyObject.MyBlob.AsUnicodeString;
MyObject.MyBlob.AsUnicodeString := ‘Some value’;

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
Support, FAQ & Manuals:

Follow latest developments at

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