From the team with love: the new TMS Component Pack 8.3

Thursday, July 14, 2016

We're excited to present the newest edition of the TMS Component Pack v8.3, our pack of over 400 VCL UI controls to make powerful, feature-rich Windows applications with Delphi & C++Builder.

The TMS Component Pack first version dates back from 1998 when our customers started asking for a bundle of our grid component and growing number of additional VCL UI controls developed by then.

TMS Component Pack is as such 18 years in the making and it's a relentless job to keep fine-tuning existing controls to changing needs, changing UI requirements, new UI paradigms & themes, new feature requests and add create brand new controls. Both surprising and exciting is that during all these 18 years, almost on a weekly basis, new ideas come in from you and from our team for component features and new components. A lot of our customers using TMS Component Pack UI controls are as passionate as our team about getting exactly the right look & feel, behavior and capabilities from the controls.

With this new version v8.3 we have added the usual list of new features, improvements and fixes. You can always consult this list here. One especially bigger extension was drag & drop support, sorting & filtering in our supercharged multicolumn treeview control. But in this blog, I wanted to draw your attention to new controls added in this release.

First of all, there is the new TAdvSearchList / TAdvSearchEdit.

The design of this component is inspired by new paradigms in search controls featured mostly on websites. Websites like Amazon, AliExpress, Google, Facebook, Booking.com, Trivago, ... all help the user in search by filtered suggestion lists as you type. TAdvSearchList is the basis for such list and offers a multicolumn list with optional categorized items, pictures, text and description with items, a place to show a number of search results and various criteria to find a match from first character, anywhere in a word, in text only or text and description etc...

Where the list control can be easily hooked up to a separat edit control and perform its search & filtering, the TAdvSearchEdit has the list embedded in a dropdown and it features additional optional buttons for directly filtering per categories when categories are used. It can as such be configured as a simple list to more complex and attractive looking lookup lists like this example:



Second new control added as is TAdvResponsiveList (preview).

The TAdvResponsiveList is a VCL UI control inspired by responsive design techniques and bringing this paradigm to Windows controls.As is the case with browsers, where we want to offer the best experience regardless of the browser client area size, Windows applications can also benefit from adapting the control's look & feel and behavior to the control's size to ensure the experience with your application is optimal regardless of the size of the screen of the user or regardless of a user running your application in a small window just in a corner of his desktop.



In a nutshell, TAdvResponsiveList offers a variable number of conditions that can be set for rendering its content depending on the size of the control. This can range from the number of columns depending on the width, the number or rows depending on the height, the absolute or relative size of cells when the control is resizing etc... As each cell offers rendering of HTML formatted text and this HTML formatted text can be the result of a template and in the conditions, variable templates can be set depending on the condition, i.e. size of the control. This way, more or less detail can be shown in the control item depending on its size.
But the sheer flexibility of this control becomes apparent when TAdvResponsiveList instances can be used as a child control in a TAdvResponsiveList and both parent and child can have their set of conditions. Or when you can create your own control descending from TAdvResponsiveList that can have fully custom drawn items.
A first developers guide to TAdvResponsiveList is available now. With TMS Component Pack 8.3, you can explore and start using the control from today in your applications. It is for now still marked as being in preview as this is all new to VCL application developers and we're eager to learn about your thoughts, comments, feedback, ideas & suggestions for next iterations of TAdvResponsiveList.

Bruno Fierens




This blog post has received 2 comments. Add a comment.



Introducing tag based search on TMS software website

Since 1995, the year Delphi was born, TMS software has been creating components and tools for developers for 21 years now and in all these years, our offerings have grown significantly. From the beginning, we have focused on VCL UI controls but soon controls for IntraWeb and .NET were added. As soon as Embarcadero introduced the cross-platform FireMonkey (FMX) framework, we started to create UI controls for this framework as well. Around the same time, a product line to help you with your business logic, the TMS Business Subscription set of products was created. Then the explosion of cloud services came and we jumped on that bandwagon with our series of cloud components to make it dead-easy to connect & consume these cloud services. Recently, our newest line of UI controls, the FNC (Framework Neutral Components) was launched where the focus is on offering you one set of components, one learning-curve and the freedom to use the controls (simultaneously or not with a single source base) for VCL Windows applications, FMX cross platform applications with Delphi or C++Builder or take a different route with the free Lazarus IDE/FPC compiler and the LCL framework to target Windows, Linux, macOS, ...

