Calendario...

Post Reply
Elias Torres
Posts: 233
Joined: Wed Aug 09, 2006 3:07 pm

Calendario...

Post by Elias Torres »

Hola a todos...

Me gustaria saber si existe alguna clase para mostrar un pequeño calendario y como debo usarla....


Saludos y gracias..

Elías Torres.
User avatar
Biel EA6DD
Posts: 680
Joined: Tue Feb 14, 2006 9:48 am
Location: Mallorca
Contact:

Post by Biel EA6DD »

Puedes usar DatePicker, busca en la ayuda DTPicker y veras como usarlo. Utiliza el calendario del sistema y es lo mas rapido y elegante.

Yo hice una adaptación de MsgDate de FiveWin, es bastanten mas lento que DatePicker, aunque me permite un mayor control. La verdad es que no la suelo usar, pero por si te vale aqui tienes el fuente.

Code: Select all

//---------------------------------------
FUNCTION  MsgDate( dDate, cPrompt,oGet )
//----------------------------------------
   local oDlg, oFont, oCursor, dSelect
   local nRow, nCol, nMonth, aMonths:={},nYear,cDay:='  '
   local cOldMode := Set( _SET_DATEFORMAT,;
                          If( __SetCentury(), "dd/mm/yyyy", "dd/mm/yy" ) )

   IF Empty(dDate)
      dDate:=Date()
   ENDIF
   FOR nMonth = 1 to 12
      AAdd( aMonths, CMonth( CToD( "01/"+padl( nMonth, 2 ) + "/98")))
   NEXT nMonth
   nMonth  := Month( dDate )
   nYear   := Year(dDate)
   dSelect := dDate

   DEFINE FONT oFont NAME GetSysFont() SIZE 0, -10

   DEFINE DIALOG oDlg SIZE 200, 190 TITLE cPrompt FONT oFont // -> 6 weeks
   oDlg:SetText(IF(cPrompt==NIL,dDateToString( dDate ),cPromt))
   @ 0.32, .70 COMBOBOX  nMonth  ITEMS  aMonths  SIZE 40,90  OF  oDlg ;
                  ON CHANGE MoveCalendar(oDlg, 1, nMonth )
   @ 6.6, 60  BTNBMP PROMPT "-" SIZE 8,8.3 ACTION ( MoveCalendar(oDlg, 3 ))
   @ 6.6, 86  BTNBMP PROMPT "+" SIZE 8,8.3 ACTION ( MoveCalendar(oDlg, 4 ))

   @ 0.42, 8.7 GET  nYear PICTURE "9999"  SIZE 14, 9 OF oDlg  WHEN .F.
   ATail( oDlg:aControls ):Cargo   = "YEAR"
   dDate-= Day( dDate ) - 1
   while DoW( dDate ) != 2 // Monday
      dDate --
   enddo
   FOR nCol:=1 TO 7
      cDay+=SubStr(CDoW(dDate++),1,3)+Space(4)
   NEXT
   dDate-=7
   @ 1.3,0 SAY cDay COLOR CLR_WHITE, CLR_HBLUE SIZE 110,6
   for nRow = 3 to 8
      for nCol = 1 to 7
         @ nRow * 10, ( nCol * 14 ) - 12 BTNBMP ;
                      PROMPT Str( Day( dDate ), 2 ) SIZE 12, 10 NOBORDER ;
                      ACTION ( dDate := ::Cargo, oDlg:End( IDOK ) )
         ATail( oDlg:aControls ):Cargo   = dDate
         ATail( oDlg:aControls ):nClrText = If( dDate == Date(), CLR_HRED,;
                     If( dDate == dSelect, CLR_HBLUE, If( Month( dDate ) == nMonth,;
                     CLR_BLACK, CLR_GRAY ) ) )
         IF ATail( oDlg:aControls ):Cargo == dSelect
            ATail( oDlg:aControls ):lPressed = .t.
         ENDIF
         dDate++
      next
   next
   dDate:=dSelect
   oDlg:Cargo:=dDate
   ACTIVATE DIALOG oDlg CENTERED ;
      ON INIT ( oDlg:aControls[ 3 ]:SetFocus() )
   IF oGet != NIL
      oGet:VarPut( If( oDlg:nResult == IDOK, dDate, dSelect ) )
      oGet:Refresh()
   ENDIF
   Set( _SET_DATEFORMAT, cOldMode )
