Numeric Entry in an EditBox

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
jj2007
Posts: 847
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric Entry in an EditBox

Postby jj2007 » Jul 13, 2018 19:12

@dodicat: I think OP's idea is to block any wrong entries right in the edit control.

I've given it a shot in Assembler, see Numbers only. Let me know if you can find any bugs... (I found half a bug already - it doesn't complain about 123.e)
RNBW
Posts: 175
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Postby RNBW » Jul 18, 2018 17:04

jj2007
I've promised myself many times that I would learn assembler, but nothing so far.

I've moved the code on a bit because the aim had always been to be able to use it in a grid of textboxes, which is part of a program I am working on. I've now done this; and because I've used Lothar Schirm's Simple Windows API Library I've placed the code there https://www.freebasic.net/forum/viewtopic.php?f=8&t=24617&start=45.

It still needs a bit of tidying up with formatting the display of numbers in the textboxes (say two or three decimal places), but that's for another day. I'm not the world's best programmer, so if anyone can see a better way to produce what I've done (but still using a grid of textboxes), I'm happy to see it.

I hope my code will be useful to someone.
RNBW
Posts: 175
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Postby RNBW » Aug 03, 2018 16:55

I NEED HELP!

You will need to use Lothar Schirm’s Simple WinAPI Library https://www.freebasic.net/forum/viewtopic.php?f=8&t=24617 to run the code.

The code is an extension of the code previously posted in this thread. What I want to do is to be able to decide, at the start of the program, how many rows I want to display in the grid. To do this, I start off with an EditBox and a Button. The number of rows is entered into the EditBox and clicking the buttons confirms this and the grid is set up accordingly.

Unfortunately, I can’t get it to work. I don’t know if it’s the hot weather, stupidity, or just my lack of ability, but I just can’t get it to work.
Can someone help please.

Code: Select all

'===============================================================
'NumericEntryIntoGridOfTextboxes_Dev01.bas
'Author: RNBW
' 3 August 2018

'INSTRUCTIONS:
  'Enter any text you want in col 2, rows 2 & 3.  It is superfluous to the exercise  and is only
  'included for my own future use.
  'Enter numbers into columns 3 and 4 in rows 2 and 3.  They will be automatically
  'checked for numeric validity in the range 0 to 9, minus and period and for only one
  'inclusion of minus and period and ensuring that the minus only occurs as the first
  'character.  It will also print out ".123" as "0.123" and "-.123" as "-0.123"
'===============================================================
' TO DO:
' Change the number of rows in the program.
' Format the numbers :
' As can be seen, the displayed numbers are a bit straggly.
' Format the numbers to a specific number of decimal places.
'===============================================================

#Include "WinGUI.bi"

Dim As Long NumOfRows=5, NumOfCols=9
Dim As String sRows, sCols

Dim Shared As HWND Window_Main, Static_Text, Label_a, Edit_a, Button_Num
Dim Shared As MSG msg
Dim As String text, text2
Dim As HWND Edit_Text(1 To NumOfRows, 1 To NumOfCols)
Dim As HWND Button_Calc
Dim As Long vPos, hPos, bWidth, bHeight, row, col
DIM AS STRING sTxt, oldsTxt
DIM AS INTEGER pos0
DIM AS DOUBLE numb(2 TO NumOfRows, 3 TO NumOfCols)
DIM AS DOUBLE totalRows(2 TO NumOfRows, 5)
DIM AS DOUBLE totalCols(4, 3 TO NumOfCols)


