FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Valid de GET y Folder, BUG?
Posts: 894
Joined: Tue Oct 11, 2005 11:57 AM

Valid de GET y Folder, BUG?

Posted: Mon Aug 03, 2026 11:02 PM

Saludos Fivewinners

Hace tiempo tengo esta duda.

Situacion:
Get con valid en un folder.
Lleno el get con la información
No presiono enter y presiono en la pestaña de otro folder
La variable que esta en el GET asume su nuevo valor SIN VALIDAR

Adjunto Ejemplo a lo mas minimo que pude.

#include "FiveWin.ch"

Function Main()
Local cText1:=space(20)
Local cText2:=space(20)
Local cText3:=space(20)
Local cText4:=space(20)

  DEFINE  DIALOG oDlg1 RESOURCE "TEST"
                 oDlg1:lHelpIcon:=.F.


 REDEFINE FOLDER oFld1 ID 100 OF oDlg1;
                 PROMPTS "Uno","Dos";
                 DIALOGS "ONE","TWO"

   Redefine Get oGet1 Var cText1 ID 101 Of oFld1:aDialogs[ 1 ] Valid Validar()

   Redefine Get oGet2 Var cText2 ID 102 Of oFld1:aDialogs[ 1 ]

   Redefine Get oGet3 Var cText3 ID 201 Of oFld1:aDialogs[ 2 ]

   Redefine Get oGet4 Var cText4 ID 202 Of oFld1:aDialogs[ 2 ] Valid Validar()


   REDEFINE Button oBtn1 ID 10 OF oDlg1 Prompt "Exit"   ACTION oDlg1:End()

  ACTIVATE DIALOG oDlg1 CENTERED

  MsgAlert(cText1,"cText1")
  MsgAlert(cText4,"cText4")

Return Nil

//--------------------------------------------------------
Function Validar()
Return MsgYesNo("Validar Get?","Verifique" )

Este es el RC

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>

LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US

TEST DIALOG DISCARDABLE 17, 36, 185, 147
STYLE WS_POPUP|DS_MODALFRAME|WS_CAPTION|WS_SYSMENU|WS_VISIBLE
CAPTION "Test"
FONT 8, "MS Sans Serif"
{
  CONTROL "", 100, "SysTabControl32", WS_TABSTOP, 4, 6, 175, 117
  CONTROL "Exit", 10, "Button", WS_TABSTOP, 62, 128, 50, 14
}

ONE DIALOG DISCARDABLE 6, 15, 175, 117
STYLE WS_CHILD|WS_VISIBLE
FONT 8, "MS Sans Serif"
{
  CONTROL "", 101, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 58, 20, 98, 12
  CONTROL "", 102, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 58, 48, 96, 12
  CONTROL "Linea 1 :", 4003, "Static", SS_RIGHT|WS_GROUP, 10, 24, 40, 8
  CONTROL "Linea 2 :", 4004, "Static", SS_RIGHT|WS_GROUP, 10, 50, 40, 8
}

TWO DIALOG DISCARDABLE 6, 15, 175, 117
STYLE WS_CHILD|WS_VISIBLE
FONT 8, "MS Sans Serif"
{
  CONTROL "", 201, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 64, 64, 92, 12
  CONTROL "", 202, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 64, 92, 96, 12
  CONTROL "Linea 3 :", 4004, "Static", SS_RIGHT|WS_GROUP, 16, 66, 40, 8
  CONTROL "Linea 4 :", 4003, "Static", SS_RIGHT|WS_GROUP, 16, 94, 40, 8
}

Cualquier GET que se quiera validar, si esta en un folder acepta los cambios sin problema si pincho en el otro folder y cierro el contenedor.
Es un BUG, no deberia dejar pinchar en la pestaña de otro folder sin validar el get activo

;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 2 * 1 TB NVME M.2, GTX 1650
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 01:15 AM

Estimado Adolfo,

Excelente observación, muchas gracias :idea:

Causa raíz

Al hacer clic en otra pestaña, TFolder:SetOption() oculta la página actual antes de que el GET pierda el foco. Cuando llega el
WM_KILLFOCUS, TControl:KillFocus() (source/classes/control.prg:1214) solo postea FM_LOSTFOCUS (que es quien evalúa el VALID vía
FWLostFocus → lValid()) si la página del control es visible — y ya no lo es. Resultado: TGet:LostFocus() asigna el buffer a la
variable pero el bValid nunca se evalúa.

