About TCalendar

AntoninoP
Posts: 347
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy
Contact:

About TCalendar

Post by AntoninoP »

Hello, In our program we ask for a range di date, using 2 DatePicker, I would like change it using the Month Calendar Control
that is supported by FiveWin by the TCalendar class.
What I saw, trying the testcal sample is the some animations are missing, I fixed it adding these pieces of code on the sample (and on every use)

Code: Select all

   // my fix
   __objDelMethod(oCal, "HandleEvent" )
   __objAddMethod(oCal, "HandleEvent", @simplyNil())
   __objDelMethod(oCal2, "HandleEvent" )
   __objAddMethod(oCal2, "HandleEvent", @simplyNil())
   // *** ***
and

Code: Select all

static function simplyNil()
return nil
another way is overriding HandleEvent in TCalendar, of course.
Here a couple of video with the missing animations :https://imgur.com/a/vA0lNfn

Another piece that is missing is the query for size of the control, that I would implement in this way:

Code: Select all

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_GETMINREQRECT )     //  hWnd  -->  { nTop, nLeft, nBottom, nRight }
{
   HWND hWnd = ( HWND ) fw_parH( 1 );
   RECT rct;

   rct.top    = 0;
   rct.left   = 0;
   rct.bottom = 0;
   rct.right  = 0;

   if( hWnd )
      MonthCal_GetMinReqRect( hWnd, &rct );

   hb_reta( 4 );

   hb_storvni( rct.top,    -1, 1 );
   hb_storvni( rct.left,   -1, 2 );
   hb_storvni( rct.bottom, -1, 3 );
   hb_storvni( rct.right,  -1, 4 );
}

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_SIZERECTTOMIN )     //  hWnd,{ nTop, nLeft, nBottom, nRight }  -->  { nTop, nLeft, nBottom, nRight }
{
   HWND hWnd = ( HWND ) fw_parH( 1 );
   RECT rct;

   rct.top    = hb_parvni( 2, 1 );
   rct.left   = hb_parvni( 2, 2 );
   rct.bottom = hb_parvni( 2, 3 );
   rct.right  = hb_parvni( 2, 4 );

   if( hWnd )
      MonthCal_SizeRectToMin( hWnd, &rct );

   hb_reta( 4 );

   hb_storvni( rct.top,    -1, 1 );
   hb_storvni( rct.left,   -1, 2 );
   hb_storvni( rct.bottom, -1, 3 );
   hb_storvni( rct.right,  -1, 4 );
}

//----------------------------------------------------------------------------//
From MSDN:

MonthCal_GetMinReqRect
Retrieves the minimum size required to display a full month in a month calendar control. Size information is presented in the form of a RECT structure.

MonthCal_SizeRectToMin
Calculates how many calendars will fit in the given rectangle, and then returns the minimum size that a rectangle needs to be to fit that number of calendars.
AntoninoP
Posts: 347
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy
Contact:

Re: About TCalendar

Post by AntoninoP »

another problem:

Code: Select all

METHOD Change() CLASS TCalendar

   static dOldDate

   if ::bChange != nil .and. dOldDate != ::GetDate()
      Eval( ::bChange, Self )
      dOldDate = ::GetDate()
   endif

return NIL
In case of multiselect, if change only the Date end bChange is not called
elvira
Posts: 462
Joined: Fri Jun 29, 2012 12:49 pm

Re: About TCalendar

Post by elvira »

Hello Antonio,

I'm afraid the class has several unpolished aspects. If you post the complete source code we can help you with the testing.

Thank you!
AntoninoP
Posts: 347
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy
Contact:

Re: About TCalendar

Post by AntoninoP »

hello,
here a modifed version of testcal.prg from sample folder

Code: Select all

#include "FiveWin.ch"
#include "dtpicker.ch"
#include "calendar.ch"
#include "wcolors.ch"

