Pickdate part 2 – a control class in development

User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Flickering solved :-)

Simply add this style here:

::nStyle = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_BORDER, WS_CLIPCHILDREN )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Kleyber
Posts: 581
Joined: Tue Oct 11, 2005 11:28 am
Location: São Luiz, Brasil

Post by Kleyber »

Nagesh,
nageswaragunupudi wrote:GradientFill( hDC, 0, 0, ::nHeight, ::nWidth, { { 1, nRGB( 128, 217, 255 ), nRGB( 54, 147, 255 ) } } )

is functionally equivalent to

Gradient( hDC, { 0, 0, ::nHeight, ::nWidth }, nRGB( 128, 217, 255 ), nRGB( 54, 147, 255 ), .t. )

You may use simple Gradient function if you are using an older version of FWH
Thanks! It worked.

Regards,
Kleyber Derick

FWH / xHb / xDevStudio / SQLLIB
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Hello Antonio,
thank you for yur help with the buttons.

METHOD PreviousMonth() and NextMonth() are ready. So you can select a period which is in 2 years, like 1.12.2008 – 31.1.2009.

Regards,
Otto

Code: Select all

 #include "FiveWin.ch"
 //----------------------------------------------------------------------------//

function Main()

   local oWnd, oPickDate

   SET DATE FRENCH

   DEFINE WINDOW oWnd TITLE "Calendar"

   oPickDate := TPickDate():New( 10, 10,,, oWnd )

   oPickDate:bSelect = { | dStart, dEnd | MsgInfo( Str( dEnd - dStart + 1 ) + " days" ) }
   oPickDate:bPainted = { | hDC, dStart, dEnd | ;
                          oPickDate:Say( 17, 20, Str( dEnd - dStart + 1 ) + " days",,,, .T., .T. ) }

   oWnd:oClient = oPickDate

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT TestDialog()

return nil

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

function TestDialog()

   local oDlg, oPickDate
   local oGet1
   local oGet2
   local cStart
   local cEnde

   DEFINE DIALOG oDlg RESOURCE "Test"

   oPickDate = TPickDate():Redefine( 10, oDlg )

   REDEFINE GET oGet1 VAR cStart ID 4008 OF oDlg
   REDEFINE GET oGet2 VAR cEnde  ID 4009 OF oDlg
   REDEFINE BUTTON ID 4007 OF oDlg  ACTION (oDlg:END())
                                                                                //, MsgInfo( Str( dEnd - dStart + 1 ) + " days" )
   oPickDate:bSelect = { | dStart, dEnd |  cStart:=dtoc(dStart),oGet1:refresh(),cEnde:=dtoc(dEnd),oGet2:refresh() }

   ACTIVATE DIALOG oDlg CENTERED

return nil

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

CLASS TPickDate FROM TControl

   DATA   dStart, dEnd, dTemp, lMove
   DATA   nYear
   DATA   oBrushSunday, oBrushSelected, oFontHeader
   DATA   nLeftStart, nTopStart
   DATA   bSelect
   DATA   nStartMonat

   CLASSDATA lRegistered AS LOGICAL

   METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, nClrFore, nClrBack )
   METHOD Redefine( nId, oWnd )
   METHOD Paint()
   METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0
   METHOD Destroy()
   METHOD LButtonDown( nRow, nCol, nKeyFlags )
   METHOD LButtonUp( nRow, nCol, nKeyFlags )

   METHOD PreviousYear() INLINE ::nYear--, ::Refresh()
   METHOD NextYear() INLINE ::nYear++, ::Refresh()

   METHOD PreviousMonth()
   METHOD NextMonth()

   METHOD EraseBkGnd( hDC ) INLINE 0
   METHOD MouseMove( nRow, nCol, nKeyFlags )

