Spiff59 Posted June 1, 2010 Share Posted June 1, 2010 (edited) Maybe I'm recreating the wheel, but a forum search found no such critter... My users find modifying the time portion of the DTP control a pain in the rear. The date portion is cake, what with the calendar pop-up, but one has to alternate between highlighting sections of the time portion of the DTP with the mouse, then switch to the keyboard, repeat, repeat. So, I thought I'd make a stab at something I could plug easily into some of my scripts to simplify time entry. I'll post what I've thrown together, and then list off some gripes about it's shortcomings afterwards... (This does also allow for a user-defined time interval for incrementing/decrementing the minutes of the control, as we only schedule appointments on the quarter-hour). expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiEdit.au3> GUICreate("", 340, 160) $read_button = GUICtrlCreateButton("Read Second TP", 55, 120, 100, 20) $kill_button = GUICtrlCreateButton("Kill Third TP", 215, 120, 100, 20) GUISetState() ; TIME_PICKER PARAMETERS ; INIT, instance, hpos, vpos, interval, HH, MM, AM/PM ; UPDT, instance ; READ, instance ; KILL, instance Global $TP_Count = 3, $TP_Event[$TP_Count], $TP_Input[$TP_Count][3], $TP_Array[$TP_Count][3], $TP_AM_PM[$TP_Count], $TP_Interval[$TP_Count][3] GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Time_Picker("INIT", 0, 10, 30, 1, 12, 30, 1) Time_Picker("INIT", 1, 30, 60, 5, 8, 30, 0) Time_Picker("INIT", 2, 90, 90, 15, 5, 45, 1) While 1 Switch GUIGetMsg() Case $read_button MsgBox(1,"", Time_Picker("READ", 1)) Case $kill_button Time_Picker("KILL", 2) Case $GUI_EVENT_CLOSE Exit EndSwitch For $x = 0 to $TP_Count - 1 If $TP_Event[$x] Then Time_Picker("UPDT", $x) Next WEnd ;------------------------------------------------------------------------------- Func Time_Picker($command, $instance, $hpos = 0, $vpos = 0, $interval = 1, $hours = 8, $minutes = 0, $am_pm = 0) Local $AM_PM_Array[2] = ["AM", "PM"] Switch $command Case "INIT" $TP_Interval[$instance][1] = 1 ; hours $TP_Interval[$instance][2] = $interval ; minutes $TP_Array[$instance][1] = $hours $TP_Array[$instance][2] = $minutes $TP_AM_PM[$instance] = $am_pm GUICtrlCreateLabel("", $hpos, $vpos, 60, 20) GUICtrlSetBkColor( -1, 0x7F9FAF) GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlCreateLabel("", $hpos + 1, $vpos + 1, 58, 3) GUICtrlSetBkColor( -1, 0xFFFFFF) GUICtrlSetState(-1, $GUI_DISABLE) $TP_Input[$instance][0] = GUICtrlCreateInput($hours, $hpos + 1, $vpos + 4, 16, 15, $ES_READONLY + $ES_RIGHT, 0) GUICtrlSetFont(-1, 8.5, 400, 0, "MS Sans Serif") GUICtrlSetBkColor( -1, 0xFFFFFF) $TP_Input[$instance][1] = GUICtrlCreateInput($minutes, $hpos + 21, $vpos + 4, 19, 15, $ES_READONLY, 0) GUICtrlSetFont(-1, 8.5, 400, 0, "MS Sans Serif") GUICtrlSetBkColor( -1, 0xFFFFFF) $TP_Input[$instance][2] = GUICtrlCreateInput($AM_PM_Array[$am_pm], $hpos + 40, $vpos + 4, 19, 15, $ES_READONLY, 0) GUICtrlSetFont(-1, 8.5, 400, 0, "MS Sans Serif") GUICtrlSetBkColor( -1, 0xFFFFFF) GUICtrlCreateLabel(":", $hpos + 17, $vpos + 4, 4, 15) GUICtrlSetFont(-1, 7, 600, 0, "MS Sans Serif") GUICtrlSetBkColor( -1, 0xFFFFFF) GUICtrlSetState(-1, $GUI_DISABLE) Case "UPDT" _GUICtrlEdit_SetSel($TP_Input[$instance][$TP_Event[$instance] - 1], 0, -1) Case "READ" Return GUICtrlRead($TP_Input[$instance][0]) & ":" & GUICtrlRead($TP_Input[$instance][1]) & " " & GUICtrlRead($TP_Input[$instance][2]) Case "KILL" $x = $TP_Input[$instance][0] - 2 For $y = 0 to 5 GUICtrlDelete($y + $x) Next EndSwitch EndFunc ;------------------------------------------------------------------------------- Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) $nNotifyCode = BitShift($wParam, 16) ;HiWord $nID = BitAnd($wParam, 0x0000FFFF) ;LoWord For $x = 0 to $TP_Count - 1 Switch $nID Case $TP_Input[$x][0] to $TP_Input[$x][2] Switch $nNotifyCode Case 256 ; gain focus GUIRegisterMsg($WM_MOUSEWHEEL, "_TP_WM_MOUSEWHEEL") $TP_Event[$x] = $nID - $TP_Input[$x][0] + 1 ; Active control: 1 = HH, 2 = MM, 3 = AM/PM Case 512 ; lose focus GUIRegisterMsg($WM_MOUSEWHEEL, "") $TP_Event[$x] = 0 EndSwitch EndSwitch Next Return $GUI_RUNDEFMSG EndFunc Func _TP_WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam) Local $TP_Array_limit[3] = [0, 12, 59], $AM_PM_Array[2] = ["AM", "PM"], $instance For $x = 0 to $TP_Count - 1 If $TP_Event[$x] then $instance = $x Next If $TP_Event[$instance] = 3 Then $TP_AM_PM[$instance] = Not $TP_AM_PM[$instance] Else $x = $TP_Event[$instance] If _WinAPI_HiWord($wParam) > 0 Then While 1 ; wheel up - subtract time If $x = 1 And $TP_Array[$instance][$x] = $TP_Array_limit[$x] Then $TP_AM_PM[$instance] = Not $TP_AM_PM[$instance] $TP_Array[$instance][$x] -= $TP_Interval[$instance][$x] If $TP_Array[$instance][$x] < Abs($x - 2) Then $TP_Array[$instance][$x] = $TP_Array_limit[$x] - $TP_Interval[$instance][$x] + 1 If $x = 2 then ; force hour change $x = 1 ContinueLoop EndIf EndIf ExitLoop WEnd Else While 1 ; wheel down - add time $TP_Array[$instance][$x] += $TP_Interval[$instance][$x] If $TP_Array[$instance][$x] > $TP_Array_limit[$x] Then $TP_Array[$instance][$x] = Abs($x - 2) If $x = 2 then ; force hour change $x = 1 ContinueLoop EndIf EndIf ExitLoop WEnd If $x = 1 And $TP_Array[$instance][$x] = $TP_Array_limit[$x] Then $TP_AM_PM[$instance] = Not $TP_AM_PM[$instance] EndIf EndIf GUICtrlSetData($TP_Input[$instance][0], $TP_Array[$instance][1]) GUICtrlSetData($TP_Input[$instance][1], StringFormat('%02s', $TP_Array[$instance][2])) GUICtrlSetData($TP_Input[$instance][2], $AM_PM_Array[$TP_AM_PM[$instance]]) Return 0 EndFunc Like I said, this is rough and unpolished, just my first version, but I see some problems that wouldn't stop me from incorporating it into scripts, but that do make it more cumbersome to do so. 1. If there was an alternate function, or a low-level DLL call, that could force the equivalent of a _GUICtrlEdit_SetSel() and would execute properly inside of the WM_COMMAND function, then I wouldn't need to set a flag and insert code into the main GUIReadMsg() loop to reselect the active control (no, I don't want to switch to OnEvent mode). A work-around for this would let me trash the manual "UPDT" function I've added. 2. I'm not too thrilled about having to add a couple lines of Globals to the top of any script I stick this into, but I'm reluctant to go the IsDeclared() route and put the Globals in the called function itself (it would feel like "bad form"). 3. The big pain, is having to massage the WM_COMMAND portion for the TIME_PICKER controls into existing WM_COMMAND functions that are already servicing other controls. It's not hard to do, but it makes this function far from "drop-in". OK, someone point me to the slick version of this that is already out there Edit: Oops! Guess I ought to have mentioned, this is all driven off the mouse wheel, but then *everyone* has a wheel mouse I would think... typos Edited June 4, 2010 by Spiff59 Link to comment Share on other sites More sharing options...
Spiff59 Posted June 2, 2010 Author Share Posted June 2, 2010 (edited) A different approach... Just adding mouse wheel support to the existing DTP. Has a much smaller "footprint" than the prior attempt, but doesn't allow for an an adjustable time interval: expandcollapse popup#include <GuiDateTimePicker.au3> #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> Global $DTP_Flag $hGUI = GUICreate("DTP with mouse wheel support", 300, 100) $hDTP = _GUICtrlDTP_Create($hGUI, 50, 40, 190) _GUICtrlDTP_SetFormat($hDTP, "ddd MMM dd, yyyy hh:mm ttt") GUISetState() GUIRegisterMsg($WM_SETCURSOR, "WM_SETCURSOR") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd ;------------------------------------------------------------------------------- Func WM_SETCURSOR($hWnd, $iMsg, $iWParam, $iLParam) ; set flag if within DTP control If $iWParam = $hDTP Then If $DTP_Flag = 0 Then GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL") ; enable when entering DTP control EndIf $DTP_Flag = 1 Else If $DTP_Flag = 1 Then GUIRegisterMsg($WM_MOUSEWHEEL, "") ; disable when exiting EndIf $DTP_Flag = 0 EndIf Return $GUI_RUNDEFMSG EndFunc Func WM_MOUSEWHEEL($hWnd, $iMsg, $iwParam, $ilParam) If $DTP_Flag Then If _WinAPI_HiWord($iwParam) > 0 Then ; mouse wheel up Send("{DOWN}") Else ; mouse wheel down Send("{UP}") EndIf EndIf Return 0 EndFunc Edited June 4, 2010 by Spiff59 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now