FUNCTION Main()
   LOCAL oWnd, oCal, oDtp1, oDtp2, oDtp3, oDtp4, oCbx
   LOCAL oSayClr
   LOCAL nColor
   LOCAL dDate1, dDate2, dDate3, dDate4, dDate5, dDate6
   LOCAL cItemClr
   LOCAL lWeekNumbers   := .F.
   LOCAL lNoTodayCircle := .F.
   LOCAL lNoToday       := .F.
   LOCAL lDayState      := .F.
   LOCAL oRange3, aRanges2 := { , }
   LOCAL oRange4
   LOCAL aColorItems    := { "MCSC_BACKGROUND  " ,;
                             "MCSC_TEXT        " ,;
                             "MCSC_TITLEBK     " ,;
                             "MCSC_TITLETEXT   " ,;
                             "MCSC_MONTHBK     " ,;
                             "MCSC_TRAILINGTEXT" }
   LOCAL oDayOfWeek, cDayOfWeek:="Monday", aDayOfWeek:={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}

   LOCAL oCal2
   LOCAL oRange1, aRanges := { , }
   LOCAL oRange2
   LOCAL oMax, nMax
   LOCAL lSunday   := .T.
   LOCAL lSaturday := .T.



     SET DATE TO BRITISH
     SET EPOCH TO 1980
   dDate1 = Date()
   dDate2 = Date()
   dDate3 = Date()
   dDate4 = Date() + 7
   dDate5 = Date()
   dDate6 = Date()

   DEFINE WINDOW oWnd TITLE "Test Calendar" FROM 0, 0 TO 600, 600 PIXEL

   // Start Calendar 1


  @ 001, 205 CALENDAR oCal VAR dDate1 OF oWnd PIXEL;
              DBLCLICK MsgInfo( oCal:GetDate() );
              ON CHANGE oDtp2:cText := oCal:GetDate() SIZE 200, 170;
              ACTION( MsgInfo( "ok" ) );
              WEEKNUMBER

   @ 001, 001 BUTTON "Get Today" OF oWnd PIXEL SIZE 100, 020 ACTION oDtp1:cText := oCal:GetToday()
   @ 025, 001 BUTTON "Set Today" OF oWnd PIXEL SIZE 100, 020 ACTION oCal:SetToday( dDate1 )
   @ 012, 105 DTPICKER oDtp1 VAR dDate1 OF oWnd PIXEL
   @ 050, 001 BUTTON "Get Color" OF oWnd PIXEL SIZE 100, 020 ACTION( oSayClr:SetColor( CLR_BLACK, oCal:GetColors( oCbx:nAt - 1 ) ), oSayClr:Refresh() )
   @ 050, 105 BUTTON "Set Color" OF oWnd PIXEL SIZE 100, 020 ACTION( nColor := ChooseColor(), ;
                                                                     oCal:SetColor( oCbx:nAt - 1, nColor ), ;
                                                                     oSayClr:SetColor( CLR_BLACK, nColor ),;
                                                                     oSayClr:Refresh() )

   @ 075, 001 COMBOBOX oCbx VAR cItemClr PROMPTS aColorItems PIXEL SIZE 205, 200 OF oWnd
   @ 100, 001 SAY oSayClr VAR "        " PIXEL SIZE 100, 020 OF oWnd BORDER

   @ 125, 001 BUTTON "Get 1 Day Week" OF oWnd SIZE 100, 20 PIXEL ACTION( cDayofWeek := aDayOfWeek[ oCal:GetFirstDayOfWeek() + 1 ], oDayOfWeek:Refresh() )
   @ 125, 105 BUTTON "Set 1 Day Week" OF oWnd SIZE 100, 20 PIXEL ACTION( oCal:SetFirstDayOfWeek( oDayOfWeek:FindString( cDayOfWeek ) - 1 ) )

   @ 150, 001 COMBOBOX oDayOfWeek VAR cDayofWeek ITEMS aDayOfWeek OF oWnd SIZE 205, 200 PIXEL

   @ 175, 001 BUTTON "Get Selected Day" OF oWnd PIXEL SIZE 100, 020 ACTION Msginfo( oCal:GetDate() )
   @ 200, 001 BUTTON "Set Selected Day" OF oWnd PIXEL SIZE 100, 020 ACTION oCal:SetDate( dDate2 )
   @ 186, 105 DTPICKER oDtp2 VAR dDate2 OF oWnd PIXEL

   @ 175, 210 BUTTON "Get Range" OF oWnd PIXEL SIZE 100, 020 ;
              ACTION( aRanges2 := oCal:GetRange(), oRange3:Refresh(), oRange4:Refresh() )
   @ 175, 310 GET oRange3 VAR aRanges2[ 1 ] OF oWnd SIZE 100, 20 PIXEL
   @ 175, 420 GET oRange4 VAR aRanges2[ 2 ] OF oWnd SIZE 100, 20 PIXEL

   @ 200, 210 BUTTON "Set Range" OF oWnd PIXEL SIZE 100, 020 ACTION oCal:SetRange( dDate5, dDate6 )
   @ 200, 315 DTPICKER oDtp3 VAR dDate5 OF oWnd PIXEL
   @ 200, 420 DTPICKER oDtp4 VAR dDate6 OF oWnd PIXEL

   @ 001, 410 CHECKBOX oCal:lWeekNumbers PROMPT "Week Numbers" OF oWnd SIZE 100, 20 PIXEL;
              ON CHANGE  oCal:SetWeekNumbers( oCal:lWeekNumbers )

   @ 025, 410 CHECKBOX oCal:lNoTodayCircle PROMPT "No Today Circle" OF oWnd SIZE 100, 20 PIXEL;
              ON CHANGE  oCal:SetNoTodayCircle( oCal:lNoTodayCircle )

   @ 050, 410 CHECKBOX oCal:lNoToday PROMPT "No Today" OF oWnd SIZE 100, 20 PIXEL;
              ON CHANGE  oCal:SetNoToday( oCal:lNoToday )

     oCal:bGotFocus  := {|| oCal:SetTitleBk( CLR_YELLOW ) }
     oCal:bLostFocus := {|| oCal:SetTitleBk( GetSysColor( COLOR_ACTIVECAPTION ) ) }

   // Start Calendar 2

   @ 250, 001 CALENDAR oCal2 VAR dDate3, dDate4 OF oWnd PIXEL MULTISELECT DAYSTATE;
              DBLCLICK MsgInfo( oCal2:GetDate() ) SIZE 550, 170 COLOR CLR_BLACK, CLR_HRED ;
              on change iif(empty(oCal2),,( aRanges := oCal2:GetDateRange(), oRange1:Refresh(), oRange2:Refresh() ))
   // I Added On Change
   @ 230, 001 SAY "MONTHS DISPLAYED: " + StrZero( ocal2:GetVisibleMonths(), 2 )  OF oWnd PIXEL COLOR CLR_WHITE, CLR_BLACK

   @ 430, 001 BUTTON "Get Selected Range" OF oWnd SIZE 100, 20 PIXEL ;
              ACTION( aRanges := oCal2:GetDateRange(), oRange1:Refresh(), oRange2:Refresh() )
   @ 430, 105 GET oRange1 VAR aRanges[ 1 ] OF oWnd SIZE 100, 20 PIXEL
   @ 430, 210 GET oRange2 VAR aRanges[ 2 ] OF oWnd SIZE 100, 20 PIXEL

     oCal2:bGotFocus  := {|| oCal2:SetTitleBk( CLR_YELLOW ) }
     oCal2:bLostFocus := {|| oCal2:SetTitleBk( CLR_HRED ) }

   nMax = oCal2:GetMaxSelCount()

   @ 455, 001 BUTTON "Set Max Selected Day" OF oWnd SIZE 150, 20 PIXEL ;
              ACTION( oCal2:SetMaxSelCount( nMax ) )

   @ 455, 155 GET oMax VAR nMax OF oWnd SIZE 50, 20 PIXEL SPINNER ;
              MIN 1 MAX 60

   @ 480, 001 CHECKBOX oCal2:lDayState PROMPT "Day State" OF oWnd SIZE 100, 20 PIXEL;
              ON CHANGE( oCal2:SetDayStateStyle( oCal2:lDayState ), ;
                        If( oCal2:lDayState, ( OnGetState( oCal2, lSunday, lSaturday ), oCal2:SetDayState() ), ) )

   @ 505, 001 CHECKBOX lSunday PROMPT "Bold Sunday" OF oWnd SIZE 100, 20 PIXEL

   @ 530, 001 CHECKBOX lSaturday PROMPT "Bold Saturday" OF oWnd SIZE 100, 20 PIXEL

    OnGetState( oCal2, lSunday, lSaturday )
    oCal2:SetDayState()
    oCal2:bOnGetState = { | oCal | OnGetState( oCal, lSunday, lSaturday ) }

   // my fixes
   __objDelMethod(oCal2, "HandleEvent" )
   __objAddMethod(oCal2, "HandleEvent", @simplyNil())
   __objDelMethod(oCal2, "Change" )
   __objAddMethod(oCal2, "Change", @TCal_Method_Change())
   // *** ***

   ACTIVATE WINDOW oWnd


