Ask Reuben
Overloading FGLLDPATH
How can I overwrite some basic Genero functionality?
I have mentioned this technique in a few articles and I felt it deserved an article of its own. I call it “Overloading FGLLDPATH” but the name is a bit of misnomer as it does not involve changing FGLLDPATH. First of all, note the following in the definition of FGLLDPATH. The directories are searched in the following order: The last place the Genero runtime searches for program modules (.42m files) is $FGLDIR/lib. This is where standard Genero functionality resides. If in FGLLDPATH there is a .42m file with the same file name as one that is in $FGLDIR/lib, it will be found and used instead of the one in $FGLDIR/lib. The same principal applies for the files that are found using FGLRESOURCEPATH as well … When the specified resource file is not an absolute path, the runtime system searches in directories in the following order: if in FGLRESOURCEPATH there is a resource file (.42f, .iem, .4ad, .4st, .4rm, .4tb, .4tm, 42s) that has the same name as one that is in $FGLDIR/lib, it will be found and used instead of the one in $FGLDIR/lib. Where a file in $FGLDIR/lib requires a source file (.42m, .42f), you will find the relevant source file in $FGLDIR/src. You can potentially utilise these look up rules to override some of the files shipped in $FGLDIR/lib. For modules and form files, take a copy of the source file, place it in your source control, modify it, and place the compiled file alongside the rest of your compiled objects in a directory referenced by FGLLDPATH, FGLRESOURCEPATH as appropriate for the type of file. Then when the runtime looks for FGLDIR/lib/filename, it will find the same filename earlier somewhere in FGLLDPATH/FGLRESOURCEPATH. Once you go down this path, the responsibility is on you … My recommendation is to keep this sort of activity to a minimum but I can certainly understand you wanting to make sure that your application is consistent with its user interface and terminology. A good example is the built-in find window. At present the source file for FGLDIR/src/fglfind.per is the following … … this file might have a few things that might not be consistent with your user interface. Copy FGLDIR/src/fglfind.per to your working area and make some modifications so that it is consistent with the rest of your user interface. In this example I have … … so that the code is now … … compile it and place the resultant fglfind.42f in with the rest of your form files. The before and after of the fglfind window is as per these screenshots …
MAIN
or the .42r program file).
MAIN
or the .42r program file).
# Property of Four Js*
# (c) Copyright Four Js 1995, 2023. All Rights Reserved.
# * Trademark of Four Js Development Tools Europe Ltd
# in the United States and elsewhere
LAYOUT(SPACING=NORMAL, STYLE="dialog4", TEXT=%"fgl.findDialog.title")
GRID
{
[l1 |s ]
[l2 |c ]
[i ]
[w ]
}
END
ATTRIBUTES
LABEL l1: TEXT=%"fgl.findDialog.lbFind", JUSTIFY=RIGHT;
EDIT s = FORMONLY.pattern;
LABEL l2: TEXT=%"fgl.findDialog.lbIn", JUSTIFY=RIGHT;
COMBOBOX c = FORMONLY.fieldId, NOT NULL;
CHECKBOX i = FORMONLY.ignoreCase, TEXT = %"fgl.findDialog.cbIgnoreCase", NOT NULL;
CHECKBOX w = FORMONLY.wrapAround, TEXT = %"fgl.findDialog.cbWrapAround", NOT NULL;
# Property of Four Js*
# (c) Copyright Four Js 1995, 2023. All Rights Reserved.
# * Trademark of Four Js Development Tools Europe Ltd
# in the United States and elsewhere
LAYOUT(SPACING=NORMAL, STYLE="dialog", TEXT="Find in Array")
GRID
{
[l1 |s ]
[l2 |c ]
[l3 |i ]
[l4 |w ]
}
END
ATTRIBUTES
LABEL l1: TEXT="Find", JUSTIFY=LEFT;
LABEL l2: TEXT="In Column", JUSTIFY=LEFT;
LABEL l3: TEXT="Ignore Case", JUSTIFY=LEFT;
LABEL l4: TEXT="Wrap Around", JUSTIFY=LEFT;
EDIT s = FORMONLY.pattern, SCROLL, PLACEHOLDER="Enter expression to find";
COMBOBOX c = FORMONLY.fieldId, NOT NULL;
CHECKBOX i = FORMONLY.ignoreCase, TEXT = " ", NOT NULL;
CHECKBOX w = FORMONLY.wrapAround, TEXT = " ", NOT NULL;
How is this working? when the built-in fglfind looks for fglfind.42f, it is finding your fglfind.42f higher up the FGLRESOURCEPATH search hierarchy than our one in $FGLDIR/lib.
Wether the new appearance is better or worse, the beauty is in the eye of the beholder. What is important though is that this window can match the rest of the windows in your application and your end-user has a consistent User Experience.
Note that some things can’t be changed, for instance in this example I have to keep the field names as referenced by the INPUT statement in fglfind() the same.
To get an understanding of what supplied functionality can be changed like this, some things you can do
- note the files in FGLDIR/lib and where applicable note the source that is in FGLDIR/src.
- add FGLDIR/src to the FGLSOURCEPATH variable and when using the debugger, break in a form/dialog that you did not write and note the source file loaded.
- note the files in $FGLDIR/webcomponents. You can create your own webcomponents using these as a starting point. Note the search path for web components implicitly looks in $FGLDIR/webcomponents first so you would need to rename your webcomponent to go down this path.
- note the files in $FGLDIR/web_utilities/services. You can use these as starting points for your own equivalents
- modify predefined localization strings
- modify runtime system messages.
As I commented above, and I’ll finish by reemphasising. Do these sorts of activities in a controlled and disciplined manner.