VMP Home
Product Information
Message Board
Download VMP
Training and Demos
Previous versions
User Contributions
VFP Tools & Downloads
Subscription Policy
Order Now
  Current bug fixes

Bug fixes for the current VMP build

This page lists the bug fixes for the current VMP build.  The download page always contains the current maintenance release of VMP, and this page contains the bug fix listing from the header comments of XXFWMAIN.PRG. 

Whenever ld you encounter what appears to be a bug in VMP, you should always check this page before reporting the bug -- you'll frequently find that the bug has already been reported by someone else, and the fix is listed here.  If you do need to report a bug, please do so by following the instructions on the Report a Bug page.

Mar 21, 2014

Build 03 (03/21/2014)

- resolved various issues including the following:
    - Mike Potjer reported the following on the VMP Message Board:
        The SECOND instance of this line of code is incorrect, the one followed by the comment "Try Users":
				XXDTES("XXFWSEMAPHORELOCK.VCX",[IF EMPTY(m.lcPath) AND USED('AppInfo')],"BO_SemaphoreLock","GetDefaultFolder_Free")
      The line of code should be:
				IF EMPTY(m.lcPath) AND USED('Users')
			          * Try Users
    - discovered, and then resolved, the same issue in the XXFwSemaphoreLock.VCX/BO_SemaphoreLock::GetDefaultFolder_Contained() method
        (again, thanks to Mike Potjer for reporting the other issue which led to this discovery)
    - per Mike Potjer's recommendation, reset-to-default the XXFwWizards.VCX/frmWizard::SetIcon() method
    - per Peter Huppelschoten's recommendation, replaced the following line in the XXFw.VCX/grdBase::PushPopRecordSource() method:
		  IF ISNULL(This.iaPushPopRecordSource)
with the following code:
		  IF     ( TYPE('This.iaPushPopRecordSource') = 'U')	;
		      OR  ISNULL(This.iaPushPopRecordSource)
Mar 15, 2014

Build 02 (03/15/2014)

