FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour raro funcionamiento de la tecla escape
Posts: 694
Joined: Fri Oct 07, 2005 06:58 AM

raro funcionamiento de la tecla escape

Posted: Thu Oct 09, 2008 07:48 AM
Hola,

En el ejemplo que muestro mas abajo se define una ventana mdi child y dentro de ella incrustado una barra de botones, una barra outlook 2003, un splitter y un dialogo.

El problema viene a al pulsar la tecla "ESC", esta hace que se evalue 2 veces el valid de la ventana mdi child.

En el dialogo hay un get:
@ 0, 0 Get oGet Var cVar Of oDlg Size 50, 12

y comprobando el código fuente la clase tget he visto que comentando la llamada a ::KeyChar() del método KeyChar se evita que se ejecute dos veces el valid:
METHOD KeyChar( nKey, nFlags ) CLASS TGet
...
   if nKey == VK_ESCAPE  // avoids a beep!
//      ::oWnd:KeyChar( nKey, nFlags )
      return 1
   endif
...


Ya me imagino que no es la solución correcta, sobre todo porque si en el ejemplo se quita la línea del get, osea se deja la definición del dialogo sin nada dentro de él, sigue ejecutando 2 veces el valid de la ventana.

Ejemplo:
#include 'Fivewin.ch' 
#include "Splitter.ch"

Procedure Main()
local oWndMain, oMenu

Define Window oWndMain Title "Ventana principal" Mdi
Set Message To "" Keyboard Clock Date Of oWndMain 2007

MENU oMenu 2007
MENUITEM '&Child' MESSAGE 'Ventana child' Action ps_Child( oWndMain )
ENDMENU
oWndMain:SetMenu( oMenu )

Activate Window oWndMain MAXIMIZED;
  Valid msgnoyes('¿Abandonar el programa?', 'Salir')
return



*---------------------------------------------------------------------
static Procedure ps_Child( oWndMain )
local oWnd, oBar, oBtn1, oBtn2

Define Window oWnd MdiChild Title 'Ventana child' of oWndMain
Set Message To "" Of oWnd 2007

Define ButtonBar oBar Size 50, 45 Of oWnd 2007
Define Button oBtn1 Of oBar Prompt 'Otro' TOP
Define Button oBtn2 Of oBar Prompt 'Edit' TOP

Activate Window oWnd On Init ps_Init(oWnd, oBar) Valid .F.
return



*---------------------------------------------------------------------
static procedure ps_Init( oWnd, oBar )
local oDlg, oGet, cVar, oOutLook, aRect, oSplit
local nWidth, nHeight

Define Dialog oDlg Of oWnd TRANSPARENT STYLE nOR( WS_CHILD, WS_VISIBLE ) 
@ 0, 0 Get oGet Var cVar Of oDlg Size 50, 12

Define OutLook2003 oOutLook Of oWnd PROMPTS "Accesos"
oWnd:oLeft := NIL

aRect := oOutLook:aDialogs[ 1 ]:GetCliRect()
@ 0, aRect:nRight SPLITTER oSplit ;
   VERTICAL _3DLOOK ;
   PREVIOUS CONTROLS oOutLook ;
   HINDS CONTROLS oDlg ; 
   SIZE 4, oWnd:nHeight - 70 PIXEL ;
   OF oWnd


ACTIVATE DIALOG oDlg NoWait Valid oWnd:End()
oWnd:bResized := {|| oSplit:AdjClient(), oOutlook:refresh(.t.) }
oDlg:Move( 0, oSplit:nRight,,, .F. )

nWidth  := oDlg:nWidth
nWidth  += oOutLook:nWidth
nWidth  += oSplit:nWidth
nHeight := oDlg:nHeight
nHeight += oBar:nHeight
nHeight += oWnd:oMsgBar:nHeight
oWnd:SetSize(nWidth, nHeight, .F.)
oWnd:bResized := {|| oSplit:AdjClient(), oDlg:SetSize( oWnd:nWidth - oOutLook:nWidth - oSplit:nWidth - 8, oSplit:nHeight - 1, .t. ),;
                     oDlg:refresh(.t.), oOutlook:refresh(.t.) }
oWnd:bValid := {|| ps_Salir()}
return



*---------------------------------------------------------------------
static function ps_Salir()
msginfo('1')
return .T.
Un saludo

Fernando González Diez

ALSIS Sistemas Informáticos
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM

raro funcionamiento de la tecla escape

Posted: Thu Oct 09, 2008 06:00 PM
Fernando,

Cambia esta línea así:
ACTIVATE DIALOG oDlg NoWait Valid ( oWnd:PostMsg( WM_CHAR, VK_ESCAPE ), .T. )
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 694
Joined: Fri Oct 07, 2005 06:58 AM