FUNCTION sNum(BYVAL sTxt AS STRING) AS STRING
   'Function to check that character input is 0-9, - or .   
   DIM AS STRING sNum1
   DIM AS INTEGER i, a, t
                                             
   FOR i = 1 TO LEN(sTxt)
      a = ASC(MID(sTxt,i,1))
      IF a = 46 THEN t = t + 1
        IF (a = 46) AND (t > 1) THEN a = 0    'only DOT after FIRST is cleared
        IF a = 45 AND i>1 THEN a = 0          'so really almost anything do, not just 8
        IF a = 46 AND i = 1 THEN sNum1 = "0" + sNum1
      IF a = 45 OR a = 46 OR a > 47 AND a < 58 THEN sNum1 = sNum1 + CHR(a)
   NEXT
   
   a=ASC(MID(sTxt,1,1))
    IF a = 45 AND MID(sTxt,2,1) = "." THEN sNum1 = "-0" + sNum1
   
   RETURN sNum1

END FUNCTION


'---------------------
' MAIN WINDOW
'---------------------
Sub OpenWindow_Main()
   Window_Main = Window_New(100, 100, 750, 400, "Numeric Input Into A Grid of Textboxes")   
End Sub

OpenWindow_Main()

' Gadgets to state number of rows
Label_a = Label_New(10,10,120,20,"How many rows?",, Window_Main)
Edit_a = EditBox_New(145,10,30,20,"", ES_CENTER or WS_BORDER, Window_Main)
Button_Num = Button_New(180,10,100,20, "Enter",, Window_Main)

' Open console
'Screen 12
'open cons for output as #1
   
'text = EditBox_GetText(Edit_a)
'NumOfRows = val(text)
'print NumOfRows

Button_Calc = Button_New(10, 60, 100, 20, "Calculate!",, Window_Main)

'-------------------------------
'  SET UP THE GRID
'-------------------------------
vPos = 90: bHeight = 20
NumOfRows = 4
'NumOfRows = val(text)
For row = 1 To NumOfRows
   'hPos = 0 : bWidth = 0
   For col = 1 To 5
      Select Case col
      Case 1
         hPos = 10: bWidth = 65
      Case 2
         hPos = 75: bWidth = 380
      End Select
      Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",, Window_Main)
   Next
Next

FOR row = 1 to 1
   for col = 3 TO 5
         SELECT CASE col
            CASE 3 TO 4
               hpos =  col*65+(455-65*3) : bWidth = 65
            CASE 5
               hPos = (10+65+380)+(col-3)*65 : bWidth = 75
         END SELECT
         Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",, Window_Main)
   NEXT
NEXT

FOR row = 2 TO 4
   FOR col = 3 TO 5
         SELECT CASE col
            CASE 3 TO 4
                hpos =  col*65+(455-65*3) : bWidth = 65
            CASE 5
                hPos = (10+65+380)+(col-3)*65 : bWidth = 75   
         END SELECT
         Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",ES_RIGHT, Window_Main)
   NEXT   
NEXT


'-----------------------------------
' SET UP HEADINGS IN ROW 1
'-----------------------------------
row = 1
For col = 3 To NumOfCols
   EditBox_SetText(Edit_Text(row,col), "Number" + Str(col-2))
   'EditBox_SetText(Edit_Text2(row,col), "Col" + Str(col-1))
Next
 EditBox_SetText(Edit_Text(row,2), "Description")
 EditBox_SetText(Edit_Text(row,5), "TOTAL")


'----------------------------------
' SET UP HEADINGS IN COL 1
'----------------------------------
 col = 1
For row = 2 To NumOfRows -1
   For col = 1 To 1
      EditBox_SetText(Edit_Text(row,col), "Row" + Str(row-1))
   Next
Next
 EditBox_SetText(Edit_Text(4,1), "TOTAL" )
 

'Set timer to 300 miliseconds:
SETTIMER(Window_Main, 0, 300, 0 )