- resolved various issues including the following:
    - Mike Potjer reported the following on the VMP Message Board:
        If you try to run the Work Areas viewer in the development environment when oForms does not exist,
        and there is more than one data session open (such as when some other developer tool, like some of
        the Thor tools, has a private session open), the Work Areas viewer fails on this line:
				XXDTES('XXFWUtil.VCX', 'WITH m.oForms', 'frmWorkAreasViewer', 'Load')
    - Mike Potjer reported the following on the VMP Message Board:
        In the 2014.02.17.01 build of VMP (and earlier) there is a bug here:
				XXDTES("XXFWNTBO.VCX",[llSuccess = .ExecuteChildBOMethod('AddAction'],"ctrBusinessObject","AddAction")
        The AddAction() method takes 3 parameters, but the ExecuteChildBOMethod() call is only passing the first and third parameters, like so:
			    llSuccess = .ExecuteChildBOMethod('AddAction'	,	;
            			                          @m.tuMsgSvc		,	;
      If you have a tuSecurityInfo value which needs to be passed on to child BO methods, it will either be ignored, or cause an error, because it is being passed to the tlForce parameter. The correct method call looks like this:
			    llSuccess = .ExecuteChildBOMethod('AddAction'	,	;
			           	                          @m.tuMsgSvc		,	;
			                                      .F.				,	;
Feb 17, 2014

Build 01 (02/14/2014)

- replaced the ; ENDIF
  with the following code:
  to resolve an issue that David Middleton reported on the VMP Message Board.
  (Thanks to Mike Potjer for sharing his insights with respect to the resolution for this issue.)
- replaced the followifollowing code in the XXFw.VCX/frmData::RemoteRefresh() method:
    IF X7CPEDIG(ThisForm, 'frmDEGridNavNoPages' ) ;
      OR X7CPEDIG(ThisForm, 'frmDEGridNavNoPages02')
   ng code in the XXFwControlBehaviors.VCX/cusCalendarTextbox::Init() event-method:
    lcString = SYS(1272, m.toTextbox)
    This.icOwnerName = SUBSTRC(m.lcString, AT_C('.', m.lcString) + 1)
  with the following code:
    This.icOwnerName = SYS(1272, m.toTextbox)
  to resolve an issue that Peter Huppelschoten reported: if you have a form with a date-bound textbox (and accompanying
  calendar commandbutton) and you have another form with a date-bound textbox (and accompanying calendar commandbutton)
  and the textboxes both have the same name, then when you close the 2nd form, the calendar commandbutton is removed
  from the 1st form.
  (Thanks to Peter Huppelschoten for pointing out the bug and a possible solution.)
- implemented the following fix in the XXFw.VCX/cusAppLibs::LoadDIMember() method:
    * If a control has a non-zero .Anchor setting and you try to move or resize the control when the
    * form is not visible, VFP ignores any changes you make to
    * - .Top
    * - .Left
    * - .Height
    * - .Width
    * The fix? Temporarily set .Anchor to 0, move/resize the control, then restore the .Anchor setting
  (Thanks to Mike Potjer for pointing out the bug and a possible solution.)
- replaced the following incorrect line in the XXFwAppLoader.VCX/cusAppLoader::CopySettingsToThisProperties() method:
    .AppTitle = .ioSettings.DefaultGraphicFile
  with the following correct line:
  .DefaultGraphicFile = .ioSettings.DefaultGraphicFile
- replaced the following incorrect line in the XXFwBC02.VCX/frmEventLog02.cmdDeleteAll::Error() method:
    lcOnError = STRTRAN(m.lcOnError, 'lineo(1)', 'nLine' )
  with the following correct line:
    lcOnError = STRTRAN(m.lcOnError, 'LINENO(1)', 'nLine' )
- replaced both occurrences of the incorrect 'lnBehavior' with the correct 'lcBehavior' in
  the XXFw.VCX/cusForms::SeticNoAccessControlBehavior() method
- replaced the incorrect line:
    inSecured = 0
  with the correct line:
    This.inSecured = 0
  in the XXFw.VCX/edtBase::SetUserSecurity() method
- replaced the following code in the XXFwNTDP.VCX/cusDataPackagerXML::DataToCursorEmptyDateTime() method:
    REPLACE (m.laDTFields[m.lnField, 3]) WITH {}
  with the following code:
    REPLACE (m.laDTFields[m.lnField, 1]) WITH {}
  (Thanks to Mike Potjer for pointing this out.)
- enveloped the following code in the XXFwMisc.VCX/cusShortcutMenu::DevDiagStuff() method with an IF ADATABASES(laDatabases) > 0 ... ENDIF:
    FOR lnDatabase = 1 TO ALEN(laDatabases, 1)
      IF m.laDatabases[m.lnDatabase, 1] == m.lcDatabase
      lcDatabase = m.laDatabases[m.lnDatabase, 2] && full path
  (Thanks to Mike Potjer for pointing this out.)
- Commented out the following line in the XXFwCtrl.VCX/txtPicklistValid::DoPicklistForm() method:
    lcSeekPrepend = .GetSeekPrefix()
  (Thanks to David Middleton for noticing and reporting that lcSeekPrepend is not referenced in that method.)
- replaced "icPictureForHOrientatio" with "icPictureForHOrientation" in the XXFw.VCX/cmdToolbar::HVOrientation() method
  (Thanks to Mike Potjer for pointing this out via the VMP Message Board [Message Id 3U61FFONN].)
- the following line in XXFwMain.Prg (this program)
    IF WVISIBLE(This.iaDS[m.lnDockState, 1])
  triggers a "Syntax error." error when This.iaDS[m.lnDockState, 1] is an empty string. In response, I enhanced the
  above line to also check if This.iaDS[m.lnDockState, 1] is not empty before allowing the following line to be run:
    HIDE WINDOW (This.iaDS[m.lnDockState, 1])
- resolved the issue that Mike Potjer reported in "BUG: Error report fails w/o optional ER_VMPVers"
  (VMP Message Board Id 3U61FFOWW). Thanks to Mike for reporting this issue.
- resolved the issue that Mike Potjer reported in "BUG: X5WinExplorer.PRG fails in Win 7"
  (VMP Message Board 3UA1FFQT6). Thanks to Mike for reporting this issue.
- resolved the issue that Mike Potjer reported on the VMP Message Board:
    BUG: MSGSVC.PRG type checking fails

    Hi Art,
    The MSGSVC.PRG included in VMP can fail if _SCREEN.oMsgSvc has been released, but the property still exists on _SCREEN.
    I haven't encountered this in a compiled app yet, but it has been causing problems in the development environment when
    I'm trying to test. It doesn't appear to happen all the time, but when I finish running the app, _SCREEN.oMsgSvc still
    exists, but is set to NULL. That causes the following 2 lines to misbehave:

    XXDTES("MSGSVC.PRG",'IF TYPE("_Screen.oMsgSvc")="U"')
    XXDTES("MSGSVC.PRG",'IF TYPE("_Screen.oMsgSvc") = "O"')

    Those 2 lines either need to check VARTYPE( _SCREEN.oMsgSvc ), or TYPE( "_SCREEN.oMsgSvc.Name" ) = "C" (or <> "C").
    OK, this is bizarre, but I actually ran into a situation where TYPE( "_SCREEN.oMsgSvc.Name" ) = "C" and VARTYPE( _SCREEN.oMsgSvc ) = "X", IOW NULL.
    I didn't think that was even possible! Anyway, I guess the only reliable fix is to use VARTYPE().
- in response to Peter Huppelschoten's recommendation, inserted:
  toward the bottom of the SpellCheck.VCX/SpellCheck::GetSuggestions() method. Peter indicated that if the spellcheck dialog was called from a modal
  form's editbox, the spellcheck form lost focus and things got messy. Show()-ing the form returns focus to the spellcheck form, and resolves the issue.
- in response to a report by Peter Huppelschoten, I replaced the following code in the XXFwNTDS.VCX/cusCBSQLConnect::GetDDSString() method:
    ALINES(laLines, m.lcString, .F., ';')
  with the following code:
    ALINES(laLines, m.lcString, 1, ';')
- in response to a bug report from Peter Huppelschoten, am now checking:
    (VARTYPE(m.oForms) = 'O')
  before running the following line of code in the XXFw.VCX/frmBase::Activate() event-method:
- resolved a Windows Aero bug in the XXFw.VCX/frmBase::BorderStyle_Assign() method that existed in VFP 9 prior to SP 2 (regarding the .Desktop property).
  Check out the comments in the XXFw.VCX/frmBase::BorderStyle_Assign() method for a fuller explanation of the issue.
  (Thanks to Mike Potjer for bringing this to my attention.)
- in reponse to the following bug report from Mike Potjer via the VMP Message Board (Message Id 3UZ0HIHJ6):
    "In our app, I am using n-tier services to manage some early app setup stuff. Under certain circumstances, this is causing oLib.oNTMessageServices
    to be loaded before oApp instantiates. That in itself isn't a problem, but because MsgSvc.DBF isn't USED() at that point, the message services class
    opens it with a different alias.

    "A little later, when XXFW.VCX/ctrApp::SetupMsgSvc() runs, it finds that the alias 'MsgSvc' is not USED(), so it attempts to open MsgSvc.DBF here:

    XXDTES("XXFW.VCX",'USE MsgSvc IN 0 SHARED',"ctrApp","SetupMsgSvc")

    "Because the table is already open with a different alias, this code fails. If you could simply add the AGAIN keyword to the USE command,
    the problem is solved."
  added the 'AGAIN' clause to 'USE MsgSvc IN 0 SHARED' call in the XXFw.VCX/ctrApp::SetupMsgSvc() method.

July 28, 2012

Build 01 (07/28/2012)

- resolved the following issue that David Middleton reported on the VMP Message Board:
    - do the following in the VM example app:
        - delete the existing Event Log table (ErrorLog.DBF/.FPT)
        - DO VMMain.Prg to create a new Event Log table
        - exit the application
        - run the following in the VFP Command Window:
        - USE ErrorLog.DBF EXCLUSIVE
        - INSERT INTO ErrorLog (Er_DatTime, Er_User, Er_UsrName) ;
                VALUES (DATE(), '6', 'Test User')
        - INSERT INTO ErrorLog (Er_DatTime, Er_User, Er_UsrName) ;
                VALUES (DATE(), '10', 'Another User')
      - DO VMMAIN and go to EventLog form
      - select either of the two records.
      - clicking the [Delete] button triggers the following error message:
          "frmdeGridNav.DeleteAction has found ThisForm.icMainViewAlias contains more than one
          record, which is not only unanticipated, but may result in the wrong record being deleted.
          You need to make sure ThisForm.ShellRequeryMainViewAlias() is coded to retrieve"

August 26, 2011

Build 01 (08/26/2011)

- resolved a "Property inAutoAdjustcolumnsToExactlyFillGrid_Pct is not found."
  error that occurred in the XXFw.VCX/grdBase::AdjustColumnWidthsToExactlyFillGrid()
  method when you attempted to run XXWBCOMWrapper.Prg
  (Thanks to Emil Baer for bringing this to my attention.)
- resolved a "Variable 'llMsgSvc_NTAliasUsed' is not found" error that occurred
  in the XXFwNT.VCX/cusMessageServices::OpenMsgSvcTable() method when running
  against SQL Server on the back-end (vs. VFP).
  (Thanks to Emil Baer for bringing this to my attention.)
- resolved a "Property GetCSType is not found." error that occurred when you
  [Right-Click]-ed on Step 4 (Specify the contents of the development/application-specific
  configuration file) of the VMP Application Setup Wizard
  (Thanks to Paco Satué for bringing this to my attention.)
- resolved an issue in the XXFw.VCX/frmData::GenAndPopPK() method that Paco Satué reported: the DefaultValue
  has a problem with DBGETPROP function when the cursor alias does not match the name of the DBF table
- resolved a "Property IAFORMINSTANCES is not found." error that occurred in the
  XXFw.VCX/cusForms::TimeoutAllForms() method
  (Thanks to Joan Mir for bringing this to my attention.)
- the Work Areas Viewer form (XXFwUtil.VCX/frmWorkAreasViewer) is now restoring the original data session
  (Thanks to Paco Satué for bringing this to my attention.)
- removed unnecessary "m." references from the XXFwNTDS.VCX/cusDataSourceBehavior::SQLExecuteLocal() method
  (Thanks to Mike Yearwood for bringing this to my attention.)
- the Error report generated by XXError.Prg:
    - now reports an exponential value in lieu of ten asterisks ('**********') for 'Disk remaining:' for very large hard drives
    - had two (2) 'Environment Listing' sections; the first 'Environment Listing' section now correctly reads 'LIST STATUS listing'
- resolved an issue that Paco Satué was experiencing in the XXWB.VCX/frmXXWBUpsize::cboSteps.Requery() method
- resolved an issue that Mike Potjer experienced in the XXFw.VCX/pgfPageRefresh::CommonPageActivate() method:
  The user entered an invalid value in a txtPicklistValid, then clicked on the tab for a different page
  without tabbing out of the textbox. Under certain conditions which Mike has not yet been able to pin
  down, the "no focus" kludge can put the form into an infinite loop of events. So skip this kludge,
  because the focus will go to the picklist form shortly anyway.
- thanks to Paco Satué for bringing this to my attention: fixed the DIMENSION-ing of the array when there
  is no error in the XXFw.VCX/cusAppStartupErrorMessage::StoreAErrorInfo() method
- in the XXFw.VCX/grdBase::When() event-method, resolved the following scenario that Mike Potjer reported:
    1. In the NT sample app, DO FORM NTDESPr1.SCX
    2. Click [Add]
    3. Tab into the Country textbox
    4. Enter an invalid country, such as XXX
    5. Press TAB to exit the textbox<
  Observed behavior:
    The menu at the top of the screen will flicker. In particular, you should see the "Lookup F2" pad
    appear and disappear a few times before the lookup form appears.
- replaced the following line in the DeleteDBC procedure in XXCreateDBCWithRemoteViewsOfVMPSystemTables.Prg:
      IF FILE(This.icDBC)
  with the following line:
  This resolves an issue that Peter Huppelschoten encountered when running a remote-data application where
  the .DBC still existed in the temporary directory but the .DCX and/or the .DCT has been deleted.
- in response to a report by Paco Satué that an error can be triggered when the Alias does not match the name
  of the View, replaced the following code in X3GetRT.Prg:
      lcRuleText   = DBGETPROP(m.lcControlSource, 'Field', 'RuleText')
  with the following code:
      lcSourceName = CURSORGETPROP('SourceName', m.lcAlias)
      lcTableField = STRTRAN(m.lcControlSource, m.lcAlias + '.', m.lcSourceName + '.')
      lcRuleText   = DBGETPROP(m.lcTableField, 'Field', 'RuleText')
  and replaced the following code:
      lcRuleText = DBGETPROP(m.lcControlSource, 'Field', 'RuleText')
  with the following code:
      lcSourceName = CURSORGETPROP('SourceName', m.lcAlias)
      lcViewField  = STRTRAN(m.lcControlSource, m.lcAlias + '.', m.lcSourceName + '.')
      lcRuleText   = DBGETPROP(m.lcViewField, 'Field', 'RuleText')
- in response to a request by Paco Satué, did the following line in the XXFw.VCX/cusStandaloneForms class:
    - replaced the following line in the Cleanup() method:
      with the following line:
    - replaced the following line in the Setup1() method:
          _Screen.AddProperty('oMsgSvc', CREATEOBJECT('cMsgSvc'))
      with the following line:
          _Screen.AddProperty('oMsgSvc', NEWOBJECT('cMsgSvc', 'MsgSvc.Prg'))
    - inserted the following code in the Setup2() method:
          IF (VARTYPE(m.oApp) # 'O') OR ISNULL(m.oApp)
            RETURN .F.
      as well as the following code:
          IF This.ilVMPDTWB
            WITH oAppConfig
             .AddCustomProperty('SetupINTL', .F.)
              * ctrApp::SetupMsgSvc() also checks this value
             .AddCustomProperty('Install_Screen_oMsgSvc', .F.)

              * X3MsgSvc.Prg needs this value
             .AddCustomProperty('DoNotUseMsgSvc', .T.)

              * XXOpenTable.Prg (indirectly) needs this value
             .AddCustomProperty('OpenTablesAtStartup', 1)
            ENDWITH			&& WITH oAppConfig
- in response to the following bug report filed by Mike Potjer:

    "When XXFW.VCX/frmBase::GetProximityLabelText() is unable to find a label to use, it fails with an Error 11
    because the variable lcText is never initialized to a character string.

    To Reproduce (I’m sure other examples could be found):

      1. EDITSOURCE('NTDEInvoices1.SCX', 1, 'NTDEInvoices1_SCX', 'grdLineItems.RightClick')
      2. Add the following code (no callback needed for testing):
             CREATEOBJECT('cusShortCutMenu', This, Thisform)
      3. Save the form
      4. DO FORM NTDEInvoices1.SCX
      5. Click the [Find] button
      6. Select an invoice which has already shipped (row is non-bold, Ship Date contains a date)
      7. Click [OK] to return to the Invoices form
      8. Right-click on any row in the grid.

    Observed Behavior:

      Error 11: “Function argument value, type, or count is invalid.”

  now initializing the variable at the beginning of the frmBase::GetProximityLabelText() method:
      lcText = SPACE(0)
- in response to the following report by Mike Potjer:

    I have an n-tier form where I want to allow the user to apply changes to a group of records. The user enters changes into
    a temporary cursor which does NOT match the structure of the ioMainDS.icAlias of the only BO in the BOM. Because there is
    only one BO, the code located here is executing:
        XXDTES('XXFWNTBO.VCX','IF ALEN(This.iaBO, 1) = 1', 'ctrBusinessObjectManager', 'ValidateControl')
    Ultimately, I get an error in the DS.ValidateControl() method when it attempts to read the value of a field which does not exist
    in the icAlias cursor. Note that the DS must have rules in it in order for the error to occur.

  replaced the following code in the XXFwNTBO.VCX/ctrBusinessObjectManager::ValidateControl() method:
      * If this business object manager is only managing one
      * business object, this is simple
      IF ALEN(This.iaBO, 1) = 1
        RETURN This.iaBO[1].ValidateControl(@m.tuMsgSvc, m.toControl, m.lcValidationAlias)
  with the following code:
      * If this business object manager is only managing one
      * business object, this is simple
      IF ALEN(This.iaBO, 1) = 1
        * Make sure the Alias matches this BO+DS.  If it doesn't,
        * the Alias may be a temporary cursor which does NOT match
        * the structure of the DS.icAlias, in which case the
        * ValidateControl() method of the DS will fail.
        IF UPPER( This.iaBO[1].ioMainDS.icAlias ) == m.lcAlias
          RETURN This.iaBO[1].ValidateControl(@m.tuMsgSvc, m.toControl, m.lcValidationAlias)
          * Ignore this control and allow validation to continue
          * on in normal fashion.
          RETURN .T.
  This makes this code consistent with code later in the BOM.ValidateControl() method, which only calls the BO.ValidateControl()
  method when the ioMainDS.icAlias matches the alias determined at the beginning of BOM.ValidateControl().
- in response to a report by Gene Pasquini that oApp.GetAppInfo('TextFactor', .F., .T.) can sometimes RETURN .NULL.,
  replaced the following line in the XXFwSec.VCX/cusLockout::MsgLockoutWarning() method:
       .icCustomText =  ALLTRIM(X3ED('D', oApp.GetAppInfo('TextFactor', .F., .T.)))
  with the following lines:
       lcCustomText = m.oApp.GetAppInfo('TextFactor', .F., .T.)
       IF NOT EMPTY(m.lcCustomText)
         lcCustomText = X3ED('D', m.lcCustomText)
      .icCustomText =  ALLTRIM(m.lcCustomText)
- in response to a request by Paco Satué, commented out the following line in the XXFw.VCX/ctrApp::SaveReset() method:
       SET STATUS BAR OFF   && to reset attributes properly
  as well as the following lines in the XXFw.VCX/ctrApp::Destroy() event-method:
- in response to the following report from Mike Potjer:

    "This is debatable as a bug, since I’m not using the button as it was originally intended. If a cmdToolbar is added to
    an .SCX form, and the button’s .Picture is set in the form instance, then the following line of code will clear the .Picture
    property, and the button will be blank:
          XXDTES('XXFw.VCX', [This.ResetToDefault('Picture')], 'cmdToolbar', 'Init')
    I’ve used this button before on .VCX-based forms without the .Picture being cleared, so I assume you would never have this problem
    when using the button on a toolbar, either, since they are always instantiated from a class."
    made the following changes in the XXFw.VCX/cmdToolbar::Init() event-method:

      - replaced the following block of code:
            IF NOT EMPTY(This.Picture)
              * I've seen problems with This.Picture not displaying
              * with the proper graphic file if This.Picture
              * has been changed at runtime (i.e., to 
              * This.icPictureForVOrientation) when a button is
              * subsequently instantiated -- some kind of property-
              * caching behavior
              CLEAR RESOURCES (This.Picture)
        with the following block of code:
            LOCAL lcPicture
            IF NOT EMPTY(THIS.Picture)
              * If this button is used on a regular .SCX-based form, the reset
              * code below will clear the .Picture property, and we don't get
              * any picture for the button.  Save the picture so that we can
              * restore the setting below.
              lcPicture = .Picture

              * I've seen problems with This.Picture not displaying
              * with the proper graphic file if This.Picture
              * has been changed at runtime (i.e., to 
              * This.icPictureForVOrientation) when a button is
              * subsequently instantiated ... some kind of property-
              * caching behavior
              CLEAR RESOURCES (.Picture)

              * If the .Picture property was cleared,
              * restore it back to its original value
              IF EMPTY(.Picture)
               .Picture = m.lcPicture
        and, in response to the following comment: "BTW, at the end of the Init(), I noticed that a default value is set for
        .icPictureForHOrientationDisabled, but not for icPictureForVOrientationDisabled", inserted the following block of code:
            IF EMPTY(THIS.icPictureForVOrientationDisabled) ;
                AND NOT EMPTY(THIS.DisabledPicture)
              THIS.icPictureForVOrientationDisabled = THIS.DisabledPicture
- in response to a report by Peter Huppelschoten, now including an 'EXCLUSIVE'
  clause in the two (2) calls to the 'USE' command

Jan 16, 2010

Build 01 (1/16/2010)

- now RETURN-ing .F. at the end of the first nested IF in the
  XXFwControlBehaviors.VCX/cusDTOTextbox::OwnerKeyPress() method;
  this resolves the following issue that Peter Huppelschoten
  reported: trying to [Tab] out of a date-bound textbox whose
  .Value is .NULL. doesn't work (focus remained in the field).
  (Thanks to Peter Huppelschoten for bringing this to my attention.)
- uncommented the following line in the XXFwUtil.VCX/frmWorkAreasViewer::Show()
    llRestore = oUser.oPrefs.RestorePrefs(ThisForm, ThisForm)
  which had accidentally been commented out in the 2005.12.15.01 build.
  (Thanks to Ric Unruh for bringing this to my attention.)
- resolved the following issue that was in the VM VMP example application:
    - run 'Tools | Options' from the menu
        - set language to German
    - run the Event Log (Administrator | Ereignisprotokoll)
        - column headers are translated except the current sort column
        - click on a column header to resort
        - all column headers now in English
  (Thanks to Andy Patrick for bringing this to my attention.)
- resolved an issue in the XXFw.VCX/frmBase::BorderStyle_Assign() method that
  "locked up" forms when that event-method was called while invoking a picklist
  form. (Thanks to Craig McFarlin for bringing this to my attention.)
- resolved an issue in the XXFwUtil.VCX/frmWorkAreasViewer.pgfInfo.pagEntireCursor.txtVoyeur::GotFocus()
  event-method that caused the grid column .ControlSource-s to get re-arranged upon,
  for example, doing the following:
    - run the the Work Areas Viewer
    - go to the 'Entire cursor' tab/page
    - go to the 'Structure' tab/page
    - go to the 'Entire cursor' tab/page
  (Upon arriving to the 'Entire cursor' tab/page the second time, the issue occurred.)
- corrected code in the XXFwUtil.VCX/frmWorkAreasViewer::Destroy() event-method. Previously,
  the code was restoring the SET DELETED setting for *all* data sessions; it now correctly
  restores the SET DELETE setting for each data session.
  (Thanks to Mike Potjer for pointing this out.)
- resolved the following scenario that Emil Baer reported:
    - DO XXDTHack WITH 'ntdecus1.scx'
    - changed BaseClass filter from 'No filter' to 'textbox'
    - renamed 1st occurrence of class 'txtntbase' to 'textbox'
    - upon pressing [Tab] to move out of the Class (textbox) into the ClassLoc (textbox), the
      BaseClass filter continues to display 'textbox' but no longer filters the list by 'textbox'
- resolved an issue toward the bottom of the XXFwNTBO.VCX/ctrBusinessObject::UnPackageNonCursorData()
  method that Mike Potjer reported
- replaced the following line in the XXFwFrm.VCX/frmStandBy::Init() event-method:
    CASE VARTYPE(m.oApp) = 'C'
  with the following line:
    CASE VARTYPE(m.oApp) = 'O'
  (Thanks to Mike Potjer for reporting this issue.)
- Resolved the "Data type mismatch" error that VMP developer Peter Huppelschoten got on the following line:
    USE IN SELECT('JunkCursor')
  under certain circumstances (e.g., extremely fast CPU and quad processor) after doing something like:
    SQLEXEC(m.lnTestHandle, m.lcSQL, 'JunkCursor')
  The resolution (a call to DOEVENTS) can be found at the following locations:
    a) XXDTES('XXFwLibs.VCX', 'DOEVENTS', 'cusConnectionSvc' , 'TestConnection')
    b) XXDTES('XXFwNTDS.VCX', 'DOEVENTS', 'cusConnectionBehaviorODBC', 'TestConnection')
    c) the DOEVENTS line after the following line in XXFwMain.Prg:
      XXDTES('XXFwMain.Prg', "llValid = SQLEXEC(m.tnStatementHandle, [SELECT 'testconnection'], 'JunkCursor') > 0")
- you can no longer get a "Cannot quit Visual FoxPro" error message under the following scenario: click on [X] (the
  Close commandbutton) on a slow machine and/or slow network and, while the form is shutting down, click [X] again.
    XXDTES('XXFw.VCX', '_Screen.Closable', 'ctrApp', 'OnShutdown')
  Thanks to Peter Huppelschoten for reporting this issue and supplying the fix:
    a) disable the button during the shutdown process and
    b) restore the close button if the shutdown process terminates