ENDCLASS

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

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, nClrFore, nClrBack ) CLASS TPickDate

   local oCbx
   local cCombo

   DEFAULT nWidth  := 800,;
      nHeight := 300,;
      nLeft   := 0,;
      nTop    := 0,;
      nYear   := Year( Date() ),;
      oWnd    := GetWndDefault()

   ::lMove      = .F.
   ::nTopStart  = 60                            // for header
   ::nLeftStart = 150                           // col header

   ::nStartMonat := 0

   ::nTop       = nTop
   ::nLeft      = nLeft
   ::nBottom    = nTop + nHeight - 1
   ::nRight     = nLeft + nWidth - 1
   ::nYear      = Year( Date() )
   ::oWnd       = oWnd

   ::dStart := ::dEnd := ::dTemp := Date()

   ::nClrText   = nClrFore
   ::nClrPane   = nClrBack
   ::nStyle     = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_BORDER, WS_CLIPCHILDREN )

   DEFINE BRUSH ::oBrushSunday COLOR nRGB( 183, 249, 185 ) // Sundays column green brush
   DEFINE BRUSH ::oBrushSelected COLOR nRGB( 240, 232, 188 ) // Selected days orange brush

   DEFINE FONT ::oFont NAME "Tahoma" SIZE 0, -12 BOLD
   DEFINE FONT ::oFontHeader NAME "Tahoma" SIZE 0, -12

   #ifdef __XPP__
   DEFAULT ::lRegistered := .F.
   #endif

   ::Register()

   if ! Empty( oWnd:hWnd )
      ::Create()
      oWnd:AddControl( Self )
      @ 4.2,  5 BUTTON "<" OF Self SIZE 20, 20 ACTION  ::PreviousMonth()
      @ 4.2, 20 BUTTON ">" OF Self SIZE 20, 20 ACTION  ::NextMonth()
   else
      oWnd:DefControl( Self )
   endif

return self
//----------------------------------------------------------------------------//

METHOD Redefine( nId, oWnd ) CLASS TPickDate

   DEFAULT oWnd := GetWndDefault()
   ::nStartMonat := 0

   ::nId        = nId
   ::oWnd       = oWnd
   ::lMove      = .F.
   ::nTopStart  = 60                           // for header
   ::nLeftStart = 150                          // col header
   ::dStart := ::dEnd := ::dTemp := Date()
   ::nYear      = Year( Date() )

   DEFINE BRUSH ::oBrushSunday COLOR nRGB( 183, 249, 185 ) // Sundays column green brush
   DEFINE BRUSH ::oBrushSelected COLOR nRGB( 240, 232, 188 ) // Selected days orange brush

   DEFINE FONT ::oFont NAME "Tahoma" SIZE 0, -12 BOLD
   DEFINE FONT ::oFontHeader NAME "Tahoma" SIZE 0, -10

   REDEFINE BUTTON ID 4002 OF ::oWnd  ACTION ::PreviousMonth()
   REDEFINE BUTTON ID 4003 OF ::oWnd  ACTION ::NextMonth()

   ::SetColor( 0, 0 )

   ::Register()

   oWnd:DefControl( Self )

return Self
//----------------------------------------------------------------------------//

METHOD LButtonUp( nRow, nCol, nKeyFlags ) CLASS TPickDate

   if ValType( ::bSelect ) == "B"
      Eval( ::bSelect, Min( ::dStart, ::dEnd ), Max( ::dStart, ::dEnd ), Self )
   endif

   ::lMove := .F.

return Super:LButtonUp( nRow, nCol, nKeyFlags )
//-----------------------------------------------------------------//

 METHOD PreviousMonth()
    ::nStartMonat--
    IF ::nStartMonat < 0
       ::nStartMonat := 11
       ::nYear--
    ENDIF

    ::Refresh()
 return 0
//-----------------------------------------------------------------//

 METHOD NextMonth()
    ::nStartMonat++
    IF ::nStartMonat > 11
       ::nStartMonat := 0
       ::nYear++
    ENDIF
    ::Refresh()
 return 0
//-----------------------------------------------------------------//

