Qwerty212 Posted June 28, 2015 Share Posted June 28, 2015 Hello. I come from: https://www.autoitscript.com/forum/topic/125747-ask-format-number-as-we-type/One user was asking if it would be possible to give format to numbers as he was typping in an input.He wanted to add a thousands separator (I know that there are a lot of examples around the forum, but this case was very interesting because he was asking about formatting in real time as the user enters data).I want to create a simple data collection for my job. I don't need negative numbers or decimal places. I want that the user cant input how many pieces there were at the morning, how many at the night and perform a simple subtract My goal is to do something like this: This is a reduced copy of my code:expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstants.au3> Global $mainGUI = GUICreate("", 410, 75, -1, -1) GUISetState(@SW_SHOW, $mainGUI) WinSetOnTop($mainGUI, "", 1) GUICtrlCreateLabel("Quantity at morning",5,8,130,33,$ES_CENTER) Local $firstnumber = GUICtrlCreateInput("", 5, 30, 130, 35, BitOR($ES_NUMBER, $ES_CENTER)) GUICtrlSetFont(-1, 16, 700) GUICtrlCreateLabel("Quantity at night",140,8,130,33,$ES_CENTER) Local $secondnumber = GUICtrlCreateInput("", 140, 30, 130, 35, BitOR($ES_NUMBER, $ES_CENTER)) GUICtrlSetFont(-1, 16, 700) GUICtrlCreateLabel("Pieces produced today",275,8,130,33,$ES_CENTER) Local $lastnumber = GUICtrlCreateInput("", 275, 30, 130, 35, BitOR($ES_NUMBER, $ES_CENTER)) GUICtrlSetFont(-1, 16, 700) GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local $iIDFrom = BitAND($wParam, 0xFFFF);LoWord Local $iCode = BitShift($wParam, 16) ;HiWord Local $sDecimal = "" If $iIDFrom = $firstnumber And $iCode = $EN_CHANGE Then $sInput = GUICtrlRead($firstnumber) Local $Output = _StringAddThousandsSep($sInput) GUICtrlSetData($firstnumber, $Output) EndIf If $iIDFrom = $secondnumber And $iCode = $EN_CHANGE Then $sInput = GUICtrlRead($secondnumber) Local $Output = _StringAddThousandsSep($sInput) GUICtrlSetData($secondnumber, $Output) If GUICtrlRead($firstnumber) <> "" Then $first = GUICtrlRead($firstnumber) StringRegExpReplace($first, ".", ""); I remove the thousand separator from the string $second = GUICtrlRead($secondnumber) StringRegExpReplace($second, ".", "") $diff = Number($second) - Number($first) Local $Output = _StringAddThousandsSep($diff) GUICtrlSetData($lastnumber, $Output) EndIf EndIf If $iIDFrom = $lastnumber And $iCode = $EN_CHANGE Then $sInput = GUICtrlRead($lastnumber) Local $Output = _StringAddThousandsSep($sInput) GUICtrlSetData($lastnumber, $Output) EndIf EndFunc ;==>_WM_COMMAND Func _StringAddThousandsSep($s_string, $i_convert_lcid = -1, $i_current_lcid = -1) ; $LOCALE_USER_DEFAULT = 0x0400 If $i_current_lcid = -1 Or $i_current_lcid = Default Then $i_current_lcid = 0x0400 If $i_convert_lcid = -1 Or $i_convert_lcid = Default Then $i_convert_lcid = 0x0400 ; Get lcid decimal and thousands separators Local $t_buff_tmp = DllStructCreate("char[4]") DllCall("kernel32.dll", "int", "GetLocaleInfo", "int", $i_current_lcid, _ "int", 0x0E, "ptr", DllStructGetPtr($t_buff_tmp), "int", 4) If @error Then Return SetError(1, 0, "") Local $s_cur_dec = DllStructGetData($t_buff_tmp, 1) DllCall("kernel32.dll", "int", "GetLocaleInfo", "int", $i_convert_lcid, _ "int", 0x0E, "ptr", DllStructGetPtr($t_buff_tmp), "int", 4) If @error Then Return SetError(1, 0, "") Local $s_con_dec = DllStructGetData($t_buff_tmp, 1) DllCall("kernel32.dll", "int", "GetLocaleInfo", "int", $i_convert_lcid, _ "int", 0x0F, "ptr", DllStructGetPtr($t_buff_tmp), "int", 4) If @error Then Return SetError(1, 0, "") Local $s_con_tho = DllStructGetData($t_buff_tmp, 1) ; For later formatting Local $i_number = StringRegExpReplace($s_string, "(\" & $s_cur_dec & "\d+\z)|(^-|\d+)|(\D)", "$2") Local $i_dec = StringRegExpReplace($s_string, "(.+?\" & $s_cur_dec & ")(\d+\z)", "$2") If @extended = 0 Then $i_dec = "" Local $i_str_len = StringLen($s_string) * 4 Local $t_numberfmt = DllStructCreate("uint;uint;uint;ptr;ptr;uint") Local $t_thousands = DllStructCreate("wchar[2]") Local $t_decimal = DllStructCreate("wchar[2]") Local $t_buffer = DllStructCreate("wchar[" & $i_str_len & "]") DllStructSetData($t_thousands, 1, $s_con_tho) DllStructSetData($t_decimal, 1, $s_con_dec) DllStructSetData($t_numberfmt, 3, 3) DllStructSetData($t_numberfmt, 4, DllStructGetPtr($t_decimal)) DllStructSetData($t_numberfmt, 5, DllStructGetPtr($t_thousands)) DllStructSetData($t_numberfmt, 6, 1) DllCall("kernel32.dll", "int", "GetNumberFormatW", _ "int", $i_convert_lcid, "int", 0, _ "wstr", $i_number, "ptr", DllStructGetPtr($t_numberfmt), _ "ptr", DllStructGetPtr($t_buffer), "int", $i_str_len) If $i_dec = "" Then $s_con_dec = "" Return DllStructGetData($t_buffer, 1) & $s_con_dec & $i_dec EndFunc ;==>_StringAddThousandsSepThanks to the examples in the forum it format the numbers to show on screen a point (".") as thousand separator in real time as I type in the inputs, but when I'm trying to perform a simple maths operation with numbers that use the separator the results are:Any idea or hint would be pretty much aprecciatted. I have tried to change the value of $i_convert_lcid = 0x0400 to spanish values and the result wans't better.Any help or tip would be pretty apreciatted. Greets from Barcelona Link to comment Share on other sites More sharing options...
mikell Posted June 28, 2015 Share Posted June 28, 2015 You don't need a so complicated thing...Please try thisexpandcollapse popup#include <WindowsConstants.au3> #include <GUIConstants.au3> Global $mainGUI = GUICreate("", 410, 75, -1, -1) GUICtrlCreateLabel("Quantity at morning",5,8,130,33,$ES_CENTER) Local $firstnumber = GUICtrlCreateInput("", 5, 30, 130, 35, BitOR($ES_NUMBER, $ES_CENTER)) GUICtrlSetFont(-1, 16, 700) GUICtrlCreateLabel("Quantity at night",140,8,130,33,$ES_CENTER) Local $secondnumber = GUICtrlCreateInput("", 140, 30, 130, 35, BitOR($ES_NUMBER, $ES_CENTER)) GUICtrlSetFont(-1, 16, 700) GUICtrlCreateLabel("Pieces produced today",275,8,130,33,$ES_CENTER) Local $lastnumber = GUICtrlCreateInput("", 275, 30, 130, 35, BitOR($ES_READONLY, $ES_CENTER)) GUICtrlSetFont(-1, 16, 700) GUICtrlSetBkColor(-1, 0xffffff) GUISetState(@SW_SHOW, $mainGUI) GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd ;============================================= Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) Local $iIDFrom = BitAND($wParam, 0xFFFF);LoWord Local $iCode = BitShift($wParam, 16) ;HiWord If $iCode = $EN_CHANGE Then If $iIDFrom = $firstnumber Then $sInput = GUICtrlRead($firstnumber) GUICtrlSetData($firstnumber, StringRegExpReplace(StringReplace($sInput, " ", ""), '(?<=\d)(?=(\d{3})+(?!\d))', " ")) EndIf If $iIDFrom = $secondnumber Then $sInput = GUICtrlRead($secondnumber) GUICtrlSetData($secondnumber, StringRegExpReplace(StringReplace($sInput, " ", ""), '(?<=\d)(?=(\d{3})+(?!\d))', " ")) EndIf $first = Number(StringReplace(GUICtrlRead($firstnumber), " ", "")) $second = Number(StringReplace(GUICtrlRead($secondnumber), " ", "")) If $second >= $first Then $diff = $second - $first GUICtrlSetData($lastnumber, StringRegExpReplace($diff, '(?<=\d)(?=(\d{3})+(?!\d))', " ")) Else GUICtrlSetData($lastnumber, "0") EndIf EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_WM_COMMAND Qwerty212 1 Link to comment Share on other sites More sharing options...
UEZ Posted June 28, 2015 Share Posted June 28, 2015 Something similar was already discussed here: https://www.autoitscript.com/forum/topic/170558-guictrlcreateinput-to-accept-only-formattted-numbers Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Qwerty212 Posted June 29, 2015 Author Share Posted June 29, 2015 @Mikell, it worked like a charm. I just have to add the point to:StringRegExpReplace(StringReplace($sInput, ".", ""), '(?<=\d)(?=(\d{3})+(?!\d))', "."))to get what I needed.Something similar was already discussed here: https://www.autoitscript.com/forum/topic/170558-guictrlcreateinput-to-accept-only-formattted-numbersI spent like 2 hours looking for examples, but I was more focused on the fact that there was going to be a huge difference due to the need of perform formating as I was typping Greets from Barcelona Link to comment Share on other sites More sharing options...
ViciousXUSMC Posted June 29, 2015 Share Posted June 29, 2015 Wow that _WM_COMMAND is like another language to me. I would love to understand more how/why it works.Last time I looked up Hiword/LoWord I almost gave myself an aneurysm. Link to comment Share on other sites More sharing options...
mikell Posted June 30, 2015 Share Posted June 30, 2015 Did you read this ?https://www.autoitscript.com/wiki/Tutorial_GUIRegisterMsg Link to comment Share on other sites More sharing options...
ViciousXUSMC Posted June 30, 2015 Share Posted June 30, 2015 No, good read though. Helps understand a bit of what is happening but not the underlying framework, that would involve a lot more research. 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