- in the XXFwIUDLog.VCX/BO_IUDLog::GenerateIUDLogWHEREClause() method, now only adding "AND" if lcWhereClause is not
    empty. (Thanks to Mike Potjer for recommending this.)
- in the XXFwFrm.VCX/frmChangePassword.txtCurrentPassword::ActionOnValid(), added the alias as a 2nd parameter to
    the OLDVAL() call. Peter Huppelschoten had indicated that without the alias/2nd parameter, although everything
    worked fine with Visual FoxPro on the back-end, he experienced a problem when his data was in SQL Server.
- resolved an error that occurred when doing the following steps:
    - fire up the NT Example application development environment
    - ensure IUD logging is enabled for the example application/database
    - make at least one change to a Customer record to ensure that there is IUD log data for it
    - [Right-Click] on any data entry control in the form and select the "Display history for this Customer record…" option
    - [Right-Click] on the IUD history form (not on a control on the form but on the form itself), and select 'Cus_PK' from the menu
  (Thanks to Mike Potjer for bringing this to my attention.)
- resolved an "Cannot insert explicit value for identity column in table 'ERRORLOG' when IDENTITY_INSERT is set to OFF."
  error that sometimes occurred when running the VMP Upsizing Wizard
  (Thanks to Peter Huppelschoten for bringing this to my attention.)
- resolved an error that occurred in the XXFwIUDLog.VCX/BO_IUDLog::CreateResultCursorAlias() method when trying to display
  all changes to a record in a table which had memo fields in it
  (Thanks to Mike Potjer for [a] bringing this to my attention and [b] supplying the code to resolve this.)
- resolved an error in the spellchecker whereby if the editbox contains more than one line, the checker did not check
  the first word of subsequent lines (i.e., lines 2, 3, 4, etc.)
  (Thanks to Ric Unruh for [a] bringing this to my attention and [b] supplying the code to resolve this.)
- resolved bug in the XXFw.VCX/cusAppLibs::LoadDIMember() method that occurs under the following circumstances:
    1. Add a page to a pageframe
    2. Change the PageOrder of the page so that it precedes a pre-existing page.
    3. Use the oLib.LoadDIMember() method to load delayed-instantiation controls on the new page.
  For example, add a 4th page, which VFP names 'Page4', and set its PageOrder = 3. Now the page named 'Page3' has
  .PageOrder = 4. When the user clicks on 'Page4' for the first time, the code in the LoadDIMember() method loads
  the DI container correctly, but then activates 'Page3'.
  (Thanks to Mike Potjer for [a] bringing this to my attention and [b] supplying the code to resolve this.)
- the XXFw.VCX/cusForms::TimeoutAllForms() method now checks the PEMSTATUS() of 'OnTimeoutReached' before the
  second call to the .OnTimeoutReached() method (thus preventing a problem with forms that do not have that method)
  (Thanks to Ric Unruh for bringing this to my attention.)
- now wrapping DATETIME() calls in the following methods with TRY-CATCH-ENDTRY:
    - XXFwControlBehaviors.VCX/cusDTOTextbox::OwnerValid()
    - XXFwControlBehaviors.VCX/cusDTOTextbox::UpdateOwnerControlSource()
  this resolves errors that occurred when a bad/invalid date was entered into a date/datetime-bound textbox
  (Thanks to Peter Huppelschoten for bringing this to my attention.)
- now SET-ting SAFETY OFF in the DeleteDBC procedure in XXCreateDBCWithRemoteViewsOfVMPSystemTables.Prg; this resolves
  an issue that Peter Huppelschoten encountered when running a subsequent occurrence of a remote-data application
- in the XXFwNT.VCX/cusMessageServices::OpenMsgSvcTable() method, the following line:
    XXLOGGER('cusMessageServices::OpenMsgSvcTable is about to RETURN .F. because the MsgSvc.DBF cannot be opened', .T.)
  now displays only if the method is unsuccessful (it used to display whether the method was successful or not)
  (Thanks to Mike Potjer for bringing this to my attention.)

Dec 15, 2008

Build 02 (12/18/2008)

- resolved an issue with the BO-level .iaChildren array property

Build 01 (12/15/2008)

- the XXFw.VCX/frmData::UpdateFormOnAdd() now calls the XXFwGrd.VCX/grdDataEntry::OnUpdateFormOnAdd()
  method; this "fulfills" the following comment that has been in the latter method for quite a while:
    "Called from ThisForm.UpdateFormOnAdd(), this method is
    called at the end of a successful ThisForm.AddAction()"
  Thanks to Mike Potjer for pointing this out.
- resolved the following scenario that Mike Potjer reported on the VMP Message Board:
  "if XXFwGrd.VCX/grdDataEntry::DeleteBlankRows() is called without first selecting the
  grid's RecordSource, it will do nothing if the current ALIAS() does not use optimistic
  table buffering. That's because the following line of code does not specify the alias
  when checking the buffering, neither does the method include code prior to this condition
  to explicitly set the work area to the RecordSource:
    XXDTES('XXFwGrd.VCX', [OR (NOT CURSORGETPROP('Buffering'], 'grdDataEntry', 'DeleteBlankRows')"
- resolved the following scenario that Mike Potjer reported: "in the XXDTGenPopCode form, the
  directory dropdown in step 4 saves a list of folders, but it doesn&'t appear to change folders
  via the dropdown (listbox). Here’s how to reproduce this:
    1. DO XXDTGenPopCode
    2. Make sure the directory dropdown contains more than one path. If not, you may need to
       select a new path, close the form, and re-run XXDTGenPopCode.
    3. Using the dropdown in step 4, Select any path other than the path displayed there when the form was opened.
    4. Click the [Generate] commandbutton
    5. The messages that appear indicate that the file was created in the path that was displayed in the dropdown
       when the form was opened, not in the path currently displayed in the dropdown.
    6. Click on the ellipsis button ([...]) in step 4. The path selected in GETDIR() dialog is the path that was
       displayed in the dropdown when the form was opened, not in the path currently displayed in the dropdown.
- in the XXFwNTDS.VCX/cusCBSQLConnect::MakeConnection() method, now calling the AERROR() function *before* the
  SQLSETPROP() call; as a result, the error information no longer gets cleared out by the SQLSETPROP() call.
    Thanks to Mike Potjer for pointing this out.
- now calling the EVALUATE() function in lieu of doing a macro substitution to make code run faster in methods of
  the cusPushPopDockableWindows class (defined in this program). Thanks to Mike Yearwood for pointing this out.
- XXDTFoxCode.Prg now contains code to establish IntelliSense for the X8RegExpTest.Prg library routine;
  thanks to Mike Potjer for pointing out the omission.
- resolved an "Operator/operand type mismatch." error that occurs in the txtAutoLaunchForm::Init() event-method
  of the following two (2) forms:
    - VMToolsOptions.SCX in the VMP VM Example Application
    - NTToolsOptions.SCX in the VMP NT Example Application
  when you do the following in either the VM or NT VMP Example applications:
    - add the following record to the AppInfo table (??System.DBF):
      - App_Item = 'InitialAutoLaunchForm'
      - App_ItemDataType = 'C'
      - App_ItemDescription = 'Report Catalog'
    - delete any InitialAutoLaunchForm from UserPrefs
        OPEN DATABASE ??
        USE ??!UserPrefs
        DELETE FOR Prf_Item = 'InitialAutoLaunchForm'
    - DO ??Main.Prg ... Report Catalog displays as expected
    - running 'Tools | Options' triggered "Operator/operand type mismatch." error
  Thanks to Andy Patrick for reporting this issue and for Mike Potjer for proposing the ultimate solution
  both on the VMP Message Board.

Oct 01, 2008

Build 01 (10/1/2008)

- resolved an error that occurred when the user [Right-Click]ed on a control
  and then pressed [Esc] or clicked outside the resultant shortcut/context menu
  (in other words, the user did not select an option from the context menu)
- resolved an issue that occurred when:
    - 1) attempting to add records to a table in which the name of
         the Primary Key (PK) was longer than six (6) characters and
    - 2) an IUDLog INSERT (table) trigger was in place
- thanks to Randy Bosma, '[Copy]' now reads '[Duplicate]' in the following text
  that appears when you click on the [Copy] commandbutton in the XXDTMsgS utility:
     This option allows you to copy the current record into a different
     MsgSvc.DBF table (the [Copy] button allows you to duplicate the
     current record into the current MsgSvc.DBF table).
- resolved the error that occurred when the user did the following:
    - [Right-Click] and select 'Display History for ... record'
    - Set filter to all users
    - click on [Apply filter]
  (thanks to Bud Wheeler for pointing this out)
- added 'WINVISTA' to the IntelliSense for X6WinOS.Prg
- resolved several bugs in the XXFWMisc.VCX/cusDESubFormCursor::SetFieldPropsV()
  method which prevented default values from being used in a sub-form view.
  (thanks to Mike Potjer for pointing out the bugs and supplying the fixes)