METHOD LButtonDown( nRow, nCol, nKeyFlags ) CLASS TPickDate

   local nClickRow := Int( ( nRow - ::nTopStart ) / ( ( ::nHeight - ::nTopStart ) / 13 ) )
   local nDay   := 0
   local cYear
   local nMonth := 0

   cYear    := STR( ::nYear, 4 )
   nMonth := nClickRow + ::nStartMonat
   IF nMonth > 12
      nMonth   := nMonth - 12
      cYear    := STR( ::nYear + 1, 4 )
   ENDIF

   nDay   := Int( ( nCol - ::nLeftStart ) / ( ( ::nWidth - ::nLeftStart ) / 37 ) ) - ;
      DoW( RegionDate( nMonth,cYear ) ) + 1

   if nDay > 0 .and. nClickRow > 0              // to work with valid dates only
      ::dStart := CToD( AllTrim( AllTrim( Str( nDay ) )+ "/"  + Str( nMonth ) )  + "/" + cYear )
      ::lMove  := .T.
      ::Refresh( .F. )
   endif

return Super:LButtonDown( nRow, nCol, nKeyFlags )
//-----------------------------------------------------------------//

METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TPickDate

   local nRowMouse := Int( ( nRow - ::nTopStart ) / ( ( ::nHeight - ::nTopStart ) / 13 ) )
   local nDay   := 0
   local dEnd
   local cYear
   local nMonth

   cYear  := STR( ::nYear, 4 )
   nMonth := nRowMouse + ::nStartMonat
   IF nMonth > 12
      nMonth   := nMonth - 12
      cYear    := STR( ::nYear+1, 4 )
   ENDIF

   nDay   := Int( ( nCol - ::nLeftStart ) / ( ( ::nWidth - ::nLeftStart ) / 37 ) ) - ;
      DoW( RegionDate( nMonth, cYear ) ) + 1

   if nDay > 0 .and. nRowMouse  > 0             // to work with valid dates only

      dEnd = CToD( AllTrim( Str( nDay ) ) + "/" + AllTrim( Str( nMonth ) ) + "/" + cYear )

      if ! Empty( dEnd ) .and. dEnd != ::dTemp  // for reducing continuous refreshes
         ::dTemp := dEnd
         ::dEnd = dEnd
         ::Refresh( .F. )

         if ValType( ::bChange ) == "B"
            Eval( ::bChange, Min( ::dStart, ::dEnd ), Max( ::dStart, ::dEnd ), Self )
         endif

      endif
   endif

return Super:MouseMove( nRow, nCol, nKeyFlags )

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