DO
   WaitEvent(Window_Main,msg)
   'if msg.hwnd = Button_Num then
      'text = EditBox_GetText(Edit_a)
      'NumOfRows = val(text)
      'print NumOfRows
   'End If
   SELECT CASE msg.message
      CASE WM_TIMER
         'Check contents of the edit box every 300 millisecinds
         For row = 2 to 3
            FOR col = 3 TO 4
               sTxt = EditBox_GetText(Edit_Text(row,col))   'get text from edit box
               oldsTxt = sTxt      'make text the oldtext                                                                                                                                     
               sTxt = sNum(sTxt)  'gets new text from function sNum(sTxt) which does the checking
               IF oldsTxt <> sTxt THEN
                  EditBox_SetText(Edit_Text(row,col), sTxt)   'if old text is not the same as the new text then use new text
                  pos0 = LEN(sTxt)   'position of character is the length of the current text
                  SENDMESSAGE(Edit_Text(row,col), EM_SETSEL, pos0, pos0)
               END IF
            NEXT col
         NEXT row
      CASE WM_LBUTTONDOWN
         'If Calculate! button is clicked then carry out calculation
         IF msg.hwnd = Button_Calc THEN
            FOR row = 2 to 4
               FOR col = 3 TO 5                                     
                    ' Total Rows
                    sTxt =  EditBox_GetText(Edit_Text(row,col))
                    numb(row,col) = VAL(sTxt)
                    totalRows(row,5) = numb(row, 3) + numb(row,4)
                    sTxt = STR(totalRows(row,5))
                    EditBox_SetText(Edit_Text(row,5), sTxt)
                    'Total Columns
                   totalCols(4,col) =  numb(2,col) +  numb(3,col)
                   sTxt = STR(totalCols(4,col))
                   EditBox_SetText(Edit_Text(4,col), sTxt)                       
               NEXT
            NEXT
         END IF
   END SELECT
LOOP UNTIL Window_Event_Close(Window_Main, msg)

End
UEZ
Posts: 184
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric Entry in an EditBox

Postby UEZ » Aug 03, 2018 18:20

Usually for checking numeric entries in an edit box I would use regex. Here an example which is not perfect but a starting point.

Code: Select all

Code moved to https://www.freebasic.net/forum/viewtopic.php?f=7&t=26929


I know regex is hard to learn but worth to have a look...

Edit: moved to viewtopic.php?f=7&t=26929
Last edited by UEZ on Aug 03, 2018 22:00, edited 1 time in total.
jj2007
Posts: 847
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric Entry in an EditBox

Postby jj2007 » Aug 03, 2018 18:29

error: cannot find -lpcre ...
UEZ
Posts: 184
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric Entry in an EditBox

Postby UEZ » Aug 03, 2018 18:41

jj2007 wrote:error: cannot find -lpcre ...


I'm trying to remember where I've downloaded the PCRE package for FB. As soon as I find it out I will reply.
RNBW
Posts: 175
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Postby RNBW » Aug 03, 2018 18:55

UEZ wrote:Usually for checking numeric entries in an edit box I would use regex. Here an example which is not perfect but a starting point.


Thank you for your response. I'll have a look at your code.

I think you may have misunderstood my problem. It is not numeric entry that is the problem. The numeric entry routine for the grid works very well.

My problem is that, as written, the number of rows in the grid (NumOfRows) is set to 4. I want to be able to change it to whatever I want when the program is running by entering the number into an EditBox at the head of the program. My problem is how to get this entry to communicate the value to the routine that sets up the grid.
UEZ
Posts: 184
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric Entry in an EditBox

Postby UEZ » Aug 03, 2018 18:59

RNBW wrote:
UEZ wrote:Usually for checking numeric entries in an edit box I would use regex. Here an example which is not perfect but a starting point.

Thank you for your response. I'll have a look at your code.

I think you may have misunderstood my problem. It is not numeric entry that is the problem. The numeric entry routine for the grid works very well.

My problem is that, as written, the number of rows in the grid (NumOfRows) is set to 4. I want to be able to change it to whatever I want when the program is running by entering the number into an EditBox at the head of the program. My problem is how to get this entry to communicate the value to the routine that sets up the grid.


Well, I wanted to show only an example how to filter for numeric entries within an edit box without creating a new thread.
So sorry when I didn't reply directly to your problem.

@jj2007: I think I got it from here: viewtopic.php?f=2&t=25070&p=224823&hilit=PCRE#p224823
srvaldez
Posts: 1655
Joined: Sep 25, 2005 21:54

