I hate to post the full code rather than a link to a PB file but I don't have access to my ftp server at the moment. I think you downloaded the wrong one from above. Here it is just in case.
Code: Select all
;-
; - Handle special case "" set that clears the current text.
; - Do I need the 'If HoldSelect\X <= __xm_Main()\MaxLength' line in the callback? Won't the limit handle it automatically.
;-
EnableExplicit
;-
Enumeration ; Special Case Formatting
#XM_Format_Currency
EndEnumeration
;-
Structure Char
c.c
EndStructure
Structure __s_xMask_Main
;
Gadget.l
;
Handle.l
;
TextMask.s
;
Text.s
;
PlaceHolder.c
;
RightToLeft.b
;
OldCallback.l
;
MaxLength.l
;
SelectAllOnFocus.b
; If True, when the the xMask gadget is selected it will select the whole line.
AdjustingText.b
; True if the callback is temporarily setting text.
EndStructure
;-
Global NewList __xm_Main.__s_xMask_Main()
;-
Procedure InsertCharacter(*HoldText.l, Index.l, Character.c)
;
CompilerIf #PB_Compiler_Unicode = #True
;
PokeC(*HoldText + (Index << 1), Character)
;
CompilerElse
;
PokeC(*HoldText + Index, Character)
;
CompilerEndIf
;
EndProcedure
;-
Procedure.l _xm_GetMaxLength(TextMask.s)
;
Define.Char *HoldChar
;
Define.b AllowAsNonFormatting
;
Define.l lResult
;
*HoldChar = @TextMask
;
While *HoldChar\c <> 0
;
If AllowAsNonFormatting
;
lResult + 1
;
AllowAsNonFormatting = #False
;
Else
;
If *HoldChar\c = '0'
; This is a required number field.
lResult + 1
;
ElseIf *HoldChar\c = '9'
; This is a non-required number field. Either a digit or a space is allowed here.
lResult + 1
;
ElseIf *HoldChar\c = 'L'
; A - Z, entry required
lResult + 1
;
ElseIf *HoldChar\c = '?'
; A - Z, entry optional.
lResult + 1
;
ElseIf *HoldChar\c = 'A'
; A - Z or 0 - 9, entry required.
lResult + 1
;
ElseIf *HoldChar\c = 'a'
; A - Z or 0 - 9, entry optional.
lResult + 1
;
ElseIf *HoldChar\c = '&'
; Any character or space, entry required.
lResult + 1
;
ElseIf *HoldChar\c = 'C'
; Any character or space, entry optional.
lResult + 1
;
ElseIf *HoldChar\c = ''
;
;
ElseIf *HoldChar\c = ' '
;
lResult + 1
;
ElseIf *HoldChar\c = '\'
; The 'force non-formatting character' character. Ignore this character and do not increase the maximum length.
AllowAsNonFormatting = #True
; The following character will be included in the display no matter what it is.
Else
; The character was a non-formating character. Add it as-is.
lResult + 1
; A display character always increases the length.
EndIf
;
EndIf
;
CompilerIf #PB_Compiler_Unicode = #True : *HoldChar + 2 : CompilerElse : *HoldChar + 1 : CompilerEndIf
;
Wend
;
ProcedureReturn lResult
;
EndProcedure
Procedure.s _xm_StripCharacters(xMask.__s_xMask_Main(), Text.s, IndexBegin.l)
; This procedure is used to to strip out unneeded characters in text being inserted into a mask.
Define.Char *HoldMask
;
Define.Char *HoldChar
;
Define.Char *OutText
;
Define.s HoldString
;
Define.b IsFormatting
;
Define.b FailedMask
;
Define.b ForceAdd
;
*HoldChar = @Text
;
*HoldMask = @xMask()\TextMask + (IndexBegin - 1)
;
HoldString = Space(Len(Text))
;
*OutText = @HoldString
;
While *HoldMask\c And *HoldChar\c
;
FailedMask = #True
;
If *HoldMask\c = '0'
; Required numeric field (0-9).
If *HoldChar\c > 47 And *HoldChar\c < 58 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '9'
; Non-required numeric field. A number (0-9) or a space is allowed.
If (*HoldChar\c > 47 And *HoldChar\c < 58) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'L'
; A - Z, entry required.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '?'
; A - Z, entry not required and may include spaces.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'A'
; A - Z or 0 - 9, entry required.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) Or (*HoldChar\c > 47 And *HoldChar\c < 58) : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'a'
; A - Z or 0 - 9, entry not required and may include spaces.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) Or (*HoldChar\c > 47 And *HoldChar\c < 58) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '&'
; Any character or space, entry required.
If *HoldChar\c > 32 And *HoldChar\c < 256 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'C'
; Any character or space, entry not required and may include spaces.
If (*HoldChar\c > 32 And *HoldChar\c < 256) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '>'
; Capitalize the following character.
IsFormatting = #True
;
ElseIf *HoldMask\c = '<'
; Decapitalize the following character.
IsFormatting = #True
;
ElseIf *HoldMask\c = '\'
; Add the next character as-is.
IsFormatting = #True
;
Else
;
ForceAdd = #True
;
If *HoldMask\c = *HoldChar\c : FailedMask = #False : EndIf
;
EndIf
;
If IsFormatting = #False
;
If FailedMask
;
ProcedureReturn Text
;
Else
;
If ForceAdd = #False
;
*OutText\c = *HoldChar\c
;
CompilerIf #PB_Compiler_Unicode = #True : *OutText + 2 : CompilerElse : *OutText + 1 : CompilerEndIf
;
EndIf
;
CompilerIf #PB_Compiler_Unicode = #True : *HoldChar + 2 : CompilerElse : *HoldChar + 1 : CompilerEndIf
;
EndIf
;
EndIf
;
ForceAdd = #False : IsFormatting = #False
;
CompilerIf #PB_Compiler_Unicode = #True : *HoldMask + 2 : CompilerElse : *HoldMask + 1 : CompilerEndIf
;
Wend
;
ProcedureReturn Left(HoldString, *OutText - @HoldString)
;
EndProcedure
Procedure.c _xm_ReturnCharacter(xMask.__s_xMask_Main(), Character.c, *Index.l, UsingPlaceholder.b = #False)
;
Define.Char *HoldMask
;
Define.b IsFormatting
;
Define.b FailedMask
;
Define.b ForceAdd
;
Define.l Position
;
Define.b DoUpper, DoLower, IsStatic
;
Define.l HoldIndex
;
*HoldMask = @xMask()\TextMask
;
While *HoldMask\c
;
FailedMask = #True
;
If ForceAdd
;
IsStatic = #True
;
Else
;
If *HoldMask\c = '0'
; Required numeric field (0-9).
If Character > 47 And Character < 58 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '9'
; Non-required numeric field. A number (0-9) or a space is allowed.
If (Character > 47 And Character < 58) Or Character = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'L'
; A - Z, entry required.
If (Character > 64 And Character < 91) Or (Character > 96 And Character < 123) : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '?'
; A - Z, entry not required and may include spaces.
If (Character > 64 And Character < 91) Or (Character > 96 And Character < 123) Or Character = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'A'
; A - Z or 0 - 9, entry required.
If (Character > 64 And Character < 91) Or (Character > 96 And Character < 123) Or (Character > 47 And Character < 58) : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'a'
; A - Z or 0 - 9, entry not required and may include spaces.
If (Character > 64 And Character < 91) Or (Character > 96 And Character < 123) Or (Character > 47 And Character < 58) Or Character = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '&'
; Any character or space, entry required.
If Character > 32 And Character < 256 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'C'
; Any character or space, entry not required and may include spaces.
If (Character > 32 And Character < 256) Or Character = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '>'
; Capitalize the following character.
IsFormatting = #True
;
DoUpper = #True
;
ElseIf *HoldMask\c = '<'
; Decapitalize the following character.
IsFormatting = #True
;
DoLower = #True
;
ElseIf *HoldMask\c = '\'
; Add the next character as-is.
IsFormatting = #True
;
ForceAdd = #True
;
Else
;
IsStatic = #True
;
EndIf
;
EndIf
;
; If IsStatic And UsingPlaceholder : FailedMask = #True : Else : FailedMask = #False : EndIf
If UsingPlaceholder : FailedMask = IsStatic : EndIf
;
If IsFormatting = #False
;
HoldIndex + 1
;
If IsStatic = #False
;
If Position = PeekL(*Index)
;
PokeL(*Index, HoldIndex - 1)
;
If FailedMask
;
ProcedureReturn 0
;
Else
;
If UsingPlaceholder
;
ProcedureReturn xMask()\PlaceHolder
;
ElseIf DoUpper
;
If Character > 96 And Character < 123 : ProcedureReturn Character - 32 : Else : ProcedureReturn Character : EndIf
;
ElseIf DoLower
;
If Character > 64 And Character < 91 : ProcedureReturn Character + 32 : Else : ProcedureReturn Character : EndIf
;
Else
;
ProcedureReturn Character
;
EndIf
;
EndIf
;
EndIf
;
Position + 1
;
Else
;
If UsingPlaceholder
;
If Position = PeekL(*Index)
;
PokeL(*Index, HoldIndex - 1)
;
ProcedureReturn 0
;
EndIf
;
EndIf
;
If Position < PeekL(*Index) : Position + 1 : EndIf
;
EndIf
;
DoUpper = #False : DoLower = #False
;
EndIf
;
ForceAdd = #False : IsFormatting = #False : IsStatic = #False
;
CompilerIf #PB_Compiler_Unicode = #True : *HoldMask + 2 : CompilerElse : *HoldMask + 1 : CompilerEndIf
;
Wend
;
ProcedureReturn 0
;
EndProcedure
Procedure.s _xm_MaskToText(xMask.__s_xMask_Main(), Text.s, ForcePlaceHolder.b = #False)
; Inserts the mask into a string gadget with the placeholder character - replacing with Text as
; possible. If ForcePlaceHolder is true, the returned string will just be the placeholder.
Define.Char *HoldChar
;
Define.Char *HoldMask
;
Define.Char *OutText
;
Define.s HoldString
;
Define.b IgnoreMask
; True if the last character was '\' - the next character is treated as an output character.
Define.b FailedMask
; True if the mask conditions are failed when inserting text.
Define.b IsFormatting
;
Define.b DoUpper, DoLower, ForceAdd
;
*HoldMask = @xMask()\TextMask
;
*HoldChar = @Text
;
HoldString = Space(xMask()\MaxLength)
;
*OutText = @HoldString
;
While *HoldMask\c
; Loop until the end-of-line character is located.
FailedMask = #True
; The mask fails by default.
IsFormatting = #False
; A formatting character is the '>' or '<' or '\' character.
If *HoldMask\c = '0'
; Required numeric field (0-9).
If *HoldChar\c > 47 And *HoldChar\c < 58 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '9'
; Non-required numeric field. A number (0-9) or a space is allowed.
If (*HoldChar\c > 47 And *HoldChar\c < 58) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'L'
; A - Z, entry required.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '?'
; A - Z, entry not required and may include spaces.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'A'
; A - Z or 0 - 9, entry required.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) Or (*HoldChar\c > 47 And *HoldChar\c < 58) : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'a'
; A - Z or 0 - 9, entry not required and may include spaces.
If (*HoldChar\c > 64 And *HoldChar\c < 91) Or (*HoldChar\c > 96 And *HoldChar\c < 123) Or (*HoldChar\c > 47 And *HoldChar\c < 58) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '&'
; Any character or space, entry required.
If *HoldChar\c > 32 And *HoldChar\c < 256 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = 'C'
; Any character or space, entry not required and may include spaces.
If (*HoldChar\c > 32 And *HoldChar\c < 256) Or *HoldChar\c = 32 : FailedMask = #False : EndIf
;
ElseIf *HoldMask\c = '>'
; Capitalize the following character.
IsFormatting = #True
;
DoUpper = #True
;
ElseIf *HoldMask\c = '<'
; Decapitalize the following character.
IsFormatting = #True
;
DoLower = #True
;
ElseIf *HoldMask\c = '\'
; Add the next character as-is.
IsFormatting = #True
;
ForceAdd = #True
;
Else
;
ForceAdd = #True
;
FailedMask = #False
;
EndIf
;
If IsFormatting = #False Or ForcePlaceHolder
;
If ForcePlaceHolder Or *HoldChar\c = 0 : FailedMask = #False : EndIf
;
If FailedMask
; The text does not match the mask.
ProcedureReturn ""
; Return an empty string.
Else
;
If ForceAdd
;
*OutText\c = *HoldMask\c
;
ElseIf ForcePlaceHolder Or *HoldChar\c = 0
;
*OutText\c = xMask()\PlaceHolder
;
Else
;
If DoUpper
;
*OutText\c = Asc(UCase(Mid(Text, *HoldChar - @Text + 1, 1)))
;
ElseIf DoLower
;
*OutText\c = Asc(LCase(Mid(Text, *HoldChar - @Text + 1, 1)))
;
Else
;
*OutText\c = *HoldChar\c
; Store the current character.
EndIf
;
CompilerIf #PB_Compiler_Unicode = #True : *HoldChar + 2 : CompilerElse : *HoldChar + 1 : CompilerEndIf
;
EndIf
;
CompilerIf #PB_Compiler_Unicode = #True : *OutText + 2 : CompilerElse : *OutText + 1 : CompilerEndIf
; Point to the next available space.
EndIf
;
DoUpper = #False : DoLower = #False : ForceAdd = #False
;
EndIf
;
CompilerIf #PB_Compiler_Unicode = #True : *HoldMask + 2 : CompilerElse : *HoldMask + 1 : CompilerEndIf
;
Wend
;
ProcedureReturn Left(HoldString, *OutText - @HoldString)
;
EndProcedure
Procedure _xm_ClearText(xMask.__s_xMask_Main(), OnlyHighlighted = #False)
;
Define.c Character
;
Define.s HoldString
;
Define.l iLoop, HoldIndex
;
Define.POINT HoldSelect
;
SendMessage_(xMask()\Handle, #EM_GETSEL, @HoldSelect\X, @HoldSelect\Y)
; Retrieve the start and end selection values. We'll use this when replacing characters.
If OnlyHighlighted And HoldSelect\X = HoldSelect\Y : ProcedureReturn : EndIf
;
If HoldSelect\X < xMask()\MaxLength
;
If HoldSelect\X < HoldSelect\Y : HoldSelect\Y - 1 : EndIf
;
HoldString = GetGadgetText(xMask()\Gadget)
;
For iLoop = HoldSelect\X To HoldSelect\Y
;
HoldIndex = iLoop
;
Character = _xm_ReturnCharacter(xMask(), 0, @HoldIndex, #True)
;
If Character : InsertCharacter(@HoldString, HoldIndex, Character) : EndIf
;
Next iLoop
;
xMask()\AdjustingText = #True
;
SetGadgetText(xMask()\Gadget, HoldString)
;
xMask()\AdjustingText = #False
;
SendMessage_(xMask()\Handle, #EM_SETSEL, HoldSelect\X, HoldSelect\X)
;
EndIf
;
EndProcedure
;-
Procedure _xm_EditCallback(HandleWindow.l, message.l, wParam.l, lParam.l)
; This is a custom callback function used by our xMask gadget. We'll use this to check
; for various events and handle them in the appropriate manner.
Define.b CaughtMatch
;
Define.l iLoop
;
Define.l lResult
;
Define.l HoldStyle
;
Define.s HoldString, HoldText
;
Define.POINT HoldSelect
;
Define.c Character
;
Define.l HoldIndex
;
ResetList(__xm_Main())
While NextElement(__xm_Main())
;
If __xm_Main()\Handle = HandleWindow : CaughtMatch = #True : Break : EndIf
;
Wend
;
If CaughtMatch = #False : ProcedureReturn : EndIf
; This should never happen but exit if the string gadget is not on the list.
HoldStyle = GetWindowLong_(__xm_Main()\Handle, #GWL_STYLE)
; Get the style of the string gadget.
If HoldStyle & #ES_READONLY = 0
; Ensure the string gadget is not read only.
If message = #WM_SETTEXT
;{ Text is changing via a 'SetGadgetText()' call.
If __xm_Main()\AdjustingText = #False
;
HoldString = _xm_MaskToText(__xm_Main(), _xm_StripCharacters(__xm_Main(), PeekS(lParam), 1), #False)
; Check the text against the mask and store the result. lParam is the pointer to the updating text.
If HoldString <> ""
;
__xm_Main()\AdjustingText = #True
;
SetGadgetText(__xm_Main()\Gadget, HoldString)
; Update the text in the control.
__xm_Main()\AdjustingText = #False
;
EndIf
;
message = 0
; Clear the message - the text is handled internally.
EndIf
;}
ElseIf message = #WM_SETFOCUS
; The edit control received focus.
If __xm_Main()\SelectAllOnFocus : SendMessage_(__xm_Main()\Handle, #EM_SETSEL, 0, -1) : EndIf
; Select all text in the edit control.
ElseIf message = #WM_CHAR
;{
If wParam = #VK_BACK
;
SendMessage_(__xm_Main()\Handle, #EM_GETSEL, @HoldSelect\X, @HoldSelect\Y)
; Retrieve the start and end selection values. We'll use this when replacing characters.
If HoldSelect\X
;
If HoldSelect\X = HoldSelect\Y : HoldSelect\X - 1 : HoldSelect\Y - 1 : EndIf
;
HoldString = GetGadgetText(__xm_Main()\Gadget)
;
For iLoop = HoldSelect\X To HoldSelect\Y
;
HoldIndex = iLoop
;
Character = _xm_ReturnCharacter(__xm_Main(), wParam, @HoldIndex, #True)
;
If Character : InsertCharacter(@HoldString, HoldIndex, Character) : EndIf
;
Next iLoop
;
__xm_Main()\AdjustingText = #True
;
SetGadgetText(__xm_Main()\Gadget, HoldString)
;
__xm_Main()\AdjustingText = #False
;
SendMessage_(__xm_Main()\Handle, #EM_SETSEL, HoldSelect\X, HoldSelect\X)
;
EndIf
;
Else
;
SendMessage_(__xm_Main()\Handle, #EM_GETSEL, @HoldSelect\X, @HoldSelect\Y)
; Retrieve the start and end selection values. We'll use this when replacing characters.
If HoldSelect\X <= __xm_Main()\MaxLength
; Do not allow any text past the maximum length.
HoldIndex = HoldSelect\X
;
Character = _xm_ReturnCharacter(__xm_Main(), wParam, @HoldSelect\X)
;
If Character
;
HoldString = GetGadgetText(__xm_Main()\Gadget)
;
InsertCharacter(@HoldString, HoldSelect\X, Character)
;
__xm_Main()\AdjustingText = #True
;
SetGadgetText(__xm_Main()\Gadget, HoldString)
;
__xm_Main()\AdjustingText = #False
;
SendMessage_(__xm_Main()\Handle, #EM_SETSEL, HoldSelect\X + 1, HoldSelect\X + 1) ; HoldSelect\y + (HoldSelect\x - HoldIndex) + 1)
;
EndIf
;
EndIf
;
EndIf
;
wParam = 0
; Flush the charcter.
;}
ElseIf message = #WM_KEYDOWN
;{ A key is down. This event will fire along with #WM_CHAR. wParam returns the virtual key code.
If wParam = #VK_DELETE
;
_xm_ClearText(__xm_Main()) : wParam = 0
;
EndIf
;}
ElseIf message = #WM_CLEAR
;{ The delete submenu from the right-click menu is called.
_xm_ClearText(__xm_Main(), #True) : message = 0
;
;}
ElseIf message = #WM_CUT
;{ The cut submenu from the right-click menu is called.
SendMessage_(__xm_Main()\Handle, #EM_GETSEL, @HoldSelect\X, @HoldSelect\Y)
; Retrieve the start and end selection values. We'll use this when replacing characters.
If HoldSelect\X = HoldSelect\Y : ProcedureReturn : EndIf
;
HoldString = Mid(GetGadgetText(__xm_Main()\Gadget), HoldSelect\X + 1, HoldSelect\Y - HoldSelect\X)
;
SetClipboardText(HoldString)
;
_xm_ClearText(__xm_Main(), #True) : message = 0
;
;}
ElseIf message = #WM_PASTE
;{ The paste submenu from the right-click menu is called.
SendMessage_(__xm_Main()\Handle, #EM_GETSEL, @HoldSelect\X, @HoldSelect\Y)
; Retrieve the start and end selection values. We'll use this when replacing characters.
If HoldSelect\X = HoldSelect\Y : ProcedureReturn : EndIf
;
HoldString = GetGadgetText(__xm_Main()\Gadget)
;
HoldText = _xm_StripCharacters(__xm_Main(), GetClipboardText(), HoldSelect\X + 1)
;
HoldIndex = 1
;
For iLoop = HoldSelect\X To HoldSelect\Y
;
Character = _xm_ReturnCharacter(__xm_Main(), Asc(Mid(HoldText, HoldIndex, 1)), @iLoop, #False)
;
If Character : InsertCharacter(@HoldString, iLoop, Character) : EndIf
;
HoldIndex + 1
;
Next iLoop
;
__xm_Main()\AdjustingText = #True
;
SetGadgetText(__xm_Main()\Gadget, HoldString)
; Update the text in the control.
__xm_Main()\AdjustingText = #False
;
SendMessage_(__xm_Main()\Handle, #EM_SETSEL, HoldSelect\Y, HoldSelect\Y)
;
message = 0
;
;}
EndIf
;
EndIf
;
lResult = CallWindowProc_(__xm_Main()\OldCallback, HandleWindow, message, wParam, lParam)
; Call the original edit control's callback function for any messages not handled.
ProcedureReturn lResult
;
EndProcedure
;-
Procedure.s xm_GetRawData(Gadget.l)
;
ResetList(__xm_Main())
While NextElement(__xm_Main())
;
If __xm_Main()\Gadget = Gadget
;
ProcedureReturn _xm_StripCharacters(__xm_Main(), GetGadgetText(__xm_Main()\Gadget), 1)
;
EndIf
;
Wend
;
ProcedureReturn ""
;
EndProcedure
Procedure RemoveGadgetMasks(Gadget.l) ; Use 0 to remove all masks.
;
ResetList(__xm_Main())
While NextElement(__xm_Main())
;
If Gadget = 0 Or Gadget = __xm_Main()\Gadget
;
SetWindowLong_(__xm_Main()\Handle, #GWL_WNDPROC, __xm_Main()\OldCallback)
; Now set the custom callback to use for the new xMask gadget.
DeleteElement(__xm_Main())
;
EndIf
;
Wend
;
EndProcedure
Procedure SetGadgetMask(Gadget.l, TextMask.s, Text.s, PlaceHolder.b, RightToLeft.b = #False, SelectAllOnFocus.b = #False)
; Modifies a string gadget to only accept certain characters based on a mask.
Define.s HoldString
; This will store the length of the wide character string, in characters.
Define.l lCount
; Used to store the number of character copied.
Define.l Handle
; The handle of the gadget.
Handle = GadgetID(Gadget)
; Get the handle of the gadget.
HoldString = Space(255)
; Allocate size for our string.
lCount = GetClassName_(Handle, @HoldString, 255)
; Call our function to retrieve the classname.
HoldString = LCase(Left(HoldString, lCount))
; Truncate the string based on the number of characters copied.
If HoldString = "edit"
; Only edit controls may be masked.
ResetList(__xm_Main())
While NextElement(__xm_Main())
;
If __xm_Main()\Gadget = Gadget : ProcedureReturn : EndIf
; Do not allow duplicates.
Wend
;
AddElement(__xm_Main())
; Add a new xMask control.
With __xm_Main()
;
\Gadget = Gadget
\Handle = Handle
;
\TextMask = TextMask
\Text = Text
;
\PlaceHolder = PlaceHolder
\RightToLeft = RightToLeft
;
\MaxLength = _xm_GetMaxLength(TextMask)
; Get the maximum allowed length of the edit control.
\SelectAllOnFocus = SelectAllOnFocus
;
EndWith
;
HoldString = _xm_MaskToText(__xm_Main(), Text, #False)
;
If HoldString = "" : HoldString = _xm_MaskToText(__xm_Main(), HoldString, #True) : EndIf
;
SetGadgetText(Gadget, HoldString)
;
SendMessage_(Handle, #EM_LIMITTEXT, __xm_Main()\MaxLength, 0)
; Set the maximum number of allowed characters.
__xm_Main()\OldCallback = GetWindowLong_(__xm_Main()\Handle, #GWL_WNDPROC)
; Store the original callback procedure address for the Edit control.
SetWindowLong_(__xm_Main()\Handle, #GWL_WNDPROC, @_xm_EditCallback())
; Now set the custom callback to use for the new xMask gadget.
EndIf
;
EndProcedure
;-
;{ Create Test Window
If OpenWindow(0, 0, 0, 400, 300, "Test", #PB_Window_TitleBar | #PB_Window_SystemMenu)
;
If CreateGadgetList(WindowID(0))
;
StringGadget(0, 10, 10, 120, 20, "")
;
SetGadgetMask(0, "999-99-9999", "123456789", '*', #False)
;
EndIf
;
EndIf
;
Define.b DoQuit
;
Define.l HoldID
;
While DoQuit = #False
;
HoldID = WaitWindowEvent()
;
If HoldID = #PB_Event_CloseWindow
; Close the program.
DoQuit = #True
;
EndIf
;
Wend
;}
;-
RemoveGadgetMasks(0)
;-
End
;-
It's just one file. Good luck and thanks to ebs for noticing the error. This post fixes it.