Day 025 - Control notes, and some thoughts on record- vs set-oriented processing

The Q&A section on controls (beginning on page 227) clarified a few things for me, among them that a control that is associated with no plane (I keep wanting to call them panes) is visible on all planes. 

I opened a project I'd last had open during a BSOD (I'm having video driver issues) and got this window:

That last message on the window looked interesting to me - I loaded the Retrieved version and went to the file menu and chose Versions. I got this window:

I noticed that I could also create a new version of my window here, and it all made me wonder if this project used SCM. So I went to the SCM menu and chose the Administrator window, but it didn't show any projects. 

From this it seems that some degree of versioning is supported outside of source code management. 

Anyway, back to planes. There's a plane mode toolbar (Display | Toolbars | Planes | Other Planes | Plane mode) that helps you visualize your controls and lets you edit the control captions. It also seems like you should be able to move items around in the toolbar but I couldn't get that to work. 

Closely related to planes are tabs. There's an example of tab management code on page 229:

SWITCH NameTabControl
  CASE 1 // first pane
  // ...process to perform...
  CASE 2 // second pane
  // ...process to perform...
  OTHER CASE
  // ...Other processes to perform...
END

Panes and planes - I'm sure I'll eventually get them straight. 

There are other useful tidbits in this section such as creating a main menu, opening an HTML page and using the property syntax to change colors. Notably, WinDev, like Clarion, uses RGB color codes. Few other tools do. 

Passing parameters

In WinDev, when you create a window there's an implicit procedure that calls that window. If you want to pass parameters to the window you need to add a statement like the following to the window's global variables code section:

PROCEDURE WindowName(Param1,Param2,Param3="some value"...)

Note the syntax for Param3 - this is an optional parameter because it's assigned a default value.

Control groups

Controls can be grouped logically. Just select the controls and choose Control | Groups | Associate the selection. At that point you are supposed to be able to name the group and then change any common properties of the contained controls by changing the values on the group.

I had trouble getting this to work - I could create the group, but I'd done so and then clicked on some other control I couldn't find a way to get back to the group - clicking on the controls just selected them individually again. 

Databases and analyses

Lesson 4.1 covers the different ways of accessing databases. Available data access modes include:

  • native
  • OLE DB
  • ODBC
  • ODBC via OLE DB

Native access is standard for:

  • HyperFileSQL (WinDev)
  • xBase
  • MS Access
  • XML
  • SQLite

Native access is optional (meaning a separate driver purchase, except as noted) for:

  • Oracle
  • AS/400
  • SQL Server
  • Sybase
  • Informix
  • DB2
  • Progress
  • MySQL (free)
  • PostgreSQL

Direct ODBC access uses the 32 bit ODBC layer (I wonder what happens when you try to build a 64 bit app...) and only supports the SQL* database access functions.

OLE DB supports both the SQL* and the HRead* functions, as does ODBC via OLE DB. 

The data access function library

The HRead* functions are part of a larger library of around HyperFileSQL 200 functions. This has caused me a little confusion, because although the H at the start of each function name apparently stands for HyperfileSQL most of these functions can be used with databases other than WinDev's own SQL database. So maybe it's a case of the library originally being written only for HyperFileSQL and the repurposed for databases in general. 

The H* functions at first struck me as purely record oriented; there is also a much smaller set of SQL* functions for set-oriented operations. 

As for the difference, flat files are record oriented - when you retrieve data, you always retrieve the entire record, since there's usually no way to differentiate the different elements of the record without first retrieving the whole record. In SQL, on the other hand, you can tell the server which field(s) you'd like from which table(s). 

The choice between record- and set-oriented processing is an important one for large systems; typically you don't want to  retrieve all of the fields in a record.

But you're not actually restricted to record-oriented processing with the H* functions. If you use them on a query (or so I'm told) you're really only dealing with the fields returned by the query, so you can effectively mix and match set- and record-oriented operations. 

I asked a question about this in the WinDev Skype chat and Pete Halsted replied:

Dave for me if I am doing any kind of "where" clause then I do an HexecuteQuery with a SQL statement in it (datasource on the fly - what we always wanted in CW). If I have a Primary key and I am trying to grab the record I usually use an Hreadseekfirst, which does grab the entire record, but usually in those situations I am dealing with several fields (dispalying form, etc. Or I am using FileToScreen to populate a screen) If I was working on a distrubuted app that I knew was going to be communicating over a slow connection etc. I woul probably do everything with Hexecutesql. But in the eniroments that I design for, reading 1 complete record in isn't a big enough cost to justify creating sql statements and managing the moves to screen fields etc. Myself. And I figure Andy once notice a few HreadseekFirst statements bettered in nearly as much as he would Select * from,  even though they do the same thing at the end of the day