Variable Mask in String Gadget

Just starting out? Need help? Post your questions and find answers here.
localmotion34
Enthusiast
Enthusiast
Posts: 665
Joined: Fri Sep 12, 2003 10:40 pm
Location: Tallahassee, Florida

Variable Mask in String Gadget

Post by localmotion34 »

Ok so I am trying to update a program I wrote to calculate protein standard curves from spectrophotometer readings.

It takes spec result values from creating a standard curve, generates a correlation coefficient and equation to then calculate protein concentrations from unknown samples.


So if I have a standard spec curve of known protein concentrations of 0, .123, .190, .245. ., 356, .399, .467 ect, it gives me the equation to figure out ANY concentration of an unknown sample based on its spec reading.

If i had a reading of .366 on an unknown, id know it lies between .356 and .399.

Heres the problem: The DLL that I use to do linear regression will totally crash if improper values are sent to it in an array of values.

Standard curve and sample readings can ONLY be between 0.0 and 1.999999. ANY other value will crash.

Because my new lab wants to use this program too, I HAVE to figure out a way to be able to mask all the string gadgets so that the users can ONLY enter:

0 or 1 or . at the FIRST character. If deleting characters, then the ending value of the string CANNOT exceed 1.9999999.

So all values entered MUST look like 0.34343 or 1.2322 or .8876 ect. If the "." character is deleted in 1.33445, then the value will be 133445 and the DLL will crash. If 5.4433 is entered then it will crash too and so on.

Here is a sample I modified from a forum post here. Can anyone lend a hand for what I need?

Code: Select all

;========================================================================
; Program:          Currency StringGadget
; Author:           Lloyd Gallant (netmaestro)
; Date:             February 8, 2007
; Target OS:        Microsoft Windows All
; Target Compiler:  PureBasic 4.xx
;
; License:          Free, Unrestricted, credit appreciated
;                   but not required
;
; TailBite:         The only obstacle to compiling this code
;                   is the optional parameters. Change those to
;                   mandatory or use the TailBite protocol
;                   and it should TailBite up without difficulty
;========================================================================
Macro LOWORD(Value)
  Value & $FFFF
EndMacro

Macro HIWORD(Value)
  (Value >> 16) & $FFFF
EndMacro 


