Jump to content

GuiMonthCal.au3 - Returning values not selected by user


Go to solution Solved by Gianni,

Recommended Posts

Hi All,

I have a start date and end date fields that are read only with button to display the calendar selection window for the user to select a different date if required however whenever the user attempts to click to change month it returns the date of the start of the month without the user selecting that date.
if the user clicks on the Month and year, it will show the overview of all the months for the year and clicking the year will change to showing the years. but once a month is selected it will return a value.
as a work around I've made it ignore the date if it is the first of the month, but I'm know this isn't a solution.

Code:

Func btnStart()
    $btnPos = ControlGetPos("Data Wizard", "", $btnSetStart)
    setCal($inStart, $dArrStart, "Start")
EndFunc   ;==>btnStart

Func btnEnd()
    $btnPos = ControlGetPos("Data Wizard", "", $btnSetEnd)
    setCal($inEnd, $dArrEnd, "End")
EndFunc   ;==>btnEnd

; Define Calendar select variables
Dim $frmCalSel, $calCont, $calArr, $btnSet

; Display calendar select at position relative to selected button
Func setCal($ctrlRef, $inDate, $type)
    WinSetTitle("Select Date", "", "Select Date " & $type)
    WinMove("Select Date " & $type, "", $calArr[3] + 10, $calArr[4] + 40)
    _GUICtrlMonthCal_SetCurSel($calCont, $inDate[1], $inDate[2], $inDate[3])
    GUISetState(@SW_SHOW, $frmCalSel)
    GUISetOnEvent($GUI_EVENT_CLOSE, "disposeCal")
EndFunc   ;==>setCal

; Cleanup Calendar select
Func disposeCal()
    GUISetState(@SW_HIDE, $frmCalSel)
EndFunc   ;==>disposeCal

; define date structure returned from calendar select
Func setDate()
    $val = _GUICtrlMonthCal_GetCurSel($calCont)
    $day = DllStructGetData($val, "Day")
    ; Check if the selected date is the first day of the month
    If $day <> 1 Then
    $locDate = (StringFormat("%02d-%02d-%04d", DllStructGetData($val, "Day"), _
            DllStructGetData($val, "Month"), _
            DllStructGetData($val, "Year")))
    $caller = @GUI_CtrlId
    If $caller = $btnSetStart Then GUICtrlSetData($inStart, $locDate)
    If $caller = $btnSetEnd Then GUICtrlSetData($inEnd, $locDate)
    Sleep(100) ; Add a short delay to ensure proper processing
    MsgBox(0,"Debug", "locDate: " & $locDate)
    MsgBox(0,"Debug", "Val: " & $locDate)
    disposeCal()
    Else
        ;MsgBox(0, "Info", "Please select a date other than the first day of the month.")
    EndIf
EndFunc   ;==>setDate 

 

Edited by SmOke_N
Added code tags, OP, see <> button at the top of your posts before you submit
Link to comment
Share on other sites

Full Code:

 

#comments-end

#Region - include files
; Standard UDFs
#include <misc.au3>
#include <Date.au3>
#include <array.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiMonthCal.au3>


#EndRegion - include files

$year = @YEAR
Dim $FileVersion = "3.5.0"
; Define AutoIT Options
Opt("WinTitleMatchMode", 1)

#Region Variable initialisation
; initialise HAS run for logging purposes
Dim $HASRUN = 0

; set state machine initial state
Dim $state = -2

#EndRegion Variable initialisation


#Region Date time calculations for gui
; TIME CALCULATIONS
Dim $startDate, $endDate
Dim $dArrStart, $tArrStart, $dArrEnd, $tArrEnd

; Calculate day of week and set start & end points 1 week into future
Dim $currDay = _DateToDayOfWeekISO(@YEAR, @MON, @MDAY) - 1 ; Set Monday to 0

If $currDay = 0 Then
    $NOW = _NowCalcDate()
Else
    $NOW = _DateAdd('D', -$currDay, _NowCalcDate())
EndIf

; Start Date - Next Week Monday
$startDate = _DateAdd('D', 7, $NOW)
_DateTimeSplit($startDate, $dArrStart, $tArrStart)
$startDateStr = $dArrStart[3] & "-" & $dArrStart[2] & "-" & $dArrStart[1]

; End Date - Next Week Friday
$endDate = _DateAdd('D', 11, $NOW)
_DateTimeSplit($endDate, $dArrEnd, $tArrEnd)
$endDateStr = $dArrEnd[3] & "-" & $dArrEnd[2] & "-" & $dArrEnd[1]

