raro funcionamiento de la tecla escape

raro funcionamiento de la tecla escape

Postby fgondi » Thu Oct 09, 2008 7: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:
Code: Select all  Expand view  RUN
@ 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 ::oWnd:KeyChar() del método KeyChar se evita que se ejecute dos veces el valid:
Code: Select all  Expand view  RUN
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:
Code: Select all  Expand view  RUN
#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
User avatar
fgondi
 
Posts: 694
Joined: Fri Oct 07, 2005 6:58 am
Location: Palencia, España

Postby Antonio Linares » Thu Oct 09, 2008 6:00 pm

Fernando,

Cambia esta línea así:
Code: Select all  Expand view  RUN
ACTIVATE DIALOG oDlg NoWait Valid ( oWnd:PostMsg( WM_CHAR, VK_ESCAPE ), .T. )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42161
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby fgondi » 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
Code: Select all  Expand view  RUN
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

Code: Select all  Expand view  RUN
#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
User avatar
fgondi
 
Posts: 694
Joined: Fri Oct 07, 2005 6:58 am
Location: Palencia, España

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

Postby fgondi » Wed Oct 15, 2008 8: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.
Code: Select all  Expand view  RUN
#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
User avatar
fgondi
 
Posts: 694
Joined: Fri Oct 07, 2005 6:58 am
Location: Palencia, España

Postby Antonio Linares » Wed Oct 15, 2008 8:15 am

Fernando,

Me alegro de que lo hayas conseguido :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42161
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Postby fgondi » 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
Code: Select all  Expand view  RUN
ACTIVATE DIALOG oDlg NoWait Valid oWnd:End()


Code: Select all  Expand view  RUN
#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
User avatar
fgondi
 
Posts: 694
Joined: Fri Oct 07, 2005 6:58 am
Location: Palencia, España


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 47 guests