Re: Numeric Entry in an EditBox

Postby srvaldez » Aug 03, 2018 19:30

there were some interesting tips regarding number filtering on the PowerBasic forum https://forum.powerbasic.com/forum/user ... -is-number
@RNBW
I ran your code with the lines un-commented that show the number in the textbox and one thing is obvious, the whole event mechanism is flawed, if there were a simple way to make a grid using WinFBE I might give the problem a try, as it is, it's more work than I want to do.
[dit] a simple grid by James Klutho http://www.planetsquires.com/protect/fo ... 3.msg30215 perhaps it could be adapted to your needs.
note that I had to remove several suffixes like & and $ to get it to compile.
jj2007
Posts: 847
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric Entry in an EditBox

Postby jj2007 » Aug 03, 2018 19:56

UEZ wrote:@jj2007: I think I got it from here: viewtopic.php?f=2&t=25070&p=224823&hilit=PCRE#p224823
Now it builds and runs, but it does not react to any commands, including the WM_CLOSE (Alt F4). I have to kill it in the console with Ctrl C.

Edit: detailed explanation here (Unicode & FB are not the best friends)
Last edited by jj2007 on Aug 05, 2018 8:16, edited 1 time in total.
RNBW
Posts: 175
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Postby RNBW » Aug 03, 2018 20:52

I don't have any difficulty with constructing a grid using EditBoxes. Nor do I have a problem with numeric entry into the EditBoxes. All I have a problem with is communicating the entry of number of rows in the grid from the first EditBox in the program to the construction of the grid.

To explain: the grid is currently set up with 4 rows by the variable NumOfRows = 4.

Let's say I want to have 8 rows and I am someone using a compiled version of the program, I would enter 8 in the first EditBox showing on the screen and this would alter NumOfRows to 8 (I would of course no longer fixing the variable NumOfRows = 4 in the original program).

What I can't do is find a way to make this work. There must be a way to do this, but it seems to be beyond me. I think it is something to do with the messaging, but I just can't get it to work and I'm hoping that someone who knows more about it can help me.
BasicCoder2
Posts: 3298
Joined: Jan 01, 2009 7:03

Re: Numeric Entry in an EditBox

Postby BasicCoder2 » Aug 03, 2018 23:24

Not sure what the problem is. Can you post the code that constructs the grid of edit boxes?
It seems to me all you need to do is,

Code: Select all

dim as integer NumOfRows
input "Enter number of rows";NumOfRows
dim as integer NumOfCols
input "Enter number of rows";NumOfCols
createEditBoxArray(NumOfRows,NumOfCols)

Using an edit or edit boxes to replace the input statements.
RNBW
Posts: 175
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Postby RNBW » Aug 04, 2018 10:13

BasicCoder2
Thank for for your response. I think I must not be explaining myself clearly.

The code for constructing the grid of EditBoxes is in the code under the comment ' SET UP THE GRID in the following code:

Code: Select all

'-------------------------------
'  SET UP THE GRID
'-------------------------------
vPos = 90: bHeight = 20
NumOfRows = 4
'NumOfRows = val(text)
For row = 1 To NumOfRows
   'hPos = 0 : bWidth = 0
   For col = 1 To 5
      Select Case col
      Case 1
         hPos = 10: bWidth = 65
      Case 2
         hPos = 75: bWidth = 380
      End Select
      Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",, Window_Main)
   Next
Next

FOR row = 1 to 1
   for col = 3 TO 5
         SELECT CASE col
            CASE 3 TO 4
               hpos =  col*65+(455-65*3) : bWidth = 65
            CASE 5
               hPos = (10+65+380)+(col-3)*65 : bWidth = 75
         END SELECT
         Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",, Window_Main)
   NEXT
NEXT