RETURN NIL

static function simplyNil()
return nil

function TCal_Method_Change()
   local Self := QSelf(), aTmp
   static dOldDate, dOldDate2

   if ::bChange != nil
      Eval( ::bChange, Self )
      if ::lMultiselect
         aTmp := ::GetDateRange()
         if dOldDate != aTmp[1] .or. dOldDate2 != aTmp[2]
            Eval( ::bChange, Self )
            dOldDate := aTmp[1]
            dOldDate2 := aTmp[2]
         endif
      else
         if dOldDate != ::GetDate()
            Eval( ::bChange, Self )
            dOldDate = ::GetDate()
         endif
      endif
   endif

return NIL



Function OnGetState( oCal, lSun, lSat )
   LOCAL i, imax, j, jmax, nDay, nDayState, nMonth
   LOCAL dStartDate
   LOCAL dCurrentDay := oCal:dDate

   oCal:GetMonthRange()

   dStartDate = oCal:dDate

   imax   := Len( oCal:aDayState )
   nMonth := Month( dStartDate )


   FOR i:=1 TO imax
      nDayState := 0

      FOR j:=1 TO 31
         nDay := DoW( dStartDate ) - 2
         IF nDay < 0
            nDay += 7
         ENDIF

         IF nDay == 5 .AND. lSat
            oCal:SetArrayDayState( i, j )
         ENDIF

         IF nDay == 6 .AND. lSUN
            oCal:SetArrayDayState( i, j )
         ENDIF

         dStartDate ++

         IF Month( dStartDate ) <> nMonth
            EXIT
         ENDIF
      NEXT

      nMonth       := Month( dStartDate )
   NEXT

   oCal:SetDate( dCurrentDay )