We have long lost count of the number of components we have on offer and we have been wrestling a lot with trying to present our products as logically structured, easy to find and to discover as possible. With the introduction of our new website v5.0 end of May this year, a strong focus was on organisation per technology/framework with color coding of technologies for easy recognition. In the product popup accessible from the top menu, the organisation is more semantically, grouping by themes like grids, charts, cloud, ...

But long on our todolist was also a system to tag our components and make tag based search possible this way. Well, today, I'm happy to introduce our tag based search on our website. Our tag based search is not replacing regular text based search or navigation mechanisms per technology/framework or theme. It is just one more way, one more tool to help you find what you are looking for.

Note that from now on, our products display their tags at the bottom of the product page and tag based search can be started from clicking on these tags but is also possible from the product popup or regular search started from the top right corner.

To see the tag search in action, here is a sample where a search for a treeview control is done. The word treeview can be typed or picked from the tag list. The search returns the different products, nicely color coded per technology in what products we offer a treeview control:



We hope this additional tool on our website will help you finding what you need faster. As time evolves and with your feedback, we'll further fine-tune & extend the tags. Let us know what you think about it and how you like it!

Bruno Fierens




This blog post has received 4 comments. Add a comment.



Delphi Cookbook 2ed for TMS FixInsight Customers

Wednesday, July 13, 2016



Delphi Cookbook 2ed by Daniele Teti is finally available. It is a best seller for PacktPub in its category, you can find more information about the book on its author blog.

I am honored to be the reviewer of the second edition. It was an exciting adventure to take a look behind the curtains of book publishing. And I have to say that Daniel did a great job.

Like any cookbook, this book is a collection of recipes. It is exactly what a "cookbook" should be. Recipes are very different - from the use of VCL styles to the drawing on a FMX ListView component, and from examples of functional programming in Delphi to importing a Java-library interface in Android. Over 60 recipes, according to the cover :)

Personally for me, the most interesting part of this book is not the essence of the recipes themselves, but the fact that the author uses all Delphi innovations when it's possible. This was very interesting to watch. Delphi has been developing very quick in recent years, and we are not always aware of how much is new in the recent versions.

I therefore recommend Delphi Cookbook primarily for those who still works with older versions of Delphi and wants to take a closer look at the innovations. Although those who work with the latest version will definetely find something to expand their horizons too. And it particularly useful as a reference book.

PacktPub was so kind to offer 50% discount on the ebook for FixInsight customers. If you order a FixInsight license in July you will get a discount coupon for the book on PacktPub website.


Roman Yankovsky




This blog post has not received any comments yet. Add a comment.



Windows 10 funnies

Thursday, July 07, 2016

This isn't the first funny Windows 10 behavior I encounter that makes a developer scratch his head but I thought to share this particular one.

As it happens, here at TMS software, we quite often deal with grid related code, be it with our VCL TAdvStringGrid or FMX TTMSFMXGrid or FNC TTMSFNCGrid and when doing some testing code for our grid, why not create a new Delphi project Grid.dproj. To my surprise, compiling & running this app from the Delphi 10.1 Berlin IDE shows a funny black notification window for a moment on startup. The notification changes randomly and always informs about some shortcut keys.
My initial thought was that our grid code somehow erratically triggered something in the new Win 10 toast notification code in the Delphi 10.1 Berlin VCL. But no, even after removing our grid component, the notification kept coming. The app reduced to its minimum of an empty form with a single label shows the notification on startup.


Form at design time


Form at runtime

Then we created a new application, called Project1.dproj and surprise,... no such shortcut notification. Next logical step .. compare the grid.dproj file and the project1.dproj file to see if there was some difference in the .dproj file that could trigger this behavior. But no, no suspicious differences found.
Next we suspected a virus and therefore tested the app source on a different Windows 10 machine and the magic notification popped up again.

At that point, Google is your friend and after a quite long search, it leaded to suspect the XBox games Grid and Grid2 where Windows shows a notification of shortcuts for games. Searching the XBox store indeed reveals such game Grid and Grid2.



