Child tables

From Team Developer SqlWindows Wiki
Jump to: navigation, search

Child Table, Grid & Column


Pointer2.png What message is send when a DropDown column item is selected (clicked) Pointer.png

When an item from a column dropdown list is selected, the message SAM_AnyEdit is send to the column message actions section.

Pointer2.png How to hide the window displayed in the taskbar when a column dropdown list is opened Pointer.png

When you open the dropdown list of a table column, a window is shown on the Windows taskbar.
To get rid of this window use this code under the message actions of the table column

First declare these three WinApi functions in the external functions section

Library name: USER32.DLL
   Function: FindWindowA
      Export Ordinal: 0
         Window Handle: HWND
         String: LPCSTR
         String: LPCSTR

   Function: GetWindowLongA
      Export Ordinal: 0
         Number: LONG
         Window Handle: HWND
         Number: INT

   Function: SetWindowLongA
      Export Ordinal: 0
         Number: LONG
         Window Handle: HWND
         Number: INT
         Number: LONG

Also declare these constants

   Number: GWL_EXSTYLE      = -20
   Number: WS_EX_TOOLWINDOW = 0x80

Here the actual code for removing the window from the taskbar

On SAM_DropDown
   Set hWndDropDown = FindWindowA( "Gupta:DropDown", "" )
   If NOT hWndDropDown
      ! Maybe it is an older TD version, so search for another classname
      Set hWndDropDown = FindWindowA( ":DropDown", "" )
   If hWndDropDown
      If NOT GetWindowLongA( hWndDropDown,GWL_EXSTYLE ) & WS_EX_TOOLWINDOW
         Call SetWindowLongA( hWndDropDown, GWL_EXSTYLE, GetWindowLongA( hWndDropDown,GWL_EXSTYLE ) | WS_EX_TOOLWINDOW )

Here you can download a sample:

Pointer2.png Double Height column headers Pointer.png

It isn't obvious that this could be done but just embed a newline in the column title to display multiple lines in the column header.
Works at design time, just embed ctrl/enter in the column's "Object Title" property, or at run time using SalTblSetColumnTitle()

Call SalTblSetColumnTitle ( tblX.columnN, "Column header part 1 
		column header part 2" )

Pointer2.png How to set popup-edit columns to read-only or to disabled state Pointer.png

On columns having cell-type 'Popup edit' there are only two states available:

  • Editable Yes
  • Editable No

When the column is editable, the text inside the popup edit box can be selected and changed.
When the column is not editable, the popup edit box is not presented when clicking on a cell.

So it is not possible to see the contents of a cell without allowing the user to change the text.

The next solution adds two more options for Popup edit columns:

  • Readonly
  • Disabled

The trick is to get the window handle of the popup edit box and use it to set it to read-only or disabled states.

Declare these constants

   Number: WM_USER              = 0x0400
   Number: SAM_GetExtEdit       = WM_USER + 119
   Number: EM_SETREADONLY       = 0x00CF

The constant SAM_GetExtEdit is an internal undocumented message to get the edit part of popup edit columns.

The next piece of code shows how to get the window handle of the edit box and set it to read-only or disabled.
Here is a table called tblTest which contains a column col1 having type 'Popup edit':

   Set nPopup = SalSendMsg( tblTest, SAM_GetExtEdit, SalTblQueryColumnID( tblTest.col1 ) - 1, 0 )
   If nPopup > 0
      Set hWndPopUp = SalNumberToWindowHandle( nPopup )
      ! Set it to READ ONLY
      Call SalSendMsg( hWndPopUp, EM_SETREADONLY, TRUE, 0 )
      ! Or set it to disabled
      Call SalDisableWindow( hWndPopUp )

Here you can download a sample:

Pointer2.png Table vs Grid: performance overview Pointer.png

To have a concrete basis on which object to use when large amounts of data need to be displayed, I performed some comparison tests on the table and grid.
The test application populates large amounts of rows and shows the time it takes to display the data.

First, I was curious about the differences between TD versions and also the difference between the good old table object and the grid.
Also to determine which method is best to populate tables and grids when performance is required: using SalTblInsertRow vs SalTblSetRange.

The test does only a raw populate, having only a few basic column types. No database access and no business logic.
At least it can give some idea which object has the potential best performance and also which TD version does it best.

So, here are the results. They are created on one fast development system. The tests are performed multiple times and are averaged.
Smaller bars in the graphs are better, the times are in milliseconds.

Table object: performance comparison between TD versions

Table AllTDVersions.png

The results are clear. On raw performance the ANSI TD 4.2 version is the best performer, followed closely by TD 6.2 and TD6.3.
There are huge differences between the latest TD versions (6.3 and 6.2) and the older ones (5.x, 6.0 and 6.1).
TD 5.x is about 2 times slower on the same test.
So when performance on tables is really needed and you are on these TD versions, there will be a great gain in porting to the latest TD versions.

Table vs Grid (only TD 5.x and up)

Table vs Grid.png

TD 5.x is not only slower on tables, but grids are really slow on those versions. TD 5.x has a crawling speed populating large datasets.
What is surprising that the grid actually performs slightly better in the latest TD versions compared to tables.
But it is a very small difference.

SalTblInsert vs SalTblSetRange (tables)

Insert vs SetRange.png

This is interesting. When you know the amount of rows to populate, the SalTblSetRange method is the most performant.
On tables, this method will be 2-4 times faster compared to SalTblInsertRow.
So, if you want to populate large amounts of data, try SalTblSetRange to see the speed you will gain.

Tables vs Grid vs methods all TD versions

TableGrid AllTDVersions.png

We see here that the huge difference between SalTblInsertRow and SalTblSetRange is not that pronounced on Grids.
The difference is smaller compared to tables.

Overall conclusion from these results:

  • SalTblSetRange is faster compared to SalTblInsertRow on all TD versions
  • TD 5.x performs poorly on tables and specially on grids
  • TD 6.2/TD 6.3 : no clear difference between table and grid performance and on par with older ANSI TD versions (4.2 was tested)
  • When large amounts of data need to be displayed as fast as possible, use Table combined with SalTblSetRange to get the best performance.

Here the test application. The archive contains also the Excel file to create the graphs.
Please do your own tests, fill in the numbers and the graphs will update and show your personal results on your system.