Page 1 of 1

Small bug in TDPicker ?

Posted: Fri Sep 21, 2007 9:36 am
by StefanHaupt
Hello Antonio,

maybe I found a small bug in the DTPicker class. Empty dates are not correct shown.

This is my change in the method SetDate ():

Code: Select all

METHOD SetDate( dDate, lEmpty ) INLINE SetDatePick( ::hWnd, Year( dDate ),;
                                  Month( dDate ), Day( dDate ),;
                                  If( (lEmpty != nil .and. lEmpty) .or. Empty (dDate), 1, 0 ) )

Now empty dates correct displayed.

Could you please review it ?

Posted: Fri Sep 21, 2007 10:46 am
by Antonio Linares
Stefan,

Already included, thanks! :-)

Posted: Sat Sep 22, 2007 3:03 pm
by RAMESHBABU
Hello friends,

How to use DTPicker class in combination with SET DATE BRITISH ?
I believe that it respects only mm/dd/yyyy. SET DATE BRITISH does
not change the date format in DTPicker !. How to use this Class with
a dd/mm/yyyy format of dates.

Thanks

- Ramesh Babu P

Posted: Sun Sep 23, 2007 3:33 am
by nageswaragunupudi
DTPicker is a windows control and does not know our clipper/harbour setting of date format. DTPicker honours only the date format set in the windows system thro international settings.

But we can also set our own custom format this way by adding the following as the last line in Initiate method:

Code: Select all

// defines from commctrl.h
#define DTM_FIRST  0x1000
#define DTM_SETFORMAT DTM_FIRST + 5

SendMessage( ::hWnd, DTM_SETFORMAT, 0, ;
( LPARAM ) SET(_SET_DATEFORMAT) ) ;
[/code]

Posted: Sun Sep 23, 2007 7:49 am
by Antonio Linares
NageswaraRao,

Thanks!

We will wait to get some feedback from users before implementing it in the Class.

Posted: Sun Sep 23, 2007 8:46 am
by RAMESHBABU
Hello Mr.Nageswara Rao

Thanks for your solution.

Code: Select all

SendMessage( ::hWnd, DTM_SETFORMAT, 0, ; 
( LPARAM ) SET(_SET_DATEFORMAT) )
What is this ( LPARAM ) ?, Where it should be defined.

- Ramesh Babu P

Posted: Sun Sep 23, 2007 9:24 am
by Antonio Linares
Ramesh,

( LPARAM ) is not needed. Simply remove it

Posted: Sun Sep 23, 2007 9:39 am
by nageswaragunupudi
Sorry again.
Yes pls remove (LPARAM)

But the date format is to be given in this style

dd ( NOT DD ) for date.
MM ( mm is for minutes) for month
yyyy ( not YYYYY ) for year

we need to make appropriate Case conversion for dd, MM, and yyyy before sedning messsage :
for BRITISH it will be
SendMessage( ::hWnd, 4101, 0, 'dd/MM/yyyy')
for Indian/Italain
SendMessage( ::hWnd, 4101, 0, 'dd-MM-yyyy')

perhaps STRTRAN(LOWER(SET(_SET_DATEFORMAT)),'mm','MM') should be OK.

Actually i changed dtmpick.c and implemetned sendmessage in a c function there.

NageswaraRao

Posted: Sun Sep 23, 2007 10:09 am
by nageswaragunupudi
Further to the above;

If we want to use the short of long date formats that are set in the windows system, we can set the style of the TDtPicker object to DTS_SHORTDATEFOMAT (= 0 and is the default) or DTS_LONGDATEFORMAT (=4).