- resolved an issue that Mike Meer discovered in the
  XXFWNTDS.VCX/cusDSBehaviorSPT::FetchData() method

Aug 08, 2008

Build 01 (8/8/2008)

- added the following line to NTMain.Prg in the VMP NT Example Application:
- resolved the following scenario:
    1. Modified the NTFW.VCX/ctrNTApp.SetUpGlobalToolBars()
       method and uncommented the following code:
         DIMENSION This.iaGlobalToolbars[1, 2]
         This.iaGlobalToolbars[1] = 'tbrNTSCADONav,NTFWFrm.VCX'

    2. DO NTMain.Prg and select 'File | Invoices (NTDEInvoices1.SCX)' menu option
    3. Selected the "0000000001" invoice
    4. Clicked on the grid column1: 'Crisis Counseling gift certificate.'
    5. Presses the “Close this form” toolbar commandbutton
    6. After pressing the button, the "Lookup F2" menu pad did not disappear and
       the menu wass totally blocked (it did not respond when the user clicked on it)
- resolved a form resizing issue in the XXFWFrm.VCX/ctrFormSizer::frmResize() method
- resolved the following issue in the XXFW.VCX/txtBase::SetDynamicAttributes() method: txtBase
  turned the .ForeColor to red for negative values for all numeric data types except 'Y' (currency)
- resolved a problem in the XXFWMisc.VCX/frmReport::ReportForm() method whereby VFP would crash
  (hard) on the following line when the developer was attempting to MODIFY a REPORT in lieu of
  running it:
- removed an extraneous txtICBase class that was in VMP_Int\ICCtrl.VCX (BaseClass of Form...)
- inspired by Mike Yearwood, replaced the following lines in the
  XXFWNTDS.VCX/cusDSBehaviorSPT::SaveActionInsert() method:
    LOCAL &lcField.
    STORE (EVALUATE(m.lcField)) TO &lcField.
  with the following lines to speed up the code:
    LOCAL (m.lcField)
    STORE (EVALUATE(m.lcField)) TO (m.lcField)
- per feedback from Bud Wheeler, replaced two (2) occurrences of 'm.lcDatabase' in the
  SP_VMP_IUDLOG_SetIUDAlias procedure in XXFwData.Prg with 'm.tcDatabase'

Oct 13, 2007

Build 03 (2/6/2008)

