Buenos dias Jose.
He podido revisar lo que me has pedido. Lo publico aquà por si ayuda a mas personas.
1) Ya puedes cerrar el dialogo al pulsar fuera del propio diálogo. Con dialogo y no con ventanas, como pedias.
2) Para que solo te aparezca un mes, dimensiona el tamaño de oCal. El methodo ::paint() no se encarga del pintado. Mira el ejemplo que te copio mas abajo. El tamaño es de 100,100 y solo aparece un mes. Antes lo definias mas grande y cabian mas meses. Nota: He simplificado al máximo el ejemplo, para que se entienda mejor.
3) bLDblClick no funcionaba. Es cierto. Ahora si funciona. Te cuento : En el metodo ::LButtonUp (que es donde controla si hay o no doble click), no se actualizaban las variables ::nRowDbl ni tampoco ::nColDbl, con lo que no se podia saber si el doble click estaba dentro del rango. Por lo tanto, en la segunda opcion del IF no se cumplÃa la primera condicion que era que ::nRowDbl fuera de tipo numerico y por tanto no se ejecutaba el Eval( ::bLDblClick, nRow, nCol )
Te copio tambien ese metodo modificado, debes cambiarlo en tcalenda.prg y compilarlo y lincarlo en tus pruebas.
Nota: Falta revisar ".and. IsOverDay( ::hWnd, nRow, nCol )" que esta desactivado, para terminar de pulir el doble click. Siempre devuelve .f. (falso). No conozco esta función, pero ¿no deberia comparar dos fechas?, Veo que compara dos posiciones x,y pero ya digo siempre devuelve falso.
La "sensibilidad" del doble click se define en tiempo con la variable ::nDelay (por defecto vale 500) y en la posición por las constantes HEIGHTDBLCLICK y WIDTHDBLCLICK
#include "fivewin.ch"
#include "calendar.ch"
STATIC oDlg
function Main()
LOCAL oWnd
SET DATE FORMAT "dd/mm/yyyy"
DEFINE WINDOW oWnd TITLE "ISOVER.PRG - Si hacemos click fuera del diálogo"
@2,2 BUTTON "Crear Diálogo" OF oWnd SIZE 150,40 ACTION MiDialogo()
oWnd:bGotFocus := { || IF( VALTYPE(oDlg)="O", ( oDlg:End(), oDlg:=nil ), ) }
ACTIVATE WINDOW oWnd MAXIMIZED
RETURN(NIL)
//-----------------------------------------------------------------------------
FUNCTION MiDialogo()
LOCAL dFecha:=Date(), oCal
DEFINE DIALOG oDlg FROM 200,300 TO 420,500 PIXEL STYLE WS_DLGFRAME
@1,1 CALENDAR oCal VAR dFecha SIZE 100,100 OF oDlg PIXEL
oCal:bLDblClick := { || MsgInfo("Hemos hecho doble click, en la fecha "+DTOC(dFecha)) }
ACTIVATE DIALOG oDlg NOWAIT
RETURN NIL
//----------------------------------------------------------------------------//
METHOD LButtonUp( nRow, nCol, nFlags ) CLASS TCalendar
if ::lDrag
return ::Super:LButtonUp( nRow, nCol, nFlags )
endif
if ::lCaptured
::lCaptured = .f.
ReleaseCapture()
::lBtnUp := .T.
IF ! ::lDblClick
::lDblClick = .T.
::oTimerDbl:Activate()
::nRowDbl := nRow // Modificado 10/12/2025 JMV
::nColDbl := nCol // " "
ELSE
IF ValType( ::nRowDbl ) == "N" /*.and. IsOverDay( ::hWnd, nRow, nCol )*/ .AND. ;
Abs( ::nRowDbl - nRow ) <= HEIGHTDBLCLICK .AND. Abs( ::nColDbl - nCol ) <= WIDTHDBLCLICK
IF ::bLDblClick != NIL
::oTimerDbl:Deactivate()
Eval( ::bLDblClick, nRow, nCol )
ENDIF
ENDIF
::lDblClick = .F.
ENDIF
endif
::Super:LButtonUp( nRow, nCol, nFlags )
return NIL
Por favor, cuentanos que tal para que otros puedan leer tus resultados.
Gracias
p.d.: actualizo un poco el tema del IsOverDay()
¿Qué hace realmente IsOverDay()?
Internamente revisa si las coordenadas del click (o del mouse move) caen dentro del rectángulo que representa el dÃa sobre el que el calendario está dibujando.
Por eso siempre te da .F. (FALSE) si:
Las coordenadas no están dentro del área calculada.
El calendario no se ha inicializado completamente.
El control tiene un offset o desplazamiento.
Se está llamando fuera del método donde se actualizan las posiciones.
Estás usando DPI altos o un skin que cambia el tamaño interno.
Entonces, la única solución que se me ocurre, es guardar en una variable de la clase la fecha del click pulsado y si coincide con la fecha del segundo click (dentro del timer), entonces que se cumpla la condición. ( es solo una idea por si alguien quiere, debe y puede modificar la clase).