Page 1 of 1

AlphaNumeric StringGadget

Posted: Fri Jan 21, 2011 1:21 am
by DarkRookie
I have a StringGadget that needs to be alphanumeric characters only.
Search thru the forums and purearea have yielded no results.

Re: AlphaNumeric StringGadget

Posted: Fri Jan 21, 2011 1:42 am
by kenmo
Here is a Windows-only version using a custom callback function.

Just threw it together quickly, so it is not the cleanest code...

But it can be easily changed to included spaces, underscores, etc.

Code: Select all

Procedure.i Alphanumeric(hwnd.i, umsg.i, wparam.i, lparam.i)
  Static OldProc.i
  If (OldProc = #Null)
    OldProc = GetWindowLongPtr_(hwnd, #GWL_USERDATA)
  EndIf
  If (umsg = #WM_CHAR)
    Select wparam
      Case 'A' To 'Z', 'a' To 'z', '0' To '9', #BS
        ProcedureReturn CallFunctionFast(OldProc, hwnd, umsg, wparam, lparam)
      Default
        ProcedureReturn #Null
    EndSelect
  Else
    ProcedureReturn CallFunctionFast(OldProc, hwnd, umsg, wparam, lparam)
  EndIf
EndProcedure

Procedure.i SetAlphaNumeric(Gadget.i)
  If (IsGadget(Gadget))
    SetWindowLongPtr_(GadgetID(Gadget), #GWL_USERDATA, GetWindowLongPtr_(GadgetID(Gadget), #GWL_WNDPROC))
    SetWindowLongPtr_(GadgetID(Gadget), #GWL_WNDPROC, @Alphanumeric())
  EndIf
EndProcedure

OpenWindow(0, 0, 0, 200, 40, "Alphanumeric", #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
StringGadget(0, 10, 10, 180, 20, "", #PB_Text_Center)

SetAlphaNumeric(0)
SetActiveGadget(0)

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Perhaps someone has a better cross-platform solution.

Re: AlphaNumeric StringGadget

Posted: Fri Jan 21, 2011 2:15 am
by TomS
There are two ways, that I know of.
Either you check the events in the mainloop or you create a callback for the gadget (subclassing). The latter works only for windows and is slightly more complicated. But you don't have so much stuff going on in the mainloop.
Since I'm not an API-crack, I can only show you the first method right now.

Ok, so there's one api-line, because SetGadgetText() sets the cursor in front of the whole string.

Code: Select all

OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StringGadget(0, 5, 5, 100, 20, "")
Repeat
	event = WaitWindowEvent(20)
	Select event
		Case #PB_Event_Gadget
			Select EventGadget()
				Case 0
					Select EventType()
						Case #PB_EventType_Change 
							content$ = GetGadgetText(0)
							If Len(content$) > Len(content_old$)
								temp$ = content$
								For char = 65 To 90
									temp$ = ReplaceString(temp$, Chr(char),"")
								Next
								For char = 97 To 122
									temp$ = ReplaceString(temp$, Chr(char),"")
								Next
								For char = 48 To 57
									temp$ = ReplaceString(temp$, Chr(char),"")
								Next
								If Len(temp$) > 0
									SetGadgetText(0, content_old$)
									SendMessage_(GadgetID(0), #EM_SETSEL, $FFFFFFF, $FFFFFFF) ;Move cursor to the end
									SetActiveGadget(0)
								Else
									content_old$ = content$
								EndIf 
							EndIf							
					EndSelect
			EndSelect 
	EndSelect	
Until event = #PB_Event_CloseWindow

Re: AlphaNumeric StringGadget

Posted: Fri Jan 21, 2011 7:28 am
by Frarth
If you want to code for all platforms, you may consider checking the strings' content by means of a filter. This is what I use whenever I need to check user input:

Code: Select all

;==================================================
; Filter String
; written by Frank Arthur (Frarth)
;==================================================
#AlphaNumeric = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
#Numeric = "0123456789"
#Number = #Numeric + "+-.,"
#PlainAscii = " !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + Chr(34)

Procedure.s FilterString(*String.Character, Filter.s)
  Protected c.s, r.s = ""
  ; include characters according to filter
  While *String\c
    c = Chr(*String\c)
    If FindString(Filter, c, 1)
      r + c
    EndIf
    *String + 1
  Wend
  ProcedureReturn r
EndProcedure

Procedure.b StringIncludes(Text.s, Filter.s)
  If FilterString(@Text, Filter) <> ""
    ProcedureReturn #True
  EndIf
EndProcedure

Procedure.b StringIs(Text.s, Filter.s)
  If Text = FilterString(@Text, Filter)
    ProcedureReturn #True
  EndIf
EndProcedure

s.s = "My daddy is 100 years old."
Debug FilterString(@s, #AlphaNumeric)
Debug FilterString(@s, #Numeric)

Debug StringIncludes(s, #AlphaNumeric)
Debug StringIncludes(s, #Numeric)

Debug StringIs(s, #AlphaNumeric)
Debug StringIs(s, #Numeric)