El fix

En source/classes/folder.prg:1124, TFolder:SetOption() ahora valida el control que tiene el foco en la página activa antes de
cambiar. Es el punto único por el que pasan todos los cambios de página (clic en pestaña, Ctrl+Tab, Alt+tecla, SetOption()
programático):

        if nOption > 0 .and. nOption != ::nOption .and. ::nOption > 0 .and. ;
              ::nOption <= Len( ::aDialogs ) .and. ::aDialogs[ ::nOption ] != nil
           oCtrl = ::aDialogs[ ::nOption ]:oCtlFocus
           if oCtrl != nil .and. GetFocus() == oCtrl:hWnd .and. ;
                 __objHasMsg( oCtrl, "lValid" ) .and. ! oCtrl:lValid()
              ::SetCurSel( ::nOption )   // revierte la pestaña
              oCtrl:SetFocus()           // devuelve el foco al GET
              return nil
           endif
        endif

El chequeo GetFocus() == oCtrl:hWnd hace que solo actúe cuando el foco está realmente en el control (caso interactivo), sin
alterar cambios de página programáticos con el foco fuera.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 01:35 AM

Mismo fix para TFolderEx

Fixes incluidos en próximo build de FWH :idea:

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 02:25 PM
Antonio Linares wrote:

Mismo fix para TFolderEx

Fixes incluidos en próximo build de FWH :idea:

Master, ¿en qué línea de TFOLDEX.PRG debo realizar ese cambio, por favor?

Gracias, tks.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 02:48 PM

Estimado Joao,

1734 + // Validate the control with focus on the current page before leaving it.
1735 + // Without this, clicking another tab hides the current page and the
1736 + // pending VALID of the active control (e.g. a TGet) is never evaluated,
1737 + // while its new value is kept anyway.
1738 + if nOption != ::nOption .and. ::nOption > 0 .and. ;
1739 + ::nOption <= Len( ::aDialogs ) .and. ::aDialogs[ ::nOption ] != nil
1740 + oCtrl = ::aDialogs[ ::nOption ]:oCtlFocus
1741 + if oCtrl != nil .and. GetFocus() == oCtrl:hWnd .and. ;
1742 + __objHasMsg( oCtrl, "lValid" ) .and. ! oCtrl:lValid()
1743 + // Validation failed: keep the current page and the focus
1744 + oCtrl:SetFocus()
1745 + return nil
1746 + endif
1747 + endif
1748 +
1733 1749 if nOption != ::nOption

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 02:59 PM
Antonio Linares wrote:

Estimado Joao,

1734 + // Validate the control with focus on the current page before leaving it.
1735 + // Without this, clicking another tab hides the current page and the
1736 + // pending VALID of the active control (e.g. a TGet) is never evaluated,
1737 + // while its new value is kept anyway.
1738 + if nOption != ::nOption .and. ::nOption > 0 .and. ;
1739 + ::nOption <= Len( ::aDialogs ) .and. ::aDialogs[ ::nOption ] != nil
1740 + oCtrl = ::aDialogs[ ::nOption ]:oCtlFocus
1741 + if oCtrl != nil .and. GetFocus() == oCtrl:hWnd .and. ;
1742 + __objHasMsg( oCtrl, "lValid" ) .and. ! oCtrl:lValid()
1743 + // Validation failed: keep the current page and the focus
1744 + oCtrl:SetFocus()
1745 + return nil
1746 + endif
1747 + endif
1748 +
1733 1749 if nOption != ::nOption

Master, esto es en el METHOD SetOption?