FOR row = 2 TO 4
   FOR col = 3 TO 5
         SELECT CASE col
            CASE 3 TO 4
                hpos =  col*65+(455-65*3) : bWidth = 65
            CASE 5
                hPos = (10+65+380)+(col-3)*65 : bWidth = 75   
         END SELECT
         Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",ES_RIGHT, Window_Main)
   NEXT   
NEXT

This is not the problem.

To try to explain more clearly:
* My original code for Numeric Entry Into a Grid Of textboxes was shown earlier in the thread.
* The grid was set up to a fixed grid of 4 rows and 5 columns.
* The code succesfully allowed filtered numeric entry into the grid, and calculations of vertical and horizontal totals.

What I want to do is to be able to vary the number of rows whilst the program is running, in particular at the startup of the program.

To do this I set up an EditBox and a Button to allow the number of rows required to be entered, using the code:

Code: Select all

' Gadgets to state number of rows
Label_a = Label_New(10,10,120,20,"How many rows?",, Window_Main)
Edit_a = EditBox_New(145,10,30,20,"", ES_CENTER or WS_BORDER, Window_Main)
Button_Num = Button_New(180,10,100,20, "Enter",, Window_Main)

* What I am tring to do is to communicate the number entered in the EditBox (Edit_a) into the variable NumOfRows.
* I appreciate that it will be necessary to change the code to remove all references to the fixed number of rows (in the variable NumOfRows = 4) from the code and just replace with the variable NumOfRows in the setup of the grid of EditBoxes.
* If the grid is then set up, I don't think I have a problem with the rest.
* The problem is that I don't seem to be able to get the value from EditBox Edit_a to the variable NumOfRows and then set up the grid.

I am happy with the rest of the code once the grid is set up from the variable NumOfRows, but I just can't get it to work.

I am using Lothar Schirm's Simple WinAPI Library https://www.freebasic.net/forum/viewtopic.php?f=8&t=24617.

I shall be grateful for any help. My head is aching with beating it up against a brick wall!!!!
BasicCoder2
Posts: 3298
Joined: Jan 01, 2009 7:03

Re: Numeric Entry in an EditBox

Postby BasicCoder2 » Aug 05, 2018 7:17

Would be much easier to roll your own :)
Somehow you need to be able to redim the array.
Can you delete the grid box at any time? Then maybe set it up again with another numOfRows value?

Here I placed the setup code in a subroutine, setUpGrid(numOfRows)
When you enter a another number of rows it sort of works but everything else goes wrong maybe you can figure it out?

Code: Select all

'===============================================================
'NumericEntryIntoGridOfTextboxes_Dev01.bas
'Author: RNBW
' 3 August 2018

'INSTRUCTIONS:
  'Enter any text you want in col 2, rows 2 & 3.  It is superfluous to the exercise  and is only
  'included for my own future use.
  'Enter numbers into columns 3 and 4 in rows 2 and 3.  They will be automatically
  'checked for numeric validity in the range 0 to 9, minus and period and for only one
  'inclusion of minus and period and ensuring that the minus only occurs as the first
  'character.  It will also print out ".123" as "0.123" and "-.123" as "-0.123"
'===============================================================
' TO DO:
' Change the number of rows in the program.
' Format the numbers :
' As can be seen, the displayed numbers are a bit straggly.
' Format the numbers to a specific number of decimal places.
'===============================================================

#Include "WinGUI.bi"

Dim  As Long NumOfRows=5
dim shared as long NumOfCols=9
Dim Shared As String sRows, sCols

Dim Shared As HWND Window_Main, Static_Text, Label_a, Edit_a, Button_Num
Dim Shared As MSG msg
Dim Shared As String text, text2
Dim Shared As HWND Edit_Text(1 To NumOfRows, 1 To NumOfCols)
Dim Shared As HWND Button_Calc
Dim Shared As Long vPos, hPos, bWidth, bHeight, row, col
DIM Shared AS STRING sTxt, oldsTxt
DIM Shared AS INTEGER pos0
DIM Shared AS DOUBLE numb(2 TO NumOfRows, 3 TO NumOfCols)
DIM Shared AS DOUBLE totalRows(2 TO NumOfRows, 5)
DIM Shared AS DOUBLE totalCols(4, 3 TO NumOfCols)