return nil
Without the lines that overwrites HandleEvent andCheck we can see the bugs I already pointed out:
  • No animation clicking on mount title
  • No selection on click and drag on range mode
  • No change event changing only end date (it is visible very well if the previous one is fixed)
Regards
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: About TCalendar

Post by Antonio Linares »

Antonino,

Many thanks for your feedback and help. It will be included in the next FWH build.

We have implemented it this way:

In class TCalendar:

METHOD HandleEvent() VIRTUAL

METHOD GetMinReqRect() INLINE MonthCal_GetMinReqRect( ::hWnd )

METHOD SizeRectToMin( aSize ) INLINE MonthCal_SizeRectToMin( ::hWnd, aSize )

Code: Select all

METHOD Change() CLASS TCalendar

   local aTmp
   
   static dOldDate, dOldDate2

   if ::bChange != nil
      Eval( ::bChange, Self )
      if ::lMultiselect
         aTmp = ::GetDateRange()
         if dOldDate != aTmp[ 1 ] .or. dOldDate2 != aTmp[ 2 ]
            Eval( ::bChange, Self )
            dOldDate  = aTmp[ 1 ]
            dOldDate2 = aTmp[ 2 ]
         endif
      else
         if dOldDate != ::GetDate()
            Eval( ::bChange, Self )
            dOldDate = ::GetDate()
         endif
      endif
   endif

return nil
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
AntoninoP
Posts: 347
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy
Contact:

Re: About TCalendar

Post by AntoninoP »

ops, there is a bug, bChange is called 2 time by Change method, here the fix:

Code: Select all

METHOD Change() CLASS TCalendar

   local aTmp
   
   static dOldDate, dOldDate2

   if ::bChange != nil
      if ::lMultiselect
         aTmp = ::GetDateRange()
         if dOldDate != aTmp[ 1 ] .or. dOldDate2 != aTmp[ 2 ]
            Eval( ::bChange, Self )
            dOldDate  = aTmp[ 1 ]
            dOldDate2 = aTmp[ 2 ]
         endif
      else
         if dOldDate != ::GetDate()
            Eval( ::bChange, Self )
            dOldDate = ::GetDate()
         endif
      endif
   endif

return nil
It is a mistake of my code
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: About TCalendar

Post by Antonio Linares »

thanks! :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
AntoninoP
Posts: 347
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy
Contact:

Re: About TCalendar

Post by AntoninoP »

Hello,
I share my Last test, where added bViewChanged called when the view changes, SetCurrentView and GetCurrentView to set and get the current view. I tried to do a only month selection, but id does a little weird animation:

Code: Select all

#include <fivewin.ch>
#include <calendar.ch>

// MyCalendar
#define MCMV_MONTH      0
#define MCMV_YEAR       1
#define MCMV_DECADE     2
#define MCMV_CENTURY    3
#define MCMV_MAX        MCMV_CENTURY

