DateTimePicker change available in EditFocusChange?

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
jonhn
Posts: 86
Joined: Thu Feb 01, 2018 8:04 am

DateTimePicker change available in EditFocusChange?

Post by jonhn »

Greetings!

Is it possible to get a DTP focus change in the EditFocusChange? Or is it available via the DateTimeSelectionChanged function? Or maybe there is another function I haven't found yet?

I simply want the user to set two dates and when leaving the second date field to "do somestuff".

When using DateTimeSelectionChanged I can get the changed contents, but every time a different date is selected this method fires... I only want it after losing focus on that control.

There is no GotFocus property for oControl if I try this below, but maybe it is a syntax error? Or maybe I'm declaring it as the wrong type?

LOCAL oControl AS OBJECT
oControl := oDateTimeSelectionEvent:Control
lGotFocus := IIf(oDateTimeSelectionEvent == NULL_OBJECT, FALSE, oControl:GotFocus)

After trying for a while I think it is why I originally used Willies DateSLE for this function, but maybe it is different with X#... hopefully.

Thank you.
Jonathan
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

DateTimePicker change available in EditFocusChange?

Post by ic2 »

Hello Jonathan,

I think this is about what you want, this sets the second date (to) to the first date if it's before the first date

Code: Select all

METHOD DateTimeSelectionChanged(oDateTimeSelectionEvent) CLASS MyWindow
//#s After selecting start date, adapts end date

	SUPER:DateTimeSelectionChanged(oDateTimeSelectionEvent)
	IF  oDateTimeSelectionEvent:Control:NameSym==#DateFrom
		IF SELF:oDCDateTo:SelectedDate<SELF:oDCDateFrom:SelectedDate
			SELF:oDCDateTo:SelectedDate:= SELF:oDCDateFrom:SelectedDate
		ENDIF
       ENDIF
RETURN NIL
Dick
User avatar
robert
Posts: 4225
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

DateTimePicker change available in EditFocusChange?

Post by robert »

Jonathan,
The DateTimeSelectionChanged event is created when the control sends DTN_DATETIMECHANGE.
https://learn.microsoft.com/en-us/windo ... timechange
A quick search online shows that the following messages are sent when the control gets / loses focus:
NM_SETFOCUS and NM_KILLFOCUS.
In the VO GUI classes these events are not yet captured.
You can overwrite the ControlNotify() method of the Window class to handle these and maybe delegate these messages to the ControlFocusChange event handler

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
jonhn
Posts: 86
Joined: Thu Feb 01, 2018 8:04 am

DateTimePicker change available in EditFocusChange?

Post by jonhn »

Thank you Robert (and Dick for the suggestion)

Robert - Is this below close to what you meant? There was no existing method so I created one and it does intercept the event, but of course my Textboxes mess with the focus and I end up with a problem. haha.

If I'm on the right track, the next step is to notify the ControlFocusChange of the Window that this control lost focus, right?

To do this, what message do I put in the call to SELF:ControlFocusChange('VO.ControlFocusChangeEvent')
(This is where I am currently stuck trying to figure out how to form the VO.ControlFocusChangeEvent)

THIS IS THE CONTROLNOTIFY I CAME UP WITH

VIRTUAL METHOD ControlNotify(oControlNotifyEvent) AS USUAL CLIPPER
LOCAL oControl AS Control

oControl := IIf(oControlNotifyEvent == NULL_OBJECT, NULL_OBJECT, oControlNotifyEvent:Control)

SUPER:ControlNotify(oControlNotifyEvent)

IF oControl != NULL_OBJECT .and. oControl:NameSym =#DTPInv_Date .and. oControlNotifyEvent:NotifyCode == NM_KILLFOCUS
textbox{SELF:owner ,"You messed with Date# 1",oControl:Name }:show()
// Send notification message to ControlFocuschange that the DTP was used and no longer has focus.
ENDIF