METHOD Paint() CLASS TPickDate
   local aInfo := ::DispBegin()
   local hDC := ::hDC, cDay, nDay, n, dDate, nColStep, nRowStep
   local dTmpDate, nClickRow := 0, nLeftCol := 0
   local nMonth := 0
   local cYear  := Str( ::nYear, 4 )
   local nTPickRow := 0

   nRowStep = ( ::nHeight - ::nTopStart ) / 13

   GradientFill( hDC, 0, 0, ::nHeight, ::nWidth, { { 1, nRGB( 128, 217, 255 ), nRGB( 54, 147, 255 ) } } )


   dDate = RegionDate(1 + ::nStartMonat, cYear )
   dDate += 8 - DoW( dDate )

   nColStep = ( ::nWidth - ::nLeftStart ) / 37

   GradientFill( hDC, 0, 0, nRowStep - 1, ::nWidth, { { 1, nRGB( 128, 217, 255 ), nRGB( 54, 147, 255 ) } } )

   ::Say( ( ::nTopStart  + ( nRowStep / 2 ) - ( ::oFont:nHeight / 2 )),;
      ( ( ::nLeftStart + nColStep ) / 2 ) - ( GetTextWidth( hDC, Str( ::nYear, 4 ), ::oFont:hFont ) / 2 ),;
      Str( ::nYear, 4 ),,, ::oFont, .T., .T. )

   // Paint Sunday background color
   for n = 1 to 36 step 7
      FillRect( hDC, { 0, ::nLeftStart + ( nColStep * n ),;
         ::nHeight - 1, ::nLeftStart + ( nColStep * ( n + 1 ) ) }, ::oBrushSunday:hBrush )
   next

   for nTPickRow = 1 to 12
      cYear := STR( ::nYear, 4 )
      nMonth := nTPickRow + ::nStartMonat
      IF nMonth > 12
         nMonth := nMonth - 12
         cYear := STR( ::nYear + 1, 4 )
      ENDIF

      ::Line( ::nTopStart + nTPickRow * nRowStep, 0,(::nTopStart  + nTPickRow * nRowStep), ::nWidth - 1 )

      ::Say( ::nTopStart + nTPickRow * nRowStep + ( nRowStep / 2 ) - ( ::oFont:nHeight / 2 ), 3,;
         cMonth( RegionDate( nMonth , cYear))   ,,, ::oFont, .T., .T. )
   next

   // fill selected days
   if ::lMove
      dTmpDate = Min( ::dStart, ::dEnd )

      while dTmpDate <= Max( ::dStart, ::dEnd )
         cYear := STR( (year( dTmpDate)), 4 )
         nTPickRow  := Month( dTmpDate ) - ::nStartMonat

        IF nTPickRow  < 1
            nTPickRow  :=  Month( dTmpDate )  + 12 - ::nStartMonat
            cYear := STR( (year( dTmpDate) ), 4 )
         ENDIF

         nLeftCol = ::nLeftStart + ( nColStep * ( DOW( RegionDate( (Month( dTmpDate ) ), cYear ) ) ) ) + ;
            nColStep * ( Day( dTmpDate ) - 1 )

         FillRect( hDC, { ::nTopStart + (nTPickRow)* nRowStep + 1,;
            nLeftCol, ::nTopStart + (nTPickRow) * nRowStep + nRowStep,;
            nLeftCol + nColStep}, ::oBrushSelected:hBrush )
         dTmpDate++
      end

   endif

   // Draw days
   for n = 1 to 36
      ::Line( 0, ::nLeftStart + ( nColStep * n ), ::nHeight - 1, ::nLeftStart + ( nColStep * n ) )
      cDay = SubStr( CDoW( dDate++ ), 1, 2 )

      ::Say( ( ::nTopStart + nRowStep * 0.4 ),;
         ::nLeftStart + ( nColStep * n ) + ( nColStep / 2 ) - ( GetTextWidth( hDC, cDay, ::oFont:hFont ) / 2 ) + 1,;
         cDay, 0, 0, ::oFontHeader, .T., .T. )
   next

   // Draw months  - day rows
   for nTPickRow = 1 to 12
      cYear  := STR(::nYear, 4 )
      nMonth := nTPickRow + ::nStartMonat
      IF nMonth > 12
         nMonth   := nMonth - 12
         cYear    := STR(::nYear + 1, 4 )
      ENDIF

      dDate = RegionDate(nMonth, cYear )
      nDay = DoW( dDate )

      while Month( dDate ) == nMonth
         cDay = AllTrim( Str( Day( dDate ) ) )
         ::Say( ( ::nTopStart  + nTPickRow * nRowStep + ( nRowStep * 0.4 ) ),;
            ::nLeftStart + ( nColStep * nDay++ ) + ( nColStep / 2 ) - ( GetTextWidth( hDC, cDay, ::oFont:hFont ) / 2 ) + 1,;
            cDay, 0, 0, ::oFontHeader, .T., .T. )
         dDate++
      end
   next

   if ValType( ::bPainted ) == "B"
      Eval( ::bPainted, hDC, Min( ::dStart, ::dEnd ), Max( ::dStart, ::dEnd ), Self )
   endif

   ::DispEnd( aInfo )

return 0

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

METHOD Destroy() CLASS TPickDate

   ::oBrushSunday:End()
   ::oBrushSelected:End()
   ::oFontHeader:End()

return Super:Destroy()

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

function RegionDate( nMonth, cYear )

return CToD( "01/" + AllTrim( Str( nMonth ) ) + "/" +  cYear )

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







rc-file


LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US