; GUI Mode set
Opt("GUIOnEventMode", 1)

; Create form to right of current screen to make pinpad more accessible when spawning Edge instance
$frmOSLPWiz = GUICreate("Data Wizard", 400, 300, @DesktopWidth - 500, 125, -1, $WS_EX_TOPMOST)
GUISetFont(12, 400, 0, "Calibri")
$lblTitle = GUICtrlCreateLabel("Data Wizard", 24, 16, 347, 37)
GUICtrlSetColor(-1, 0xFF6A00)
GUICtrlSetFont(-1, 20, 800, 0, "Calibri")

$lblStart = GUICtrlCreateLabel("Start Date:", 24, 168, 73, 23)
$lblEnd = GUICtrlCreateLabel("End Date:", 216, 168, 67, 23)

$inStart = GUICtrlCreateInput($startDateStr, 24, 190, 113, 27, BitOR($ES_AUTOHSCROLL, $ES_READONLY, $ES_NUMBER))
$inEnd = GUICtrlCreateInput($endDateStr, 216, 190, 113, 27, BitOR($ES_AUTOHSCROLL, $ES_READONLY, $ES_NUMBER))
$btnSetStart = GUICtrlCreateButton("+", 140, 189, 27, 29, $WS_GROUP)
GUICtrlSetOnEvent($btnSetStart, "btnStart")
$btnSetEnd = GUICtrlCreateButton("+", 332, 189, 27, 29, $WS_GROUP)
GUICtrlSetOnEvent($btnSetEnd, "btnEnd")

GUISetOnEvent($GUI_EVENT_CLOSE, "programKill")
GUISetState(@SW_SHOW)

; CALENDAR FORM CREATION
$frmCalSel = GUICreate("Select Date ", 240, 180, 0, 0, -1, $WS_EX_TOOLWINDOW, $frmOSLPWiz)

; Set Calendar to active to create controls
GUISwitch($frmCalSel)
$calCont = _GUICtrlMonthCal_Create($frmCalSel, 2, 2)

; Deal with variable size of calendar control
$calArr = _GUICtrlMonthCal_GetMinReqRectArray($calCont)
$frmWidth = $calArr[3] + 10
$frmHeight = $calArr[4] + 10

GUISetState(@SW_HIDE, $frmCalSel)
GUISetOnEvent($GUI_EVENT_CLOSE, "disposeCal", $frmCalSel)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

; Set Main form to active window
GUISwitch($frmOSLPWiz)

; NOTIFY METHOD TO DEAL WITH DATE SELECT
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $calCont
            Switch $iCode
                Case $MCN_SELCHANGE ; Sent by a month calendar control when the currently selected date or range of dates changes
                    setDate()
                Case $MCN_SELECT
                    setDate()
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY


Func btnStart()
    $btnPos = ControlGetPos("Data Wizard", "", $btnSetStart)
    $parentPos = WinGetPos("Data Wizard")
    setCal($inStart, $dArrStart, "Start")
EndFunc   ;==>btnStart

Func btnEnd()
    $btnPos = ControlGetPos("Data Wizard", "", $btnSetEnd)
    $parentPos = WinGetPos("Data Wizard")
    setCal($inEnd, $dArrEnd, "End")
EndFunc   ;==>btnEnd

; Define Calendar select variables
Dim $frmCalSel, $calCont, $calArr, $btnSet

; Display calendar select at position relative to selected button
Func setCal($ctrlRef, $inDate, $type)
    Local $btnPos = ControlGetPos("Data Wizard", "", $ctrlRef)
    Local $parentPos = WinGetPos("Data Wizard")
    Local $calLeft = $parentPos[0] + $btnPos[0]
    Local $calTop = $parentPos[1] + $btnPos[1] + $btnPos[3] + 5
    WinSetTitle("Select Date", "", "Select Date " & $type)
    WinMove("Select Date " & $type, "", $calLeft, $calTop + 20)
    _GUICtrlMonthCal_SetCurSel($calCont, $inDate[1], $inDate[2], $inDate[3])
    GUISetState(@SW_SHOW, $frmCalSel)
    GUISetOnEvent($GUI_EVENT_CLOSE, "disposeCal")
EndFunc   ;==>setCal

; Cleanup Calendar select
Func disposeCal()
    GUISetState(@SW_HIDE, $frmCalSel)
