View Issue Details

IDProjectCategoryView StatusLast Update
0001614JEDI VCL00 JVCL Componentspublic2004-04-11 02:21
ReporterglchapmanAssigned Touser72 
Status resolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0001614: D5: TJvDateTimePicker.MsgSetDateTime: invalid call to CheckNullValue
DescriptionBefore returning, TJvDateTimePicker.MsgSetDateTime calls CheckNullValue, which checks the current value of the DateTime property to see if it is the null value. Unfortunately (in Delphi 5 anyway), TCommonCalender.SetDateTime does not update the FDateTime field until after MsgSetDateTime has returned. Thus the CheckNullValue call checks the old DateTime rather than the one being set through MsgSetDateTime.
Additional InformationMy inclination would be to fix this by changing CheckNullValue so that it accepts a datetime parameter as the value to test. However, changing CheckNullValue's signature would break any subclasses which have overridden it. I'm not sure what the JVCL policy is on that sort of thing, so I'll leave it to you to determine the best fix.
TagsNo tags attached.



2004-04-10 00:22



add overloaded CheckNullValue:

    function CheckNullValue: Boolean; overload;virtual;
    function CheckNullValue(const ANullText, AFormat: string; AKind: TDateTimeKind; ADateTime, ANullDate: TDateTime): Boolean;overload;virtual;


function TJvDateTimePicker.CheckNullValue: Boolean;
  Result := CheckNullValue(NullText, Format, Kind, DateTime, NullDate);

function TJvDateTimePicker.CheckNullValue(const ANullText, AFormat: string;
  AKind: TDateTimeKind; ADateTime, ANullDate: TDateTime): Boolean;
 // Warren added NullText length check so that this feature can be disabled if not used!
   if Length(ANullText) = 0 then begin
        Result := false;
   end else
       Result := ((AKind = dtkDate) and (Trunc(ADateTime) = Trunc(ANullDate)) or
    ((AKind = dtkTime) and WithinDelta(ADateTime, ANullDate)));

  if Result then
    SendMessage(Handle, DTM_SETFORMAT, 0, Integer(PChar(ANullText)))
    SendMessage(Handle, DTM_SETFORMAT, 0, Integer(PChar(AFormat)));

change MsgSetDateTime:

function TJvDateTimePicker.MsgSetDateTime(Value: TSystemTime): Boolean;
  Result := inherited MsgSetDateTime(Value);
  CheckNullValue(NullText, Format, Kind, SystemTimeToDateTime(Value), NullDate);

Would that work?


2004-04-10 07:04

viewer   ~0003783

It works, but there is still potential breakage of subclasses since an overridden CheckNullValue(void) will no longer be called when processing MsgSetDateTime. Rather than that silent, run-time breakage, I would prefer an explicit compile-time breakage through changing the signature of CheckNullValue. It should be a trivial change for any subclass to adapt to the new signature.


2004-04-10 07:05

reporter   ~0003784

Damn, forgot to log in again. The previous comment was by me.


2004-04-10 07:23

reporter   ~0003785

Thinking a little more, how about using your suggested fix, but removing the virtual from the first (no parameters) overload of CheckNullValue. This would compile-time break any subclasses which overrode CheckNullValue (forcing them to adopt to the new virtual signature), but would allow any subclasses which simply called CheckNullValue() to compile without change.


2004-04-10 14:13


Sounds OK to me. I'll try it and see what happens...


2004-04-11 02:21


Seems to work fine. Update in CVS

Issue History

Date Modified Username Field Change
2004-04-09 17:47 glchapman New Issue
2004-04-10 00:22 user72 Note Added: 0003771
2004-04-10 00:24 user72 Status new => feedback
2004-04-10 07:04 anonymous Note Added: 0003783
2004-04-10 07:05 glchapman Note Added: 0003784
2004-04-10 07:23 glchapman Note Added: 0003785
2004-04-10 14:13 user72 Note Added: 0003791
2004-04-11 02:21 user72 Status feedback => resolved
2004-04-11 02:21 user72 Resolution open => fixed
2004-04-11 02:21 user72 Assigned To => user72
2004-04-11 02:21 user72 Note Added: 0003794