TEST DIALOG DISCARDABLE 12, 26, 544, 363
STYLE WS_POPUP|DS_MODALFRAME|WS_CAPTION|WS_SYSMENU|WS_VISIBLE
CAPTION "Select a period"
FONT 8, "MS Sans Serif"
BEGIN
  CONTROL "", 10, "TPickDate", 0x00800000, 12, 64, 496, 247
  CONTROL "OK", 4007, "Button", WS_TABSTOP, 464, 320, 45, 15
  CONTROL "Editbox", 4008, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 180, 324, 72, 12
  CONTROL "Editbox", 4009, "Edit", ES_AUTOHSCROLL|WS_BORDER|WS_TABSTOP, 256, 324, 72, 12
  CONTROL "Nächtigungsstatistik", 4001, "Static", WS_GROUP, 16, 28, 188, 8
  CONTROL "-", 4002, "Button", WS_TABSTOP, 16, 48, 16, 15
  CONTROL "+", 4003, "Button", WS_TABSTOP, 36, 48, 16, 15
END







User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Dear Otto,

This is the right way to create the buttons for REDEFINE. The BUTTONs don't have to be REDEFINEd. See the implementation (redefined) of method Initiate():

Code: Select all

#include "FiveWin.ch" 

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

function Main() 

   local oWnd, oPickDate 

   SET DATE FRENCH 

   DEFINE WINDOW oWnd TITLE "Calendar" 

   oPickDate := TPickDate():New( 10, 10,,, oWnd ) 

   oPickDate:bSelect = { | dStart, dEnd | MsgInfo( Str( dEnd - dStart + 1 ) + " days" ) }
   oPickDate:bPainted = { | hDC, dStart, dEnd | ;
                          oPickDate:Say( 17, 20, Str( dEnd - dStart + 1 ) + " days",,,, .T., .T. ) }

   oWnd:oClient = oPickDate 

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT TestDialog()
   
return nil 

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

function TestDialog()

   local oDlg, oPickDate
   
   DEFINE DIALOG oDlg RESOURCE "Test"
   
   oPickDate = TPickDate():Redefine( 10, oDlg )

   oPickDate:bSelect = { | dStart, dEnd | MsgInfo( Str( dEnd - dStart + 1 ) + " days" ) }
   
   ACTIVATE DIALOG oDlg CENTERED
   
return nil   

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


CLASS TPickDate FROM TControl 

   DATA   dStart, dEnd, dTemp, lMove 
   DATA   nYear 
   DATA   oBrushSunday, oBrushSelected, oFontHeader 
   DATA   nLeftStart, nTopStart 
   DATA   bSelect 

   CLASSDATA lRegistered AS LOGICAL 

   METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, nClrFore, nClrBack ) 
   METHOD Redefine( nId, oWnd )
   METHOD Initiate( hDlg )
   METHOD Paint() 
   METHOD Display() INLINE ::BeginPaint(), ::Paint(), ::EndPaint(), 0 
   METHOD Destroy() 
   METHOD LButtonDown( nRow, nCol, nKeyFlags ) 
   METHOD LButtonUp( nRow, nCol, nKeyFlags ) 
   METHOD PreviousYear() INLINE ::nYear--, ::Refresh() 
   METHOD NextYear() INLINE ::nYear++, ::Refresh() 
   METHOD EraseBkGnd( hDC ) INLINE 0 
   METHOD MouseMove( nRow, nCol, nKeyFlags ) 

ENDCLASS 

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