FUNCTION sNum(BYVAL sTxt AS STRING) AS STRING
   'Function to check that character input is 0-9, - or .   
   DIM AS STRING sNum1
   DIM AS INTEGER i, a, t
                                             
   FOR i = 1 TO LEN(sTxt)
      a = ASC(MID(sTxt,i,1))
      IF a = 46 THEN t = t + 1
        IF (a = 46) AND (t > 1) THEN a = 0    'only DOT after FIRST is cleared
        IF a = 45 AND i>1 THEN a = 0          'so really almost anything do, not just 8
        IF a = 46 AND i = 1 THEN sNum1 = "0" + sNum1
      IF a = 45 OR a = 46 OR a > 47 AND a < 58 THEN sNum1 = sNum1 + CHR(a)
   NEXT
   
   a=ASC(MID(sTxt,1,1))
    IF a = 45 AND MID(sTxt,2,1) = "." THEN sNum1 = "-0" + sNum1
   
   RETURN sNum1

END FUNCTION


'---------------------
' MAIN WINDOW
'---------------------
Sub OpenWindow_Main()
   Window_Main = Window_New(100, 100, 750, 400, "Numeric Input Into A Grid of Textboxes")   
End Sub

OpenWindow_Main()

' Gadgets to state number of rows
Label_a = Label_New(10,10,120,20,"How many rows?",, Window_Main)
Edit_a = EditBox_New(145,10,30,20,"", ES_CENTER or WS_BORDER, Window_Main)
Button_Num = Button_New(180,10,100,20, "Enter",, Window_Main)

' Open console
'Screen 12
'open cons for output as #1
   
'text = EditBox_GetText(Edit_a)
'NumOfRows = val(text)
'print NumOfRows

Button_Calc = Button_New(10, 60, 100, 20, "Calculate!",, Window_Main)

sub setUpGrid(NumOfRows as long)
   
    '-------------------------------
    '  SET UP THE GRID
    '-------------------------------
    vPos = 90: bHeight = 20
    'NumOfRows = 4
    ' NumOfRows = val(text)
    For row = 1 To NumOfRows
       'hPos = 0 : bWidth = 0
       For col = 1 To 5
           Select Case col
           Case 1
               hPos = 10: bWidth = 65
           Case 2
               hPos = 75: bWidth = 380
           End Select
           Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",, Window_Main)
       Next
    Next

    FOR row = 1 to 1
        for col = 3 TO 5
            SELECT CASE col
                CASE 3 TO 4
                    hpos =  col*65+(455-65*3) : bWidth = 65
                CASE 5
                    hPos = (10+65+380)+(col-3)*65 : bWidth = 75
             END SELECT
             Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",, Window_Main)
       NEXT
    NEXT

    FOR row = 2 TO numOfRows '4
        FOR col = 3 TO 5
            SELECT CASE col
                CASE 3 TO 4
                    hpos =  col*65+(455-65*3) : bWidth = 65
                CASE 5
                    hPos = (10+65+380)+(col-3)*65 : bWidth = 75   
             END SELECT
             Edit_Text(row, col) = EditBox_New(hPos, vPos+bHeight*(row-1), bWidth+1, bHeight+1, "",ES_RIGHT, Window_Main)
       NEXT   
    NEXT


    '-----------------------------------
    ' SET UP HEADINGS IN ROW 1
    '-----------------------------------
    row = 1
    For col = 3 To NumOfCols
        EditBox_SetText(Edit_Text(row,col), "Number" + Str(col-2))
       'EditBox_SetText(Edit_Text2(row,col), "Col" + Str(col-1))
    Next
    EditBox_SetText(Edit_Text(row,2), "Description")
    EditBox_SetText(Edit_Text(row,5), "TOTAL")


    '----------------------------------
    ' SET UP HEADINGS IN COL 1
    '----------------------------------
    col = 1
    For row = 2 To NumOfRows -1
        For col = 1 To 1
            EditBox_SetText(Edit_Text(row,col), "Row" + Str(row-1))
        Next
    Next
    EditBox_SetText(Edit_Text(numOfRows,1), "TOTAL" )
   