- fixed a bug in A.Prg so that it now displays "[generate an XXDTES()/EDITSOURCE() line]" message for Ctrl+F4/Ctrl+F5
- resolved the following issue (which affected other n-Tier forms [ultimately] based on the XXFWFrm.VCX/frmDEGridNav2Pages
    - when you do the following:
      - fire up the NT Example Application development environment
      - click the [Add] commandbutton
      - enter Customer Code and Name
      - select the Notes tab (4th page)
      - click the [Cancel] commandbutton
    the data entry control (editbox) on the Notes tab (4th page) was blank and disabled because the updateable cursor is EOF()
- fixed the following bug: when the IncludeLoginCancelCommandButtons AppConfig item was set to .T., pressing [Enter] in the
  password textbox on the last password attempt triggered an "Unable to login the login in V_LoginHistoryOneUser" error.
- thanks to Joan Mir, corrected the Spanish equivalents of the following phrases:
    - "Display history for field"
    - "Display history for record"
  and ensured that the above two (2) shortcut/context menu options work when a VMP application is run in Spanish (via INTL)

Build 02 (11/7/2007)

- now having the Unload() event-method of the VMDECUS_LinkedInvoices1 form (in the VM example application)
  release any locks so that it does not report that you have the record locked the next time you run the form
- the XXFWNTBO.VCX/ctrBusinessObject::DeleteAction() method now checks the return value when it calls
  the XXFWNTBO.VCX/ctrBusinessObject::ExecuteChildBOMethod() method
- corrected a bug in the XXFWSemaphoreLock.VCX/BO_SemaphoreLock::SLock() method
- eliminated the "Too many arguments." error that occurred in X7FieldList.Prg when running in VFP 8
- fixed the following bug: when the IncludeLoginCancelCommandButtons AppConfig item was set to .T., after
  typing only the user id and before passing to the password textbox, clicking on the [Login] commandbutton
  allowed you to log in without entering a password.

Build 01 (10/13/2007)

- resolved an issue in the XXProcDT.Prg::frmNewerVersionOfVMPIsAvailable.lblClickHereBugFixes.Click()
  event-method that did not take the VMP developer to the correct bug fixes page (after VMP
  discovered that the developer was not using the very latest version of VMP)
- resolved an issue in X3VUSPHN.Prg that allowed it to return invalid length phone numbers
- fixed a typo in the XXFW.VCX/frmData::GenPK() method
- fixed a bug in the XXFW.VCX/edtBase::Init() event-method (documented on the VMP Message
  Board by Albert Gostick [cf. Message Id 26W198HK9])
- added a DODEFAULT() after the THIS.ORCleanup() line in the XXFWNT.Prg/sesNTBase::Destroy() event-method
- resolved an "Expression is not valid outside of WITH/ENDWITH." error in the
  XXFWFrm.VCX/frmPixViewer::SpecifyUserPrefs() method

Aug 14, 2007

Build 01 (8/14/2007)

- resolved an issue in the XXFWSec.VCX/cusLockout::GetLockout() method that occurred when the user (administrator)
  did not fill in (i.e., left empty) the explanatory text when doing a lockout (Admin | Lock users out)
- resolved an issue in the SpellCheck.VCX/SpellCheck::OriginalString_Assign() event-method that resulted
  in a word not getting replaced if it was a subset of the replacement word
- resolved a refresh issue with the Country label in the following forms in the NT example application:
    - NTDECty1.SCX
    - NTDECty2.SCX
    - NTDECty3.SCX
    - NTDECty3a.SCX
    - NTDECty4.SCX
- resolved an issue in the XXFWCal.VCX/frmAbstractCalendar::SetInitialVisibleLocation() method
  when the calendar (form) position was one (or more) of the following:
    - 4 = Above, Left
    - 5 = Above, Centered
    - 6 = Above, Right
- eliminated the "Property DOCKPOSITION is not found." error that occurred in:
    - the XXFW.VCX/frmBase::Destroy() event-method
    - the XXFW.VCX/cusForms::ReleaseAllForms() method
  when a VMP form running in VFP 8 was closed
- now preventing the following obscure (yet possible) scenarios:
    - Scenario 1:
        Steps to reproduce
           - in the VMP example application, DO FORM VMDECusV.SCX
           - ensuring that the selected customer is 'Abstract Distractions',
             go to the 'Contact People' tab (page 3)
           - with the Contact names in ascending order, select the record for 'Andy Betaque'
           - press the [Down Arrow] key to move to the next Contact record
           - WITHOUT PRESSING ANY OTHER KEY, click the 'Last Name' header (caption) to
             toggle the sort order to descending
        Observed behavior
           - the form goes into Edit mode
           - the ShellBeforeAppendBlank() and ShellAfterAppendBlank() methods get executed
           - the record for 'Andy Betaque' is highlighted again
           - now preventing the following obscure (yet possible) scenario:
    - Scenario 2:
        Steps to reproduce
           - in the VMP example application, MODIFY FORM VMDECus4_2003.SCX and set the
             .AllowAddNew property of grdContacts on Page 3 to .T.
           - DO FORM VMDECus4_2003.SCX
           - ensuring that the selected customer is 'Abstract Distractions',
             go to the 'Contact People' tab (page 3)
           - with the Contact names in ascending order, select the record for 'Andy Betaque'
           - press the [Down Arrow] key to move to the next Contact record
           - WITHOUT PRESSING ANY OTHER KEY, click the 'Last Name' header (caption) to
             toggle the sort order to descending
        Observed behavior
           - the form goes into Edit mode
           - the ShellBeforeAppendBlank() and ShellAfterAppendBlank() methods get executed
           - the record for 'Andy Betaque' is highlighted again
- corrected IntelliSense in XXDTFoxCode.Prg for:
    - X8ShellExecute.Prg
    - X8ValidURL.Prg
- XXDTUnusedClassesPJX.Prg does not report false positives it used to report

May 18, 2007

Build 01 (5/18/2007)

- resolved a "Syntax Error" that occurred in the XXFWComp.VCX/ctrMover::RemoveAction() method when the .RowSource
  was an expression that contained one (1) or more periods and the user clicked on the [Remove] commandbutton
- resolved an "OLE error code 0x800200005: Type mismatch." that error occurred in the XXFW.VCX/tbrBase::ORCleanupAllMembers()
  method when that method attempted to set an ActiveX control's .Font property to .NULL.
- in the XXFWNTDP.VCX/cusDataPackagerXML::DataToCursorIsNotDiffGram() method:
  - resolved an error that occurred when either:
      (a) the PK field was not specified or
      (b) a wrong name was specified for the PK field
  - resolved an error that occurred when you attempted to populate an existing cursor with multiple data
    records: the primary key field contained the same value for *ALL* records added to the cursor
- in the XXFWNT.VCX/cusMessageServices::GetMessageText() method:
  - resolved an error that occurred when the iaMessages array of the message package contained a key
    (rather than a data object)
  - resolved an error that occurred when an invalid message package was passed

Dec 08, 2006 build

Build 06 (3/31/2007)

- resolved the issue in the VMP NT example application NTDECusC4 form whereby you could add a duplicate Contact
- resolved a bug that occurred in the XXFW.VCX/frmData::SaveMessageOnFailure() method when an n-tier rule failed
- resolved a bug in the XXFWNT.VCX/cusMessagePackage::GetSpecificTableupdateFailureKey() method that occurred
  in the following scenario:
    - no AutoInc
    - no field .Caption/s
    - user got the following error:
        Uniqueness of index "name" is violated (Error 1884)

Build 05 (2/17/2007)

- implemented additional code in the XXFWSec.VCX/cusLockout::MsgLockoutWarning() method
  so that it now reads the latest/current value of 'TextFactor' from the AppInfo table
- eliminated the "Property value is out of bounds." error that occurred when, in VFP 8,
  you on either an editbox or a textbox and select "Format..."
- now RETURN-ing .F. in the XXFWControlBehaviors.VCX/cusDTOTextbox::OwnerKeyPress() method
  if the following expression evaluates to .F.:
    IF (This.icType = 'D') AND (NOT VARTYPE(toTextbox.Value) = 'D')
- in the XXFW.VCX/txtBase::KeyPress() event-method, now resetting the .SelStart and .SelLength
  properties if the call to the OwnerKeyPress() method RETURNs .T.
- in the NTDECus2 form (in the VMP NT Example application):
    - the [Print] and [Delete] commandbuttons now get enabled when you [Retrieve] one or more records
    - the [Print] and [Delete] commandbuttons now get disabled when you [Clear Data]

Build 04 (12/22/2006)

- eliminated a problem in the XXFWComp.VCX/cmdPicklistValid::Refresh() method

Build 03 (12/21/2006)

- eliminated the "Property value is out of bounds." error that occurred when, in VFP 8, you attempt to either run an application or
  run a form standalone
- eliminated a "Data type mismatch." error that can occur in the following methods under certain circumstances:
    - XXFWComp.VCX/ctrPicklistValid::SaveControlValues()
    - XXFWMisc.VCX/ctrSelCriteria::SaveControlValues()
- eliminated the following problem in the XXFWNTDS.VCX/ctrDataSource::FetchFieldsForOnePK() method; if you passed an asterisk ("*")
  as the tcFieldList parameter to return all fields, then you could not access the Primary Key (PK) field by its name

Build 02 (12/16/2006)

- XXDTFoxCode.Prg now contains code to establish IntelliSense for the new X6StringDelimiters.Prg library routine
- added code to the XXFW.VCX/pgfBase::PageCount_Assign() method that replicates code in the txtBase::ToolTipText_Assign() method
  to SET TALK OFF if SET('Talk') was set to 'ON' (without this code, numbers were [incorrectly] being displayed to _Screen).

Build 01 (12/8/2006)

- resolved issue in the XXFWFrm.VCX/frmReportCatalog::RunReport() method that occurred when a Report Catalog (Rep_)Class was missing
- resolved error in the XXFWComp.VCX/ctrPicklistValid::OnPicklistvalidTextboxInteractiveChange() method that occurs if there is no
  icAlternateLookupAlias (because there is no value to lookup)
- in both the XXFW.VCX/ctrBase::GetFirstControl() and XXFW.VCX/pgfBase::GetFirstControl() methods, resolved case mismatch issues and
  why the methods did not always correctly return the first control
- resolved a bug in the XXTools.VCX/frsXXDTSearch::StringFoundIn() method whereby when "Exclude comments?" is checked, then a line
    (a) following a comment line with an embedded semi-colon (i.e., a comment that contains, but does not end with, a semi-colon)
    (b) following a line that is part of a continued comment and/or itself ends with a semi-colon
  was not getting displayed in the results of the (XXDTSearch) search
- resolved a bug in the XXFWNTBR.VCX/cusRule::Init() event-method: a rule inheriting from XXFWNTBR.VCX/cusRule is allowed to be instan-
  tiated to a property, but caused an error and crashed an application if you attempted to instantiate it as a member of a non-tier class

Sep 22, 2006 build

Build 02 (9/29/2006)

- eliminated the "Unknown ASQLHANDLES - Undefined" error that occurred in XXFWMain.Prg when you built a VMP 2005 project in VFP 8
- eliminated the "Command contains unrecognized phrase/keyword." error that occurred in the XXFWSemaphoreLock.VCX/BO_SemaphoreLock::CreateFreeTable()
  method when you built a VMP 2005 project in VFP 8
- now making _Screen visible in the ShowError procedure in XXError.Prg if it's not already visible (e.g., if an SDI application)
- eliminated the "Property value is out of bounds." error that occurred when you RightClick-ed in the listbox on the General tab of the
  EventLog form when running in VFP 8

Build 01 (9/22/2006)

- in X3WinMsg.Prg, eliminated the last parameter (tlSilent); as a result, removed the redundant sound that the program generates
  when the user establishes a sound via the Windows Control Panel for 'Question'.
- in response to the above, no longer passing the last (5th) parameter when calling X3WinMsg.Prg from X3MsgSvc.Prg
- the XXFWUtil.VCX/cusSettings::LoadPropertiesFromDataSource() method did not refresh (requery) the remote view if a value
  in that view had been modified on the back-end; it now does.
- resolved the "Database 'VM' is not open" error." that occurred upon DO-ing RDMain (in the Remote Data application)
- modified the ReleaseAppObjects procedure in this program (XXFWMain.Prg) to SQLDisconnect() one active connection at a time to
  eliminate/prevent application from crashing (fatal error) when trying to close all open connection handles via SQLDisconnect(0)
- corrected an issue with XXDTSearch that prevented it from including a line in the search results when, prior to the line,
  there was a comment that was continued on at least one other line
- resolved error that occurred in the XXFWFrm.VCX/ctrFormSizer::frmResize() method when, for example, you have NODEFAULT-ed
  the SetSizerInfo() method for a pageframe
- resolved error that occurred in XXFWData.Prg when, in XXWBAppSetup (the Application Setup Wizard), a VMP developer specifies to not
  use default VMP naming conventions and then specifies a "main DATABASE name" that does *not* match the 2-character table name prefix
- resolved "double text" issue with cusHyperlinkTextbox when the (corresponding) textbox's BorderStyle = 0 (None)
- resolved an issue in the XXFWFrm.VCX/frmMover::Init() event-method that occurred when .ioCallingForm is omitted from the parameter object
- resolved a "Syntax Error" that occurred in the XXFWComp.VCX/ctrMover::AddAllAction() method when the .RowSource is an expression that
  contains one (1) or more periods and the user clicked on the [Add All] commandbutton

Jul 08, 2006 build

Build 02 (7/11/2006)

- resolved an issue in the cusPushPopDockableWindows::Destroy() event-method (toward the bottom of XXFWMain.Prg) that caused the following:
  - when [New...] was clicked for a form (on the Documents tab/page) of a Project Manager (to which a VMP Project Hook is attached);
    if [Esc]ape was then pressed in the resultant XXWBNewForm, a "Function argument value, type or count is invalid." error occurred
  - toolbars (e.g., Standard) not getting restored after running a VMP form/application
  - on a label / select Builder... / click [OK] / a "Function argument value, type or count is invalid." error occurred
- resolved the fact that the filter was not being restored properly in the XXFWNTDS.VCX/ctrDataSource::Validate() method

Build 01 (Initial Build)

- resolved an issue in the XXFWLibs.VCX/cusDBCSvc::OpenTable() method whereby if the file that is being opened was already
  being USED() and if the text of the filename passed to the method (m.lcTable) was anything other than all upper case,
  a line of code was incorrectly deciding that it does not match the contained table name.
- resolved bug in X8ShellExecute.PRG that was due to the VFP limitation that the JUSTEXT() function cannot handle strings
  that contain more than 259 characters
- resolved the following issue in the XXFW.VCX/frmBase::CheckRequiredFields() method: if the ControlSource is 'This.Parent.'
  (or anything beyond that), everything after 'This.Parent' gets truncated, and you get an error later because m.lcControlSource
  EVALUATE()s to an object, rather than a value
- in the XXFWFrm.VCX/ctrFormSizer::SizeMenu() method, no longer allowing the form to "run off" the right edge as well as the bottom
  (if, for example, you select '140%' when the form is in the lower right corner of [the] _Screen)
- resolved bug in the XXFWNTDS.VCX/ctrDataSource::Validate() method that can cause the validation to fail with a filtered Data Source (DS)

Aug 25, 2005 build

Build 08 (5/31/2006)
- replaced 'GOTO BOTTOM' in the XXFWGrd.VCX/grdDataEntry::DeleteCurrentRow() method with the following code:
    GOTO BOTTOM IN (This.RecordSource)
- resolved error [in the frmData::DeleteAction() method] that occurred when you clicked on [Delete] in the Event Log
- corrected the ASCAN() call in XXWBBODS.Prg to enable the following: in the same (middle-tier) .VCX,
  you can now create a BO whose name is a subset of the name of another BO in the same class library
- replaced 'SHOW WINDOW Properties BOTTOM' in XXBuilder.Prg with 'SHOW WINDOW Properties SAME'
- in the NTDECusInvLin1 form in the NT Example application, resolved the fact that -- when you clicked on
  the [Add Inv] commandbutton on the Invoices tab on a Customer that has no Invoices (e.g., a new Customer) --
  the following message displayed:
      "Please enter all the required Invoice fields before adding another Invoice."
  and no invoice was created (added).
- modified the FetchData(), FetchList() and FetchDataPost() methods of the XXFWNTDS.VCX/ctrDataSource class
  so that VMP now correctly restores index tags when:
    - user preferences are in effect and
    - the sort order is DESCENDING
  This modification automatically corrects the grid behavior on the "Contact People" tab of the following
  NT Example application forms: NTDECusC1, NTDECusC2, NTDECusC2a, NTDECusC4, NTDECusC5, NTDECusC6 and NTDECusC8.
- resolved the following issue (in Windows XP Pro): if you go to Display Properties, the Appearance tab, and click
  the Effects button, there is a checkbox for "Use the following method to smooth edges of screen fonts:", and
  underneath is a combobox with the options Standard and ClearType. If the checkbox is checked and ClearType is selected,
  labels with .BackStyle property set to 0-Transparent appear bold upon switching between tabs in a pageframe (e.g., the
  zReadMe label on VM/NT Example Application forms).
- in X3MsgSvc.Prg, now restoring the work area to the one that was selected when the program was called
- corrected the ctrPVStateProvince_DisplayCountry.lblDisplay::Refresh() method so that it no longer erroneously displays
  "Canada" as the lblDisplay.Caption in the following forms in the NT example application: NTDECty1, NTDECty2 and NTDECty2a.

Build 07 (5/20/2006)
- fixed the following bug in NTDECusC6.VCX/frmNTDECusC6WizardSubform:
    - either: (1) fire up the VM NT Example Application and, from the 'Other | Wizard forms' sub-menu,
                  select the "Customers + Contacts/wizard subform (NTDECusC6.SCX)" option
           or (2) run the following from the Command Window:
                    DO FORM NTDECusC6.SCX
    - go to the "Contact People" tab
    - click [Update]
    - click [Next] three (3) times
    - triggered an ioBOMgr error
- solved a bug in the XXFWCtrl.VCX/txtPicklistValid::SetPicklistFormParameters() method by doing the following:
    - commented out code in that method
    - moved code from the ProcessNewValue() method to the Refresh() method
- the XXFW.VCX/ctrBase::SetControlSourceProxyValue() method now checks if the form has an EditAction() method before calling that method
- corrected the comment for the 2nd parameter (tlPack) of the XXFWLibs.VCX/cusDBCSvc::Reindex() method
- immediately below the 'THIS.WindowType = 1' assignments in the following methods of the XXFW.VCX/frmData class:
    - Init() event-method
    - SetupDESubform method
  inserted the following comments:
        * N.B. If you get a "Property WINDOWTYPE is read-only." error when VFP attempts to
        * execute the above assignment, it may very well be due to the fact that the
        * form's .Visible property is explicitly set to .T. in the Property Sheet.
        * ResetToDefault-ing the form's .Visible property back to its default of .T.
        * solves the problem.
- refactored the following methods so that they no longer call RETURN within a WITH...ENDWITH construct:
    - frmWorkAreasViewer::ApplyPresentationFont()
    - XXFWFrm.VCX/frmFormat.txtFontName::InteractiveChange()
    - XXFWFrm.VCX/frmFormat.txtFontStyle::InteractiveChange()
    - XXFWFrm.VCX/frmReportDestinationSPF::Init()
    - XXFWGrd.VCX/grdDataEntry::AlreadyInGrid()
    - XXFWMisc.VCX/cusDESubformCursor::SetFieldPropSC()
    - XXFWMisc.VCX/cusDESubformCursor::SetFieldPropSV()
    - XXFWMisc.VCX/ctrViewMgr::RequeryViews()
    - XXFWMisc.VCX/ctrViewMgr::StopTimer()
- removed the 'WITH This' and 'ENDWITH' lines from the XXFWLibs.VCX/cusDBCSvc::OpenTable() method

Build 06 (4/20/2006)
- fixed a bug in XXDTSearch whereby you could not modify a line that ended with the word "property"
    [e.g., the following line in the XXFWUtil.VCX/cusSettingsVFPTable::zReadMe() method:
           "record in THIS.icDataSource is loaded to a custom property "]
- corrected issues in the XXFWPick.VCX/frmPicklist::cmdOK.Refresh() method
- no longer UPPER()-casing the .icDataSource property in the XXFWNTDS.VCX/ctrDataSource::Init() event-method
- replaced the duplicate "ASORT(laFields, 1, -1, 0)" lines in the XXFWNTDS.VCX/cusDSBehaviorSPT::FetchData() method with the following lines:
  - ASORT(laFields1, 1, -1, 0)
  - ASORT(laFields2, 1, -1, 0)
- enhanced the comments in X5PItems.Prg

Build 05 (4/15/2006)
- in XXFWData.Prg, corrected problem with the ULH_UUIDNA field not being correctly populated in the following two (2) views:
    - v_LoginHistoryOneUser
    - v_LoginHistoryAllUsers
  now assigning a DefaultValue for that field
- removed erroneous NOT from A.Prg that caused VFP9-SP1 not to display the correct _Screen.Caption
- corrected code in the following two methods of the XXFWControlBehaviors.VCX/cusRequiredControl class:
  - ContainerTrue()
  - ContainerFalse()
- moved an UPPER() in the XXFWPick.VCX/frmPicklist::SetupRuntimePicklistForm() method
- fixed a bug in the XXFWFrm.VCX/frmStandby::Init() event-method that was triggered when the passed
  message was too long, thus overflowing the size limit of the label's .Caption
- replaced the incorrect text "ctrBOMgr" with the correct text "ctrBusinessObjectManager" in:
  - the property description for the custom XXFW.VCX/frmData.icBOMgrClass property and in
  - the XXFWNTBO.VCX/ctrBusinessObject::zReadMe() method

Build 04 (4/06/2006)
- now installing CalendarD.BMP to the Graphics\PreXP sub-folder
- fixed bug where specifying last day of week in a calendar-enabled textbox (default keys are K,k) returned the *first* day of the week -- not the last -- when the first day of the week was set to Sunday (day 1)
- if the DeleteAction() call in the DeleteCurrentRow() method fails, data-entry grids in n-Tier forms now:
  - display a message (specified in the message package object) to the user
  - no longer cause the form to go into "EDIT" mode
- moved duplicate IF...ENDIF check to the correct place in the XXFWNTDS.VCX/ctrDataSource::Validate() method

Build 03
- added code to colBase::Init() to ensure that XXFW.VCX is in the SET CLASSLIB list
- fixed bug in several BO_SemaphoreLock methods, where lcSL_Context doesn't always get set properly
- modified the update of cusDataPackagerXML::PopulateDataSet() made in 2005.06.07.12 to fix a problem with specifying the ALIASes to whose record pointers are saved/restored

Build 02
- fixed bug in the new cusMenu::AddUserNametoLogOutOptionOfFileMenu() method, that causes a "Menu has not been defined with DEFINE POPUP" error in some INTL-enabled scenarios
- updated cusUserPrefs::ResetAllPrefs() to handle "ALLUSERS" scenarios where Usr_PK is of Integer data type
- fixed bug in several of the BO_SemaphoreLock::SUnlock_*...() methods, where some of the lcSL_* variables were not getting set properly in some scenarios
- modified tbrSCADONav.cmdNext.SetExprProps()/cmdPrevious.SetExprProps() to change the hotkeys from Ctrl+UpArrow/Ctrl+DownArrow to Ctrl+LeftArrow/Ctrl+RightArrow, so as to not conflict with a typical AppConfig "PageNavigationKeyCodes" setting

Build 01
- modified frmPicklist::EmptyPicklist() to save/reset the icMainAlias properly
- updated the default value for grdPicklist.ilAnyDeSelected from .T. to .F. in the Properties Sheet
- re-fixed a bug in XXERROR.PRG that resulted in some error text not being included in GenerateBasicErrorText()
- changed the VARTYPE(loRegExp.Multiline) test in X8RegExpTest.PRG on the TYPE("loRegExp.Multiline")
- added a missing SELECT (m.lnSelect) to txtPicklistValid::Refresh()

Jun 07, 2005 build

Build 12
- modified cusDataPackagerXML::PopulateDataSet() to restore record pointers irrespective of the THIS.inEmptyDateTimeBehavior value, because the XMLAdapter.ToXML() method sends the cursor to EOF()
- modified cusHyperlinkTextbox::ApplyHyperlink() to set the hyperlink label.BackStyle to 0

Build 11
- fixed 3 bugs in ctrDataSource::FetchFieldsForOnePK() where the PK field wasn't always processed properly and the field list memory variable wasn't referenced consistently
- fixed a bug in XXWBBODS.PRG when all 8 parameters are passed, to set the BOClassName properly
- split new grdDataEntry::Init() code introduced in Build 02 into a new SetDefaultPropertyValuesNT method, making it easier to augment/override that action
- modified ctrDataSource::FetchFieldsForOnePK() to support AS fields in the list
- modified frmData::LoadBOMgr() and Destroy() to do a more consistent job of handling the "shared BOMgr" behavior

Build 10
- enhanced X8BEALL.PRG to expand tcSourceClass to tcInclBaseClasses and add new tcExclBaseClasses
- re-fixed a bug in chkBase::Valid(), where the IF NOT VARTYPE(m.loActiveForm) = "O" should be IF VARTYPE(m.loActiveForm)
- fixed problem in cusSettings::UpdateCurrentRecord() where the App_ItemDescription field was not being saved properly in a default oAppInfo implementation
- modified frmData::ORCleanup() to not release THIS.ioBOMgr, but rather leave it around until frmData::Destroy() calls its ORCleanup() and then releases ioBOMgr
- enhanced frmData::SaveMessageOnFailure() and the (XXFWDATA.PRG-generated) VMP_RI/VMP_RI_Error Stored Procedures to give more/better information in some Trigger-failure scenarios

Build 09
- fixed a bug in chkBase::Valid(), where the IF NOT VARTYPE(m.loActiveForm) = "O" should be IF VARTYPE(m.loActiveForm)
- modified the ProgrammaticChange() of xxxBase classes to suppress the (redundant) call to THIS.OnChange() when the KeyPress event is in the stack
- modified frmData::SetInitialMainAliasRecno() to insert a missing ".ioMainDS" object in one of the CASE results
- fixed a bug in frmData::DeleteAction(), where an UPPER() string was being compared to a string that was most likely mixed case, in the first CASE of the first DO CASE in that method

Build 08
- modified A.PRG/XXPROCDT.PRG to kill the current VFP session when you go to the VMP Downloads page when a newer build is available, minimizing the possibility that when you do the install, an existing VFP session will prevent VMP framework files from being copied
- modified txtPicklistValid::MenuLookup() to suppress the normal validation no matter what, including when it is called from the OnButtonClick
- modified the VMP Application Setup Wizard to respect your procedural hooks (if any) called from XXFWDATA.PRG, to update the AppConfig/AppInfo default settings
- modified the Developer's Toolbar/Properties dropdown to handle a grid whose AllowCellSelection = .F.
- modified pgfDEForms::OnUpdateFormOnSave() to add an IF..ENDIF left out of the .07 modification, to test for a Save subsequent to an <Add>
- modified grdBase::SetinCurrentRecno() to add THIS.Refresh() from the list of methods that don't cause THIS.ClearFindTextbox() to fire
- enhanced pgfPageRefresh::ResetPageRefreshIndicator() to accept an optional toPage parameter and therefore only reset the page refresh indicator for that page
- enhanced grdBase::PushPopRecordSource() to force the tlNoDoScroll parameter to .T. whenever THIS.ShellRequery() is in the execution stack, indicating that the grid.RecordSource is being completely rebuilt/refetched

Build 07
- modified cusUserPrefs::UpdateBuffer() to check whether the User Preferences view is open
- modified cusPushPopOrder::Init() to fix a problem that can result in the restored tag being set to DESCENDING
- modified X8ShellExecute() to do a better job of respecting the X8FindExecutable() association for web browser tcURLorFilenameS
- replaced the grdPicklist reference in frmPick::SetRecordPointerOnAdd() with the correct grdPicklist1
- modified pgfDEForms::OnUpdateFormOnSave() to respect a page refresh expression specified at the page level
- modified frmData::SaveAction(), SaveMessageOnFailure() to create and populate a private pc_SaveActionDebugging_SectionThatFailed variable, containing additional debugging information that is included in developer messaging and the ErrorLog.ER_LstMemo entry
- modified pjhVMP::icFileName_Assign() to handle .H files
- modified XXWBRI to fix a problem when navigating from an AllowCellSelection=.F. row
- fixed a typo in txtPicklistValid::SuppressCustomValid(), in the expression for the first IF statement

Build 06
- modified the PopulateRITable local proc of XXFWDATA.PRG to properly set the XRI_UPDATE_TYPE to "C" for the Users->IUDLog record
- updated the Build 05 modification to ctrDataSource::DeleteAction() to take child/grandchild/etc.-specific action
- modified the XXDTHACK form to fix a problem running in VFP 8, where Anchor resizing is not available
- added a Language dropdown to the XXDTMSGS interface so you can view/edit the c<Language> fields
- fixed a bug in ctrDataSource::ValidateControl() that causes it to RETURN .T. when there is more than one rule object and one object evaluates to .F. but the last such rule evaluated RETURNs .T.
- updated XXDTSearch to include .SPRs in the search thru source code, making it more useful when searching legacy code

Build 05
- modified cusCalendarTextbox::SetupHotkeysAndToolTipText() to fix a problem in INTL-enabled apps, where a recent modification incorrectly refers to a toControl object
- modified ctrApp::ReindexTables() to post any pending changes in the UserPrefs view buffer when the reindex will be handled by SDT::Reindex(), which would otherwise just TABLEREVERT() that buffer
- modified cusChildCursorSvc::GenAndPopKeys() to properly restore the DESCENDING status on SET ORDER TO
- modified ctrMover::OnRefresh() to "refresh" the AutoHideScrollbar property
- reset to default the frmReport::StoreActiveFormToCallingForm() method to eliminate the NODEFAULT
- modified pgfDEForms::CommonPageActivate() to properly respect scenarios where the ComparisonValue is set at the page level
- updated frmAbstractCalendar::SetInitialVisibleLocation() to support SDI/Top-Level Form scenarios
- re-factored the VMP_RI... Stored Procedures (XXFWDATA.PRG) to replace the ON ERROR error handling with TRY/CATCH error handling
- enhanced the DeleteAction method of BOMgr, BO, and DS to pass the message on to sibling and child BOs, but siblings do nothing with the message, and children only execute a FetchClear()

Build 04
- modified ctrDataSource::ValidateControl() to make additional logic checks when storing the iaVCInfo array
- added a missing LOOP command to cusSettings::LoadPropertiessFromDataSource() to the initial IF..ENDIF block of the SCAN..ENDSCAN, to properly respect the optional tcSetting parameter

Build 03
- adjusted the .02 modification to grdDataEntry::Init() to handle those rare scenarios where THIS.ioBO isn't set for a data-entry grid on an n-Tier form
- adjusted the .02 modification to frmData::SetInitialMainAliasRecno() to refer to frmDEGridNav.ioPicklistGrid rather than THIS.grdPicklist1
- modified frmBase::ProximityLabel() to add an optional parameter that supports a Proximity Label that is currently set to invisible
- modified the Validate(), ValidateControl(), and ValidateFieldValue() methods of ctrDataSource to validate custom rule objects before the corresponding .DBC-based field/row rules

Build 02
- moved the DODEFAULT() in frmData::Destroy() to occur before the block of code to call THIS.ioBOMgr.ORCleanup()
- added TTOC(DATETIME()) to the Caption of the "System Error" form generated by XXERROR.PRG
- modified XXFWDATA.PRG, cusForms::SetCalendarBehaviors(), cusCalendarTextbox::SetupHotkeysAndToolTipText()/KeyPress(), ctrCalendar::SetupHotkeys()/KeyPress(), STRINGS.DBF, XXFWDATA.PRG to respect AppConfig records for "NextDayKeys" and "PrevDayKeys" -- DO XXDTMEST
- modified frmBase::StoreActiveFormToCallingForm() and frmBase::Activate() to only store THISFORM to THISFORM.ioCallingForm.ioCalledForm when THISFORM is modeless, including creating a new frmBase::StoreTHISFORMToCalledForm method
- modified grdDataEntry::Init() to automatically set parent-child properties when THIS.ioBO is set (n-Tier scenarios)
- fixed a problem in XXTOOLS.VCX/cusCreatePopCode with Currency fields in some tables with few/small fields
- fixed frmXXWBRI::UpdateTriggers() code that can remove the VMPRI() trigger call improperly in some scenarios
- modified frmPicklist::InitialFormSetup() to handle non-character tuInitialValue
- modified frmData::SetInitialMainAliasRecno() to handle additional n-Tier scenarios for frmPicklist and frmDEGridNav forms
- fixed logic in pgfDEForms::OnUpdateFormOnCancel() to do a better job of resetting the page refresh indicator

Build 01
- modified the SP_VMP_IUDLog() Stored Procedure in XXFWDATA.PRG to properly exclude non-"regular" fields from IUD_UFields population
- modified cusShortcutMenu::DevDiagStuff() to pass the 2nd parameter to the 2 calls to X3TAGXPR()

Mar 18, 2005 build

Build 16
- removed the txtPicklistValid::Init() modification made in the .13 refresh, to revert to the behavior where the txtPV is not automatically disabled for those specified conditions
- modified frmPicklist::InitialFormSetup() to not carry the Look For string over if it is the explicit string "!NONE!"
- replaced the hard-coded reference to THIS.txtPV in ctrPicklistValid::OnPicklistvalidTextboxInteractiveChange() with the proper toPV reference
- added OnRefresh method to frmBase, pgfBase, ctrBase and eliminated all Refresh code, to prevent redundant Refresh calls, as explained in the header comments of the new OnRefresh methods
- modified cusHyperlinkTextbox::ApplyHyperLink() to do a better job when the hyperlink text is longer than the textbox.Width accommodates
- modified ctrBusinessObjectManager::RemoveBusinessObject() to fix an error when deleting the BO from the iaBO array
- modified ctrDataSource::ORCleanup() to call THIS.Close() unconditionally
- modified txtPicklistValid::Destroy() to close the unique-use cursor in n-Tier services scenarios
- modified XXOpenDataBase.PRG, XXOpenTable.PRG, and cusDBCSvc::OpenData() to support passing the tlExclusive parameter to XXOpenDatabase() as .NULL., indicating that it doesn't matter if the specified database is already open for SHARED or EXCLUSIVE use

Build 15
- modified XXFWMAIN.PRG to set the refresh number to 15 rather than the bogus 10 that was left in while testing prior to Build 14

Build 14
- modified ctrDataSource::FetchList/FetchData to reverse the FetchListAfter/FetchListBefore modification made in the .13 build (thus preserving the old behavior)
- modified ctrDataSource::FetchList/FetchData to insert new FetchListAfterSQLExecute/FetchDataAfterDSBehaviorAfterFetchData shell methods (thus providing for the new functionality in the .13 refresh, while preserving the old behavior)

Build 13
- updated the "IFND" IntelliSense record (XXDTFoxCode.PRG) to handle more LPARAMETERS statements, and to insert the m. qualifier
- removed the "BOMB" command from NTDECUSC8.SCX
- fixed bug in ctrPicklistValid::OnPicklistvalidTextboxInteractiveChange() to refer to THIS.txtPV.ilAlternateLookup rather than THIS.ilAlternateLookup
- modified frmPicklist::GotFocus() to "carry over" the tuInitialValue to txtFind.Value when the initial controlling column is the one specified in grdPicklist.inInitialControllingColumn
- fixed bug in frmData::DeleteAction() to replace the erroneous luPKValueMV references to luPKValueMA
- re-factored frmData::UpdateFormOnCancel() to message the OnUpdateFormOnCancel of ioDEPageFrame, data-entry grids, ctrDERegisteredComposites when pcMode = "ADD"
- modified the WINMSG local procedure in X3MSGSVC.PRG to handle scenarios where tuVariable is not a Character string
- modified the Create_oAppConfig_Object procedure in XXFWMAIN.PRG to add the .DBF extension to tcAppConfigFile if necessary
- un-commented the SET CONFIRM code in txtPicklistFind::GotFocus/LostFocus, that somehow got commented sometime after it was added to the .08 refresh
- modified ctrSelCriteria::SaveControlValues()/RestoreControlValues() to handle scenarios where there are no SelCriteria controls at the ctrSelCriteria level (such as when Sel Criteria controls are all in containers in the ctrSelCriteria)
- modified ctrDataSource::FetchList() to move the call to FetchListAfter() to immediately after the call to THIS.SQLExecute(), and before FetchListPost()
- modified ctrDataSource::FetchData() to move the call to FetchDataAfter() to immediately after the call to THIS.ioDSBehavior.FetchData(), and before FetchDataPost()
- modified frmData::RequeryShowingDataEntryGrids() to immediately RETURN in n-Tier scenarios, since middle-tier objects handle refreshing/requerying data
- modified txtPicklistValid::Init() to start out disabled in unbound scenarios, to prevent such a control from "flashing" from enabled to disabled on loading a form with "blank" data
- modified cmdPicklistValid::Init() to start out disabled, knowing that it will be refreshed on form instantiation, whereupon its Enabled will match its sibling txtPicklistValid
- modified edtBase::AutoExpandOpenTable() to ignore VMP wizard/builder/tools usages, fixing a problem with XXWBDEFV, on selecting the <Post> button

Build 12
- modified ctrSelCriteria::AllEmptyControlValues() to correct 2nd CASE, which calls nested selection criteria containers
- modified ctrSelCriteria::Init() to add an additional BINDEVENT() to handle member.Value changes via a manually-invoked picklist of a txtPicklistValid
- modified ctrPicklistValid::ClearControlValues() to take specific/custom action that covers (n-Tier) scenarios where there is no cusSelCriteria object attached to the txtPicklistValid instance
- modified VMDVRULE.PRG to correct the reference to the SP_VMP_IUDLog() function in the Delete Trigger for the Cities table
- added NTDECTY4.SCX form to the NT example app

Build 11
- modified the Destroy and ORCleanup of most xxxBase classes, and frmData::RegisterDataEntryGrids and grdDataEntry::ORCleanup to handle RemoveObject() scenarios
- modified frmThermoBar to restore the chiseled 3D look by setting frmThermoBar.Themes to .F., and to adjust the size of the colored bar programmatically
- set the Enabled to .F. of cmdSave and cmdCancel on frmDEGridNav2Pages so the initial focus is handled correctly
- modified frmData::DeleteAction() to cover additional scenarios
- modified cusMenu::UpdateWindowMenuItem() to additionally call SetMarkOfBar(), now that bars are released and rebuilt from scratch
- modified XXSYNCPK.PRG to handle scenarios where the Primary Key index tag is DESCENDING
- modified txtPicklistValid::MenuLookup() to not set ilSuppressValid to .NULL. when the picklist has been called from the button in a ctrPicklistValid
- updated the interface from a MESSAGEBOX() to a VFP form when the "auto daily build check" discovers that a newer version of VMP is available
- added missing Spanish translations to MSGSVC.DBF/STRINGS.DBF, courtesy of VMP developer Jorge Mota
- modified ctrSelCriteria::AllEmptyControlValues() to handle scenarios where there are no members directly in the ctrSelCriteria

Build 10
- modified frmReportCatalog::Load() to fix a bug that prevents any reports from being loaded when the ReportCatalog is a local/remote view
- modified frmReportCatalog.pgfReports.Page1::Activate() to prevent a second/duplicate call to THISFORM.UpdateReportsList() on form instantiation
- modified edtBase::AutoExpandOpenTable() to support scenarios where MemoAE is a remote view, and to only create one MemoAE cursor per form, for all editboxes
- modified cusShortcutMenu to fix a problem when XXIUDLOG.PRG/SetDatabaseFromEnvironment finds no IUDLog table
- modified XXDTSearch to correct the Match Whole Word behavior in some scenarios where the search string is all digits
- modified frmBase to make the icAppConfigFile property Protected, and updated frmBase::zReadMe/cusStandaloneForms::Setup2() accordingly
- modified frmData::SaveMessageOnFailure() to replace VARTYPE(gaVMPRIErrors) with TYPE("gaVMPRIErrors")
- modified pgfPageRefresh::CommonPageActivate() to not perform its SetFocus behavior when called explicitly from THISFORM.UpdateFormOnNav()
- modified the XXDTAppConfig.PRG interface to make the necessary DODEFAULT() so that the selected file is properly displayed
- modified cusMenu::UpdateWindowMenuItem() to release the bar before (re)defining it, so that VFP resizes the width of the bar to match its prompt text
- modified cusGridPreference::RestorePrefs() to correct a problem when a Column.ColumnOrder is updated in the Designer

Build 09
- modified pgfPageRefresh::ManualPageRefreshAction() to fix a bug introduced in 2005.03.18.05 that resulted in the current active page being refreshed twice during THISFORM.UpdateFormOnNav(), most problematic that the OnPageActivate/ShellRequery of any grids/registered composites on the active page fires twice
- modified pgfDEForms::CommonPageActivate() to handle initial activation on instantiation of Page1 on non-frmDEGridNav2Pages forms
- modified cusUserPrefs::SetInitialDesignedValues() to explicitly set the Prf_ItemDescription to keep remote databases happy
- modified grdBase::SetUserSecurity() to respect NO ACCESS columns when THISFORM.ilReadOnly = .t.
- modified cusDSBehaviorSPT::SaveActionInsert() to wrap the INSERT in a TRY/CATCH block, and to speed up the loop that stores local variables
- modified XXPROCDT.PRG/VMPRequirementsAndAssumptions to check for an empty/invalid _Builder setting
- modified XXFWCOMP.VCX/ctrGetFile.cmdGetFile1.Click() and ctrGetFile.txtFileName1.ProgrammaticChange() to fix 2 problems with displaying the selected file properly and to never store the X7DISPTH() version of the file to cmdGetFile1.icSelectedFile
- modified XXWBUpsize.PRG and XXWB.VCX/frmXXWBUpsize to handle more scenarios where the path to the VMP database contains embedded spaces
- modified XXCreateDBCWithRemoteViewsOfVMPSystemTables.PRG/Create_MemoAE_Views() to swap the remote MEMOAE view definitions in the IF m.llMAE_UsrFK
- modified grdBase::SeekValue() to not refresh the grid until after any seek tag has been reset
- modified the Refresh() of cmdDEGridAdd, cmdDEGridDelete, cmdDataGeneral, cmdBase to respect FULL ACCESS on a ReadOnly form when the new AppConfig/"RespectFullAccessControlsOnReadOnlyForms" record has been set to "1"
- modified frmReport::ReportFormCommand() to force SET REPORTBEHAVIOR 80 when the clauses include TO FILE .. ASCII
- modified XXSQLEXE.PRG/XXRQUERY.PRG to do a better job of detecting n-Tier scenarios, and respecting the ConnectionObject.ilCheckHandleOnEveryGet, rather than testing the connection handle locally

Build 08
- modified frmData::RemoteRefresh() to update an loForm reference to loCallingForm
- modified ctrApp::InstallGlobalErrorHandler() to give an ASSERT if the required "Fatal" messages are missing from the app-specific MSGSVC.DBF
- modified XXFWDATA.PRG/IndexXXTable to fix a bug when the VMPRI table is not open and its indexes are to be created
- modified the WinMsg local procedure in X3MSGSVC.PRG to replace the 2 luRetVal references with the proper lcRetVal references
- modified grdBase::MakeCurrentRowTopmost() and ChangeDisplayOrder() so that ChangeDisplayOrder() calls THIS.RealRefresh() when THIS.MakeCurrentRowTopmost() finds that THIS.RelativeRow = 1
- modified txtPicklistFind::GotFocus/LostFocus to SET CONFIRM ON while focus is in that textbox
- modified XXDTExplicitPEM and XXDTCountCode to respect the "Search files marked Excluded" checkbox
- removed cmdBase::MouseMove method code
- modified XXAPPINF.PRG to insert two missing SELECT (m.lnSelect) lines
- modified cusForms::ActiveControlValid() to improve performance
- modified a CASE in grdGeneral02::Init() to fix a problem restoring the sort order when the Column1 is the controlling column

Build 07
- modified frmBase::GetProximityLabelText() to set the worst-case-scenario text for local views/contained tables
- modified cusUserSecurity::UserBelongsToGroup() to fix a bug when passing the optional tuUsr_PK parameter as an Integer
- made numerous updates and a couple of bug fixes to BO_IUDLog::PopulateIUD_UFields()
- added a CASE to cusDSBehaviorSPT::SaveActionUpdateRecord() to handle ISBLANK() logical fields

Build 06
- modified ctrDataSource::ApplyDefaultValues() to handle scenarios where a Date is used as the DefaultValue for a DateTime field, and vice versa
- updated VMP_RI_Open Stored Procedure (XXFWDATA.PRG) to use TRY/CATCH rather than ON ERROR error trapping, to fix a problem in some scenarios where VMP_RI_Open() fails and VFP aborts the entire VMP_RI stored procedure
- updated VMP_RI and VMP_RI_Error Stored Procedures (XXFWDATA.PRG) to generate improved gaVMPRIErrors messaging when the Child Table cannot be opened
- modified frmData::RemoteRefresh() to immediately RETURN .f. when a form discovers that a called modal form executed the SaveAction that precipitated the RemoteRefresh
- modified pgfPageRefresh::CommonPageActivate() to prevent a SetFocus when the current active form is not THISFORM
- modified cusDataSourceBehavior::PopulateIdentityPK() to add a missing THIS.PARENT qualifier
- modified cusDataSourceBehavior::Close() to not close the parent DataSource.icTableName
- fixed bug in XXFWDATA.PRG/SP_VMP_IUDLog() that caused some Memo fields to not be logged properly
- modified BO_IUDLog::PopulateResultCursor() to fix a bug when the logged table contains more than one Memo field
- modified XXSYNCPK.PRG to properly reference the taUpdatedRows array in order to update its contents

Build 05
- fixed bug in cusLockout::GetLockout() to refresh the oAppInfo.DataFactor value before checking its value, includes enhancing cusSettings::LoadPropertiesFromDataSource() to accept an optional tcSetting parameter
- modified pgfDEForms::CommonPageActivate() to respect a Page-level iaPageRefreshComparisonValueExpression setting, also frmDEGridNav2Pages/frmDEGridNav2Pages02::Init to suppress the ShellRequeryMainViewAlias for Page1
- modified frmData::UpdateFormOnNav() to defer to the CommonPageActivate of any pgfDEForms instance rather than always calling ShellRequeryMainViewAlias() directly in scenarios where the form contains a pgfDEForms (such as frmDEGridNav2Pages forms)
- modified frmBase::Load and frmBase::Show to reset the setup for the sizer control when/if the form Height/Width are changed during instantiation
- modified txtBase/spnBase::Click to ensure that the ilMouseDownOnGotFocus property exists
- modified XXFWDATA.PRG to add 2 index tags to the VMPRI table, and adjust the VMP_RI Stored Procedure to Rushmore Optimize the SCAN FORs on Novell networks running VFP 9.0
- modified grdBase/grdBase02::AdjustColumnWidthsToExactlyFillGrid() to fix a bug in the comparison of the available width to the Percentage factor
- fixed bug in XXSYNCPK.PRG that can fail to restore SET DELETED
- modified XXDTBuildXXLIB.PRG to update the list VMP framework files pulled into the XXLIB.EXE
- modified frmAbstractCalendar::OKAction() to move the ActionOnCalendarFormSelection behavior to cusCalendarTextbox::DoCalendarForm()
- modified the Work Areas Viewer to support VFP 9.0+ BINARY index tags
- modified XXSyncPK.PRG to support an additional tlHighestChar parameter, and to deal with tables whose PK field is AutoInc-generated
- modified cusPushPopSQLThermo::Init() to add explicit support for a docked Command Window
- modified the RightClick of these VMP base control classes to add a default Shortcut menu behavior: spnBase, chkBase, cboBase, lstBase, opgBase
- modified frmBase::ProximityLabel() to not EXIT when a qualifying label is found just above the passed toControl, but rather to wait and see if label is found just to the left of toControl
- modified cusShortcutMenu to add 2 new Diagnostic Mode options, for displaying field/record history (from IUDLog)
- added the IUD_DT index tag to IUDLog table: XXDTES("XXFWDATA.PRG","IUD_DT")
- modified SP_VMP_IUDLog_ActionOnCheckFileSize (in XXFWDATA.PRG) to also execute any external IUD_CFS.PRG: _VFP.Help(FULLPATH("VMPHELP.CHM"),,"SP_VMP_IUDLog_ActionOnCheckFileSize header comments")
- added IUD_Stack, IUD_SYS0, IUD_DS fields to the IUDLog table, and an index tag on UPPER(IUD_SYS0): XXDTES("XXFWDATA.PRG","IUD_Stack M")
- fixed bug in XXFWDATA.PRG/IUDLogStoredProcedures that resulted in all CRLFs being removed from the Stored Procedures when the SP_VMP_IUDLog* Stored Procedures got removed
- replaced the SP_VMP_IUDLog_Suppress() Stored Procedure with separate SP_VMP_IUDLog_RW() and SP_VMP_IUDLog_XLogging() stored procedures
- added support for creating a semaphore file to suppress the population of IUD_Exception and IUD_Stack except when desired during debugging

Build 04
- modified the Audit Trail/Logging feature (XXFWDATA.PRG) to rename some fields, add the IUD_UFields field and its population logic, switch the field value storage to XML, and improve performance -- this feature is now considered "finished"
- fixed a bug in XXDTSearch that prevented RightClick on the Project/Folder dropdowns from working properly
- added code to frmSelCriteria::AddSelCriteriaContainer() to reposition the cmdClearAll button

Build 03
- renamed grdBase02::ColumnsWidthToGridDiff to grdBase02::ColumnsWidthToGridWidthDiff, fixing a crash here: XXDTES("XXFWBC02.VCX","lnCW = THIS.ColumnsWidthToGridWidthDiff()","grdbase02","ADJUSTCOLUMNWIDTHSTOEXACTLYFILLGRID")
- modified ctrApp::SetupMultipleInstances() to fix a problem where the 1st app instance/window was not being restored/activated
- fixed bug in XXFWDATA.PRG that resulted in the IUDLog table not created for the VM and NT example apps, when the "auto" update on installing a new build was run
- modified the OLDVAL~CurrentValue separator in IUDLog.IUD_BA*Values (Memo/Blob/Varbinary) fields from a single tilde/CHR(126) to CHR(126)+CHR(255)+CHR(126), for more bulletproof parsing
- modified XXFWDATA.PRG to add support for creating "dedicated" IUDLog_<TableName> tables _VFP.Help(FULLPATH("VMPHELP.CHM"),,"Advanced IUDLog features")
- modified the Audit Trail/Logging feature (XXFWDATA.PRG) to save all field values for buffered Updates, same as un-buffered Updates as well as Inserts and Deletes

Build 02
- fixed bug in XXFWDATA.PRG that resulted in the IUDLog table not created for the VM and NT example apps
- sped up the SP_VMP_IUDLog Stored Procedure (XXFWDATA.PRG/Audit Trail)
- split the SP_VMP_IUDLog Stored Procedure up into several individual per-task Stored Procedures
- added SP_VMP_IUDLog.. Stored Procedures to provide for setting a "warning" when the IUDLog.DBF/.FPT is approaching the VFP 2G file size limit
- added new X8GUID.PRG library routine to generate a GUID
- added IUDLog.IUD_TransID and IUDLog.IUD_TXNLevel fields and their population
- modified frmData::SaveAction() and ctrBusinessObjectManager::SaveAction() to generate a "transaction ID GUID" for populating to IUDLog.IUD_TransID
- moved sensitive header comments from SP_VMP_IUDLog..() Stored Procedures into the VMP help file

Build 01
- modified cmdCalendar::Refresh()/UIEnable() to ensure that the button is refreshed (Visible/Enabled set) when it's on a page of a pageframe that *doesn't* inherit from XXFW.VCX/pgfPageRefresh
- fixed a typo in frmData::LoadBOMgr(), where "ioCallingForm" was spelled with an extra "l": "ioCalllingForm", which prevented that first IF from evaluating to .T. properly
- modified cusCalendarTextbox::OwnerKeypress() to match the FirstDayOfWeek/LastDayOfWeek hotkey actions to any "CalendarFirstDayOfWeek" AppConfig setting

Jan 28, 2005 build

Build 08
- modified XXFWDATA.PRG/CreateUsersTable to check for the existence of the glX8ED memvar
- modified cusDBCSvc::OpenData() and OpenAllTables() to pass the tnDataSession parameter so that when tables are to be opened, they get opened in the indicated data session
- modified the cmdPath::Click() of XXWBNewForm.PRG to properly leave the path setting alone after Cancelling from the GetDir() dialog
- added a new pgfBase::PageCount_Assign method to ensure that decrementing the PageCount doesn't fail because of dangling object references to data-entry grids or registered composites
- Reset To Default the grdNavigate::SetUserSecurity() method, so that normal VMP grid/column security can be applied to grdNavigate (the grdNav on frmDEGridNav forms)
- added txtBase::Click and spnBase::Click to code a replacement workaround for the code that was formerly in txtBase/spnBase::GotFocus but quit working in VFP 9.0, to select the contents when the mouse is used to select the control and SelectOnEntry=.T. or "K"$Format
- modified grdBase::ReSort() and grdGeneral02::ReSort() to work around a VFP anomaly where an invisible column's header can actually be clicked under certain circumstances
- modified grdBase::Init() and grdBase02::Init() to ignore invisible columns when establishing the ilScrollLock behavior

Build 07
- fixed a typo in grdBase::SetColors() that can prevent the Grid.SelectedItemBackColor not being set per the AppConfig setting
- fixed a bug in cusPushPopCursorState::Destroy() that can result in the ASCENDING/DESCENDING status of the index tag from not being restored properly
- modified frmPicklist::Init() and txtPicklistValid::SetPicklistFormParameters() to properly respect the frmPicklist.ilAdd setting if the txtPicklistValid.ilPicklistFormAddButton is left set to .NULL.
- modified XXDTMEST to check for ReadOnly MSGSVC.DBF/STRINGS.DBF and message the user accordingly
- modified cusLockout::SetLockout() and cusLockout::GetLockout() to store the AppInfo "TextFactor" record's App_ItemValue as an ALLTRIM()med string rather than filling the entire field (encrypted)
- reversed the behavior of the optional 7th parameter accepted by XXFWDATA.PRG, from enabling the default behavior to suppressing the default behavior (changed from tlUseBinaryDELETEDTagsInVFP9OrHigher to tlNoBinaryDELETEDTagsInVFP9OrHigher)
- modified cmdPicklistValid::Refresh, SetUserSecurity, and Visible_Assign, to set the button's Enabled/Visible properties based on its "owner" txtPicklistValid

Build 06
- added THIS.Close() to ctrDataSource::ORCleanup(), as an adjustment to the mod made in build .05 to cusDataSourceBehavior::Destroy()

Build 05
- modified XXFWMAIN.PRG/ReleaseAppObjects and ctrApp::CleanupOnAppTerminate() to not run CleanupOnAppTerminate to not redundantly call CleanupOnAppTerminate during normal app termination
- modified XXWBNewForm.PRG to hide the Properties Sheet if it's on top and therefore interferes with the KEYBOARD "y"
- modified frmEventLog::LoadBO() to use a different test for the existence of the ErrorLog table in a remote database
- modified grdDataEntry::OnUpdateFormOnCancel() and grdDataEntry::Destroy() to support some n-Tier "Prefill" scenarios
- modified ctrDataSource::FetchData() to attempt to save/restore the THIS.icAlias record pointer
- added the THISFORM parameter to the call to oForms::RealActiveControl() in the BeforeRowColChange method of grdDataEntry and grdDataEntry02, but only when not called due to a member txtPicklistValid invoking its picklist form
- modified txtBase::CustomValid() to add code to support a cusDTOTextbox behavior for a textbox on an n-Tier data-entry subform
- modified cmdBase::SetReadOnlySecured() add a missing THIS qualifier
- modified ctrDataSource::icAlias_Assign and ctrBusinessObject::OpenDataSources() to support additional update-DS.icAlias-on-the-fly scenarios
- fixed a bug in XXERROR.PRG that resulted in some error text not being included in GenerateBasicErrorText()
- commented out the THIS.Close() line of code in cusDataSourceBehavior::Destroy()
- modified cusReindex::ReindexData() to add support for VFP 9 BINARY index tags

Build 04
- modified cusForms::GetFormID() so that it handles spaces between the Class,ClassName portions of the first parameter
- modified cusForms::RegisterForm() to property set the 3rd column of the iaFormInstances[] array to "CREATEOBJECT" for class-based forms
- modified ctrDataSource::ApplyDefaultValues() to reset the loException variable properly

Build 03
- moved the ADDPROPERTY(THIS,"ilDestroying",.f.) line from frmBase::Init() to frmBase::Load() so ilDestroying is available in certain "DirectLoad" scenarios
- replaced the erroneous line llConnectionCheck = .f. in XXSQLEXE.PRG with the proper line llHandleCheck = .f.
- fixed bug in cusPushPopSQLThermo that resulted in the Command Window being made visible in some scenarios when running a VMP app in the development environment
- modified cusTempDBC::Init/Destroy to push/pop the SET DATABASE
- modified frmEventLog::LoadBOMgr() to fix a problem that prevents the form from loading in some 1-tier scenarios
- fixed a bug in A.PRG that caused a crash when checking for a newer build of VMP
- modified frmData::IsBufferDirty() to correctly push/pop the proper ALIAS() and RECNO()

Build 02
- modified X8ConvChar.PRG (and X2CNVCHR.PRG) to transform a blank tuValue to a logical .F. when tcDataType = "L"
- added cusUserPrefs::SetInitialDesignedValues() and modified the RestorePrefs method of cusUserPrefs/cusGridPreference to eliminate the need for the user to set a preference-effected property TWICE subsquent to the UserPrefs being empty (ZAPped/just-distributed/new user/etc.)
- modified XXDTMEST.PRG to fix a strange VFP9 problem re-indexing the STRINGS.DBF table
- modified ctrDataSource::icAlias_Assign() to cover additional scenarios
- modified grdBase::Init() to remove llCaptionPaddingApplied logic
- replaced the X3CPEDIG() reference in frmReportEventLog::PrepareData() with X7CPEDIG()
- modified frmBase::StandaloneSetup() to fix a problem in some scenarios where {SHIFT+F11} calls the Work Areas Viewer from a modal form called from a modeless form
- modified cusForms::DoForm() to fix a problem where an ilAllowMultipleInstances=.F. form can incorrectly be interpreted as being called "from itself"
- inserted a line of code into ctrBusinessObjectManager::RegisterBO(), to set the BO's ioBOMgr property, thus supporting additional BOMgr+BO scenarios
- fixed the FLUSH FORCE code in frmData::UpdateBuffers() to properly comma-separate the list of tables
- replaced two X3MSGVC("rawtext") with X3MSGSVC("RawTextOK")
- modified SelectAllRows() in grdPicklist, grdPicklist02 to properly reset the RELATION when the RecordSource is the source of more than 1 relation
- modified grdDataEntry::DeleteCurrentRow() to handle repositioning the record pointer properly in n-Tier scenarios
- modified ctrDataSource::IsBufferDirty() to correctly push/pop the proper ALIAS() and RECNO()
- modified cusUserSecurity::GetAccessOtherUser() to fix several minor issues

Build 01 - initial release