AlphaNumeric StringGadget

Just starting out? Need help? Post your questions and find answers here.
User avatar
DarkRookie
User
User
Posts: 20
Joined: Wed Nov 24, 2010 5:47 pm

AlphaNumeric StringGadget

Post by DarkRookie »

I have a StringGadget that needs to be alphanumeric characters only.
Search thru the forums and purearea have yielded no results.
It is better to have a dumb question than a wrong answer!
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: AlphaNumeric StringGadget

Post 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.
User avatar
TomS
Enthusiast
Enthusiast
Posts: 342
Joined: Sun Mar 18, 2007 2:26 pm
Location: Munich, Germany

Re: AlphaNumeric StringGadget

Post 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
User avatar
Frarth
Enthusiast
Enthusiast
Posts: 241
Joined: Tue Jul 21, 2009 11:11 am
Location: On the planet
Contact:

Re: AlphaNumeric StringGadget

Post 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)
PureBasic 5.41 LTS | Xubuntu 16.04 (x32) | Windows 7 (x64)
Post Reply