end sub

'=============================================
setUpGrid(4)
'=============================================

'Set timer to 300 miliseconds:
SETTIMER(Window_Main, 0, 300, 0 )

DO
   WaitEvent(Window_Main,msg)
   
   if msg.hwnd = Button_Num then
      text = EditBox_GetText(Edit_a)
      NumOfRows = val(text)
      setUpGrid(NumOfRows)
      print NumOfRows
   End If
   
   SELECT CASE msg.message
      CASE WM_TIMER
         'Check contents of the edit box every 300 millisecinds
         For row = 2 to 3
            FOR col = 3 TO 4
               sTxt = EditBox_GetText(Edit_Text(row,col))   'get text from edit box
               oldsTxt = sTxt      'make text the oldtext                                                                                                                                     
               sTxt = sNum(sTxt)  'gets new text from function sNum(sTxt) which does the checking
               IF oldsTxt <> sTxt THEN
                  EditBox_SetText(Edit_Text(row,col), sTxt)   'if old text is not the same as the new text then use new text
                  pos0 = LEN(sTxt)   'position of character is the length of the current text
                  SENDMESSAGE(Edit_Text(row,col), EM_SETSEL, pos0, pos0)
               END IF
            NEXT col
         NEXT row
      CASE WM_LBUTTONDOWN
         'If Calculate! button is clicked then carry out calculation
         IF msg.hwnd = Button_Calc THEN
            FOR row = 2 to numOfRows '4
               FOR col = 3 TO 5                                     
                    ' Total Rows
                    sTxt =  EditBox_GetText(Edit_Text(row,col))
                    numb(row,col) = VAL(sTxt)
                    totalRows(row,5) = numb(row, 3) + numb(row,4)
                    sTxt = STR(totalRows(row,5))
                    EditBox_SetText(Edit_Text(row,5), sTxt)
                    'Total Columns
                   totalCols(numOfRows,col) =  numb(2,col) +  numb(3,col)
                   sTxt = STR(totalCols(numOfRows,col))
                   EditBox_SetText(Edit_Text(numOfRows,col), sTxt)                       
               NEXT
            NEXT
         END IF
   END SELECT
LOOP UNTIL Window_Event_Close(Window_Main, msg)

End
BasicCoder2
Posts: 3298
Joined: Jan 01, 2009 7:03

Re: Numeric Entry in an EditBox

Postby BasicCoder2 » Aug 05, 2018 9:14

As I mentioned above I find rolling my own faster and easier than trying to figure out how to use a GUI library.
Perhaps these examples might give a clue as to how to solve the problem using redim?

Code: Select all

type TextBox
    as integer x
    as integer y
    as integer w
    as integer h
    as string  t    'text
    as integer a    'active=1
    as integer j    'justify left = 0 /center = 1/right = 2
    as integer posX 'retains info when text larger than width of text box
    as integer cur  'tb.cur
end type

'' Define a variable-length array
Redim shared array() As TextBox

'' ReDim array to have 3*4 elements
sub makeArray(col as integer, row as integer)
    ReDim preserve array(0 To col, 0 To row)
end sub

sub displayArray()
    dim as integer n
    For i as integer = LBound(array, 1) To UBound(array, 1)
        For j as integer = LBound(array, 2) To UBound(array, 2)
            array(i, j).t = str(n)
            Print array(i, j).t;"   ";
            n += 1
        Next
        Print
    Next
    Print
end sub

dim as integer colSize,rowSize

makeArray(5,5)
displayArray()
do
    input "Enter col,row";colSize,rowSize
    while colSize < 1 or rowSize < 1
        input "Enter col,row";colSize,rowSize
    wend

    makeArray(colSize,rowSize)
    displayArray()
    sleep 2
