dragan Posted March 20, 2013 Share Posted March 20, 2013 Can I increase the hour limit in my Date control? I have tried this: #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GuiDateTimePicker.au3> $Form1 = GUICreate("Form1", 400, 200) Global $TheTime = GUICtrlCreateDate('02:00', 5, 5, 150, 21, $DTS_TIMEFORMAT) _GUICtrlDTP_SetFormat(GUICtrlGetHandle($TheTime), "HH:mm ' Hour:minute'") Global $aRange[14] = [True, 0, 1, 1, 00, 00, 00, True, 3000, 12, 31, 99, 99, 99] _GUICtrlDTP_SetRange(GUICtrlGetHandle($TheTime), $aRange) GUISetState(@SW_SHOW) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE But it still goes only to 23/59 when I try to change hours/minutes, and I would like to change to 99:99 (max value) Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 20, 2013 Moderators Share Posted March 20, 2013 dragan, I think you are going to have to create a custom "control" with labels, inputs and updowns for that. It is not too difficult - I have done it several times and I will try to find an example later. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
dragan Posted March 20, 2013 Author Share Posted March 20, 2013 Hi Melba23,I tried to make custom control, and this is closest to my idea. However, at the moment I'm limited by my autoit skills:expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <Constants.au3> #include <GuiEdit.au3> Global $edittingNumber = 1 $Form1 = GUICreate("Form1", 400, 200) $hEdit = GUICtrlCreateInput('02.00', 5, 5, 150, 21, $ES_NUMBER);, 0, 0) GUICtrlSetLimit(-1, 5) $hUpDown = GUICtrlCreateUpdown(-1) $wProcHandle = DllCallbackRegister("_EditWindowProc", "ptr", "hwnd;uint;wparam;lparam") $wProcOldLocal = _WinAPI_SetWindowLong(GUICtrlGetHandle($hEdit), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle)) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _WinAPI_SetWindowLong(GUICtrlGetHandle($hEdit), $GWL_WNDPROC, $wProcOldLocal) DllCallbackFree($wProcHandle) Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $iCode = DllStructGetData($tNMHDR, "Code") Switch BitAND($wParam, 0xFFFF) Case $hEdit ConsoleWrite('- ' & $iCode & @CRLF) Return True Case $hUpDown ConsoleWrite('! ' & $iCode & @CRLF) Local $tStruct = DllStructCreate("hwnd;long;int;long;long", $lParam) If DllStructGetData($tStruct, 3) = 0xFFFFFD2E Then ; $UDN_DELTAPOS Local $divider = 1 If $edittingNumber = 1 Then $divider = 1 Else $divider = 100 EndIf Local $calc = DllStructGetData($tStruct, 5)/$divider Local $readVal = Number(GUICtrlRead($hEdit)) Local $newVal = $readVal + $calc If $newVal >= 100 then $newVal = 0 ElseIf $newVal < 0 then $newVal = 99.99 EndIf Local $theVal = StringFormat("%#.2f", $newVal) Local $splitVal = StringSplit($theVal, '.') Local $firstVal = StringFormat("%02d", $newVal) Local $finalVal = $firstVal & '.' & $splitVal[$splitVal[0]] Local $theDot = StringInStr($finalVal, '.') Local $iCount = StringLen($finalVal) GUICtrlSetData($hEdit, $finalVal) Return True EndIf EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _EditWindowProc($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Switch $hWnd case GUICtrlGetHandle($hEdit) Switch $iMsg Case $WM_GETDLGCODE ConsoleWrite('-> ' & $wParam & @CRLF) Local $curRead = GUICtrlRead($hEdit) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') Switch $wParam Case 110, 190 ;dot (.) If NOT $theDot Then If $curRead = '' Then GUICtrlSetData($hEdit, '00.') Else GUICtrlSetData($hEdit, StringFormat("%02d", $curRead) & '.') EndIf Else _GUICtrlEdit_SetSel($hEdit, $theDot, $iCount) EndIf $edittingNumber = 2 Return True Case 38 ;up Local $splitVal = StringSplit($curRead, '.') If $splitVal[0] < 2 then Return _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) Local $finalVal If $edittingNumber = 1 Then Local $newVal = $splitVal[1]+1 If $newVal >= 100 then $newVal = 0 $finalVal = StringFormat("%02d", $newVal) & '.' & StringFormat("%02d", $splitVal[2]) Else Local $newVal = $splitVal[2]+1 If $newVal >= 100 then $newVal = 0 $splitVal[1] += 1 If $splitVal[1] >= 100 then $splitVal[1] = 0 EndIf $finalVal = StringFormat("%02d", $splitVal[1]) & '.' & StringFormat("%02d", $newVal) EndIf GUICtrlSetData($hEdit, $finalVal) Return True Case 40 ;down Local $splitVal = StringSplit($curRead, '.') If $splitVal[0] < 2 then Return _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) Local $finalVal If $edittingNumber = 1 Then Local $newVal = $splitVal[1]-1 If $newVal < 0 then $newVal = 99 $finalVal = StringFormat("%02d", $newVal) & '.' & StringFormat("%02d", $splitVal[2]) Else Local $newVal = $splitVal[2]-1 If $newVal < 0 then $newVal = 99 $splitVal[1] -= 1 If $splitVal[1] < 0 then $splitVal[1] = 99 EndIf $finalVal = StringFormat("%02d", $splitVal[1]) & '.' & StringFormat("%02d", $newVal) EndIf GUICtrlSetData($hEdit, $finalVal) Return True Case 37 ;left If $edittingNumber = 2 Then $edittingNumber = 1 _GUICtrlEdit_SetSel($hEdit, 0, $theDot) ;<------- doesn't work ConsoleWrite('>> ' & $edittingNumber & @CRLF) Return True EndIf Case 39 ;right If $edittingNumber = 1 Then $edittingNumber = 2 _GUICtrlEdit_SetSel($hEdit, $theDot, $iCount+1) ;<------- doesn't work ConsoleWrite('>> ' & $edittingNumber & @CRLF) Return True EndIf Case 48 to 57 If $iCount >= 2 then If NOT $theDot Then GUICtrlSetData($hEdit, $curRead & '.') _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) EndIf EndIf EndSwitch Case 513 ConsoleWrite('~~> ' & $edittingNumber & @CRLF) Local $curRead = GUICtrlRead($hEdit) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') If NOT $theDot Then Else _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) Local $iPos = _GUICtrlEdit_GetSel($hEdit) If IsArray($iPos) Then ConsoleWrite('+> ' & $iPos[0] & ', ' & $iPos[1] & ', ' & $theDot & @CRLF) If $iPos[0] < $theDot Then $edittingNumber = 1 _GUICtrlEdit_SetSel($hEdit, 0, $theDot-1) Else $edittingNumber = 2 _GUICtrlEdit_SetSel($hEdit, $theDot, $iCount+1) EndIf ConsoleWrite('!> ' & $edittingNumber & @CRLF) Return True EndIf EndIf Case $WM_GETDLGCODE EndSwitch EndSwitch Return _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) EndFuncI do have some questions though, why is my script failing at the left/right keyboard clicks in the _EditWindowProc function? It's not failing, but it fails to select things I want it to select. Also, can I make Up/Down control to NOT select entire input after changing value, but select only left/right parts of the input. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 20, 2013 Moderators Share Posted March 20, 2013 dragan, Sorry, I was dragged away to do something else and I forgot to look out my example code. It is a good bit simpler than yours: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <UpDownConstants.au3> #include <StaticConstants.au3> #include <EditConstants.au3> $hGUI = GUICreate("Test", 500, 500) ; Create hours input $cInput_Hour = GUICtrlCreateInput("0", 10, 50, 20, 20) GUICtrlSetState(-1, $GUI_HIDE) Local $cUpDown_Hour = GUICtrlCreateUpdown($cInput_Hour, $UDS_WRAP) GUICtrlSetLimit($cUpDown_Hour, 99, 0) $cInput_Min = GUICtrlCreateInput("0", 80, 50, 20, 20) GUICtrlSetState(-1, $GUI_HIDE) Local $cUpDown_Min = GUICtrlCreateUpdown($cInput_Min, $UDS_WRAP) GUICtrlSetLimit($cUpDown_Min, 59, 0) $cTimer_Label = GUICtrlCreateLabel("00:00", 30, 50, 50, 20, $SS_CENTER) GUICtrlSetFont(-1, 12) GUISetState() GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam ; If it was an update message from the inputs If BitShift($wParam, 16) = $EN_CHANGE Then Switch BitAND($wParam, 0xFFFF) Case $cInput_Hour, $cInput_Min ; Set the label to the new total GUICtrlSetData($cTimer_Label, StringFormat("%02i", GUICtrlRead($cInput_Hour)) & ":" & StringFormat("%02i", GUICtrlRead($cInput_Min))) EndSwitch EndIf EndFunc ;==>_WM_COMMAND Is that the sort of thing you were looking for? M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
dragan Posted March 20, 2013 Author Share Posted March 20, 2013 (edited) Thanks Melba23, but I would like user to be able to type numbers manually as well, like he can with Data Control. And also to be able to use up/down/left/right buttons on keyboard to change values. I want pretty much ALL that Data Control can, but without the limit of 60 minutes and 24 hours. I realize I can just change your labels into Edits, but in my control, you can type a number, like 12 for example, and soon as you start typing next number (55 for example), the script will insert dot automatically. Though user can type dot if he pleases instead of the script doing that for him. Also the up/down control will increase/decrease number where you last clicked (whether it is left side, or the right side). I do appreciate for the example script, but I am gonna stick with this custom edit control until I find something more useful. Thanks Edited March 20, 2013 by dragan Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 20, 2013 Moderators Share Posted March 20, 2013 dragan, Fussy! How does this do? expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <UpDownConstants.au3> #include <StaticConstants.au3> #include <GUIEdit.au3> #include <WinAPI.au3> Global $sFocus $hGUI = GUICreate("Test", 500, 500) ; Create hours input $cInput_Hour = GUICtrlCreateInput("00", 10, 50, 40, 20) $cUpDown_Hour = GUICtrlCreateUpdown($cInput_Hour, BitOR($UDS_WRAP, $UDS_ALIGNLEFT)) GUICtrlSetLimit($cUpDown_Hour, 99, 0) $cInput_Min = GUICtrlCreateInput("00", 55, 50, 40, 20) $cUpDown_Min = GUICtrlCreateUpdown($cInput_Min, $UDS_WRAP) GUICtrlSetLimit($cUpDown_Min, 59, 0) GUICtrlCreateLabel(":", 50, 50, 5, 20, $SS_CENTER) $cButton = GUICtrlCreateButton("Read", 10, 100, 80, 30) GUICtrlSetState(-1, $GUI_FOCUS) $cUpDummy = GUICtrlCreateDummy() $cDownDummy = GUICtrlCreateDummy() GUISetState() GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") ; Set GUIAccelerators Local $aAccelKeys[2][2] = [["{UP}", $cUpDummy],["{DOWN}", $cDownDummy]] GUISetAccelerators($aAccelKeys) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $cButton $sTimer = GUICtrlRead($cInput_Hour) & ":" & GUICtrlRead($cInput_Min) MsgBox(0, "Timer", $sTimer) Case $cUpDummy Switch $sFocus Case "Hour" $iHour = Number(GUICtrlRead($cInput_Hour)) If $iHour <> 99 Then GUICtrlSetData($cInput_Hour, $iHour + 1) Else GUICtrlSetData($cInput_Hour, "00") EndIf Case "Min" $iMin = Number(GUICtrlRead($cInput_Min)) If $iMin <> 59 Then GUICtrlSetData($cInput_Min, $iMin + 1) Else GUICtrlSetData($cInput_Min, "00") EndIf EndSwitch Case $cDownDummy Switch $sFocus Case "Hour" $iHour = Number(GUICtrlRead($cInput_Hour)) If $iHour <> 0 Then GUICtrlSetData($cInput_Hour, $iHour - 1) Else GUICtrlSetData($cInput_Hour, "99") EndIf Case "Min" $iMin = Number(GUICtrlRead($cInput_Min)) If $iMin <> 0 Then GUICtrlSetData($cInput_Min, $iMin - 1) Else GUICtrlSetData($cInput_Min, "59") EndIf EndSwitch EndSwitch WEnd Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam $iCID = BitAND($wParam, 0xFFFF) $iCode = BitShift($wParam, 16) Switch $iCode Case $EN_SETFOCUS Switch $iCID Case $cInput_Hour $sFocus = "Hour" Case $cInput_Min $sFocus = "Min" EndSwitch _GUICtrlEdit_SetSel($iCID, -1, -1) Case $EN_CHANGE Switch $iCID Case $cInput_Hour, $cInput_Min $sContent = GUICtrlRead($iCID) $aSel = _GUICtrlEdit_GetSel($iCID) Switch StringLen($sContent) Case 0 To 2 GUICtrlSetData($iCID, StringFormat("%02i", $sContent)) Case Else GUICtrlSetData($iCID, StringLeft($sContent, 2)) EndSwitch _GUICtrlEdit_SetSel($iCID, $aSel[0], $aSel[1]) EndSwitch EndSwitch EndFunc ;==>_WM_COMMAND M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
dragan Posted March 20, 2013 Author Share Posted March 20, 2013 using Accelerators instead of registering keys in control? Very clever, how did I not come up with this? Thanks, much appreciated. Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted March 20, 2013 Moderators Share Posted March 20, 2013 dragan, Glad I could help. Please let us see the final result. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
dragan Posted March 21, 2013 Author Share Posted March 21, 2013 (edited) This is my final custom control. The only thing that's not working as I wanted is documented in the code. And it's just a minor thing: selecting value after changing it via up/down controls. I know the script is big (~300 lines) only for one control, but at least I covered all things I needed. And like I said, I am limited by my AutoIt skills, I am sure someone could do all of this much more efficient and simple. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <Constants.au3> #include <GuiEdit.au3> Global $edittingNumber = 1 Global $inputHasFocus = True Global $Form1 = GUICreate("Form1", 400, 200) Global $theInputCtrl = GUICtrlCreateInput('02.00', 5, 5, 80, 21, BitOR($ES_NUMBER, $ES_LEFT, $ES_AUTOHSCROLL)) GUICtrlSetLimit(-1, 5) Global $theUpDownCtrl = GUICtrlCreateUpdown(-1) Global $wProcHandle = DllCallbackRegister("_EditWindowProc", "ptr", "hwnd;uint;wparam;lparam") Global $wProcOldLocal = _WinAPI_SetWindowLong(GUICtrlGetHandle($theInputCtrl), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle)) Global $cUpDummy = GUICtrlCreateDummy() Global $cDownDummy = GUICtrlCreateDummy() Global $cLeftDummy = GUICtrlCreateDummy() Global $cRightDummy = GUICtrlCreateDummy() Global $cDotDummy = GUICtrlCreateDummy() Local $aAccelKeys[6][2] = [["{UP}", $cUpDummy],["{DOWN}", $cDownDummy], ["{LEFT}", $cLeftDummy], ["{RIGHT}", $cRightDummy], ["{.}", $cDotDummy], ["{NUMPADDOT}", $cDotDummy]] GUISetAccelerators($aAccelKeys) GUICtrlCreateButton('Loose focus from input', 5, 60, 200, 25) GUISetState(@SW_SHOW, $Form1) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _WinAPI_SetWindowLong(GUICtrlGetHandle($theInputCtrl), $GWL_WNDPROC, $wProcOldLocal) DllCallbackFree($wProcHandle) Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam $tNMHDR = DllStructCreate($tagNMHDR, $lParam) $iCode = DllStructGetData($tNMHDR, "Code") Switch BitAND($wParam, 0xFFFF) Case $theUpDownCtrl Local $tStruct = DllStructCreate("hwnd;long;int;long;long", $lParam) If DllStructGetData($tStruct, 3) = 0xFFFFFD2E Then ; $UDN_DELTAPOS Local $divider = 1 If $edittingNumber = 1 Then $divider = 1 Else $divider = 100 EndIf Local $calc = DllStructGetData($tStruct, 5)/$divider Local $readVal = Number(GUICtrlRead($theInputCtrl)) Local $newVal = $readVal + $calc If $newVal >= 100 then $newVal = 100-$newVal ElseIf $newVal < 0 then $newVal = 100+$newVal EndIf Local $theVal = StringFormat("%#.2f", $newVal) Local $splitVal = StringSplit($theVal, '.') Local $firstVal = StringFormat("%02d", $newVal) Local $finalVal = $firstVal & '.' & $splitVal[$splitVal[0]] Local $theDot = StringInStr($finalVal, '.') Local $iCount = StringLen($finalVal) GUICtrlSetData($theInputCtrl, $finalVal) If $edittingNumber = 1 Then _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) ;<---- not overriding the original function... Else _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) ;<---- not overriding the original function... EndIf Return True ;<---- ...even with return value EndIf EndSwitch Return $GUI_RUNDEFMSG EndFunc Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam) Local $nID = BitAND($iwParam, 0x0000FFFF) #forceref $hWnd, $iMsg, $iwParam, $ilParam $iCode = _WinAPI_HiWord($iwParam) Switch $nID Case $cDotDummy If NOT $inputHasFocus then Return $GUI_RUNDEFMSG Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') If NOT $theDot Then If $curRead = '' Then GUICtrlSetData($theInputCtrl, '00.') Else Local $iPos = _GUICtrlEdit_GetSel($theInputCtrl) If IsArray($iPos) Then Local $finalVal = StringFormat("%02d", Number(StringLeft($curRead, $iPos[0]))) & '.' & StringTrimLeft($curRead, $iPos[0]) GUICtrlSetData($theInputCtrl, $finalVal) EndIf EndIf Else Local $leftSide = StringFormat("%02d", Number(StringLeft($curRead, $theDot))) Local $rightSide = StringFormat("%02d", Number(StringTrimLeft($curRead, $theDot))) Local $finalVal = $leftSide & '.' & $rightSide GUICtrlSetData($theInputCtrl, $finalVal) $theDot = StringInStr($finalVal, '.') $iCount = StringLen($finalVal) _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) EndIf $edittingNumber = 2 Case $cUpDummy If NOT $inputHasFocus then Return $GUI_RUNDEFMSG _FixTheInput() Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') Local $splitVal = StringSplit($curRead, '.') If $splitVal[0] < 2 then Return $GUI_RUNDEFMSG Local $finalVal If $edittingNumber = 1 Then Local $newVal = $splitVal[1]+1 If $newVal >= 100 then $newVal = 100-$newVal $finalVal = StringFormat("%02d", $newVal) & '.' & StringFormat("%02d", Number($splitVal[2])) GUICtrlSetData($theInputCtrl, $finalVal) _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) Else Local $newVal = $splitVal[2]+1 If $newVal >= 100 then $newVal = 100-$newVal $splitVal[1] += 1 If $splitVal[1] >= 100 then $splitVal[1] = 100-$splitVal[1] EndIf $finalVal = StringFormat("%02d", $splitVal[1]) & '.' & StringFormat("%02d", Number($newVal)) GUICtrlSetData($theInputCtrl, $finalVal) _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) EndIf Return True Case $cDownDummy If NOT $inputHasFocus then Return $GUI_RUNDEFMSG _FixTheInput() Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') Local $splitVal = StringSplit($curRead, '.') If $splitVal[0] < 2 then Return $GUI_RUNDEFMSG Local $finalVal If $edittingNumber = 1 Then Local $newVal = $splitVal[1]-1 If $newVal < 0 then $newVal = 100+$newVal $finalVal = StringFormat("%02d", $newVal) & '.' & StringFormat("%02d", Number($splitVal[2])) GUICtrlSetData($theInputCtrl, $finalVal) _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) Else Local $newVal = $splitVal[2]-1 If $newVal < 0 then $newVal = 100+$newVal $splitVal[1] -= 1 If $splitVal[1] < 0 then $splitVal[1] = 100+$splitVal[1] EndIf $finalVal = StringFormat("%02d", $splitVal[1]) & '.' & StringFormat("%02d", Number($newVal)) GUICtrlSetData($theInputCtrl, $finalVal) _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) EndIf Return True Case $cLeftDummy If NOT $inputHasFocus then Return $GUI_RUNDEFMSG _FixTheInput() Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') If $edittingNumber = 2 Then $edittingNumber = 1 EndIf _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) Return True Case $cRightDummy If NOT $inputHasFocus then Return $GUI_RUNDEFMSG _FixTheInput() Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') If $edittingNumber = 1 Then $edittingNumber = 2 EndIf _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) Return True Case $theInputCtrl Switch $iCode Case $EN_SETFOCUS $inputHasFocus = True Case $EN_KILLFOCUS $inputHasFocus = False _FixTheInput() ;~ Case $EN_CHANGE ;I tried this too, but no luck... ;~ Local $curRead = GUICtrlRead($theInputCtrl) ;~ Local $iCount = StringLen($curRead) ;~ Local $theDot = StringInStr($curRead, '.') ;~ If $edittingNumber = 1 Then ;~ _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) ;~ Else ;~ _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) ;~ EndIf EndSwitch EndSwitch Return $GUI_RUNDEFMSG EndFunc Func _FixTheInput() Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') If NOT $theDot Then If $curRead = '' Then GUICtrlSetData($theInputCtrl, '00.00') Else If $iCount >= 3 then $curRead = StringFormat("%.2f", $curRead/((10^$iCount)/100)) EndIf Local $firstNumber = StringFormat("%02d", $curRead) $theDot = StringInStr($curRead, '.') Local $secondNumber = '00' If $theDot then $secondNumber = Number(StringTrimLeft($curRead, $theDot)) If StringLen($secondNumber) = 1 then $secondNumber &= '0' EndIf GUICtrlSetData($theInputCtrl, $firstNumber & '.' & $secondNumber) EndIf Else Local $firstNumber = StringFormat("%02d", Number(StringLeft($curRead, $theDot))) Local $secondNumber = Number(StringTrimLeft($curRead, $theDot)) If StringLen($secondNumber) = 1 then $secondNumber &= '0' GUICtrlSetData($theInputCtrl, $firstNumber & '.' & $secondNumber) EndIf EndFunc Func _EditWindowProc($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam Switch $hWnd case GUICtrlGetHandle($theInputCtrl) Switch $iMsg Case $WM_GETDLGCODE Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') Switch $wParam Case 48 to 57 If $iCount >= 2 then If NOT $theDot Then Local $iPos = _GUICtrlEdit_GetSel($theInputCtrl) If IsArray($iPos) Then If $iPos[0] = 2 Then GUICtrlSetData($theInputCtrl, $curRead & '.') Return _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) Else Local $finalVal = StringLeft($curRead, $iPos[0]) & ($wParam-48) & '.' & StringTrimLeft($curRead, $iPos[0]) GUICtrlSetData($theInputCtrl, $finalVal) Return True EndIf EndIf Else Local $iPos = _GUICtrlEdit_GetSel($theInputCtrl) If IsArray($iPos) Then Switch $iPos[0] Case 0 _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) Case 2 _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) EndSwitch EndIf EndIf EndIf EndSwitch Case 533 Local $curRead = GUICtrlRead($theInputCtrl) Local $iCount = StringLen($curRead) Local $theDot = StringInStr($curRead, '.') If NOT $theDot Then If $curRead = '' Then GUICtrlSetData($theInputCtrl, '00.00') Else Local $firstNumber = StringFormat("%02d", Number($curRead)) GUICtrlSetData($theInputCtrl, $firstNumber & '.00') EndIf Else _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) Local $iPos = _GUICtrlEdit_GetSel($theInputCtrl) If IsArray($iPos) Then If $iPos[0] <> $iPos[1] then Return True If $iPos[0] < $theDot Then $edittingNumber = 1 _GUICtrlEdit_SetSel($theInputCtrl, 0, $theDot-1) Else $edittingNumber = 2 _GUICtrlEdit_SetSel($theInputCtrl, $theDot, $iCount) EndIf Return True EndIf EndIf EndSwitch EndSwitch Return _WinAPI_CallWindowProc($wProcOldLocal, $hWnd, $iMsg, $wParam, $lParam) EndFunc Features are: - Auto-adding dot: You can type number like: 4567, but you will get: 45.67 - Detecting manual typed dot: If you type 5, then press dot, and type 33, you will get: 05.33 - you can press keyboard left/right to focus on that part of the number - keyboard up/down to change value of the selected number part - using UpDownControl you can change value of the selected number part (partially working like the one in Date control, because it's not selecting that part after changing it's value, but it's selecting entire input) - Auto-configuring format style if the input control lost the focus (like Date control is using) Edited March 21, 2013 by dragan 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