METHOD New( nTop, nLeft, nWidth, nHeight, oWnd, nYear, nClrFore, nClrBack ) CLASS TPickDate 

   DEFAULT nWidth  := 800,; 
           nHeight := 300,; 
           nLeft   := 0,; 
           nTop    := 0,; 
           nYear   := Year( Date() ),; 
           oWnd    := GetWndDefault() 

   ::lMove      = .F. 
   ::nTopStart  = 60                           // for header 
   ::nLeftStart = 150                          // col header 

   ::nTop       = nTop 
   ::nLeft      = nLeft 
   ::nBottom    = nTop + nHeight - 1 
   ::nRight     = nLeft + nWidth - 1 
   ::nYear      = Year( Date() ) 
   ::oWnd       = oWnd 

   ::dStart := ::dEnd := ::dTemp := Date() 

   ::nClrText   = nClrFore 
   ::nClrPane   = nClrBack 
   ::nStyle     = nOr( WS_CHILD, WS_VISIBLE, WS_TABSTOP, WS_BORDER, WS_CLIPCHILDREN ) 
   
   DEFINE BRUSH ::oBrushSunday COLOR nRGB( 183, 249, 185 ) // Sundays column green brush 
   DEFINE BRUSH ::oBrushSelected COLOR nRGB( 240, 232, 188 ) // Selected days orange brush

   DEFINE FONT ::oFont NAME "Tahoma" SIZE 0, -12 BOLD 
   DEFINE FONT ::oFontHeader NAME "Tahoma" SIZE 0, -12 

   #ifdef __XPP__ 
      DEFAULT ::lRegistered := .F. 
   #endif 

   ::Register() 

   if ! Empty( oWnd:hWnd ) 
      ::Create() 
      oWnd:AddControl( Self ) 
      @ 4.2,  5 BUTTON "<" OF Self SIZE 20, 20 ACTION ::PreviousYear()
      @ 4.2, 20 BUTTON ">" OF Self SIZE 20, 20 ACTION ::NextYear()
   else 
      oWnd:DefControl( Self ) 
   endif 

return self 

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

METHOD Redefine( nId, oWnd ) CLASS TPickDate

   DEFAULT oWnd := GetWndDefault()
   
   ::nId        = nId
   ::oWnd       = oWnd
   ::lMove      = .F. 
   ::nTopStart  = 60                           // for header 
   ::nLeftStart = 150                          // col header 
   ::dStart := ::dEnd := ::dTemp := Date() 
   ::nYear      = Year( Date() ) 

   DEFINE BRUSH ::oBrushSunday COLOR nRGB( 183, 249, 185 ) // Sundays column green brush 
   DEFINE BRUSH ::oBrushSelected COLOR nRGB( 240, 232, 188 ) // Selected days orange brush

   DEFINE FONT ::oFont NAME "Tahoma" SIZE 0, -12 BOLD 
   DEFINE FONT ::oFontHeader NAME "Tahoma" SIZE 0, -12 
   
   ::SetColor( 0, 0 )
   
   ::Register()   

   oWnd:DefControl( Self )
   
return Self

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

METHOD Initiate( hDlg ) CLASS TPickDate

   Super:Initiate( hDlg )
   
   @ 4.2,  5 BUTTON "<" OF Self SIZE 20, 20 ACTION ::PreviousYear()
   @ 4.2, 20 BUTTON ">" OF Self SIZE 20, 20 ACTION ::NextYear()

return nil   

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