loop until multikey(&H01)
sleep


Code: Select all

screenres 1028,600,32
color rgb(0,0,0),rgb(255,255,255):cls


type TextBox
    as integer x
    as integer y
    as integer w
    as integer h
    as string  t    'text
    as integer a    'active=1
    as integer j    'justify left = 0 /center = 1/right = 2
    as integer posX 'retains info when text larger than width of text box
    as integer cur  'tb.cur
end type

'' Define a variable-length array
Redim shared tb1(0 to 5,0 to 5) As TextBox  'create a 5x5 textbox array

sub drawTextBox(tb as textBox)
    dim as integer shiftX
    screenlock()
   
    '*******************  THIS DRAWS THE BOX ***************************
    'clear rectangle
    line (tb.x,tb.y)-(tb.x+tb.w+8,tb.y+tb.h),rgb(255,255,255),bf
    'draw border
    line (tb.x,tb.y)-(tb.x+tb.w+8,tb.y+tb.h),rgb(127,127,127),b
    line (tb.x+1,tb.y+1)-(tb.x+tb.w+7,tb.y+tb.h-1),rgb(127,127,127),b
    '*******************************************************************
   
    if tb.a = 1 then
        'keep tb.cur within the box
        if tb.cur > tb.posX+tb.w/8 then
            tb.posX = tb.posX + 1
        end if
   
        if tb.cur < tb.posX+1 then
            if tb.posX>0 then
                tb.posX = tb.posX - 1
            end if
        end if
    end if

    if len(tb.t)*8 > tb.w or tb.j = 0 then
        draw string (tb.x+4,tb.y+4),mid(tb.t,tb.posX+1,tb.w\8)   
        if tb.a = 1 then
            line (tb.x+tb.cur*8+4-tb.posX*8,tb.y+2)-(tb.x+tb.cur*8+5-tb.posX*8,tb.y + 14),rgb(10,10,10),bf  'draw tb.cur
        end if
    else
        if tb.j = 1 then shiftX = tb.w\2-len(tb.t)*8/2
        if tb.j = 2 then shiftX = tb.w-len(tb.t)*8
        draw string (tb.x+4+shiftX,tb.y+4),tb.t
        if tb.a = 1 then
            line (tb.x+tb.cur*8+4+shiftX,tb.y+2)-(tb.x+tb.cur*8+5+shiftX,tb.y + 14),rgb(10,10,10),bf  'draw tb.cur
        end if
    end if
   
    screenunlock()

end sub

'' ReDim array to have 3*4 elements
sub makeArray(col as integer, row as integer)
    ReDim preserve tb1(0 To col, 0 To row)
    for j as integer = 0 to row
        for i as integer = 0 to col
            tb1(i,j).x = i*100+50         
            tb1(i,j).y = j*18+50
            tb1(i,j).w = 11*8   'wide enough for 10 characters 8 pixels wide
            tb1(i,j).h = 16
            tb1(i,j).t = ""
            tb1(i,j).a = 0     
            tb1(i,j).j = 0
        next i
    next j
end sub

sub displayArray()
    screenlock
    cls
    dim as integer n
    For i as integer = LBound(tb1, 1) To UBound(tb1, 1)
        For j as integer = LBound(tb1, 2) To UBound(tb1, 2)
            tb1(i, j).t = str(n)
            'Print tb1(i, j).t;"   ";
            drawTextBox(tb1(i,j))
            n += 1
        Next
        'Print
    Next
    'Print
    screenunlock
end sub

dim as integer colSize,rowSize

makeArray(5,5)
displayArray()
do
    input "Enter col,row";colSize,rowSize
    while colSize < 1 or rowSize < 1
        input "Enter col,row";colSize,rowSize
    wend

    makeArray(colSize,rowSize)
    displayArray()
    sleep 2
loop until multikey(&H01)
sleep
Last edited by BasicCoder2 on Aug 06, 2018 21:00, edited 2 times in total.

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 0 guests