// TEST CODE
proc main()
   LOCAL oDlg, oMonth, dData1 := Date(),dData2 := Date(), oMonth2, dMese := Date()
   DEFINE DIALOG oDlg SIZE 700,400 PIXEL TRUEPIXEL;
      TITLE "Test MonthCal"
   //@ 10,10 CALENDAR oMonth VAR dData1,dData2 PIXEL NOTADAY NOTODAYCIRCLE SIZE 500,20
   oMonth := MyCalendar():New( 10, 10, { | u | If( PCount()==0, dData1, dData1:= u ) }, { | u | If( PCount()==0, dData2, dData2:= u ) },, 500, 20,,,,, .F.,, .T.,, .F., .F.,,,,,, .F., .T., .T., .F. )
   // only month calendar test
   //@ 210,10 CALENDAR oMonth2 VAR dMese PIXEL NOTADAY NOTODAYCIRCLE SIZE 700,20
   oMonth2 := MyCalendar():New( 210, 10, { | u | If( PCount()==0, dMese, dMese:= u ) }, nil,, 700, 20,,,,, .F.,, .T.,, .F., .F.,,,,,, .F., .T., .T., .F. )
   oMonth2:bViewChanged := {|Self,nOld,nNew| iif(nNew<MCMV_YEAR,::SetCurrentView(MCMV_YEAR),) }
   ACTIVATE DIALOG oDlg CENTERED ON INIT (oMonth2:SetCurrentView(MCMV_YEAR))


// MyCalendar
#define SWP_NOSIZE        0x0001
#define SWP_NOMOVE        0x0002
#define SWP_NOZORDER      0x0004

#define MCN_VIEWCHANGE      (-750)

CLASS MyCalendar FROM TCalendar
   DATA bViewChanged

   METHOD New(...) CONSTRUCTOR

   METHOD HandleEvent( nMsg, nWParam, nLParam )
   METHOD Change()
   METHOD Notify( nIdCtrl, nPtrNMHDR )

   // use SetGet?
   METHOD Initiate( hDlg )
   METHOD SetCurrentView(id) INLINE MonthCal_SetCurrentView(::hWnd, id)
   METHOD GetCurrentView() INLINE MonthCal_GetCurrentView(::hWnd)

endclass

METHOD New(...) CLASS MyCalendar
   LOCAL rc
   ::Super:new(...)
   if !Empty( ::hWnd )
      rc := MonthCal_SizeRectToMin( ::hWnd, GetClientRect( ::hWnd ) )
      SetWindowPos(::hWnd, 0, 0, 0, rc[4], rc[3], nOr(SWP_NOZORDER, SWP_NOMOVE))
      ::CoorsUpdate()
   endif
return Self

METHOD Initiate( hDlg )  CLASS MyCalendar
   LOCAL rc
   ::Super:Initiate(hDlg)
   if !Empty( ::hWnd )
      rc := MonthCal_SizeRectToMin( ::hWnd, GetClientRect( ::hWnd ) )
      SetWindowPos(::hWnd, 0, 0, 0, rc[4], rc[3], nOr(SWP_NOZORDER, SWP_NOMOVE))
      ::CoorsUpdate()
   endif
return nil

METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS MyCalendar
   // TODO: Verify others messages
   if nMsg==WM_LBUTTONUP
      ::Super:HandleEvent( nMsg, nWParam, nLParam )
   endif
return nil

METHOD Change() CLASS MyCalendar
   local aTmp
   static dOldDate, dOldDate2

   if ::bChange != nil
      if ::lMultiselect
         aTmp := ::GetDateRange()
         if dOldDate != aTmp[1] .or. dOldDate2 != aTmp[2]
            Eval( ::bChange, Self )
            dOldDate := aTmp[1]
            dOldDate2 := aTmp[2]
         endif
      else
         if dOldDate != ::GetDate()
            Eval( ::bChange, Self )
            dOldDate = ::GetDate()
         endif
      endif
   endif
return NIL

METHOD Notify( nIdCtrl, nPtrNMHDR ) CLASS MyCalendar
   local nCode := GetNMHDRCode( nPtrNMHDR ), nOld, nNew
   if nCode == MCN_VIEWCHANGE
      if !empty(::bViewChanged)
         MonthCal_GetViewChangeValues(nPtrNMHDR, @nOld, @nNew)
         eval(::bViewChanged, self, nOld, nNew)
      endif
      return nil
   endif
return ::Super:Notify( nIdCtrl, nPtrNMHDR )

//----------------------------------------------------------------------------//