Procedure SubClass_String(hwnd, message, wParam, lParam)
  Protected OldStringProc = GetProp_(hwnd, "OldStringProc") 
  Select message
    Case #WM_CONTEXTMENU
      ProcedureReturn -1
    Case #WM_PASTE
      ProcedureReturn -1
    Case #WM_KILLFOCUS
      content$  = Trim(GetGadgetText(GetDlgCtrlID_(hwnd)))
      Decimal_loc = FindString(content$,Chr(46),1)
      If Decimal_loc
        If Decimal_loc = 1
          content$ = "0" + content$
          SetGadgetText(GetDlgCtrlID_(hwnd), content$)
        EndIf
      Else
        If content$ <> ""
          content$ + Chr(46) + "00"
          SetGadgetText(GetDlgCtrlID_(hwnd), content$)
        EndIf
      EndIf
    Case #WM_CHAR
      Result=0
      content$ = GetGadgetText(GetDlgCtrlID_(hwnd))
      Position= LOWORD(SendMessage_(hwnd, #EM_GETSEL, 0, 0))+1
      Select Position
        Case 1
          Select  wParam
            Case 46
              If FindString(content$,Chr(46),0)
                ProcedureReturn 0
              Else
                ProcedureReturn CallWindowProc_(OldStringProc,hwnd, message, wParam, lParam)
              EndIf 
            Case 48,49
              ProcedureReturn CallWindowProc_(OldStringProc,hwnd, message, wParam, lParam)
            Default
              If wParam = 8 ; cant let too high a value be entered
                SendMessage_(hwnd, #WM_CHAR, 46, 1)
                SendMessage_(hwnd, #EM_SETSEL, 1,1)
                Debug 888888
              ElseIf wParam <> 8 And wParam <> 13 And wParam <> 27 ; Back, Esc and Enter are not errors
                ProcedureReturn 0
              EndIf 
          EndSelect 
        Case 2
          content$ = GetGadgetText(GetDlgCtrlID_(hwnd))
          Select content$
            Case "."
              Select  wParam
                Case 46 ; Test for more than one decimal
                  ProcedureReturn 0  
                Case 48 To 57
                  ProcedureReturn CallWindowProc_(OldStringProc, hwnd, message, wParam, lParam)
                Default 
                  ProcedureReturn 0
              EndSelect
            Case "0"
              Select  wParam
                Case 46 ; Test for more than one decimal
                  ProcedureReturn CallWindowProc_(OldStringProc, hwnd, message, wParam, lParam) 
                Default 
                  ProcedureReturn 0
              EndSelect
            Case "1"
              Select  wParam
                Case 46 ; Test for more than one decimal
                  ProcedureReturn CallWindowProc_(OldStringProc, hwnd, message, wParam, lParam) 
                Default 
                  ProcedureReturn 0
              EndSelect
            Default
              If wParam = 8 ; cant let too high a value be entered
                SendMessage_(hwnd, #WM_CHAR, 46, 2)
                SendMessage_(hwnd, #EM_SETSEL, 1,1)
                Debug Position
                Debug 99999
              ElseIf wParam <> 8 And wParam <> 13 And wParam <> 27 ; Back, Esc and Enter are not errors
                ProcedureReturn 0
              EndIf 
          EndSelect
        Case 3 To 400
          Select  wParam
            Case 46 ; Test for more than one decimal
              ProcedureReturn 0  
            Case 48 To 57
              ProcedureReturn CallWindowProc_(OldStringProc, hwnd, message, wParam, lParam)
            Default 
              If wParam <> 8 And wParam <> 13 And wParam <> 27 ; Back, Esc and Enter are not errors
                ProcedureReturn 0
              EndIf 
          EndSelect
      EndSelect 
      
    Case #WM_DESTROY
      RemoveProp_(hwnd, "OldStringProc") 
      SetWindowLong_(hwnd, #GWL_WNDPROC, OldStringProc)
  EndSelect
  ProcedureReturn CallWindowProc_(OldStringProc, hwnd, message, wParam, lParam)
EndProcedure
    
ProcedureDLL CurrencyStringGadget(GadgetNumber, x, y, Width, Height, DefaultText$, flags, MaxChars=11, Decimal=46)
  Shared OldStringProc
  Result = StringGadget(GadgetNumber, x, y, Width, Height, DefaultText$, flags)
  
  If GadgetNumber = #PB_Any
    GadID = GadgetID(Result)
  Else
    GadID = Result
  EndIf
  
  OldStringProc = SetWindowLong_(GadID, #GWL_WNDPROC, @SubClass_String())
  SetProp_(GadID, "OldStringProc", OldStringProc)
  SetProp_(GadID, "Decimal", Decimal)
  SetProp_(GadID, "MaxChars", MaxChars)
  
  ProcedureReturn Result
EndProcedure
    
    
OpenWindow(0,0,0,320,240,"",$CF0001)
CreateGadgetList(WindowID(0))
CurrencyStringGadget(0, 100, 100, 100, 20, "", 0, 2)        ; Maximum two digits before the decimal place
CurrencyStringGadget(1, 100, 140, 100, 20, "", 0, 11, ',')  ; Max 11 digits before decimal place, comma is decimal char
SetActiveGadget(0)
Repeat:Until WaitWindowEvent()=#WM_CLOSE 

Code: Select all

!.WHILE status != dwPassedOut
! Invoke AllocateDrink, dwBeerAmount
!MOV Mug, Beer
!Invoke Drink, Mug, dwBeerAmount
!.endw
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Have you thought of validating the input before sending it to the dll?
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

There might be a clue for you in my example here:
http://elfecc.no-ip.info/purebasic/#MaskedInput

I think this was 3.94 code and hasn't been touched in a while.
Post Reply