RETURN  If( oDlg:nResult == IDOK, dDate, dSelect )
//----------------------------------------------
STATIC FUNCTION MoveCalendar( oDlg, nMode, nVar)
//----------------------------------------------
   local dSelect      := oDlg:Cargo
   local n
   local nFirstButton := 0
   local nLastButton  := 0
   local nDate        := 0
   local nSkip        := 0
   local nPYear       := 0
   local nDay, nMonth, nYear
   local dWork
   local nDays := 0
   for n := 1 TO Len( oDlg:aControls )
      if oDlg:aControls[ n ]:ClassName() == "TBTNBMP"
         nFirstButton := If( nFirstButton == 0, If(nSkip<2, 0, n), nFirstButton )
         nLastButton  := n
         nSkip++
         oDlg:aControls[ n ]:lPressed := .F.
      endif
      if ValType( oDlg:aControls[ n ]:Cargo ) == "C"
        if oDlg:aControls[ n ]:Cargo == "YEAR"
           nPYear     := n
        endif
      endif
   next n

   nDay   := Day( dSelect )
   nMonth := Month( dSelect )
   nYear  := Year( dSelect )

   do case
      case nMode == 1 //Cambio de mes
         nMonth := nVar
      case nMode == 3
         nYear --
      case nMode == 4
         nYear ++
   ENDCASE
   dSelect      := CToD( padl( nDay, 2) + "/"+padl( nMonth, 2 ) + "/"+right(padl( nYear, 4 ), 2))
   WHILE Empty(dSelect)  //Retorcede hasta fecha vailida
      dSelect      := CToD( padl( --nDay, 2) + "/"+padl( nMonth, 2 ) + "/" +right(padl( nYear, 4 ), 2))
   END
   cLongDate    := dDateToString( dSelect )
   oDlg:SetText(cLongDate)
   oDlg:aControls[ nPYear ]:VarPut( nYear)

   dWork    := Ctod( "01/" + padl( nMonth, 2 ) + "/" + right(padl( nYear, 4 ), 2))
   while DoW( dWork ) > 1
      dWork --
   enddo

   for n := nFirstButton TO nLastButton
      oDlg:aControls[ n ]:SetText( Str( Day( dWork ), 2 ) )

      oDlg:aControls[ n ]:Cargo   = dWork
      oDlg:aControls[ n ]:nClrText = If( dWork == Date(), CLR_HRED,;
                 If( dWork == dSelect, CLR_HBLUE, If( Month( dWork ) == nMonth,;
                 CLR_BLACK, CLR_GRAY ) ) )

      if dWork == dSelect
         oDlg:aControls[ n ]:lPressed = .T.
      endif
      dWork++
   next n

   for n := 1 TO Len( oDlg:aControls )
      oDlg:aControls[ n ]:Refresh()
   next n
   oDlg:Cargo   := dSelect
return nil
Modo de uso , coloco un boton pequeño a la derecha del GET con el siguiente código.

Code: Select all

REDEFINE BUTTON ID 4 OF oDlg ACTION (MsgDate( dFecha,,oGetFec))
Saludos desde Mallorca
Biel Maimó
http://bielsys.blogspot.com/
Elias Torres
Posts: 233
Joined: Wed Aug 09, 2006 3:07 pm

Post by Elias Torres »

Gracias Biel, pero tengo un problema a la hora de usarlo.... Vamos a ver si utilizo el código que me has mandado me da un error al compilar algo asi como:

"unresolved external symbol HB_FUN_DDATETOSTRING..."

es decir que la funcion datetostring() no me la reconoce. Por otro lado no encuentro la ayuda sobre DTPicker....He visto que FW tiene una propia llamada msgdate() pero tampoco me la reconoce. Supongo que a lo mejor tengo que incluir algun "include" pero nose cual es...


Saludos.

Elías Torres.
User avatar
Biel EA6DD
Posts: 680
Joined: Tue Feb 14, 2006 9:48 am
Location: Mallorca
Contact:

Post by Biel EA6DD »