#pragma BEGINDUMP
#include <Windows.h>
#include <CommCtrl.h>
#include <hbapi.h>
#include <hbdate.h>
#include <fwh.h>

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_GETMINREQRECT )     //  hWnd  -->  { nTop, nLeft, nBottom, nRight }
{
   HWND hWnd = ( HWND ) fw_parH( 1 );
   RECT rct;

   rct.top    = 0;
   rct.left   = 0;
   rct.bottom = 0;
   rct.right  = 0;

   if( hWnd )
      MonthCal_GetMinReqRect( hWnd, &rct );

   hb_reta( 4 );

   hb_storvni( rct.top,    -1, 1 );
   hb_storvni( rct.left,   -1, 2 );
   hb_storvni( rct.bottom, -1, 3 );
   hb_storvni( rct.right,  -1, 4 );
}

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_SIZERECTTOMIN )     //  hWnd,{ nTop, nLeft, nBottom, nRight }  -->  { nTop, nLeft, nBottom, nRight }
{
   HWND hWnd = ( HWND ) fw_parH( 1 );
   RECT rct;

   rct.top    = hb_parvni( 2, 1 );
   rct.left   = hb_parvni( 2, 2 );
   rct.bottom = hb_parvni( 2, 3 );
   rct.right  = hb_parvni( 2, 4 );

   if( hWnd )
      MonthCal_SizeRectToMin( hWnd, &rct );

   hb_reta( 4 );

   hb_storvni( rct.top,    -1, 1 );
   hb_storvni( rct.left,   -1, 2 );
   hb_storvni( rct.bottom, -1, 3 );
   hb_storvni( rct.right,  -1, 4 );
}

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_SETCURRENTVIEW )     //  hWnd, id
{
   MonthCal_SetCurrentView(( HWND ) fw_parH( 1 ), hb_parni( 2 ));
}

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_GETCURRENTVIEW )     //  hWnd -> id
{
   hb_retni(MonthCal_GetCurrentView(( HWND ) fw_parH( 1 )));
}

//----------------------------------------------------------------------------//

HB_FUNC( MONTHCAL_GETVIEWCHANGEVALUES )     //  NMVIEWCHANGE, @bOld, @nNew
{
   LPNMVIEWCHANGE lParam = (LPNMVIEWCHANGE) fw_parH( 1 );
   hb_storni(lParam->dwOldView, 2 );
   hb_storni(lParam->dwNewView, 3 );
}

#pragma ENDDUMP
I added some code to automatic resize to best dimension at init
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: About TCalendar

Post by Antonio Linares »

Antonino,

many thanks.

We have included the new DATA and the new Methods SetCurrentView() and GetCurrentView() for the next FWH build

When we run your posted code we get this:
Image
regards, saludos

Antonio Linares
www.fivetechsoft.com
AntoninoP
Posts: 347
Joined: Tue Feb 10, 2015 9:48 am
Location: Albenga, Italy
Contact:

Re: About TCalendar

Post by AntoninoP »

I just re-try with FiveWin 18.01
Image
in your screenshot these lines are not executed:

Code: Select all

      rc := MonthCal_SizeRectToMin( ::hWnd, GetClientRect( ::hWnd ) )
      SetWindowPos(::hWnd, 0, 0, 0, rc[4], rc[3], nOr(SWP_NOZORDER, SWP_NOMOVE))
      ::CoorsUpdate()
I did put them on New and on Initiate
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: About TCalendar

Post by Silvio.Falconi »

A question..
I have the calendar on my Project as you see on this picture
I use sample01.prg

, if I resize the splitter on right

Image

I wish the calendar resize until the splitter, showing 3 months per row or depending on the space created up to the splitter
How can I solve?
probable on dialog tcalendar not resize good?
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: About TCalendar

Post by Silvio.Falconi »

I tried

oPanel := ::oExBar:AddPanel( Upper( "Jump To Date" ), "d:\fwh\bitmaps\32x32\calendar.bmp", 480 )
// @ 40, 15 CALENDAR ::oDtPick VAR ::dDateStart OF oPanel PIXEL SIZE 220, 157 WEEKNUMBER DAYSTATE
::oDtPick := MyCalendar():New( 40, 10, { | u | If( PCount()==0, ::dDateStart, ::dDateStart:= u ) }, nil,oPanel, 700, 520,,,,, .F.,, .T.,, .F., .F.,,,,,, .F., .T., .T., .F. )
::oDtPick:bViewChanged := {|Self,nOld,nNew| iif(nNew<MCMV_YEAR,::SetCurrentView(MCMV_YEAR),) }

::oDtPick:bChange = { | o | ::ChangeDate( o ) }

but I have this result

Image

then if I resize the splitter

I have this result not seeing the sequence of the mounths

Image
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: About TCalendar

Post by Silvio.Falconi »

Now I tried with

::oDtPick := MyCalendar():New( 30, 1, { | u | If( PCount()==0, ::dDateStart, ::dDateStart:= u ) }, nil,oPanel, 200, 160,,,,, .F.,, .T.,, .F., .F.,,,,,, .F., .T., .T., .F. )