METHOD Paint() CLASS TPickDate
 
   local aInfo := ::DispBegin() 
   local hDC := ::hDC, cDay, nDay, n, dDate, nColStep, nRowStep 
   local dTmpDate, nMonth := 0, nLeftCol := 0

   FillRect( hDC, GetClientRect( ::hWnd ), ::oBrush:hBrush ) 

   nRowStep = ( ::nHeight - ::nTopStart ) / 13 

   GradientFill( hDC, 0, 0, ::nHeight, ::nWidth, { { 1, nRGB( 128, 217, 255 ), nRGB( 54, 147, 255 ) } } ) 

   dDate = CToD( "01/01/" + Str( ::nYear, 4 ) )
   dDate += 8 - DoW( dDate )

   nColStep = ( ::nWidth - ::nLeftStart ) / 37 

   GradientFill( hDC, 0, 0, nRowStep - 1, ::nWidth, { { 1, nRGB( 128, 217, 255 ), nRGB( 54, 147, 255 ) } } ) 

   ::Say( ( ::nTopStart  + ( nRowStep / 2 ) - ( ::oFont:nHeight / 2 )),; 
          ( ( ::nLeftStart + nColStep ) / 2 ) - ( GetTextWidth( hDC, Str( ::nYear, 4 ), ::oFont:hFont ) / 2 ),; 
          Str( ::nYear, 4 ),,, ::oFont, .T., .T. ) 

   // Paint Sunday background color 
   for n = 1 to 36 step 7 
      FillRect( hDC, { 0, ::nLeftStart + ( nColStep * n ),;
                ::nHeight - 1, ::nLeftStart + ( nColStep * ( n + 1 ) ) }, ::oBrushSunday:hBrush ) 
   next 

   for nMonth = 1 to 12 
       ::Line( ::nTopStart + nMonth * nRowStep, 0,(::nTopStart  + nMonth * nRowStep), ::nWidth - 1 ) 
       ::Say( ::nTopStart + nMonth * nRowStep + ( nRowStep / 2 ) - ( ::oFont:nHeight / 2 ), 3, cMonth( RegionDate(nMonth, Str( Year( Date() ), 4 )))   ,,, ::oFont, .T., .T. ) 
   next 

   // fill selected days
   if ::lMove
      dTmpDate = Min( ::dStart, ::dEnd ) 

      while dTmpDate <= Max( ::dStart, ::dEnd )
         nMonth = Month( dTmpDate ) 
         nLeftCol = ::nLeftStart + ( nColStep * ( DOW( RegionDate( nMonth, Str( ::nYear, 4 ) ) ) ) ) + ; 
                    nColStep * ( Day( dTmpDate ) - 1 ) 
         FillRect( hDC, { ::nTopStart + month(dTmpDate) * nRowStep + 1,; 
                   nLeftCol, ::nTopStart + Month( dTmpDate ) * nRowStep + nRowStep,; 
                   nLeftCol + nColStep}, ::oBrushSelected:hBrush ) 
         dTmpDate++ 
      end 

   endif 

   // Draw days 
   for n = 1 to 36 
      ::Line( 0, ::nLeftStart + ( nColStep * n ), ::nHeight - 1, ::nLeftStart + ( nColStep * n ) ) 
      cDay = SubStr( CDoW( dDate++ ), 1, 2 ) 

      ::Say( ( ::nTopStart + nRowStep * 0.4 ),; 
         ::nLeftStart + ( nColStep * n ) + ( nColStep / 2 ) - ( GetTextWidth( hDC, cDay, ::oFont:hFont ) / 2 ) + 1,; 
         cDay, 0, 0, ::oFont, .T., .T. ) 
   next 

   // Draw months 
   for nMonth = 1 to 12 
      dDate = RegionDate(nMonth,Str( ::nYear, 4 ) ) 
      nDay = DoW( dDate ) 

      while Month( dDate ) == nMonth 
         cDay = AllTrim( Str( Day( dDate ) ) ) 
         ::Say( ( ::nTopStart  + nMonth * nRowStep + ( nRowStep * 0.4 ) ),; 
            ::nLeftStart + ( nColStep * nDay++ ) + ( nColStep / 2 ) - ( GetTextWidth( hDC, cDay, ::oFont:hFont ) / 2 ) + 1,; 
            cDay, 0, 0, ::oFontHeader, .T., .T. ) 
         dDate++ 
      end 
   next 

   if ValType( ::bPainted ) == "B"
      Eval( ::bPainted, hDC, Min( ::dStart, ::dEnd ), Max( ::dStart, ::dEnd ), Self )
   endif   

   ::DispEnd( aInfo ) 

return 0 

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

METHOD Destroy() CLASS TPickDate 

   ::oBrushSunday:End()
   ::oBrushSelected:End()
   ::oFontHeader:End() 
   
return Super:Destroy() 

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

METHOD LButtonDown( nRow, nCol, nKeyFlags ) CLASS TPickDate 

   local nMonth := Int( ( nRow - ::nTopStart ) / ( ( ::nHeight - ::nTopStart ) / 13 ) ) 
   local nDay   := Int( ( nCol - ::nLeftStart ) / ( ( ::nWidth - ::nLeftStart ) / 37 ) ) - ;
                   DoW( RegionDate( nMonth, Str( ::nYear, 4 ) ) ) + 1 

   if nDay > 0 .and. nMonth > 0  // to work with valid dates only
      ::dStart := CToD( AllTrim( AllTrim( Str( nDay ) )+ "/"  + Str( nMonth ) )  + "/" + Str( ::nYear, 4 ) ) 
      ::lMove  := .T. 
      ::Refresh( .F. ) 
   endif 