raro funcionamiento de la tecla escape

Posted: Tue Oct 14, 2008 12:08 PM
Antonio,

Gracias por la respuesta.

El cambio que me indicas funciona correctamente siempre y cuando el valid cierre el cuadro de dialogo.

Con que se cambie el valid a .F. ya pasa dos veces por el msginfo
ACTIVATE DIALOG oDlg NoWait Valid ( oWnd:PostMsg( WM_CHAR, VK_ESCAPE ), .F. )


El objetivo que busco es que al pulsar "esc" valide si los get's están activos y si es así, los desactive y no cierre la ventana. Y si los get's estan desactivados cierre la ventana. Adjunto ejemplo

#include 'Fivewin.ch' 
#include "Splitter.ch" 

Procedure Main() 
local oWndMain, oMenu 

Define Window oWndMain Title "Ventana principal" Mdi 
Set Message To "" Keyboard Clock Date Of oWndMain 2007 

MENU oMenu 2007 
MENUITEM '&Child' MESSAGE 'Ventana child' Action ps_Child( oWndMain ) 
ENDMENU 
oWndMain:SetMenu( oMenu ) 

Activate Window oWndMain MAXIMIZED; 
  Valid msgnoyes('¿Abandonar el programa?', 'Salir') 
return 



*--------------------------------------------------------------------- 
static Procedure ps_Child( oWndMain ) 
local oWnd, oBar, oBtn1, oBtn2 

Define Window oWnd MdiChild Title 'Ventana child' of oWndMain 
Set Message To "" Of oWnd 2007 

Define ButtonBar oBar Size 50, 45 Of oWnd 2007 
Define Button oBtn1 Of oBar Prompt 'Otro' TOP 
Define Button oBtn2 Of oBar Prompt 'Edit' TOP 

Activate Window oWnd On Init ps_Init(oWnd, oBar) Valid .F. 
return 



*--------------------------------------------------------------------- 
static procedure ps_Init( oWnd, oBar ) 
local oDlg, oGet, cVar, oOutLook, aRect, oSplit 
local nWidth, nHeight 

Define Dialog oDlg Of oWnd TRANSPARENT STYLE nOR( WS_CHILD, WS_VISIBLE ) 
@ 0, 0 Get oGet Var cVar Of oDlg Size 50, 12 

Define OutLook2003 oOutLook Of oWnd PROMPTS "Accesos" 
oWnd:oLeft := NIL 

aRect := oOutLook:aDialogs[ 1 ]:GetCliRect() 
@ 0, aRect:nRight SPLITTER oSplit ; 
   VERTICAL _3DLOOK ; 
   PREVIOUS CONTROLS oOutLook ; 
   HINDS CONTROLS oDlg ; 
   SIZE 4, oWnd:nHeight - 70 PIXEL ; 
   OF oWnd 


ACTIVATE DIALOG oDlg NoWait Valid .F. ( oWnd:PostMsg( WM_CHAR, VK_ESCAPE ), .F. )
oWnd:bResized := {|| oSplit:AdjClient(), oOutlook:refresh(.t.) } 
oDlg:Move( 0, oSplit:nRight,,, .F. ) 

nWidth  := oDlg:nWidth 
nWidth  += oOutLook:nWidth 
nWidth  += oSplit:nWidth 
nHeight := oDlg:nHeight 
nHeight += oBar:nHeight 
nHeight += oWnd:oMsgBar:nHeight 
oWnd:SetSize(nWidth, nHeight, .F.) 
oWnd:bResized := {|| oSplit:AdjClient(), oDlg:SetSize( oWnd:nWidth - oOutLook:nWidth - oSplit:nWidth - 8, oSplit:nHeight - 1, .t. ),; 
                     oDlg:refresh(.t.), oOutlook:refresh(.t.) } 
oWnd:bValid := {|| ps_Salir(oGet, oDlg)} 
return 



*--------------------------------------------------------------------- 
static function ps_Salir(oGet, oDlg) 

if oGet:lActive
  oGet:Disable()
  return .F.
endif
msginfo('1') 
oDlg:bValid := NIL
oDlg:End()
return .T.
Un saludo

Fernando González Diez

ALSIS Sistemas Informáticos
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM

raro funcionamiento de la tecla escape

Posted: Tue Oct 14, 2008 11:08 PM

Fernando,

El problema es que una vez que el GET se deshabilita, la tecla ESC ya no va a ser procesada.

El que ESC se procese dos veces puedes controlarlo con:

SetDialogEsc( .F. )

No te serviría un botón de la barra que al pulsarlo sea para salir ? como si se pulsase la X de cierre de la ventana

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 694
Joined: Fri Oct 07, 2005 06:58 AM

raro funcionamiento de la tecla escape

Posted: Wed Oct 15, 2008 08:05 AM
Antonio,

