dBASE Plus release 2.7
OVERVIEW
dBASE Plus 2.70 is compatible with Windows 7 and Vista and maintains backward compatibility with Windows XP.
dBASE Plus 2.70 adheres to Microsoft's User Account Control (UAC) rules which allow dBASE and dBASE applications to benefit from the enhanced security provided by these rules.
In order to receive the maximum protection provided by UAC, dBASE Plus 2.70 defaults to running with standard user rights when installed on Windows 7 or Vista.
dBASE Plus 2.70 contains a number of new features to assist you in working with standard user rights and to simplify upgrading your applications to adhere to UAC as well.
What exactly are the UAC rules from a software developers viewpoint?
Window's UAC rules are intended to:
- Protect installed program files from being modified or damaged by users or programs that should not have access to them.
- Keep each user's files, configuration settings, etc. separate from other users except where shared files or settings are needed.
-
Restrict access to any machine wide settings to
the maximum extent possible.
By default, only users with Administrator privileges have access to machine wide settings.
Windows 7 and Windows Vista implement these rules by carefully
limiting default permissions on folders under the Program Files folder
tree, the ProgramData folder tree, the Windows folder tree, and the Users
folder tree.
Permissions to registry keys are also carefully limited so that standard
users will not be allowed to modify any settings that can affect other
users.
In order to follow UAC rules a program must:
- place executable code under the Program Files folder tree and NOT attempt to modify or create any new files under this folder tree while running the program. (Standard users generally have read and execute permissions to files under this folder tree. However, programs may be configured to require administrator privileges which would prevent standard users from running them).
- place shared configuration and data files under the ProgramData folder tree - but NOT attempt to modify or create any new files under this folder tree while running the program. (By default, standard users have readonly access to this folder tree).
- place master copies of files needed by each user under the ProgramData folder tree (to be copied to each user's private folder tree).
- setup a private folder tree under the Users folder tree for each user when a user first runs the program so that each user can modify their private files however they wish without interferring with other users.
How will dBASE Plus 2.70 support UAC rules?
Installation:
During installation on Windows 7 or Vista, dBASE will install folders containing a default configuration file (plus.ini), sample code, sample application files, and converter utilities under the C:\ProgramData\dBASE\Plus folder.
(Note that on Windows XP, the default for 2.70 will be to continue installing dBASE Plus as it has in past versions).
In addition, during installation the Borland Database Engine (BDE) will be configured slightly differently than in the past to place its configuration file under the ProgramData tree and set the BDE's NET DIR setting to point to this same folder under ProgramData.
Starting dBASE Plus
When dBASE Plus 2.70 is started, it ensures that the user has a dBASE specific folder in their private user folder tree to hold their user specific configuration data (in plus.ini), their private copies of the sample and converter files and any temporary files created while running dBASE.
In addition, the first time dBASE is run by a user it will run a new user setup utility to setup the user's sample and converter files, and generate all the default Source Aliases and default User BDE Aliases.
Also during startup, dBASE will check the user's plus.ini configuration file for any User BDE Aliases and if found, load them into the default BDE session so they will be available for immediate use.
User BDE Aliases are new in dBASE Plus 2.70. They are private BDE Aliases and are stored in each user's plus.ini file. New User BDE Aliases can be created via the Database Wizard accessible within dQuery or via code or via manually editing the plus.ini file. (Note that BDE Aliases can still be created via the BDE Administrator for use by all users on a computer but require Administrator rights to create or delete them).
dBASE Runtime and Applications
The dBASE Plus 2.70 Runtime Engine will perform many of the same startup tasks as the described above for the dBASE Plus IDE. When started the runtime engine will ensure that the user has an application specific folder in their private user folder tree and will ensure they have their own application specific .ini file (unless the application is setup to run without an .ini). If any User BDE Aliases are found in the user's .ini file, they will be loaded into the default BDE session to make them available to the application.
Optionally, an application can be built to perform additional tasks to setup a new user. dBASE Plus 2.70 ships with new sample code that can be modified to customize a user's private configuration such as to copy folders or files from a ProgramData subfolder or to add custom User BDE Aliases.
New Properties and Methods
dBASE Plus 2.70 includes a set of new properties and new methods to make it easier to customize an application to observe UAC rules as follows:
- _app.useUACPaths - True if dBASE Plus or application should follow UAC rules, otherwise False.
- _app.iniFile - Contains full path to plus.ini or an application's .ini file.
- _app.currentUserPath - Full path to the user's private dBASE or application folder.
- _app.allUsersPath - Full path to the shared folder where shared files or folders may be located for dBASE Plus or for an application.
- _app.roamingUsersPath - Full path the the current users' roaming folder path where you can choose to store data for an application that will roam from one workstation to another if a network hosting an application is configured to support roaming users.
- session.addAlias() - method for adding User BDE Aliases to the current BDE session
- session.deleteAlias() - method for removing a User BDE Alias from the current BDE session (other than the default session)
- the BUILD command includes new options to specify the default UAC behaviour and where or whether to use an .ini file
- the dQuery design tool installed with dBASE Plus has been upgraded to support User BDE Aliases and to follow UAC rules.
In qBDEMgr.cc, provided with the sample code installed with dBASE Plus, there are new methods for saving User BDE Aliases to _app.iniFile or loading them from _app.iniFile.
NEW FEATURES
_app Object
QAID:6478 Implemented additional UAC compatibility code by adding useUACPaths property to _app object.
Indicates whether or not dBASE or a dBASE application should follow UAC rules.
Background - Vista and Windows 7 expect applications to adhere to certain conventions to make it easier for Windows to prevent program files from being modified or corrupted - whether by user error or by malicious users or by viruses.
Programs that do not follow these conventions are subject to more scrutiny by Windows before the program is launched (via Windows User Access Controls (UAC) mechanism) and may trigger additional warnings by Windows or cause Windows to prevent the program from executing at all (depending on the user's access rights, the current Windows policy settings and the configuration of any manifest files for the application).
useUACPaths gives dBASE Plus the ability to adhere to the Vista and Windows 7 conventions with regard to the location where dBASE Plus creates and stores its .ini file (containing user settings), where dBASE instructs the BDE to create its temporary files and the default path for the default session at dBASE startup.
During startup, dBASE and dBASE applications will determine the setting for useUACPaths (as described below) and then check useUACpaths to determine the location for various files and folders including plus.ini or an application's .ini file.
When set to False, dBASE and dBASE applications will set the locations for .ini files, conversion utilities, include files, various sample files, and temprorary files to locations used in previous versions of dBASE.
When set to True, dBASE will set the locations for .ini files, conversion utilities, include files, various sample files, and temporary files to folders within the current user's private folder tree as required by Window's UAC rules. dBASE determines the path for the user's private folder tree by retrieving the following Window's special folder paths: CSIDL_LOCAL_APPDATA and CSIDL_APPDATA.
How _app.useUACPaths is set when starting
dBASE Plus (Plus.exe) or an application .exe (Plusrun.exe):
During startup of plus.exe:
- Checks if registry key HKEY_LOCAL_MACHINE\SOFTWARE\dBASE\PLUS\series1\useUACPaths exists and is set to y or Y
If
yes,
Sets
_app.useUACPaths to TRUE
Otherwise,
Sets
_app.useUACPaths to FALSE
- Next, checks if -v switch was passed to plus.exe on the command line which would override default setting above.
If yes,
If
-v1 (or -V1) found on command line,
Sets
_app.useUACPaths to TRUE
If
-v0 (or -V0) found on command line,
Sets
_app.useUACPaths to FALSE
In summary for plus.exe:
If a useUACPaths registry key exists for dBASE Plus, it sets the default for _app.useUACPaths.
If this key does NOT exist, _app.useUACPaths is defaulted to FALSE.
If a -v switch is passed on the command line, it will override the default set above.
During startup of plusrun.exe
- Check if registry key HKEY_LOCAL_MACHINE\SOFTWARE\dBASE\PLUS\series1\useUACPaths exists and is set to y or Y.
If
yes,
Sets
_app.useUACPaths to TRUE
Otherwise,
Sets
_app.useUACPaths to FALSE
- Next, checks if -v switch was passed to plusrun.exe (or an application .exe) on the command line which would override default setting above.
If yes,
If
-v1 (or -V1) found on command line,
Sets
_app.useUACPaths to TRUE
If
-v0 (or -V0) found on command line,
Sets
_app.useUACPaths to FALSE
- If no -v switch was passed via command line plusrun.exe checks the registry for an application specific registry key specifying the setting for useUACPaths:
HKEY_LOCAL_MACHINE\SOFTWARE\dBASE\PLUS\RuntimeApps\<app file name>\useUACPaths
If this key is found, it overrides the default set via the above dBASE\PLUS\series1 registry key
If
its set to y or Y
Sets
_app.useUACPaths to TRUE
If
its set to n or N
Sets
_app.useUACPaths to FALSE
- If no -v switch was passed via the command line AND no RuntimeApps registry key setting was found for the application, then the application .exe is checked to see if has an embedded setting to set _app.useUACPaths to TRUE.
If
an embedded UAC flag is found
Sets
_app.useUACPaths to TRUE
In summary for an application .exe:
If a useUACPaths registry key exists for dBASE Plus, its used to set the default for app.useUACPaths.
If this key does NOT exist, _app.useUACPaths is defaulted to FALSE.
If an application .exe is built with an embedded UAC setting, the embedded setting will override the global default set for dBASE Plus above.
If an application specific registry key exists, its setting will override the dBASE Plus registry key setting and the embedded UAC setting in the application .exe (if one exists).
If a -v switch is passed on the command line, it will override all of the above settings.
Items affected by _app.useUACPaths
During startup, dBASE PLUS or dBASE PLUS Runtime checks _app.useUACPaths for the following items :
Determines default location for plus.ini or an application .ini file
When useUACPaths is true the dBASE Plus plus.ini or an application .ini file will load from a user's local folder tree rather than from the same folder as plus.exe or an application .exe was launched.
First Plus.exe or plusrun.exe will ensure that the following folders exist and create them if they do not yet exist:
For PLUS.EXE:
<CSIDL_LOCAL_APPDATA>\<dBASE Plus subpath>\Bin
<CSIDL_APPDATA>\<dBASE Plus subpath>\Bin
For an application .exe:
<CSIDL_LOCAL_APPDATA>\<application launch subpath>
<CSIDL_APPDATA>\<application
launch subpath>
The <... subpath> For Both dBASE PLUS IDE and a dBASE Plus Application are evaluated as follows...
- If the launch path contains either "\Program Files" or "\Program Files (x86)", the launch subpath is set to the portion of the launch path remaining, once the portion containing the "\Program Files" or "\Program Files (x86)" folder is removed.
For Example:
If dBASE plus is installed in folder:
C:\Program Files\dBASE\Plus
the <dBASE Plus subpath> will be set to:
\dBASE\Plus
If an application .exe is installed in folder:
C:\Program Files\YourCompany\YourApp
the <application launch subpath> will be set to:
\YourCompany\YourApp
- If the launch path does NOT contain "\Program Files" or "Program Files (x86)", then the <.... subpath> is set to the path remaining after removing the drive letter and colon or removing the top level UNC path from the launch path.
For Example:
If dBASE Plus is launched from:
C:\dBASE\PLUS
The <application launch subpath> is set to:
\dBASE\PLUS
An application built by dBASE Plus is launched from:
\\YourUNCPath\YourCompany\YourApp
The <application launch subpath> is set to:
\YourCompany\YourApp
Next plus.exe or plusrun.exe will ensure an .ini file is loaded as follows:
Check for ini file in a path passed via -C command line switch
If found, load .ini from this path
If not found,
Check for .ini in <CSIDL_LOCAL_APPDATA>\<.... subpath>[\Bin]
If not found,
Check for .ini in <CSIDL_COMMON_APPDATA>\<.... subpath>[\Bin]
if found, copy to <CSIDL_LOCAL_APPDATA>\<.... subpath>[\Bin]
if not found,
Check for .ini in Exe launch path
If found, copy to <CSIDL_LOCAL_APPDATA>\<.... subpath>[\Bin]
If not found,
Create new plus.ini file in:
<CSIDL_LOCAL_APPDATA>\<.... subpath>[\Bin]
The open .ini is now located in <CSIDL_LOCAL_APPDATA>\<.... subpath>[\Bin]
Determines whether or not
:dBStartup:InitNewUser.pro is run the first time a particular user launches
dBASE Plus (or a dBASE application).
In dBASE Plus, InitNewUser.pro will create private copies of the various converter and sample folders as follows:
Converters
dBLClasses
dQuerySamples
Include
Media
Samples
Web
In a dBASE application, a custom InitNewUser.pro can be used to perform custom setup tasks for a new user.
Sets Source Alias paths to match the private locations for the following Source Aliases:
DOS5Conv
Examples
FormControls
Forms
Images
Movies
Nonvisual
Output
ReportControls
Reports
Samples
Toolbars
Webwizards
Determines default BDE Alias paths for the following aliases:
dBASESamples
dQuerySamples
dBASEContax
dBASESignup
dBASETemp
dQueryTemp
Used by dQuery to determine the location of:
dquery.ini
dquery temporary files
My DataModules folder
Default Location for generated code and project files
Used by Project Explorer to determine the location of:
projexp.ini
Project Explorer temporary files
My Projects folder
Used by the Web Wizards to determine the location for it’s temporary files.
More _app object changes....
Added iniFile property to _app object to surface the full path and filename to the dBASE or dBASE application .ini file. This takes the guess work out of figuring out which folder the .ini file is located in.
Added allUsersPath property to _app object which is a reference to the Bin folder in the Windows CSIDL_COMMON_APPDATA directory
Added currentUserPath property to _app object which is a reference to the Bin folder in the Windows CSIDL_LOCAL_APPDATA directory
New RMDIR (RD) COMMAND
QAID:134 Added new command RMDIR (Remove Directory) to dBASE PLUS. Also added synonym command RD which works the same way.
RMDIR / RD
Removes a directory
Syntax:
RMDIR <directory>
or
RD <directory>
<directory> - The directory you want to remove. This can be a full directory path or a relative directory path.
Description
RMDIR attempts to remove the specified directory. It can only remove a directory if the directory is empty and is not currently in use by any program.
RD works exactly the same way as RMDIR.
Example:
RMDIR mydir
- Will attempt to remove directory mydir
RMDIR C:\somefolder\otherfolder
- Will attempt to remove directory otherfolder
RD mydir
- Will attempt to remove directory mydir
RD C:\somefolder\otherfolder
- Will attempt to remove directory otherfolder
Session Class
QAID:6478 Added new tempPath property to the Session class.
tempPath contains the path for the session's temporary files and may be changed to use an alternate directory (as long as no queries or stored procedures are active). (This implements private directories as per QAID: 223)
Added new method addAlias() - adds User BDE Aliases to the BDE session associated with a session object
Syntax:
<oRef>.addAlias(<cAlias>,<cDriver>,[<cOptions>])
where :
<oRef> - is a session object
<cAlias> - Name of User BDE Alias (up to 31 characters)
<cDriver> - Name of BDE Driver for specified alias. These correspond to the driver names listed within BDE Administrator:
DBASE
PARADOX
ASCII
SQL Link Driver Names
<cOptions> - String of driver dependent options. For a DBASE alias the PATH: option is required as follows:
PATH:<Full Path to Folder>
If more than one option is needed separate options with a semi-colon.
Added new method deleteAlias() - removes a User BDE Alias from the BDE session associated with a session object (does not work for the default session object in _app.session)
Syntax:
<oRef>.deleteAlias(<cAlias>])
<oRef> - a session object
<cAlias> - Name of User BDE Alias (up to 31 characters)
Plus IDE
QAID 6609 Added ability for dBASE Plus to execute a dBL program the first time a new user launches plus.exe.
This dBL program can be used to perform any user specific setup code such as:
- creating user specific copies of code and data demo folders
- opening a window with information for a new user or a newly upgraded user
For dBASE Plus 2.70, the following folder and file will be installed:
New Folder:
C:\Program Files\dBASE\Plus\Bin\dBLCore\Startup
New File:
C:\Program Files\dBASE\Plus\Bin\dBLCore\Startup\InitNewUser.pro
During Startup for a new user, dBASE Plus 2.70 will issue the command:
DO :DBSTARTUP:INITNEWUSER.PRO
Also during startup, a new Source Alias, DBSTARTUP will be defined to point to the new folder:
C:\PROGRAM FILES\dBASE\PLUS\Bin\dBLCore\Startup
(or C:\Program Files (x86)\dBASE\PLUS\Bin\dBLCore\Startup.)
BUILD Command
QAID 3680 Revised Syntax for BUILD command to add INI clause as follows:
BUILD <filename>[, <filename> ...] /FROM <resp-filename>
[ICON <filename>] [SPLASH <filename>] [TO <exe-filename>]
[WEB] [INI [ON | OFF | ROAM]]
Where:
INI OFF - indicates that application will NOT create or use an ini file
INI ROAM - indicates that application will create and use an ini file under the user's CSIDL_APPDATA folder
INI or INI ON - indicates that application .exe will create and use an ini file in whichever folder other UseUACPaths settings specify. This is the same as NOT specifying an INI clause at all.
Revised Syntax for BUILD command to add UAC clause as follows:
Revised Syntax:
BUILD <filename>[, <filename> ...] /FROM <resp-filename>
[ICON <filename>] [SPLASH <filename>] [TO <exe-filename>]
[WEB] [INI [ON | OFF | ROAM]]
[UAC]
When UAC is specified the resulting .exe is built with an embedded default to set _app.UseUACPaths to True when the .exe is run.
This embedded UAC setting overrides the runtime engine default set via the registry key:
HKLM\SOFTWARE\dBASE\PLUS\Series1\UseUACPaths
However, the embedded setting can be overridden by setting a RuntimeApp specific registry setting in registry key:
HKLM\SOFTWARE\dBASE\PLUS\RuntimeApps\<app file name>\UseUACPaths
Or by using the -v command line switch:
-v1 sets UseUACPaths to true
-v0 sets UseUACPaths to false
FILE( ) Function
QAID 1542 Added ability allow source alias paths to be used with the File() function.
GETFILE( ) and PUTFILE() Functions
QAID 6621 Added ability to GetFile() and PutFile() to pass a File Type Group name in the File Type List parameter such as:
f = getfile("","Title",true,"Web Images (*.jpg,*.png,*.gif,*.bmp)")
Here "Web Images" is a custom group name that includes the file types specified within the parenthesis.
Added ability to use a built-in File Type Group name such as: "Form ()". dBASE will detect the left and right parenthesis and search for a matching built-in group name. If found, the list of file types associated with the built-in group will be added to the string that is added to the File Types combobox in the GetFile() or PutFile() dialog.
File Types between parenthesis must be separated by either a comma or a semi-colon and can be specified in any of the following formats:
<ext> or .<ext> or *.<ext>
where <ext> means a file extension such as jpg or txt.
If a File Type List string is specified that contains unbalanced parenthesis or right parenthesis before left parenthesis, a new error will be triggered with the message:
"Unbalanced parenthesis in file type list"
Code Enhancement
QAID 1321 Added ability to specify a source alias in a #include directive.
For example:
#include :MyCode:MyHeader.h
Modified file search routine for the #include directive to search in the following locations if no path (or source alias) is provided for the file:
<CSIDL_LOCAL_APPDATA>\dBASE\PLUS\include
<CSIDL_COMMON_APPDATA>\dBASE\PLUS\include
These additional locations will be search if _app.useUACPaths is true and the file was not found earlier in search sequence.
The revised search sequence is:
Check if source alias is specified.
If yes, substitute path for alias and check if file exists
If found, return
If no source alias, or file not found,
Search for file exactly as specified in #include statement
If path is included, the path will be searched.
If no path is included, the current directory will be searched.
If not found, check if file extension was specified.
If not, add ".h" to the filename and search again for the file as in current folder or specified path.
If not found,
If no path was specified,
If _app.useUACPaths is true,
Search for file in:
<CSIDL_LOCAL_APPDATA>\dBASE\PLUS\include
If not found,
Search for file in:
<CSIDL_COMMON_APPDATA>\dBASE\PLUS\include
If not found (or _app.useUACPaths is false),
Search for file in:
_dbwinhome + "\include"
If not found,
Search for file on path specified via INCLUDE environment variable.
Note that INCLUDE must contain only one path with a trailing backslash in order for a search to be successful.
FIXES
Forms and Form Controls
QAID 6590 Fixed MAV that could occur if form's popup menu is released before form's destructor executes (such as in form's onClose handler).
QAID 6580 Fixed painting of border for Editor controls and TextLabel controls when form is first opened. These borders were not painting in dBASE Plus 2.62 due to a regression in build 2102 for QAID: 6547
Source Editor
QAID 3168 Fixed a bug in which the Editor would GPF if there were 2 instances of any designer modifying the same file.
For example, if 2 instances of dQuery were allowed to open and the same.dmd was opened in both.
QAID 6302 Fixed GPF that occurred when opening Source Editor while running dBASE Plus on a 64 bit version of Windows.
QAID 3170 Fixed a bug which causes data corruption and/or a GPF in the Editor when very many lines are highlighted (1000-2000), and the "Comment Lines" menu option is invoked.
The source of the problem is that dBASE is running out of memory, because of an inefficient scheme storing Undo information (repeated 1000-2000 times in this case).
Code was added to reclaim wasted memory every 100 iterations.
Container
QAID 6623 Fixed container's OnPaint() function to always repaint visible container components to enable text object's to repaint with correct background color when they are transparent and the container's colorNormal property is changed.
Text Object
QAID 6624 Fixed Text object so it fully repaints when it is notified that one of its font properties has been changed.
Previously, some font property changes did not trigger a full repaint, such as changing text.fontsize, and did not update the text's horizontal position when its alignment is set to center the text.
ErrorLevel
QAID 134 Updated internal errorLevel[] array to include the following recently added errors:
405 Path Too Long
406 Directory is not empty
407 Directory is in use
408 Cannot remove directory
409 Directory not found
410 Cannot change with active Query or StoredProc objects
Find Dialog
QAID 534 Fixed default setting of Up and Down radio buttons to ensure only one of them is set at a time