::oDtPick:bViewChanged := {|Self,nOld,nNew| iif(nNew<MCMV_YEAR,::SetCurrentView(MCMV_YEAR),) }
::oDtPick:bChange = { | o | ::ChangeDate( o ) }


oPanel:bResized := <||
local oRect :=oPanel:GetCliRect()
::oDtPick:nWidth := oRect:nRight
return nil
>

seem to run , but there is something bad
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: About TCalendar

Post by Silvio.Falconi »

the test of Antonino run ok
I add resizable system to resize the calendar

Image

Code: Select all

    #include <fivewin.ch>
    #include <calendar.ch>

    // MyCalendar
    #define MCMV_MONTH      0
    #define MCMV_YEAR       1
    #define MCMV_DECADE     2
    #define MCMV_CENTURY    3
    #define MCMV_MAX        MCMV_CENTURY

    // TEST CODE
    proc main()
       LOCAL oDlg, oMonth, dData1 := Date(),dData2 := Date(), oMonth2, dMese := Date()
       DEFINE DIALOG oDlg SIZE 700,400 PIXEL TRUEPIXEL;
          TITLE "Test MonthCal"   RESIZABLE
       //@ 10,10 CALENDAR oMonth VAR dData1,dData2 PIXEL NOTADAY NOTODAYCIRCLE SIZE 500,20
       oMonth := MyCalendar():New( 10, 10, { | u | If( PCount()==0, dData1, dData1:= u ) }, { | u | If( PCount()==0, dData2, dData2:= u ) },, 500, 20,,,,, .F.,, .T.,, .F., .F.,,,,,, .F., .T., .T., .F. )
       // only month calendar test
       //@ 210,10 CALENDAR oMonth2 VAR dMese PIXEL NOTADAY NOTODAYCIRCLE SIZE 700,20
       oMonth2 := MyCalendar():New( 210, 10, { | u | If( PCount()==0, dMese, dMese:= u ) }, nil,, 700, 160,,,,, .F.,, .T.,, .F., .F.,,,,,, .F., .T., .T., .F. )
       oMonth2:bViewChanged := {|Self,nOld,nNew| iif(nNew<MCMV_YEAR,::SetCurrentView(MCMV_YEAR),) }


                           oDlg:bResized  := <||
                           local oRect       := oDlg:GetCliRect()
                              oMonth2:nWidth     := oRect:nRight
                           return nil
                     >

       ACTIVATE DIALOG oDlg CENTERED;
       ON INIT (oMonth2:SetCurrentView(MCMV_YEAR),EVAL( oDlg:bResized))


    // MyCalendar
    #define SWP_NOSIZE        0x0001
    #define SWP_NOMOVE        0x0002
    #define SWP_NOZORDER      0x0004

    #define MCN_VIEWCHANGE      (-750)

    CLASS MyCalendar FROM TCalendar
       DATA bViewChanged

       METHOD New(...) CONSTRUCTOR

       METHOD HandleEvent( nMsg, nWParam, nLParam )
       METHOD Change()
       METHOD Notify( nIdCtrl, nPtrNMHDR )

       // use SetGet?
       METHOD Initiate( hDlg )
       METHOD SetCurrentView(id) INLINE MonthCal_SetCurrentView(::hWnd, id)
       METHOD GetCurrentView() INLINE MonthCal_GetCurrentView(::hWnd)

    endclass

    METHOD New(...) CLASS MyCalendar
       LOCAL rc
       ::Super:new(...)
       if !Empty( ::hWnd )
          rc := MonthCal_SizeRectToMin( ::hWnd, GetClientRect( ::hWnd ) )
          SetWindowPos(::hWnd, 0, 0, 0, rc[4], rc[3], nOr(SWP_NOZORDER, SWP_NOMOVE))
          ::CoorsUpdate()
       endif
    return Self

    METHOD Initiate( hDlg )  CLASS MyCalendar
       LOCAL rc
       ::Super:Initiate(hDlg)
       if !Empty( ::hWnd )
          rc := MonthCal_SizeRectToMin( ::hWnd, GetClientRect( ::hWnd ) )
          SetWindowPos(::hWnd, 0, 0, 0, rc[4], rc[3], nOr(SWP_NOZORDER, SWP_NOMOVE))
          ::CoorsUpdate()
       endif
    return nil

    METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS MyCalendar
       // TODO: Verify others messages
       if nMsg==WM_LBUTTONUP
          ::Super:HandleEvent( nMsg, nWParam, nLParam )
       endif
    return nil

    METHOD Change() CLASS MyCalendar
       local aTmp
       static dOldDate, dOldDate2

       if ::bChange != nil
          if ::lMultiselect
             aTmp := ::GetDateRange()
             if dOldDate != aTmp[1] .or. dOldDate2 != aTmp[2]
                Eval( ::bChange, Self )
                dOldDate := aTmp[1]
                dOldDate2 := aTmp[2]
             endif
          else
             if dOldDate != ::GetDate()
                Eval( ::bChange, Self )
                dOldDate = ::GetDate()
             endif
          endif
       endif
    return NIL

    METHOD Notify( nIdCtrl, nPtrNMHDR ) CLASS MyCalendar
       local nCode := GetNMHDRCode( nPtrNMHDR ), nOld, nNew
       if nCode == MCN_VIEWCHANGE
          if !empty(::bViewChanged)
             MonthCal_GetViewChangeValues(nPtrNMHDR, @nOld, @nNew)
             eval(::bViewChanged, self, nOld, nNew)
          endif
          return nil
       endif
    return ::Super:Notify( nIdCtrl, nPtrNMHDR )

    //----------------------------------------------------------------------------//

    #pragma BEGINDUMP
    #include <Windows.h>
    #include <CommCtrl.h>
    #include <hbapi.h>
    #include <hbdate.h>
    #include <fwh.h>

    //----------------------------------------------------------------------------//

    HB_FUNC( MONTHCAL_GETMINREQRECT )     //  hWnd  -->  { nTop, nLeft, nBottom, nRight }
    {
       HWND hWnd = ( HWND ) fw_parH( 1 );
       RECT rct;

       rct.top    = 0;
       rct.left   = 0;
       rct.bottom = 0;
       rct.right  = 0;

       if( hWnd )
          MonthCal_GetMinReqRect( hWnd, &rct );

       hb_reta( 4 );

       hb_storvni( rct.top,    -1, 1 );
       hb_storvni( rct.left,   -1, 2 );
       hb_storvni( rct.bottom, -1, 3 );
       hb_storvni( rct.right,  -1, 4 );
    }

    //----------------------------------------------------------------------------//

    HB_FUNC( MONTHCAL_SIZERECTTOMIN )     //  hWnd,{ nTop, nLeft, nBottom, nRight }  -->  { nTop, nLeft, nBottom, nRight }
    {
       HWND hWnd = ( HWND ) fw_parH( 1 );
       RECT rct;

       rct.top    = hb_parvni( 2, 1 );
       rct.left   = hb_parvni( 2, 2 );
       rct.bottom = hb_parvni( 2, 3 );
       rct.right  = hb_parvni( 2, 4 );

       if( hWnd )
          MonthCal_SizeRectToMin( hWnd, &rct );

       hb_reta( 4 );

       hb_storvni( rct.top,    -1, 1 );
       hb_storvni( rct.left,   -1, 2 );
       hb_storvni( rct.bottom, -1, 3 );
       hb_storvni( rct.right,  -1, 4 );
    }

    //----------------------------------------------------------------------------//

    HB_FUNC( MONTHCAL_SETCURRENTVIEW )     //  hWnd, id
    {
       MonthCal_SetCurrentView(( HWND ) fw_parH( 1 ), hb_parni( 2 ));
    }

    //----------------------------------------------------------------------------//

    HB_FUNC( MONTHCAL_GETCURRENTVIEW )     //  hWnd -> id
    {
       hb_retni(MonthCal_GetCurrentView(( HWND ) fw_parH( 1 )));
    }

    //----------------------------------------------------------------------------//

    HB_FUNC( MONTHCAL_GETVIEWCHANGEVALUES )     //  NMVIEWCHANGE, @bOld, @nNew
    {
       LPNMVIEWCHANGE lParam = (LPNMVIEWCHANGE) fw_parH( 1 );
       hb_storni(lParam->dwOldView, 2 );
       hb_storni(lParam->dwNewView, 3 );
    }

    #pragma ENDDUMP


When I put the resize system on sample01 ( tcalex) not run !!
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: About TCalendar

Post by Antonio Linares »

Antonino,

function MonthCal_SizeRectToMin() seems not to be working at all, in example:

rc := MonthCal_SizeRectToMin( ::hWnd, { 1, 1, 20, 20 } )
XBrowse( rc ) // you get { 1, 1, 20, 20 }

It seems to be working fine this way:
rc := MonthCal_GetMinReqRect( ::hWnd )
XBrowse( rc )
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply