ttleser Posted April 30, 2009 Share Posted April 30, 2009 I've got a GUI input box and I need it to tell me when I'm inputting anything other than...A. Only Numbers (ex. 0340384)orB. Numbers with a single period with more numbers (3434.9834) or (.049) or (438.9)I'm basically looking for have the input box act just like it were a calculator input (only numbers and one decimal point), though my new script isn't for a calculator.I'm using MrCreators script >> http://www.autoitscript.com/forum/index.ph...OnlyNumbers.au3 and I've tried modifying the script many ways, I can get it to do only numbers and a single period, but if a 2nd period is typed it erases the 1st..Here's MrCreator's script:expandcollapse popup#include-once #include <GuiConstants.au3> If Not IsDeclared("WM_COMMAND") Then Global Const $WM_COMMAND = 0x0111 If Not IsDeclared("WM_MOVE") Then Global Const $WM_MOVE = 0x0003 If Not IsDeclared("WM_LBUTTONDOWN") Then Global Const $WM_LBUTTONDOWN = 0x0201 If Not IsDeclared("WM_RBUTTONDOWN") Then Global Const $WM_RBUTTONDOWN = 0x0204 Global $sToolTip_Text[2] = ["You can only type a number or period here", "Unacceptable Character:"] Global $sInputs_Array[1] GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") GUIRegisterMsg($WM_MOVE, "WM_CLEAR_TOOLTIP") GUIRegisterMsg($WM_LBUTTONDOWN, "WM_CLEAR_TOOLTIP") GUIRegisterMsg($WM_RBUTTONDOWN, "WM_CLEAR_TOOLTIP") ; $CtrlId must be an ID value, -1 can not be used! Func _GuiInputSetOnlyNumbers($CtrlId) Local $iUbound = UBound($sInputs_Array) ReDim $sInputs_Array[$iUbound+1] $sInputs_Array[$iUbound] = $CtrlId EndFunc Func _Input_Changed($hWnd, $CtrlId) ToolTip("") Local $Read_Input = GUICtrlRead($CtrlId) If StringRegExp($Read_Input, '[^0-9][^.]{0,1}') Then GUICtrlSetData($CtrlId, StringRegExpReplace($Read_Input, '[^0-9][^\.]', '')) Local $Gui_Get_Pos = WinGetPos($hWnd) Local $Ctrl_Get_Pos = ControlGetPos($hWnd, "", $CtrlId) Local Const $SM_CYCAPTION = 4;Titelbar heigth Local Const $SM_CXFIXEDFRAME = 7;Window border size Local $X_Pos = $Gui_Get_Pos[0] + $Ctrl_Get_Pos[0] + $Ctrl_Get_Pos[2] + GetSystemMetrics($SM_CXFIXEDFRAME) Local $Y_Pos = $Gui_Get_Pos[1] + $Ctrl_Get_Pos[1] + $Ctrl_Get_Pos[3] + GetSystemMetrics($SM_CYCAPTION) ToolTip($sToolTip_Text[0], $X_Pos, $Y_Pos, $sToolTip_Text[1], 3, 1+4) DllCall("user32.dll", "int", "MessageBeep", "int", 0x0) EndIf EndFunc Func WM_CLEAR_TOOLTIP($hWnd, $iMsg, $wParam, $lParam) ToolTip("") Return $GUI_RUNDEFMSG EndFunc Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) If $hWnd = 0 Or Not WinExists($hWnd) Then Return $GUI_RUNDEFMSG Local $nNotifyCode = BitShift($wParam, 16) Local $nID = BitAND($wParam, 0xFFFF) Local Const $EN_CHANGE = 0x300 Local Const $EN_UPDATE = 0x400 Local Const $EN_SETFOCUS = 0x100 Local Const $EN_KILLFOCUS = 0x200 For $i = 1 To UBound($sInputs_Array)-1 If $nID = $sInputs_Array[$i] Then Switch $nNotifyCode Case $EN_UPDATE;$EN_CHANGE _Input_Changed($hWnd, $sInputs_Array[$i]) Case $EN_SETFOCUS, $EN_KILLFOCUS ToolTip("") EndSwitch ExitLoop EndIf Next Return $GUI_RUNDEFMSG EndFunc Func GetSystemMetrics($Flag) Local $iRet = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $Flag) Return $iRet[0] EndFuncAnd here's the testing code#include <GuiConstants.au3> #include <GUIInputSetOnlyNumbers.au3> $GUI = GUICreate("_GUIInputSetOnlyNumbers() Demo", 400, 100) $Input_1 = GUICtrlCreateInput("", 20, 10, 360, 20) _GuiInputSetOnlyNumbers($Input_1) $Input_2 = GUICtrlCreateInput("", 20, 40, 360, 20) _GuiInputSetOnlyNumbers($Input_2) $Exit = GUICtrlCreateButton("Exit", 20, 70, 60, 20) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $Exit ExitLoop EndSwitch WEndI'm thinking the problem is with these lines...If StringRegExp($Read_Input, '[^0-9][^.]{0,1}') Then GUICtrlSetData($CtrlId, StringRegExpReplace($Read_Input, '[^0-9][^\.]', '')) Link to comment Share on other sites More sharing options...
GEOSoft Posted April 30, 2009 Share Posted April 30, 2009 (edited) "([\d]*\.?[\d]+)|([\d+])" EDIT: Not tested but this probably works too "([\d]*\.?[\d]+)" Edited April 30, 2009 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
ttleser Posted April 30, 2009 Author Share Posted April 30, 2009 Thanks for the reply, but that didn't work. Anything I type in the box immediately gives me the message saying I've typed something that it doesn't like. Here's what I changed: If StringRegExp($Read_Input, "([\d]*\.?[\d]+)|([\d+])") Then GUICtrlSetData($CtrlId, StringRegExpReplace($Read_Input, '[^0-9][^\.]', '')) Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted April 30, 2009 Moderators Share Posted April 30, 2009 (edited) Global $s_data = ".399.049.3939testing3990.888" $s_data = _Give_Me_Only_Digits_And_One_Decimal($s_data) ConsoleWrite($s_data & @CRLF) Func _Give_Me_Only_Digits_And_One_Decimal($s_data) If StringRegExp($s_data, "(?:\..*?\.|(?!\.)\D)") = 0 Then Return $s_data Local $a_sre = StringRegExp($s_data, "^\d*\.", 1) If Not @error Then Return StringRegExpReplace($s_data, "^(" & $a_sre[0] & ")|(?:(\D+)|(\d+))", "\1\3") EndIf Return StringRegExpReplace($s_data, "(\d+)|(\D+)", "\1") EndFunc Edit: Actually, this would probably be just fine:Func _Give_Me_Only_Digits_And_One_Decimal($s_data) If StringRegExp($s_data, "(?:\..*?\.|(?!\.)\D)") = 0 Then Return $s_data Return StringRegExpReplace($s_data, "^(\d*\.\d*)|(?:(\D+)|(\d+))", "\1\3") EndFunc Edited April 30, 2009 by SmOke_N Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Malkey Posted April 30, 2009 Share Posted April 30, 2009 If SmOke_N's example works, use his.Here is another.expandcollapse popup; #include <GuiConstants.au3> If Not IsDeclared("WM_COMMAND") Then Global Const $WM_COMMAND = 0x0111 If Not IsDeclared("WM_MOVE") Then Global Const $WM_MOVE = 0x0003 If Not IsDeclared("WM_LBUTTONDOWN") Then Global Const $WM_LBUTTONDOWN = 0x0201 If Not IsDeclared("WM_RBUTTONDOWN") Then Global Const $WM_RBUTTONDOWN = 0x0204 Global $sToolTip_Text[2] = ["You can only type a number or period here", "Unacceptable Character:"] Global $sInputs_Array[1], $flag = 0 GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND") GUIRegisterMsg($WM_MOVE, "WM_CLEAR_TOOLTIP") GUIRegisterMsg($WM_LBUTTONDOWN, "WM_CLEAR_TOOLTIP") GUIRegisterMsg($WM_RBUTTONDOWN, "WM_CLEAR_TOOLTIP") $GUI = GUICreate("_GUIInputSetOnlyNumbers() Demo", 400, 100) $Input_1 = GUICtrlCreateInput("", 20, 10, 360, 20) _GuiInputSetOnlyNumbers($Input_1) $Input_2 = GUICtrlCreateInput("", 20, 40, 360, 20) _GuiInputSetOnlyNumbers($Input_2) $Exit = GUICtrlCreateButton("Exit", 20, 70, 60, 20) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $Exit ExitLoop EndSwitch WEnd ; $CtrlId must be an ID value, -1 can not be used! Func _GuiInputSetOnlyNumbers($CtrlId) Local $iUbound = UBound($sInputs_Array) ReDim $sInputs_Array[$iUbound + 1] $sInputs_Array[$iUbound] = $CtrlId EndFunc ;==>_GuiInputSetOnlyNumbers Func _Input_Changed($hWnd, $CtrlId) ToolTip("") Local $Read_Input = GUICtrlRead($CtrlId) StringReplace($Read_Input, ".", ".") Local $Num = @extended; Number of decimal points present If $Num > 1 Then $flag = 1; Stops 2 decimal points If $Num = 1 Then; one decimal point is present Local $aAns = StringSplit($Read_Input, ".") Local $iAns1 = StringLen($aAns[1]); Number of digits before decimal point. Local $iAns2 = StringLen($aAns[2]); Number of digits after decimal point. ;(3434.9834) or (.049) or (438.9) <-- Prevent these numbers occurring If ($iAns1 = 4 And $iAns2 > 4) Or ($iAns1 = "" And $iAns2 > 3) Or ($iAns1 = 3 And $iAns2 > 1) Then $flag = 1 EndIf If StringRegExp($Read_Input, '[^0-9\.][^.]{0,1}') Or $flag = 1 Then GUICtrlSetData($CtrlId, StringTrimRight($Read_Input, 1)); Remove last character entered. ;GUICtrlSetData($CtrlId, StringRegExpReplace($Read_Input, '[^0-9\.][^\.]', '')) Local $Gui_Get_Pos = WinGetPos($hWnd) Local $Ctrl_Get_Pos = ControlGetPos($hWnd, "", $CtrlId) Local Const $SM_CYCAPTION = 4;Titelbar heigth Local Const $SM_CXFIXEDFRAME = 7;Window border size $X_Pos = $Gui_Get_Pos[0] + $Ctrl_Get_Pos[0] + $Ctrl_Get_Pos[2] + GetSystemMetrics($SM_CXFIXEDFRAME) $Y_Pos = $Gui_Get_Pos[1] + $Ctrl_Get_Pos[1] + $Ctrl_Get_Pos[3] + GetSystemMetrics($SM_CYCAPTION) ToolTip($sToolTip_Text[0], $X_Pos, $Y_Pos, $sToolTip_Text[1], 3, 1 + 4) DllCall("user32.dll", "int", "MessageBeep", "int", 0x0) $flag = 0 EndIf EndFunc ;==>_Input_Changed Func WM_CLEAR_TOOLTIP($hWnd, $iMsg, $wParam, $lParam) ToolTip("") Return $GUI_RUNDEFMSG EndFunc ;==>WM_CLEAR_TOOLTIP Func MY_WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) If $hWnd = 0 Or Not WinExists($hWnd) Then Return $GUI_RUNDEFMSG Local $nNotifyCode = BitShift($wParam, 16) Local $nID = BitAND($wParam, 0xFFFF) Local Const $EN_CHANGE = 0x300 Local Const $EN_UPDATE = 0x400 Local Const $EN_SETFOCUS = 0x100 Local Const $EN_KILLFOCUS = 0x200 For $i = 1 To UBound($sInputs_Array) - 1 If $nID = $sInputs_Array[$i] Then Switch $nNotifyCode Case $EN_UPDATE;$EN_CHANGE _Input_Changed($hWnd, $sInputs_Array[$i]) Case $EN_SETFOCUS, $EN_KILLFOCUS ToolTip("") EndSwitch ExitLoop EndIf Next Return $GUI_RUNDEFMSG EndFunc ;==>MY_WM_COMMAND Func GetSystemMetrics($flag) Local $iRet = DllCall('user32.dll', 'int', 'GetSystemMetrics', 'int', $flag) Return $iRet[0] EndFunc ;==>GetSystemMetrics ;About line #56, you can add more conditional expressions to the "If" statement to produce a fail on input if required. Link to comment Share on other sites More sharing options...
GEOSoft Posted April 30, 2009 Share Posted April 30, 2009 Is there something wrong with the simple approach? Local $Read_Input = GUICtrlRead($CtrlId) ;; Add code for multiple decimal points here. If NOT StringRegExp(StringRight($Read_Input, 1), "\.|\d") Then $Read_Input = StringTrimRight($Read_Input, 1) GUICtrlSetData($CtrlId, $Read_Input) EndIf George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
ttleser Posted April 30, 2009 Author Share Posted April 30, 2009 Thanks all that replied, but I used Malkey's code as his allowed the same type of reaction like I was looking for where it would have the tooltip pop up if something wrong was typed...@Malkey - LOL. I tested it and found that it would error if I had entered a value with more than 3 digits to the right of the decimal point... What I posted was an example of what I was looking for.. I removed the IF statement and it functions exactly like what I needed. ;(3434.9834) or (.049) or (438.9) <-- Prevent these numbers occurring If ($iAns1 = 4 And $iAns2 > 4) Or ($iAns1 = "" And $iAns2 > 3) Or ($iAns1 = 3 And $iAns2 > 1) Then $flag = 1Question though. What would I need to do to restrict the value to only greater than a .05? Doesn't matter what's on the left side of the decimal point, but the right can only be .05 or greater.. .01, .001 wouldn't work, but .05, .06 or greater would. My program needs to restrict the input to only 2 digits on the right side of the decimal point but it can't be less than .05.Is it possible to have 2 tooltips come up depending on the issue? If I tried to type period twice or a non-number it would have the normal saying of "You can only type a number or period here", but if you tried to type a value less than .05, it would say ".05 is the maximum value on the right of the decimal point" (or something like that).Thanks much! Link to comment Share on other sites More sharing options...
GEOSoft Posted April 30, 2009 Share Posted April 30, 2009 If Number($sStr) < .05 Then ....Do whatever George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted April 30, 2009 Moderators Share Posted April 30, 2009 Thanks all that replied, but I used Malkey's code as his allowed the same type of reaction like I was looking for where it would have the tooltip pop up if something wrong was typed...Kind of silly really. The first line of the function code I provided could have been modded to your needs without error. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
ttleser Posted April 30, 2009 Author Share Posted April 30, 2009 @GeoSoft - I don't think that'll work. What if it were 3.03 or 13.04? Would it still "Do whatever" in those instances? I want the script to say "Look, I don't care what numbers are on the left of the period, but what's on the right of the period better not be less than .05" Link to comment Share on other sites More sharing options...
ttleser Posted April 30, 2009 Author Share Posted April 30, 2009 Actually, I figured something out. I added some more code, might be clunky but it works. Add 2 more IF statements to the _Input_Changed function. If (StringInStr($Read_Input,".") <> 0 AND StringMid($Read_Input,(StringInStr($Read_Input,".")+1),1) = 0 AND StringMid($Read_Input,(StringInStr($Read_Input,".")+2),1) < 5 AND $iAns2 >= 2) Then $flag = 2 AND If StringRegExp($Read_Input, '[^0-9\.][^.]{0,1}') OR $flag = 2 Then GUICtrlSetData($CtrlId, StringTrimRight($Read_Input, 1)); Remove last character entered. ;GUICtrlSetData($CtrlId, StringRegExpReplace($Read_Input, '[^0-9\.][^\.]', '')) Local $Gui_Get_Pos = WinGetPos($hWnd) Local $Ctrl_Get_Pos = ControlGetPos($hWnd, "", $CtrlId) Local Const $SM_CYCAPTION = 4;Titelbar heigth Local Const $SM_CXFIXEDFRAME = 7;Window border size $X_Pos = $Gui_Get_Pos[0] + $Ctrl_Get_Pos[0] + $Ctrl_Get_Pos[2] + GetSystemMetrics($SM_CXFIXEDFRAME) $Y_Pos = $Gui_Get_Pos[1] + $Ctrl_Get_Pos[1] + $Ctrl_Get_Pos[3] + GetSystemMetrics($SM_CYCAPTION) ToolTip(".05 is the minimum value", $X_Pos, $Y_Pos, $sToolTip_Text[1], 3, 1 + 4) DllCall("user32.dll", "int", "MessageBeep", "int", 0x0) $flag = 0 EndIf Link to comment Share on other sites More sharing options...
GEOSoft Posted May 1, 2009 Share Posted May 1, 2009 (edited) Sorry I didn't get back sooner. I thought any number larger than .05 was okay. To do what you want I should have posted If Number(StringMid($sStr, StringInStr($sStr, "."))) < .05 Then ....Do whatever Edited May 1, 2009 by GEOSoft George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!" 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