con SetDialogEsc(.F.) ya hace justo lo que quiero.
Muchisimas gracias por tu ayuda.

No te serviría un botón de la barra que al pulsarlo sea para salir ? como si se pulsase la X de cierre de la ventana

En las aplicaciones tengo definido un botón para realizar esa tarea. El problema es que cuando están en modo edición y se equivocan pulsan "Esc" y se les cierra la ventana lo que provoca cabreo hacia la aplicación.

Con los cambios que me has indicado ya controlo lo que quería, muchisimas gracias, de nuevo.

Adjunto ejemplo definitivo:
Get por defecto desabilitado
Al pulsar en el botón "edit" se habilita y manda la instrucción SetDialogEsc(.F.)
Si se pulsa la tecla "Esc" o el botón "Salir", comprueba si esta en edición. si no lo esta cierra la ventana y si lo está pregunta si se quiere cancelar la edición.
#include 'Fivewin.ch' 
#include "Splitter.ch" 

Procedure Main() 
local oWndMain, oMenu 

Define Window oWndMain Title "Ventana principal" Mdi 
Set Message To "" Keyboard Clock Date Of oWndMain 2007 

MENU oMenu 2007 
MENUITEM '&Child' MESSAGE 'Ventana child' Action ps_Child( oWndMain ) 
ENDMENU 
oWndMain:SetMenu( oMenu ) 

Activate Window oWndMain MAXIMIZED; 
  Valid msgnoyes('¿Abandonar el programa?', 'Salir') 
return 



*--------------------------------------------------------------------- 
static Procedure ps_Child( oWndMain ) 
local oWnd, oBar, oBtn1, oBtn2 

Define Window oWnd MdiChild Title 'Ventana child' of oWndMain 
Set Message To "" Of oWnd 2007 

Define ButtonBar oBar Size 50, 45 Of oWnd 2007 
Define Button oBtn2 Of oBar Prompt 'Edit' TOP 
Define Button oBtn1 Of oBar Prompt 'Salir' TOP Action oWnd:End()

Activate Window oWnd On Init ps_Init(oWnd, oBar, oBtn2) Valid .F. 
return 



*--------------------------------------------------------------------- 
static procedure ps_Init( oWnd, oBar, oBtn2 ) 
local oDlg, oGet, cVar, oOutLook, aRect, oSplit 
local nWidth, nHeight 

Define Dialog oDlg Of oWnd TRANSPARENT STYLE nOR( WS_CHILD, WS_VISIBLE ) 
@ 0, 0 Get oGet Var cVar Of oDlg Size 50, 12 
oGet:Disable()

Define OutLook2003 oOutLook Of oWnd PROMPTS "Accesos" 
oWnd:oLeft := NIL 

aRect := oOutLook:aDialogs[ 1 ]:GetCliRect() 
@ 0, aRect:nRight SPLITTER oSplit ; 
   VERTICAL _3DLOOK ; 
   PREVIOUS CONTROLS oOutLook ; 
   HINDS CONTROLS oDlg ; 
   SIZE 4, oWnd:nHeight - 70 PIXEL ; 
   OF oWnd 


ACTIVATE DIALOG oDlg NoWait Valid ( oWnd:PostMsg( WM_CHAR, VK_ESCAPE ), .F. )
oWnd:bResized := {|| oSplit:AdjClient(), oOutlook:refresh(.t.) } 
oDlg:Move( 0, oSplit:nRight,,, .F. ) 

nWidth  := oDlg:nWidth 
nWidth  += oOutLook:nWidth 
nWidth  += oSplit:nWidth 
nHeight := oDlg:nHeight 
nHeight += oBar:nHeight 
nHeight += oWnd:oMsgBar:nHeight 
oWnd:SetSize(nWidth, nHeight, .F.) 
oWnd:bResized := {|| oSplit:AdjClient(), oDlg:SetSize( oWnd:nWidth - oOutLook:nWidth - oSplit:nWidth - 8, oSplit:nHeight - 1, .t. ),; 
                     oDlg:refresh(.t.), oOutlook:refresh(.t.) } 
oWnd:bValid   := {|| ps_Salir(oGet, oWnd, oDlg)} 
oBtn2:bAction := {|| SetDialogEsc( .F. ), oGet:Enable(), oGet:SetFocus() }

return 



*--------------------------------------------------------------------- 
static function ps_Salir(oGet, oWnd, oDlg) 

if oGet:lActive
  if MsgYesNo('¿Desea cancelar la modificación de los datos?', 'Cancelar la modificiación')
    oGet:Disable()
    oWnd:SetFocus()
    oDlg:SetFocus()
    SetDialogEsc( .T. )
  else
    oGet:SetFocus()
  endif
  return .F.
