Valid de GET y Folder, BUG?

Post Reply
User avatar
Adolfo
Posts: 900
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile
Contact:

Valid de GET y Folder, BUG?

Post by Adolfo »

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.

Code: Select all | Expand

#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

Code: Select all | Expand

#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
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Valid de GET y Folder, BUG?

Post by Antonio Linares »

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):

Code: Select all | Expand

        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
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Valid de GET y Folder, BUG?

Post by Antonio Linares »

Mismo fix para TFolderEx

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

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
karinha
Posts: 8720
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil
Contact:

Re: Valid de GET y Folder, BUG?

Post by karinha »

Antonio Linares wrote: Tue Aug 04, 2026 1:35 am

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
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Valid de GET y Folder, BUG?

Post by Antonio Linares »

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
User avatar
karinha
Posts: 8720
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil
Contact:

Re: Valid de GET y Folder, BUG?

Post by karinha »

Antonio Linares wrote: Tue Aug 04, 2026 2: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

Master, esto es en el METHOD SetOption?

Code: Select all | Expand

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
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Valid de GET y Folder, BUG?

Post by Antonio Linares »

Sí, correcto :idea:

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
karinha
Posts: 8720
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil
Contact:

Re: Valid de GET y Folder, BUG?

Post by karinha »

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.

Code: Select all | Expand

//-----------------------------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

Image

Gracias, tks.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Valid de GET y Folder, BUG?

Post by Antonio Linares »

Esta línea sobra:

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

regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply