CHT Build 26B.00.00
Some time early 2019, we reported a problem to SV about the WHAT() function in the newly released Clarion 11, in conjunction with the BIND() function, in order to bind variables from a VIEW underlying a browse, process or report to give these variables "friendly" names for easier querying.
Back when we first reported this problem, we found that under certain circumstances, some data BIND() calls were causing the Clarion RUN-TIME to choke (i.e. GPF) in C11, though not in 91 or c10, using identical code and identical data structures.
We found some notes recently, that we'd made at the time, in one of our libraries to the effect that BIND() could cause a GPF in C11 and we have just reviewed the problem in both C11 and C11.1.
The notes were written before C11.1 but, having just checked, the reported problem still exhibits in C11.1.
Our conclusion, at the time, was that there are low-level differences in the implementation of BIND(), between the Clarion (C9.1 and C10) vs (C11 and C11.1) run-time libraries.
The problem, however, is not with BIND() per se, but with some ambiguity as regards the use of WHAT() returning a REFERENCE TO A FIELD in some cases and a VALUE FROM A FIELD in other cases.
CHT successfully made a workaround to our filtering classes as regards our implementation of AUTOBIND, to BIND() data table variables with friendlier names for use in CHT queries.
By way of example, a backend field name, such as "CUS:Funky_Field_Name" can be made easily queryable as, ACCOUNT, or CUSTOMER, and so on, depending on the purpose of the field and how you therefore title it in the header of your browse.
To accommodate the run-time differences in C11/C11.1, as noted above, we made some changes to our data filtering library for this CHT template AUTOBIND feature in its use of BIND() statements affiliated with WHAT() queries on table data structures.
Our library code had up until then always automatically called BIND() for a field name such as CUS:ACCOUNT and would AUTOBIND it as "ACCOUNT", without the prefix, so it could queried using simply "ACCOUNT" rather that "CUS:ACCOUNT".
The code changes we made at that time solved the BIND() related GPF's in C11, by not performing any automatic binding on backend variables under circumstances and with data structures that would result in likely C11 GPF's.
It turns out that data structures without "EXTERNAL" names, are good candidates for C11 data inspection issues involving use of the WHAT() function with Clarion11, Clarion11.1.
Hence, we were able to continue (as we are today) using identical CHT class-library code in all versions of Clarion for which CHT develops. (C91, C10, C11, C11.1). And since then, those changes have been perfectly fine and safe, as regards the disappearance of the GPF problem in C11 and C11.1. Problem solved, right?
Yes, the GPF problem is solved, but at the expense of some automatic binding of VIEW structures in browses, processes and reports. That's why we ask you to familiarize yourselves with the information that follows.
So the C11, C11.1 version of WHAT() is still funky today and returns sometimes a reference to the field (expected) and sometimes a value from the field (bad when not expected) depending on the variable type and naming convention in the table structure, which is generated by ABC into a data VIEW structure for browses, reports and processes.
The problem that arises, can be understood as the difference between binding CUS:ACCOUNT to the friendly query word "ACCOUNT" (expected) and the VALUE in the CUS:ACCOUNT field, say, "BARNEY's BAR AND GRILL ON THE RIVER STYX" (not expected and not friendly).
Our automatic binding operation happens in CHT when "AUTOBIND" is set "ON" in any of our templates. In other words, CUS:ACCOUNT becomes "ACCOUNT" for querying via Clarion "NAME BINDING".
No problem there, at all, except for the WHAT() glitch in C11 and C11.1. The one for which we performed a workaround.
As already stated above, our workaround at the time we reported this, was to not call BIND() when the result of a WHAT() inspection of the VIEW field returned anything suspect, like a field VALUE instead of a field NAME.
That resulted, of course, in our AUTOBIND feature not having any effect under certain circumstances, due to it having carefully avoided binding suspect back-end variables, depending on the complexity of the data structure in the file layout and/or the lack of "EXTERNAL" field names in the dictionary.
We have ALWAYS provided alternate means to BIND friendly names to your table fields, (this has been the case for years) in order to provide easy querying on our CHT template browses and with CHT template processes and reports.
The AUTOBIND feature that we've always provided, while useful, is of limited value depending on dictionary data table field names and types.
It can BIND() CUS:ACCOUNT to "ACCOUNT" (a good thing). However, it's of limited value to bind "CUS:Funky_Field_Name" to "FUNKY_FIELD_NAME" for easy querying.
When for whatever reason, you encounter a field name like "CUS:Funky_Field_Name" in your data tables, we provide a "QUERY HOT FIELDS" dialog with which a sensible name like "ACCOUNT" or "CITY", or whatever the field actually represents, and thereafter you can query the field by that more friendly name.
This can happen in plenty of real-world circumstances when you inherit data tables designed with say, DANISH field names and want to query a browse addressed at an ENGLISH audience or vice versa.
In other words, all of our templates involving querying and filtering provide a means for CHT users to BIND friendly query names to less-than-friendly back-end field names.
For example, you have a browse, and you need to send a data-limiting query from that browse to a process so that only the data matching the query is handled by the process.
It is the developer's responsibility to see that the BINDing of friendly names which works effortlessly in the BROWSE procedure, is reflected in the PROCESS or REPORT to which you are sending the query. To do that you must complete the "QUERY HOT FIELDS" dialog on our template for the report or process.
Our PROCESS template
As any Clarion developer worthy of calling himself a "Clarion Developer" knows full well that BIND() has procedural scope. So a perfectly viable query word like "ACCOUNT" for CUS:ACCOUNT works fine in your CHT browse procedure, but doesn't work in a your CHT process, to which you may be sending the very same query. That's BECAUSE IT'S A SEPARATE PROCEDURE, and BIND normally has procedural scope when binding is handled at the procedural level, as it is with most browses.
And that's why we provide a "QUERY HOT FIELDS" dialog on our process and report filtering templates, so that you can establish binding, THERE, that matches the binding taking place in your browse.
Clarion's working "SMARTER NOT HARDER" mantra is true BOTH in the sense that SMART means the opposite of SLOW or LAZY, but also in the sense that SMART can imply "PAIN" like when something that "bites you in the ass" can "SMART" due to a basic lack of Clarion "SMARTS".
The point, is, you will end up working "HARDER NOT SMARTER" unless you intimately get to know and understand how Clarion works, and also how CHT works at leveraging the things that Clarion DOES WELL, and filling in the gaps, for things Clarion CAN'T do or DOES LESS WELL.
This template will now automatically populate on all window procedures from CHT Global template ApplicationImagesEx.
The presence of EmbedWindowFunctions on a window procedure makes visible quite a number of CHT Control and Extension templates that otherwise might not have been visible unless you manually inserted the template on your window procedure beforehand.
This template always self-populated on your window procedures from our global template ApplicationImagesEx. But wait, some of you never actually bothered to go to the ApplicationImageEx template to enable it. So, in effect, it did nothing on your application because while disabled, ApplicationImagesEx does not auto-populate ProcedureImageEx.
As of the last build update, 26A.01.00, ApplicationImagesEx is fully enabled by default. There is no longer a "Disable" setting on this template. This continues of course, in 26B.00.00. We have however, given you global control over the three local settings being exercised on the window procedure by ProcedureImagesEx.
While ProcedureImagesEx is now present on your window procedures you still can fully control from our global ApplicationImagesEx template, which of the three outcomes listed below is excercised locally.
ApplicationImagesEx and ProcedureImagesEx have styling effects (images, fonts, and colors) on your application windows using the following rules-of-thumb.
through global styling from
local-window styling on its
anything about styling, images,
fonts and colors
As we make edits to CHT templates for the next CHT release, (April 17th approx) it becomes immediately obvious that it is important to keep an eye on the size of your Clarion template registry file "TemplateRegistryXX.TRF".
Because we're editing and constantly reregistering changes, it took only a day or two for our registry .TRF to grow from approximately 12.5 MB to 250MB. We could feel Clarion slowing down incrementally as these reregistrations took place.
Since the Clarion template development system has no window previewer, template coders like ourselves cannot view the layout of a template interface (although intuition, and experience are helpful) without closing the template file and opening an application. This, of course causes the currently registered template chains to reregister and that triggers .TRF growth. The rate of growth depends on how many templates are registered, but the rate of growth is exponential.
Obviously, the rate of growth on our development machine is probably considerably faster than on yours, unless you too have a personal template chain that you are maintaining and changing, or you're regularly updating or changing your selection of registered templates. Growth is not by what's new and changed, unfortunately, its by the total number and size of templates already registered. That's why we're saying that growth is exponential.
When any template set is changed, or a template chain is added or removed, in fact, any action that causes template reregistration causes the template .TRF file to grow. It never shrinks, even when a template chaine is unregistered.
To that end, we've given you an app in /accessory/bin/ called HNDTPLREGISTER.EXE to assist you with quick template chain full, from-scratch, template registration. The app shows you the size of your current .REG file, deletes it and registers the selected template chains (.TPLs with their .TPWs).
So, the difference between a small, fast, .REG file and a huge, unweildy one, is in the operational methodology implied in these words: "Reregistration" and "Registration". The former implies adding to, or changing, an existing .REG file while the latter implies deleting the .REG file and re-creating it from scratch. HNDTPLREGISTER.EXE does the latter. It recreates the .REG file using the selected template (.TPL) chains.
There is a video available via HNDVIDEOJOURNAL.EXE called "FEB 8, HANDYVERSIONRESOURCE TEMPLATE REVIEW" which near the end discusses the use of HNDTPLREGISTRY.EXE, some time after minute 45 (approx) of the video.