endif
msginfo('1') 
oDlg:bValid := NIL
oDlg:End()
return .T.
Un saludo

Fernando González Diez

ALSIS Sistemas Informáticos
Posts: 44162
Joined: Thu Oct 06, 2005 05:47 PM

raro funcionamiento de la tecla escape

Posted: Wed Oct 15, 2008 08:15 AM

Fernando,

Me alegro de que lo hayas conseguido :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 694
Joined: Fri Oct 07, 2005 06:58 AM

raro funcionamiento de la tecla escape

Posted: Wed Oct 15, 2008 10:15 AM
En el ejemplo definitivo con SetDialogEsc( .F. ) me había liado.

Es mas sencillo todavía, lo único que debo hacer es incluir al comienzo del programa SetDialogEsc( .F. )

Con eso puedo incluso llamar directamente a ownd:close desde el valid del cuadro de dialogo
ACTIVATE DIALOG oDlg NoWait Valid oWnd:End()


#include 'Fivewin.ch' 
#include "Splitter.ch" 

Procedure Main() 
local oWndMain, oMenu 

SetDialogEsc( .F. )
Define Window oWndMain Title "Ventana principal" Mdi 
Set Message To "" Keyboard Clock Date Of oWndMain 2007 

MENU oMenu 2007 
MENUITEM '&Child' MESSAGE 'Ventana child' Action ps_Child( oWndMain ) 
ENDMENU 
oWndMain:SetMenu( oMenu ) 

Activate Window oWndMain MAXIMIZED; 
  Valid msgnoyes('¿Abandonar el programa?', 'Salir') 
return 



*--------------------------------------------------------------------- 
static Procedure ps_Child( oWndMain ) 
local oWnd, oBar, oBtn1, oBtn2 

Define Window oWnd MdiChild Title 'Ventana child' of oWndMain 
Set Message To "" Of oWnd 2007 

Define ButtonBar oBar Size 50, 45 Of oWnd 2007 
Define Button oBtn2 Of oBar Prompt 'Edit' TOP 
Define Button oBtn1 Of oBar Prompt 'Salir' TOP Action oWnd:End()

Activate Window oWnd On Init ps_Init(oWnd, oBar, oBtn2) Valid .F. 
return 



*--------------------------------------------------------------------- 
static procedure ps_Init( oWnd, oBar, oBtn2 ) 
local oDlg, oGet, cVar, oOutLook, aRect, oSplit 
local nWidth, nHeight 

Define Dialog oDlg Of oWnd TRANSPARENT STYLE nOR( WS_CHILD, WS_VISIBLE ) 
@ 0, 0 Get oGet Var cVar Of oDlg Size 50, 12 
oGet:Disable()

Define OutLook2003 oOutLook Of oWnd PROMPTS "Accesos" 
oWnd:oLeft := NIL 

aRect := oOutLook:aDialogs[ 1 ]:GetCliRect() 
@ 0, aRect:nRight SPLITTER oSplit ; 
   VERTICAL _3DLOOK ; 
   PREVIOUS CONTROLS oOutLook ; 
   HINDS CONTROLS oDlg ; 
   SIZE 4, oWnd:nHeight - 70 PIXEL ; 
   OF oWnd 


ACTIVATE DIALOG oDlg NoWait Valid oWnd:End()
oWnd:bResized := {|| oSplit:AdjClient(), oOutlook:refresh(.t.) } 
oDlg:Move( 0, oSplit:nRight,,, .F. ) 

nWidth  := oDlg:nWidth 
nWidth  += oOutLook:nWidth 
nWidth  += oSplit:nWidth 
nHeight := oDlg:nHeight 
nHeight += oBar:nHeight 
nHeight += oWnd:oMsgBar:nHeight 
oWnd:SetSize(nWidth, nHeight, .F.) 
oWnd:bResized := {|| oSplit:AdjClient(), oDlg:SetSize( oWnd:nWidth - oOutLook:nWidth - oSplit:nWidth - 8, oSplit:nHeight - 1, .t. ),; 
                     oDlg:refresh(.t.), oOutlook:refresh(.t.) } 
oWnd:bValid   := {|| ps_Salir(oGet, oWnd, oDlg)} 
oBtn2:bAction := {|| oGet:Enable(), oGet:SetFocus() }

return 



*--------------------------------------------------------------------- 
static function ps_Salir(oGet, oWnd, oDlg) 

if oGet:lActive
  if MsgYesNo('¿Desea cancelar la modificación de los datos?', 'Cancelar la modificiación')
    oGet:Disable()
    oWnd:SetFocus()
    oDlg:SetFocus()
  else
    oGet:SetFocus()
  endif
  return .F.
endif
msginfo('1') 
return .T.
Un saludo

Fernando González Diez

ALSIS Sistemas Informáticos

Continue the discussion