return Super:LButtonDown( nRow, nCol, nKeyFlags ) 

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

METHOD LButtonUp( nRow, nCol, nKeyFlags ) CLASS TPickDate 

   if ValType( ::bSelect ) == "B"
      Eval( ::bSelect, Min( ::dStart, ::dEnd ), Max( ::dStart, ::dEnd ), Self )
   endif   

   ::lMove := .F. 
   
return Super:LButtonUp( nRow, nCol, nKeyFlags ) 

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

METHOD MouseMove( nRow, nCol, nKeyFlags ) CLASS TPickDate
 
   local nMonth := Int( ( nRow - ::nTopStart ) / ( ( ::nHeight - ::nTopStart ) / 13 ) ) 
   local nDay   := Int( ( nCol - ::nLeftStart ) / ( ( ::nWidth - ::nLeftStart ) / 37 ) ) - ; 
                   DoW( RegionDate( nMonth, Str( ::nYear, 4 ) ) ) + 1 
   local dEnd                

   if ::lMove .and. nDay > 0 .and. nMonth > 0  // to work with valid dates only
      dEnd = CToD( AllTrim( Str( nDay ) ) + "/" + AllTrim( Str( nMonth ) ) + "/" + Str( ::nYear, 4 ) ) 

      if ! Empty( dEnd ) .and. dEnd != ::dTemp     // for reducing continuous refreshes 
         ::dTemp := dEnd 
         ::dEnd = dEnd
         ::Refresh( .F. )
         if ValType( ::bChange ) == "B"
            Eval( ::bChange, Min( ::dStart, ::dEnd ), Max( ::dStart, ::dEnd ), Self )
         endif    
      endif 
   endif   

return Super:MouseMove( nRow, nCol, nKeyFlags ) 

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

function RegionDate( nMonth, cYear ) 

return CToD( "01/" + AllTrim( Str( nMonth ) ) + "/" +  cYear ) 

//-----------------------------------------------------------------// 
regards, saludos

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

Post by Antonio Linares »

The reason to create the buttons from the method Initiate() is because from method Redefine() we still don't have a valid windows handle for pickdate, so we can't create childs controls on top of it.

The method Initiate() is the first method that is processed for redefined controls to get a windows valid handle, so once Super:Initiate( hDlg ) is called, then the <control>:hWnd is valid.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Hello Antonio,
Thank you.
But now I have again the problem with the flickering if it is redefine.

Have you had a look into previous/next month. Do you think this is ok or do you have a better solution.

Regards,
Otto



rc-file



TEST DIALOG DISCARDABLE 12, 26, 544, 363
STYLE WS_POPUP|DS_MODALFRAME|WS_CAPTION|WS_SYSMENU|WS_VISIBLE|WS_CLIPCHILDREN
CAPTION "Select a period"
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Otto,

You have to give the style WS_CLIPCHILDREN to the control TPickDate itself, not to the dialogbox:

CONTROL "", 10, "TPickDate", 0 | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN, 12, 64, 496, 247
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Antonio, thank you.
User avatar
José Vicente Beltrán
Posts: 279
Joined: Mon Oct 10, 2005 8:55 am
Location: Algeciras, España
Contact:

To Otto and all

Post by José Vicente Beltrán »

Hi Otto, thanks for the idea of the TPickDate

my little contribution over the class include a note book EXE and him PRG and RC, both respectively for use alone (the EXE) or built in your application code.

My code is old but valid how exercise.

http://cid-6be220caaa0bc6fd.skydrive.li ... 0ANUAL.zip

:shock:
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Post by Otto »

Thank you José.

To use TPickdate to select and show dates and periods for a calendar is good adoption.
Thank you for sharing. I will study your code.
Regards,
Otto
Post Reply