IF oControl != NULL_OBJECT .and. oControl:NameSym =#DTPRet_Date .and. oControlNotifyEvent:NotifyCode == NM_KILLFOCUS
textbox{,"You messed with Date# 2",oControl:Name }:show()
// Send notification message TO ControlFocuschange that the DTP was used and no longer has focus.
ENDIF
RETURN NIL

Many thanks!
Jonathan
User avatar
robert
Posts: 4225
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

DateTimePicker change available in EditFocusChange?

Post by robert »

Jonathan,
I would not create a controlFocusChangeEvent at all .
Why not create a new method that has the parameters oControl and lGotFocus and call that method from here and from the controlFocusChangeEvent on the window.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
jonhn
Posts: 86
Joined: Thu Feb 01, 2018 8:04 am

DateTimePicker change available in EditFocusChange?

Post by jonhn »

Thank you Robert,
I thought that would be too simple! After some experimenting it now seems to be working very nicely.
Thank you for the pointers!
Regards,
Jonathan
User avatar
robert
Posts: 4225
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

DateTimePicker change available in EditFocusChange?

Post by robert »

Jonathan,
The simplest solution is often the best !

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
jonhn
Posts: 86
Joined: Thu Feb 01, 2018 8:04 am

DateTimePicker change available in EditFocusChange?

Post by jonhn »

Sorry - I'm back. Wasn't quite so simple... or maybe.
I'm getting a stack overflow (I assume) after selecting a few different dates - the DateThing method is being called again (and again) by ControlNotify.

How should I let ControlNotify know that we have dealt with the DateSelectionChange and to forget about it?


METHOD DateThing(oControl AS Control)
LOCAL oControlCurrent AS Control

//check if user is still in the date field or if they've moved away.
oControlCurrent := GetFocusedObject() // What control now has focus? If not the date field the...