Hola Elias,
parece que se me olvido de poner la funcion dDateToString. Aqui la tienes.

Code: Select all

//------------------------------------
static function dDateToString( dDate )
//------------------------------------
   local cSay := CDoW( dDate ) + ", " + ;
                   Str( Day( dDate ), 2 ) + " " + ;
                   CMonth( dDate ) + " " + ;
                   Str( Year( dDate ), 4 )
return cSay
Referente a DTPicker, en Fivewin comands guide, en la pestaña busqueda, dtpicker.
Include file: DTPICKER.CH

Creating a DTPICKER from source code

@ <nRow>, <nCol> DTPICKER [ <oDTPicker> VAR ] <uVar> ;


[ OF | WINDOW | DIALOG <oWnd> ] ;

[ COLOR | COLORS <nClrText> [,<nClrBack> ] ] ;

[ SIZE <nWidth>, <nHeight> ];

[ FONT <oFont> ] ;

[ DESIGN ] ;

[ CURSOR <oCursor> ] ;

[ PIXEL ] ;

[ UPDATE ] ;

[ MESSAGE <cMsg> ] ;

[ WHEN <uWhen> ] ;

[ VALID <uValid> ] ;

[ ON CHANGE <uChange> ] ;

[ HELPID | HELP ID <nHelpId> ]



Using a DTPicker from a resource Dialog Box

REDEFINE DTPICKER [ <oDTPikcer> VAR ] <uVar> ;


[ ID <nId> ] ;

[ OF | WINDOW | DIALOG <oWnd> ] ;

[ HELPID | HELP ID <nHelpId> ] ;

[ COLOR | COLORS <nClrText> [,<nClrBack> ] ] ;

[ VALID <ValidFunc> ] ;

[ FONT <oFont> ] ;

[ CURSOR <oCursor> ] ;

[ MESSAGE <cMsg> ] ;

[ UPDATE ] ;

[ WHEN <WhenFunc> ] ;

[ ON CHANGE <uChange> ] ;
Desde código

Code: Select all

LOCAL dTmp:=Date()
@ 1, 1 DTPICKER dTmp SIZE 50, 12 OF oDlg
Saludos desde Mallorca
Biel Maimó
http://bielsys.blogspot.com/
Elias Torres
Posts: 233
Joined: Wed Aug 09, 2006 3:07 pm

Post by Elias Torres »

Biel, gracias por la ayuda. Te comento lo que me ocurre...
Al utilizar msgdate(), me muestra el calendario, pero al avanzar de mes y luego retroceder, el año me lo cambia y en vez de poner 2007 me pone 1907... Y a parte me da un error en una variable, concretamente en IDOK cuando pulso sobre el dia que quiero, me dice que esa variable no existe.

Otra duda que me ha surgido, se supone que ya está implementado la clase msgdate(), pero debo poner todo el codigo en mi programa para que me lo muestre. No me bastaría con llamar a esa funcion solamente?...

Alguna sugerencia?

Saludos y gracias.

Elías Torres.
User avatar
Biel EA6DD
Posts: 680
Joined: Tue Feb 14, 2006 9:48 am
Location: Mallorca
Contact:

Post by Biel EA6DD »

Hola Elias,
incluye las siguientes lineas en tu programa.
Al inicio de la aplicacion

Code: Select all

Set EPOCH TO 1919
y en el prg donde hayas colocado los fuentes de msgdate

Code: Select all

#define IDOK 1
Y creo que con esto ya te funcionara correctamente.
De todas formas prueba el DTPicker que esta muy bien, y es el calendario nativo del sistema operativo.

Referente a lo que comentas de si hace falta incluir los fuentes, pues en la versión que tengo yo de FWPPC que no es la última, msgdate no estaba implementado, por tanto, si es necesario, en la tuya si ya esta implementado, no haria falta incluir los fuentes.
Saludos desde Mallorca
Biel Maimó
http://bielsys.blogspot.com/
Elias Torres
Posts: 233
Joined: Wed Aug 09, 2006 3:07 pm

Post by Elias Torres »

Gracias Biel, probaré lo que me comentas y tambien la otra opcion..
Ya te diré que tal..

Saludos.

Elías Torres.
Post Reply