METHOD SetOption( nOption ) CLASS TFolderEx

   LOCAL nOldOption := ::nOption
   LOCAL nOpt, nOldOpt, i, lVisible

   nOption = Max( 1, Min( nOption, Len( ::aPrompts ) ) )

   IF ! ::aEnable[ noption ]
   RETURN NIL
   ENDIF

   if nOption != ::nOption  // aqui el cambio Master?

   Nuevo codigo aqui?


   // Mantener esto master?
   IF ::aSrcPrompt != NIL
   nOpt = nOption
   FOR EACH lVisible IN ::aVisible
   IF lVisible
   nOpt--
   ENDIF
   IF nOpt == 0
   exit
   ENDIF
   END
   ::nOption = 1
   ENDIF
   ::nOption = nOption
   IF ::aSrcPrompt != NIL
   nOldOpt = nOldOption
   i = 0
   FOR EACH lVisible IN ::aVisible
   IF lVisible
   nOldOpt--
   ENDIF
   i++
   IF nOldOpt == 0
   exit
   ENDIF
   END
   nOldOption = i
   ENDIF

   IF ::lAnimation
   ::AnimateOpt( , nOldOption )
   ELSE
   ::aDialogs[ nOldOption ]:Hide()
   ::aDialogs[ ::nOption ]:Show()
   ::aDialogs[ ::nOption ]:SetFocus()
   ENDIF
   if ! Empty( ::bAction )
   Eval( ::bAction, nOption, nOldOption, Self )
   endif

   ::ChangeOrder()
   ::Refresh()

   endif


return nil

Gracias, tks.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 03:02 PM

Sí, correcto :idea:

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 03:33 PM

Master, it doesn't seem to have any effect when using WORKSHOP.exe the best. Hahaha. The source code indentation is terrible to read; please review that.

Master, parece que no surtió ningún efecto al usar WORKSHOP.exe. Jajaja. La indentación del código fuente es pésima para la lectura; por favor, revisa eso.

//-----------------------------METHOD SetOption-----------------------------//

METHOD SetOption( nOption ) CLASS TFolderEx

   LOCAL nOldOption := ::nOption
   LOCAL nOpt, nOldOpt, i, lVisible

   nOption = Max( 1, Min( nOption, Len( ::aPrompts ) ) )

   IF .NOT. ::aEnable[ noption ]
      RETURN NIL
   ENDIF

   // https://forums.fivetechsupport.com/viewtopic.php?p=285952#p285952
   IF nOption != ::nOption // MODIFICADO By Antonio Linares en: 04/08/2026

  // Validate the control with focus on the current page before leaving it.
  // Without this, clicking another tab hides the current page and the
  // pending VALID of the active control (e.g. a TGet) is never evaluated,
  // while its new value is kept anyway.
  IF nOption != ::nOption .AND. ::nOption > 0 .AND. ;
     ::nOption <= Len( ::aDialogs ) .AND. ::aDialogs[ ::nOption ] != nil

     oCtrl = ::aDialogs[ ::nOption ]:oCtlFocus

     IF oCtrl != nil .AND. GetFocus() == oCtrl:hWnd .AND. ;
        __objHasMsg( oCtrl, "lValid" ) .AND. ! oCtrl:lValid()

        // Validation failed: keep the current page and the focus
        oCtrl:SetFocus()

        RETURN NIL

     ENDIF

  ENDIF

  IF ::aSrcPrompt != NIL

     nOpt = nOption

     FOR EACH lVisible IN ::aVisible

        IF lVisible

           nOpt--

        ENDIF

        IF nOpt == 0
           EXIT
        ENDIF

     END

     ::nOption = 1

  ENDIF

  ::nOption = nOption

  IF ::aSrcPrompt != NIL

     nOldOpt = nOldOption

     i = 0

     FOR EACH lVisible IN ::aVisible

        IF lVisible

           nOldOpt--

        ENDIF

        i++

        IF nOldOpt == 0
           EXIT
        ENDIF

     END

     nOldOption = i

  ENDIF

  IF ::lAnimation

     ::AnimateOpt( , nOldOption )

  ELSE

     ::aDialogs[ nOldOption ]:Hide()
     ::aDialogs[ ::nOption ]:Show()
     ::aDialogs[ ::nOption ]:SetFocus()

  ENDIF

  IF .NOT. EMPTY( ::bAction )

     Eval( ::bAction, nOption, nOldOption, Self )

  ENDIF

  ::ChangeOrder()
  ::Refresh()

   ENDIF

RETURN NIL

Imagen:

https://imgur.com/euoPuAP

Gracias, tks.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 44508
Joined: Thu Oct 06, 2005 05:47 PM

Re: Valid de GET y Folder, BUG?

Posted: Tue Aug 04, 2026 03:50 PM

Esta línea sobra:

IF nOption != ::nOption // MODIFICADO By Antonio Linares en: 04/08/2026

regards, saludos

Antonio Linares
www.fivetechsoft.com

Continue the discussion