IF oControlCurrent != NULL_OBJECT .and. ((oControl:NameSym ==#DTPRet_Date .and. oControlCurrent:NameSym != #DTPRet_Date) .or. oControl:NameSym ==#DTPInv_Date .and. oControlCurrent:NameSym != #DTPInv_Date )

IF SELF:OldInv_date <> SELF:odcDTPInv_date:Value
SELF:DatesChanged()
ELSEIF SELF:OldRet_date <> SELF:odcDTPRet_date:Value
SELF:DatesChanged()
ENDIF
ENDIF
RETURN NIL


VIRTUAL METHOD ControlNotify(oControlNotifyEvent) AS USUAL CLIPPER
LOCAL oControl AS Control

oControl := IIf(oControlNotifyEvent == NULL_OBJECT, NULL_OBJECT, oControlNotifyEvent:Control)

SUPER:ControlNotify(oControlNotifyEvent)

IF oControl != NULL_OBJECT .and. oControl:NameSym =#DTPInv_Date .and. oControlNotifyEvent:NotifyCode == NM_KILLFOCUS //.and. !lGotFocus
SELF:DateThing(oControl )
// Send notification message to DateThing that the DTP was used and no longer has focus.
ENDIF
IF oControl != NULL_OBJECT .and. oControl:NameSym =#DTPRet_Date .and. oControlNotifyEvent:NotifyCode == NM_KILLFOCUS // .and. !lGotFocus
SELF:DateThing(oControl )
// Send notification message TO DateThing that the DTP was used and no longer has focus.
ENDIF
RETURN NIL
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am

DateTimePicker change available in EditFocusChange?

Post by Karl-Heinz »

Robert & Jonathan,

i think there is no need to overwrite ControlNotify(). The Dispatch() in the control.prg handles WM_SETFOCUS / WM_KILLFOCUS and calls SELF:FocusChange(), which finally triggers oParent:ControlFocusChange().

Code: Select all

METHOD Dispatch(oEvent) CLASS Control
[...]
       
        //PP-040421 Improved focus handling
    CASE msg == WM_SETFOCUS .OR. msg == WM_KILLFOCUS
        //uRet := SELF:FocusChange(__ObjectCastClassPtr(oEvt, __pCFocusChangeEvent))
        uRet := SELF:FocusChange(FocusChangeEvent{oEvt})
[...]

Code: Select all

METHOD FocusChange(oFocusChangeEvent) CLASS Control
    //PP-040518 Update from S Ebert
  
    IF IsInstanceOf(oParent,#DataWindow) .OR. IsInstanceOf(oParent,#DialogWindow)
        //RETURN oParent:ControlFocusChange(__ObjectCastClassPtr(oFocusChangeEvent, __pCControlFocusChangeEvent))
        RETURN oParent:ControlFocusChange(ControlFocusChangeEvent{oFocusChangeEvent})
    ELSEIF IsInstanceOf(oParent, #__FormWindow) //It's a browser of a DataWindow
        IF oFocusChangeEvent:GotFocus
            oParent:DataWindow:LastFocus := SELF
        ENDIF
    ENDIF
    
    RETURN NIL
i added two DTPs to a Dialog and the event properties show the expected results.

Code: Select all

METHOD ControlFocusChange(oControlFocusChangeEvent)  CLASS  MainDialog 

	SUPER:ControlFocusChange(oControlFocusChangeEvent)

	
	? oControlFocusChangeEvent:Control:Namesym , oControlFocusChangeEvent:GotFocus 

	IF IsInstanceOf ( oControlFocusChangeEvent:Control , #DATETIMEPICKER )
		?? "", oControlFocusChangeEvent:Control:SelectedDate		
		
	ENDIF 	

	RETURN NIL


regards
Karl-Heinz
Jamal
Posts: 314
Joined: Mon Jul 03, 2017 7:02 pm

DateTimePicker change available in EditFocusChange?

Post by Jamal »

A small contribution in addition to Karl's solution if you are using VO 2.8 (sp2838).

Since the ControlFocusChange event is not visible in the Window properties dialog, the following can be made to the CAVOWED.INF and CAVOWED.TPL located in the C:CAVO28BIN folder. The advantage of this modification that you have access to this event from the Window Editor and applies to all window types.

Please backup the above files before making any modifications!

In CAVOWED.TPL:
Below the
[ClassDeclaration]
class %FORM:NAME% inherit %FORM:CLASSNAME%

Add:
[ControlFocusChange]
method ControlFocusChange(oControlFocusChangeEvent) class %FORM:NAME%
tlocal oControl as Control
toControl := IIf(oControlFocusChangeEvent == NULL_OBJECT, NULL_OBJECT, oControlFocusChangeEvent:Control)
tsuper:ControlFocusChange(oControlFocusChangeEvent)
t//Put your changes here
treturn NIL


In CAVOWED.INF

Add:
Method93=ControlFocusChange,ControlFocusChange(CODE:ControlFocusChange)


In the section:
;**** Association between Tabs and methods/assigns/styles

Update the Control Events line to:

Control Events=(Window Control Events)ControlFocusChange,ButtonClick,ButtonDoubleClick,EditChange,EditFocusChange,EditScroll,Keydown,Keyup,ListBoxClick,ListBoxSelect,HorizontalScroll,VerticalScroll,HorizontalSlide,VerticalSlide,HorizontalSpin,VerticalSpin
2022-10-21_15-04-01.jpg
2022-10-21_15-04-01.jpg (75.69 KiB) Viewed 574 times

Generated code:

Code: Select all

method ControlFocusChange(oControlFocusChangeEvent) class DragDropDlg
	local oControl as Control
	oControl := IIf(oControlFocusChangeEvent == NULL_OBJECT, NULL_OBJECT, oControlFocusChangeEvent:Control)
	super:ControlFocusChange(oControlFocusChangeEvent)
	//Put your changes here   
	return NIL
HTH,
Jamal
Post Reply