And yes, renaming the Delphi project to grid2.dproj will also make the notification appear for grid2.exe but not so with grid3.dproj or any other combination.

Being still intrigued by this Windows behavior, we thought that Windows 10 had perhaps some registry key that contains apps for which to show these notifications on startup, but nowhere grid.exe or grid2.exe could be found in the registry. That leaves us with the assumption that somewhere hidden in the Windows 10 source code, there must be a hardcoded reference to grid.exe and grid2.exe.
Conclusion in a nutshell: do not ship Delphi apps named grid.exe or grid2.exe to your customer if you want to avoid your customer asking questions about a weird notification coming up. :)

Bruno Fierens




This blog post has received 4 comments. Add a comment.



TMS X-Cloud Todolist with FNC

Wednesday, June 22, 2016

It's almost three months since we released the first version of the TMS FNC UI Pack, a set of Framework Neutral Components (FNC), and have meanwhile released 2 major updates which include the TTMSFNCTabSet/TTMSFNCPageControl (v1.1), the recently introduced TTMSFNCListBox/TTMSFNCCheckedListBox and significant improvements / new features to the TTMSFNCTreeView such as filtering, sorting, keyboard lookup, clipboard support, ... (v1.2).

As already explained in previous blog posts (http://www.tmssoftware.com/site/blog.asp?post=335 and http://tmssoftware.com/site/blog.asp?post=346), the TMS FNC UI Pack is a set of UI controls that can be used from VCL Windows applications, FireMonkey (FMX) Windows, Mac OS-X, iOS, Android applications and LCL framework based Lazarus applications for Windows, Linux, Mac OS-X, ... . The TMS FNC UI Pack contains highly complex & feature-rich components such as grid, planner, rich editor, treeview, toolbars. So, with a single set of controls, you have the freedom of choice to use Delphi, C++Builder or the free Lazarus to create applications for a myriad of operating systems, you have a single learning curve to these components and as demonstrated here, you can use a single source to create apps for multiple targets.

This blog post will cover the TTMSFNCCheckedListBox, which is one of the new components that are added in the latest release (v1.2) of the TMS FNC UI Pack, show how to use myCloudData.net to store data and demonstrate how easy it is to switch between FMX, VCL and LCL with one shared source code. myCloudData is an easy to use & flexible service to make use of structured storage in the cloud from Windows, web, mobile or IoT apps and is offered by tmssoftware.com. myCloudData is OAUTH/JSON REST based and our TMS Cloud Pack includes a component to access the service and thus your data seamlessly.

Click image for more screenshots.

A single shared source

As with our TV-guide sample we have created a single shared source file that is used in a FMX, VCL and LCL project. The unit starts by defining the business logic class that will be instantiated in our application main form unit.
  TTODOListLogic = class
  private
    FTable: TMyCloudDataTable;
    FListBox: TTMSFNCCheckedListBox;
    FMyCloudDataAccess: TMyCloudDataAccess;
    FOnConnected: TNotifyEvent;
    FBitmapContainer: TTMSFNCBitmapContainer;
  protected
    procedure DoConnected(Sender: TObject);
  public
    destructor Destroy; override;
    procedure InitListBox(AListBox: TTMSFNCCheckedListBox);
    procedure InitMyCloudData;
    procedure Refresh;
    procedure InitializeTable;
    procedure AddNewItem(AText: string; ADate: TDateTime; APriority: TPriority);
    procedure DeleteItem;
    procedure Connect;
    procedure DoBeforeDrawItem(Sender: TObject; AGraphics: TTMSFNCGraphics; ARect: TRectF; AItem: TTMSFNCListBoxItem; var AAllow: Boolean; var ADefaultDraw: Boolean);
    procedure DoItemCheckChanged(Sender: TObject; AItem: TTMSFNCCheckedListBoxItem);
    procedure DoItemCompare(Sender: TObject; Item1, Item2: TTMSFNCListBoxItem; var ACompareResult: Integer);
    property OnConnected: TNotifyEvent read FOnConnected write FOnConnected;
    property BitmapContainer: TTMSFNCBitmapContainer read FBitmapContainer write FBitmapContainer;
  end;
Each framework has its own set of units in order to compile succesfully. We use the conditional defines added to our project to make the difference between each framework.
uses
  Classes, SysUtils, DB
  {$IFDEF VCL}
  ,VCL.TMSFNCListBox, VCL.TMSFNCCheckedListBox, CloudMyCloudData, CloudBase, VCL.TMSFNCUtils,
  CloudCustomMyCloudData, VCL.TMSFNCGraphics, VCL.Dialogs, VCL.TMSFNCTypes, Types, VCL.TMSFNCBitmapContainer;
  {$ENDIF}

  {$IFDEF FMX}
  ,FMX.TMSFNCListBox, FMX.TMSFNCCheckedListBox, FMX.TMSCloudMyCloudData, FMX.TMSCloudBase,
  FMX.TMSFNCUtils, FMX.TMSCloudCustomMyCloudData, FMX.TMSFNCGraphics, FMX.TMSFNCTypes, FMX.Dialogs, Types, FMX.TMSFNCBitmapContainer;
  {$ENDIF}

  {$IFDEF LCL}
  ,LCLTMSFNCListBox, LCLTMSFNCCheckedListBox, LCLTMSCloudMyCloudData, LCLTMSCloudBase,
  LCLTMSFNCUtils, LCLTMSCloudCustomMyCloudData, LCLTMSFNCGraphics, Dialogs, LCLTMSFNCTypes, LCLTMSFNCBitmapContainer;
  {$ENDIF}

myCloudData

As our todolist is storing its todo items in the cloud we take advantage of our own service, that can virtually store anything we want. The initialization is done programmatically.
procedure TTODOListLogic.InitMyCloudData;
begin
  FMyCloudDataAccess := TMyCloudDataAccess.Create(nil);
  FMyCloudDataAccess.PersistTokens.Location := plIniFile;
  {$IFDEF FMX}
  FMyCloudDataAccess.PersistTokens.Key := TTMSFNCUtils.GetDocumentsPath + PthDel + 'myclouddatafmx.ini';
  FMyCloudDataAccess.OnConnected := DoConnected;
  {$ENDIF}
  {$IFDEF VCL}
  FMyCloudDataAccess.PersistTokens.Key := TTMSFNCUtils.GetDocumentsPath + PthDel + 'myclouddatavcl.ini';
  FMyCloudDataAccess.OnConnected := DoConnected;
  {$ENDIF}
  {$IFDEF LCL}
  FMyCloudDataAccess.PersistTokens.Key := TTMSFNCUtils.GetDocumentsPath + PthDel + 'myclouddatalcl.ini';
  FMyCloudDataAccess.OnConnected := @DoConnected;
  {$ENDIF}
  FMyCloudDataAccess.PersistTokens.Section := 'tokens';
  FMyCloudDataAccess.App.Key := MYCLOUDDATAKEY;
  FMyCloudDataAccess.App.Secret := MYCLOUDDATASECRET;
  FMyCloudDataAccess.App.CallBackPort := 8888;
  FMyCloudDataAccess.App.CallBackURL := 'http://127.0.0.1:8888';
end;
You might notice 3 things here. First is the TMyCloudDataAccess class which is common between FMX, VCL and LCL. This is defined earlier in our business logic as the unit names are different for FMX, VCL and LCL.
type
  {$IFDEF VCL}
  TMyCloudDataAccess = class(TAdvMyCloudData);
  {$ENDIF}

  {$IFDEF FMX}
  TMyCloudDataAccess = class(TTMSFMXCloudMyCloudData);
  {$ENDIF}

  {$IFDEF LCL}
  TMyCloudDataAccess = class(TTMSLCLCloudMyCloudData);
  {$ENDIF}
Second, is the event handler assignment, that we also need to wrap with conditional defines because LCL works with an additional @. Third is the ini file that is also created with a framework suffix, as the token and token encryption are unique per application and not shareable. After defining our business logic, it's time to setup our GUI. The form unit is shared between FMX, VCL and LCL and there you will also notice the uses list and the form file is separated with defines. After designing our form (using the TTMSFNCCheckedListBox, some tool bar buttons (TTMSFNCToolBarButton) we are ready to connect to our business logic and create a working todo list that stores its items in the cloud.
procedure TTODOListForm.DoConnected(Sender: TObject);
begin
  Panel1.Enabled := True;
  Panel2.Enabled := True;
  TMSFNCToolBarButton2.Enabled := False;
  TMSFNCCheckedListBox1.Enabled := True;
  TMSFNCToolBarButton4.Enabled := True;
  TMSFNCToolBarButton5.Enabled := True;
  TMSFNCToolBarButton6.Enabled := True;
  TMSFNCToolBarItemPicker1.Enabled := True;
  FTODOListLogic.InitializeTable;
  FTODOListLogic.Refresh;
end;

procedure TTODOListForm.FormCreate(Sender: TObject);
begin
  FTODOListLogic := TTODOListLogic.Create;
  FTODOListLogic.InitListBox(TMSFNCCheckedListBox1);
  FTODOListLogic.InitMyCloudData;
  {$IFDEF LCL}
  FTODOListLogic.OnConnected := @DoConnected;
  {$ELSE}
  FTODOListLogic.OnConnected := DoConnected;
  {$ENDIF}
  TMSFNCCheckedListBox1.BitmapContainer := TMSFNCBitmapContainer1;
  TMSFNCToolBarItemPicker1.BitmapContainer := TMSFNCBitmapContainer1;
  TMSFNCToolBarItemPicker1.Bitmaps.Clear;
  TMSFNCToolBarItemPicker1.Bitmaps.AddBitmapName('low');
  TMSFNCToolBarItemPicker1.DisabledBitmaps.Assign(TMSFNCToolBarItemPicker1.Bitmaps);
  TMSFNCToolBarButton2.DisabledBitmaps.Assign(TMSFNCToolBarButton2.Bitmaps);
  TMSFNCToolBarButton4.DisabledBitmaps.Assign(TMSFNCToolBarButton4.Bitmaps);
  TMSFNCToolBarButton5.DisabledBitmaps.Assign(TMSFNCToolBarButton5.Bitmaps);
  TMSFNCToolBarButton6.DisabledBitmaps.Assign(TMSFNCToolBarButton6.Bitmaps);

  dt := TMyDateTimePicker.Create(Self);
  {$IFDEF FMX}
  dt.Position.X := 5;
  dt.Position.Y := 40;
  {$ELSE}
  dt.Left := 5;
  dt.Top := 40;
  {$ENDIF}
  dt.Date := Now;
  dt.Parent := Panel1;
  dt.Width := 105;
end;

procedure TTODOListForm.FormDestroy(Sender: TObject);
begin
  FTODOListLogic.Free;
end;

procedure TTODOListForm.TMSFNCCheckedListBox1ItemSelected(Sender: TObject;
  AItem: TTMSFNCListBoxItem);
begin
  TMSFNCToolBarButton6.Enabled := True;
end;

procedure TTODOListForm.TMSFNCToolBarButton1Click(Sender: TObject);
begin
  FTODOListLogic.Refresh;
end;

procedure TTODOListForm.TMSFNCToolBarButton2Click(Sender: TObject);
begin
  FTODOListLogic.Connect;
end;

procedure TTODOListForm.TMSFNCToolBarButton3Click(Sender: TObject);
begin
  FTODOListLogic.DeleteItem;
end;

procedure TTODOListForm.TMSFNCToolBarButton4Click(Sender: TObject);
begin
  FTODOListLogic.AddNewItem(Edit1.Text, dt.Date, TPriority(TMSFNCToolBarItemPicker1.SelectedItemIndex));
end;

procedure TTODOListForm.TMSFNCToolBarItemPicker1ItemSelected(Sender: TObject;
  AItemIndex: Integer);
begin
  TMSFNCToolBarItemPicker1.Bitmaps.Clear;
  TMSFNCToolBarItemPicker1.Bitmaps.AddBitmapName(TMSFNCBitmapContainer1.Items[AItemIndex].Name);
  TMSFNCToolBarItemPicker1.DisabledBitmaps.Assign(TMSFNCToolBarItemPicker1.Bitmaps);
end;
When starting the application, and clicking the connect button, our business logic unit will do the work. It will create a table in myCloudData, send a notification to our GUI, which will then allow to add items to our listbox, refresh or delete existing items, and this is done with one source code, available on multiple frameworks, multiple platforms.

The full source code is available for download

Click image for more screenshots.

Pieter Scheldeman




This blog post has not received any comments yet. Add a comment.




Previous  |  Next  |  Index