For blank dates 'or' the style with DTS_SHOWNONE (= 2 ) (eg. oDtp:nStyle := nor( oDtp:nStyle, 2 ).

Now, we can also use the same class for timeformats or composite DATETIME formats also.

for pure time format ( using DATETIME value ) :
oDtp:nStyle := DTS_TIMEFORMAT

(But this needs some changes in the datepick.c, as explained later).

We can also use this for full datetime values by setting our own format as 'dd/MM/yyy HH:mm:ss' ( or anything like that with any additional text also)

Changes to be made in datepick.c ( to properly handle time part of DATETIME values) :

While setting we need to set hour, mins, secs and millsecs also. Similary while getting, we need to set hour, mins, secs, millisecs also in the datetime value. These changes will make the class useful for picking date or time or datetime.

my revised code is like this :

SETDATETIMEPICK( hWnd, dDateTime, GTD_NONE )
GETDATETIMEPICK( hWnd ) --> dDateTime

Code: Select all

HB_FUNC ( SETDATEPICK ) // (hWnd, tDateTime, GTD_NONE )
{
   SYSTEMTIME  sysTime;
   PHB_ITEM    pDate;

   int         iYear, iMonth, iDay, iHour, iMinute, iSecs, iMilli ;
   DOUBLE      dSecs ;

   pDate             = hb_param( 2, HB_IT_DATE );
   hb_itemGetDT( pDate, &iYear, &iMonth, &iDay, &iHour, &iMinute, &dSecs );
   iSecs             = (int) dSecs;
   dSecs             -= (double) iSecs;
   dSecs             *= 1000.0;
   iMilli             =  (int) dSecs;

   sysTime.wYear         = iYear;
   sysTime.wMonth        = iMonth;
   sysTime.wDay          = iDay;
   sysTime.wDayOfWeek    = 0;
   sysTime.wHour         = iHour;
   sysTime.wMinute       = iMinute;
   sysTime.wSecond       = iSecs ;
   sysTime.wMilliseconds = iMilli ;

   SendMessage( ( HWND ) hb_parnl( 1 ), DTM_SETSYSTEMTIME, hb_parni( 3 ),
                ( LPARAM ) &sysTime );
}

HB_FUNC( GETDATEPICK ) // (hWnd)
   SYSTEMTIME st;

   DOUBLE   dSecs ;


   SendMessage( ( HWND ) hb_parnl( 1 ), DTM_GETSYSTEMTIME, 0, ( LPARAM ) &st );

   dSecs       = (DOUBLE) st.wSecond ;
   dSecs       += (DOUBLE) st.wMilliseconds * 0.001 ;

   hb_retdt( st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, dSecs, 0 ) ;
}
However millisecs are set to zero after the dtpicker class of windows is used. That information is lost, unless we save it and restore later.


NageswaraRao

Posted: Mon Sep 24, 2007 9:15 am
by nageswaragunupudi
Minimum and/or Maximum range also can be specified for dtpicker. The code i use for setting rage is this :

Code: Select all

// defines are in commctrl.ch
// DTM_SETRANGE 0x1004

void datetosystime( PHB_ITEM pDate, SYSTEMTIME * pst )
{

   int         iYear, iMonth, iDay, iHour, iMinute, iSecs, iMilli ;
   DOUBLE      dSecs ;

   hb_itemGetDT( pDate, &iYear, &iMonth, &iDay, &iHour, &iMinute, &dSecs );
   iSecs             = (int) dSecs;
   dSecs             -= (double) iSecs;
   dSecs             *= 1000.0;
   iMilli             =  (int) dSecs;

   pst->wYear         = iYear;
   pst->wMonth        = iMonth;
   pst->wDay          = iDay;
   pst->wDayOfWeek    = 0;
   pst->wHour         = iHour;
   pst->wMinute       = iMinute;
   pst->wSecond       = iSecs ;
   pst->wMilliseconds = iMilli ;

   return ;
}

HB_FUNC (DATETIMEPICK_SETRANGE) // ( hWnd, dMin, dMax )
{
   SYSTEMTIME st[2];
   DWORD flags = 0;
   PHB_ITEM pDate;

   if ( ISDATE(2) )
   {
      flags    = GDTR_MIN ;        // 1
      pDate    = hb_param ( 2, HB_IT_DATE ) ;
      datetosystime( pDate, &( st[0] ) ) ;
   }
   if ( ISDATE(3) )
   {
      flags    |= GDTR_MAX ;      // 2
      pDate    = hb_param ( 3, HB_IT_DATE ) ;
      datetosystime( pDate, &( st[1] ) ) ;
   }

   SendMessage( (HWND) hb_parnl( 1 ), DTM_SETRANGE, flags, ( LPARAM ) &st );
}
NageswaraRao