EndFunc   ;==>disposeCal

; define date structure returned from calendar select
Func setDate()
    $val = _GUICtrlMonthCal_GetCurSel($calCont)
    $day = DllStructGetData($val, "Day")
    
    ; Check if the selected date is the first day of the month
    If $day <> 1 Then
    $locDate = (StringFormat("%02d-%02d-%04d", DllStructGetData($val, "Day"), _
            DllStructGetData($val, "Month"), _
            DllStructGetData($val, "Year")))
    $caller = @GUI_CtrlId
    If $caller = $btnSetStart Then GUICtrlSetData($inStart, $locDate)
    If $caller = $btnSetEnd Then GUICtrlSetData($inEnd, $locDate)
    Sleep(100) ; Add a short delay to ensure proper processing
    MsgBox(0,"Debug", "locDate: " & $locDate)
    MsgBox(0,"Debug", "Val: " & $locDate)
    disposeCal()
    Else
        MsgBox(0, "Info", "Please select a date other than the first day of the month.")
    EndIf
    
EndFunc   ;==>setDate 

; **************************
#EndRegion GUI FUNCTIONS

; Loop until user exits
While GUIGetMsg() <> -3
    Sleep(10)
WEnd

Func programKill()
    ; cleanup GUI and exit script
    if $frmOSLPWiz then GUIDelete($frmOSLPWiz)
    Exit
EndFunc   ;==>programKill

 

Edited by SmOke_N
Added code <> tags
Link to comment
Share on other sites

Thank you, Andreik, for suggesting the use of _GUICtrlMonthCal_HitTest(). I appreciate your input. Since I wasn't familiar with this function, I referred to the AutoIt Docs to understand its usage before applying it. However, upon testing the provided example in a new script, I encountered a similar issue to the one I'm currently facing. Despite not clicking on any date, the function returns a date value. Below is a screenshot illustrating the unexpected outcome:
https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlMonthCal_HitTest.htm
image.png.17fab6e84b507c546e2ac1c75001a933.png

I'm uncertain if I'm missing something in my implementation or if there's an underlying issue with the function itself. Any further guidance or insights would be greatly appreciated.

Link to comment
Share on other sites

You should update the calendar when the button is clicked.

; Display calendar select at position relative to selected button
Func setCal($ctrlRef, $inDate, $type)
    Local $btnPos = ControlGetPos("Data Wizard", "", $ctrlRef)
    Local $parentPos = WinGetPos("Data Wizard")
    Local $calLeft = $parentPos[0] + $btnPos[0]
    Local $calTop = $parentPos[1] + $btnPos[1] + $btnPos[3] + 5
    WinSetTitle("Select Date", "", "Select Date " & $type)
    WinMove("Select Date " & $type, "", $calLeft, $calTop + 20)
    
    
    ;the changes start here.
    ConsoleWrite("setting date "& $inDate[1]&" "& $inDate[2]&" "& $inDate[3]&@CRLF); the data used has been incorrect since the first call to the function.

    ;updating
     $val = _GUICtrlMonthCal_GetCurSel($calCont)
    _GUICtrlMonthCal_SetCurSel($calCont, DllStructGetData($val,"Year"), DllStructGetData($val, "Month"), DllStructGetData($val, "Day"))
    
    
    GUISetState(@SW_SHOW, $frmCalSel)
    GUISetOnEvent($GUI_EVENT_CLOSE, "disposeCal")
EndFunc   ;==>setCal

 

Edited by Numeric1
Link to comment
Share on other sites

Hi Numeric1

Thank you for your updated code it is much cleaner than the code I had Implemented in the setDate function however, the same issue is occurring (I do understand the last post on this topic got away from the issue and I need to bring it back into the issue I'm facing).

If the user brings up the calendar and then attempts to click the arrow forwards to go to March, it will return a 1/3/2024 date but all the user was attempting to do was change month to then select the date.
this occurs whenever your changing months.

Link to comment
Share on other sites

  • Solution

you are calling the setDate() function in response to the $MCN_SELCHANGE event. This event fires when you change the month and consequently setDate() fires when the user changes the month.
simply don't call setDate() in response to the $MCN_SELCHANGE event and the problem shouldn't arise.
hope it helps

Switch $iCode
                Case $MCN_SELCHANGE ; Sent by a month calendar control when the currently selected date or range of dates changes
                    ; setDate() ; <== comment out this line
                Case $MCN_SELECT
                    setDate()
            EndSwitch

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...