Page 2 of 2

Re: VALID EN DIALOGO NOWAIT NO funciona con telca ESC

PostPosted: Mon Apr 03, 2017 9:40 pm
by carlos vargas
umm, usualmente el folder en si en FWH no toma foco, ya que es un contenedor, yo creo que ni eso, ya que lo que contiene son dialogos child, quienes son lo que contiene controles, quienes son los que llaman al valid.
que quien toma foco es el primer control contenido en el primer dialogo child.
prueba poniendo un control en el primer page del folder.

Re: VALID EN DIALOGO NOWAIT NO funciona con telca ESC

PostPosted: Tue Apr 04, 2017 6:17 am
by Antonio Linares
Prueba si te sirve esta solución:

viewtopic.php?f=18&t=33874&p=200274#p200274

Re: VALID EN DIALOGO NOWAIT NO funciona con telca ESC

PostPosted: Tue Apr 04, 2017 7:15 pm
by miarcod
Gracias, pero no funciona

Sigo investigando y ahora he comprobado que este comportamiento sólo ocurre si el folder no tiene controles (lo que no suele suceder) o de los controles que tiene, no hay ninguno activo, Si hay un control activo la validación se ejecuta correctamente y el dialogo no se cierra pero si no tiene controles o todos los controles del diálogo estan desactivados (lo que me sucede constantemente, por ejemplo cuando estamos en modo consulta) el dialogo se cierra siempre despues de ejecutar el valid

he modificado el ejemplo para comprobar lo que digo

Code: Select all  Expand view
STATIC FUNCTION Prueba1(oWnd)
Local oDlg, oFld, oGet1, cGet1, oGet3, cGet3, oBtn

DEFINE DIALOG oDlg TITLE "Dialogo"

@ 1,1 FOLDER oFld  PROMPT "Uno", "Dos", "Tres", "Cuatro" OF oDlg

cGet1 := SPACE(10)
@ 1,1 GET oGet1 VAR cGet1 OF oFld:aDialogs[1]

cGet3 := SPACE(10)
@ 1,1 GET oGet3 VAR cGet3 OF oFld:aDialogs[3]
oGet3:Disable()

@ 1,1 BUTTON oBtn  OF oFld:aDialogs[4]

ACTIVATE DIALOG oDlg NOWAIT CENTER;
         VALID MsgYesNo("Salir")

RETURN NIL

En esta modificacion del ejemplo, si se pulsa escape cuando estamos en el primer o en el cuarto folder, el valid se ejecuta correctamente; sin embargo, si se pulsa en el segundo o en el tercero, el dialogo se cierra.
¿Habria alguna forma de modificar la CLASE para que busque algún control activo del dialogo en el que se encuentra el folder para pasarle el foco y que de esta forma no se me cierre el dialogo?

Gracias

Re: VALID EN DIALOGO NOWAIT NO funciona con telca ESC

PostPosted: Wed Apr 05, 2017 6:34 am
by Antonio Linares
Parece que este comportamiento y el reportado por Enrico estan basados en el mismo bug:

viewtopic.php?p=200302

He encontrado una solución para este error. En la clase TDialog estas líneas deben ser añadidas en el método Command()

Code: Select all  Expand view
     case nID == IDCANCEL .and. ! ::lModal
           if ::lValid()
              ::bValid = nil
              ::End()
              return .T.
           endif  
           return .F.


justo encima de case nID != 0

Te agradezco si lo pruebas puesto que es dificil saber que efectos colaterales pueda tener por lo que debe ser probado por muchos usuarios antes de que pueda ser incluido en FWH

Re: VALID EN DIALOGO NOWAIT NO funciona con telca ESC

PostPosted: Wed Apr 05, 2017 4:22 pm
by miarcod
Funciona

A continuación pongo el codigo que he implementado

Code: Select all  Expand view
#include "FiveWin.ch"
#include "Constant.ch"

#define CBN_SELCHANGE      1
#define CBN_CLOSEUP        8

#include "xhb.ch"
#include "xhbcls.ch"

//----------------------------------------------------------------------------//
FUNCTION OverrideAndExtend()
   OVERRIDE METHOD Command  IN CLASS TDialog WITH MiTDialogCommand
RETURN NIL


//----------------------------------------------------------------------------//
FUNCTION MiTDialogCommand(nWParam, nLParam)
//METHOD Command( nWParam, nLParam ) CLASS TDialog

   local oWnd, nNotifyCode, nID, hWndCtl

   LOCAL Self := HB_QSelf()

   nNotifyCode = nHiWord( nWParam )
   nID         = nLoWord( nWParam )
   hWndCtl     = nLParam

   do case
      case ::oPopup != nil
           ::oPopup:Command( nID )

      case hWndCtl == 0 .and. ::oMenu != nil .and. ;
           If( nNotifyCode == BN_CLICKED, nID != IDCANCEL, .f. )
           ::oMenu:Command( nID )

      case GetClassName( hWndCtl ) == "ToolbarWindow32"
           oWndFromHwnd( hWndCtl ):Command( nWParam, nLParam )
           return .T. // otherwise a child dialog gets closed

      case ::oMenu != nil .and. nId != 2 .and. nNotifyCode != BN_CLICKED
           if nNotifyCode == 1
              ::oMenu:Command( nID )
           endif

      case nID == IDCANCEL .and. ! ::lModal
           if ::lValid()
              ::bValid = nil
              ::End()
              return .T.
           endif
           return .F.

      case nID != 0
           do case
              case nNotifyCode == BN_CLICKED
                   if hWndCtl != 0 .and. nID != IDCANCEL
                      oWnd := oWndFromhWnd( hWndCtl )
                      if ValType( ::nResult ) == "O" // latest control which had focus
                         // There is a pending Valid, it is not a clicked button
                         if oWnd != nil
                            if ! oWnd:lCancel
                               if ::nResult:nID != nID .and. ! ::nResult:lValid()
                                  return nil
                               endif
                            endif
                         else
                            if ::nResult:nID != nID .and. ! ::nResult:lValid()
                               return nil
                            endif
                         endif
                      endif

                      if AScan( ::aControls, { |o| o:nID == nID } ) > 0
                         #ifdef __XPP__
                            PostMessage( hWndCtl, FM_CLICK, 0, 0 )
                         #else
                            SendMessage( hWndCtl, FM_CLICK, 0, 0 )
                         #endif
                      elseif nID == IDOK
                         ::End( IDOK )
                      endif
                   else
                      if nID == IDOK
                         ::GoNextCtrl( GetFocus() )
                         if ! ::lModal
                            return 0
                         endif
                      elseif hWndCtl != 0 .and. ; // There is a control for IDCANCEL
                             AScan( ::aControls, { |o| o:nID == nID } ) > 0
                             SendMessage( hWndCtl, FM_CLICK, 0, 0 )
                             return .F.
                      else
                         ::End( IDCANCEL )
                      endif
                   endif

              case nNotifyCode == CBN_SELCHANGE
                   SendMessage( hWndCtl, FM_CHANGE, 0, 0 )

              case nNotifyCode == CBN_CLOSEUP
                   SendMessage( hWndCtl, FM_CLOSEUP, 0, 0 )

           endcase
   endcase

return nil
 


He creado una funcion que sobreescribe el metodo command de la clase TDialogo y aparentemente funciona. Si detecto algun problema lo comunicaré.

Gracias a todos