Numeric Entry in an EditBox

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

BasicCoder2 wrote: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?
Thank you. The changes you have made do get over the problem of re-dimensioning the grid and yes, there are problems with the later code that needs changing to match the re-dimensioning and none of the maths seems to work. I'll look at this.

I'll also look at your code in your later post
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?
With regards the top horizontal row with description, number1, number2, total and left column with row1, row2 , total I would keep them separate from the actual array of editable text box array.
Thank you for your help.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Numeric Entry in an EditBox

Post by BasicCoder2 »

RNBW wrote:The changes you have made do get over the problem of re-dimensioning the grid and yes, there are problems with the later code that needs changing to match the re-dimensioning and none of the maths seems to work. I'll look at this.
Because I don't know what the API is doing there may be other problems.
It seems to me that there should be the ability to delete a control and just create a new one in order to resize the array. You don't want to be simply creating extra controls over the top of the previous ones.
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

I have got most things working, but not all. For some reason the data entered into the first row off calculation is being ignored. It may be that the original grid may have to be deleted first. I'm looking at a few workarounds.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Numeric Entry in an EditBox

Post by MrSwiss »

RNBW wrote:It may be that the original grid may have to be deleted ...
This isn't a "maybe", this is a fact, unless you are planning,
to create a "massive" memory leak!

Safe way is:
  • Delete previous array (using Erase), freeing mem.
    ReDim array (make certain, it is originally defined "dynamic")
What you call "grid" is usually done, as a: 2 dimensional array ...
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

BasicCoder2/MrSwiss

I've had another go at the code.
I've considered REDIM but it is not actually needed. The sizing of the array will only be required once (I shall look to hide the first row of gadgets after the grid has been sized). I've REMd the initial setUpGrid() at line 152 to achieve this.

Generally, the program works, all except for the totalling in the last column of the totals of the rows. I'm not sure why.

Code: Select all

'=========================================================
' NumericEntryIntoGridOfTextboxes_BC2_Dev05.bas
' Author: RNBW
' With modifications by BasicCoder2 5 August 2018
' 5 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:
' Total of the rows in the last column doesn't work.
' 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  Shared As Long NumOfRows = 10
dim shared as long NumOfCols = 5
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, NumOfCols)
DIM Shared AS DOUBLE totalCols(NumOfRows, 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,270,20,"How many rows do you want to calculate",, Window_Main)
Edit_a = EditBox_New(300,10,30,20,"", ES_CENTER or WS_BORDER, Window_Main)
Button_Num = Button_New(350,10,100,20, "Enter",, Window_Main)

'Open console
'Screen 12
'open cons for output as #1

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

sub setUpGrid(NumOfRows as long)
   
    '-------------------------------
    '  SET UP THE GRID
    '-------------------------------
    vPos = 90: bHeight = 20
    For row = 1 To NumOfRows
       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
        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))
    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(2)
'=============================================

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

DO
   WaitEvent(Window_Main,msg)
   SELECT CASE msg.message
  ' CASE WM_LBUTTONDOWN   
   'SELECT CASE msg.message
      CASE WM_TIMER
         'Check contents of the edit box every 300 millisecinds
         For row = 2 to NumOfRows
            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 msg.hwnd = Button_Num then
            text = EditBox_GetText(Edit_a)
            NumOfRows = val(text)
            NumOfRows = NumOfRows + 2
            setUpGrid(NumOfRows)
            print NumOfRows
         Else
         'If Calculate! button is clicked then carry out calculation
         IF msg.hwnd = Button_Calc THEN             
            totalCols(NumOfRows,col) = 0
            FOR row = 2 to NumOfRows
               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--->
                    sTxt = EditBox_GetText(Edit_Text(row,col))
                    numb(row,col) = val(sTxt)
                   totalCols(NumOfRows,col) =  totalCols(NumOfRows,col) +  numb(row-1,col)
                   'print row; "  "; col; "  "; numb(row,col)
                   sTxt = STR(totalCols(NumOfRows,col))
                   EditBox_SetText(Edit_Text(NumOfRows,col), sTxt) 
                   print row; "  "; col; "  "; numb(row,col)                                       
               NEXT
            NEXT
            end if
         END IF
   END SELECT
LOOP UNTIL Window_Event_Close(Window_Main, msg)

End
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Numeric Entry in an EditBox

Post by BasicCoder2 »

RNBW wrote:I've had another go at the code.
I've considered REDIM but it is not actually needed.
Well a version of Redim of a grid control probably is needed for reasons mentioned. You are probably generating a another grid control rather than resizing the same grid control.
The ability to resize the number of rows or columns in a grid control should be one of its methods.
A messy work around without really knowing what you are doing is fraught with dangers.
There is probably a very simple solution not covered by WinGUI_FB
https://docs.microsoft.com/en-us/dotnet ... t-run-time
It seems to me if there is no resize method you would need to have a delete control option followed by an add a new control to hack a resize function.
https://www.aspforums.net/Threads/71311 ... orm-C-Net/

I am strictly a retro programmer who makes his own GUI controls, the workings of which I do understand.
I can write my own grid control with a resize method if needed.

By the way you do not need to credit me with any "modifications" as they are only suggestions not working solutions.
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

I'm not sure I agree with you about REDIM, but this may be my lack of knowledge. However, I've introduced the following code in the sub setUpGrid()
and it seems to work still.

Code: Select all

    
    '-------------------------------
    '  SET UP THE GRID
    '-------------------------------
    reDim As HWND Edit_Text(1 To NumOfRows, 1 To NumOfCols)
    reDIM AS DOUBLE numb(2 TO NumOfRows, 3 TO NumOfCols)
    reDIM AS DOUBLE totalRows(2 TO NumOfRows, NumOfCols)
    reDIM AS DOUBLE totalCols(NumOfRows, 3 TO NumOfCols)
By the way, crediting you in the code is just my way of saying thank you to those who help me out with code. If you would rather I didn't please say and I will delete.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Numeric Entry in an EditBox

Post by BasicCoder2 »

RNBW wrote:By the way, crediting you in the code is just my way of saying thank you to those who help me out with code. If you would rather I didn't please say and I will delete.
I will let you know if I offer anything I want credit for. Somethings I would rather not admit to coding :) Thanks anyway.

There are still some strange results. When I reduce it from 5 to 2 rows I get this:

Imageprogram for screenshots for windows
Which makes me wonder if one grid control is being created and displayed over a previously created grid control.
Instead of redimensioning the grid you might be just creating more and more of them.
Another glitch is the contents of a textbox might not displayed unless it is clicked.
To me this illustrates that using a restricted library may make some things easy but other things impossible.
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

BasicCoder2
Point taken about credits!
I noticed the same as you with the scenario that if you re-entered a grid size smaller than the previous, there would still be some of the previous grid showing. Definitely not what I want. Unfortunately, I didn't see it until after I'd posted and I was on my way to bed. Not too critical for me because I will only want it for a single use.
I'm currently scouring the internet for methods of deleting WinAPI controls.
I may also look at different libraries to see if they are more flexible.
One day, I might have a go at coding my own GUI. I might have a look at yours and Lothar Schirm's 'home grown' GUIs as starters.

I do appreciate the help you have given. It's very helpful to have another set of eyes looking at what you are trying to produce. One can code with blinkers!
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

A quick and dirty way to ensure only one grid is set up is to compile as Win64 or Win 32 Console and set up the grid from the Console. As below:

Code: Select all

'===============================================================
'NumericEntryIntoGridOfTextboxes_Dev04.bas
'Author: RNBW
' 6 August 2018

'-------------------------------------------------------------------------------------------------------
' Compile as Win64 Console or Win32 Console
'--------------------------------------------------------------------------------------------------------------
  '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:
'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 integer NumOfRows = 10, NumOfCols = 5, MaxRow
Dim As String sRows, sCols

Dim Shared As HWND Window_Main, Static_Text
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

' Ask how many rows to be provided
print "********************************************************* "
print "*********************************************************"
Input "HOW MANY ROWS TO CALCULATE (MIN 2) "; NumOfRows
NumOfRows = NumOfRows+2
MaxRow = NumOfRows

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

OpenWindow_Main()

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

'-------------------------------
'  SET UP THE GRID
'-------------------------------
vPos = 40: bHeight = 20
'NumOfRows = 4
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
   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" )
 

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

DO
   WaitEvent(Window_Main,msg)
   SELECT CASE msg.message
      CASE WM_TIMER
         'Check contents of the edit box every 300 millisecinds
         For row = 2 to NumOfRows-1
            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
            totalCols(MaxRow,col) = 0
            FOR row = 2 to NumOfRows
               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(MaxRow,col) = totalCols(row,col)                   
                    totalCols(MaxRow,col) = totalCols(MaxRow,col) + numb(row-1,col) 'totalCols(NumOfRows,col) +  numb(row,col)                    
                    sTxt = STR(totalCols(MaxRow,col))
                    EditBox_SetText(Edit_Text(MaxRow,col), sTxt)  
                    'totalCols(2,col) = totalCols(2,col)                     
               NEXT
            NEXT 
         END IF
   END SELECT
LOOP UNTIL Window_Event_Close(Window_Main, msg)

End
Not quite the presentation I was looking for, but it works.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Numeric Entry in an EditBox

Post by BasicCoder2 »

RNBW wrote:I'm currently scouring the internet for methods of deleting WinAPI controls.
So no luck? I did the same.
https://stackoverflow.com/questions/208 ... base-table
http://www.kettic.com/winforms_ui/cshar ... lete.shtml
And there appears to be methods to an add and remove a whole control not just a row or column in a grid control.
panel1.Controls.Add(btn)
panel1.Controls.Remove(btn)
But I have no idea how to do that in FreeBASIC.
Perhaps post the question to the Windows section of this forum?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric Entry in an EditBox

Post by jj2007 »

RNBW wrote:I'm currently scouring the internet for methods of deleting WinAPI controls.
Try something simple: SendMessage(hControl, WM_CLOSE, 0, 0)
PaulSquires
Posts: 999
Joined: Jul 14, 2005 23:41

Re: Numeric Entry in an EditBox

Post by PaulSquires »

jj2007 wrote:
RNBW wrote:I'm currently scouring the internet for methods of deleting WinAPI controls.
Try something simple: SendMessage(hControl, WM_CLOSE, 0, 0)
I haven't tried your code or the gui library you are using but shouldn't a simple DestroyWindow call do the trick?
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric Entry in an EditBox

Post by jj2007 »

PaulSquires wrote:
jj2007 wrote:
RNBW wrote:I'm currently scouring the internet for methods of deleting WinAPI controls.
Try something simple: SendMessage(hControl, WM_CLOSE, 0, 0)
I haven't tried your code or the gui library you are using but shouldn't a simple DestroyWindow call do the trick?
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Yes, DestroyWindow does the trick. Sending WM_CLOSE, too, and to me it looks less rude. I tested both of them, of course. No idea, though, what will happen under the hood. If I had to destroy/close a Million controls in a tight loop, I would probably investigate.
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric Entry in an EditBox

Post by RNBW »

BasicCoder2
I did see a few things in various programming dialects, but, like yourself, wasn't sure how to do in FreeBasic.

PaulSquires
Unfortunately, the link didn't work.

jj2007
Tried your suggested solution and entered it into the message loop, having introduced another button to generate the closure:
Else
' Click Close Grid button to close grid
' This closes all down except for column 2
if msg.hwnd = Button_CloseGrid THEN
for row = 1 to NumOfRows
for col = 1 to 5
SendMessage(Edit_Text(row,col), WM_CLOSE, 0, 0)
next
Next
This partially worked. It removed everything in the grid except for column 2. Now I can't see why it would not close column 2. Any idea what I'm doing wrong? The full code is below:

Code: Select all

'=========================================================
' NumericEntryIntoGridOfTextboxes_BC2_Dev05C.bas
' Author: RNBW
' 7 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:
' Totalling the rows and columns doesn't work.
' 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  Shared As Long NumOfRows = 10
dim shared as long NumOfCols = 5
Dim Shared As String sRows, sCols

Dim Shared As HWND Window_Main, Static_Text, Label_a, Edit_a, Button_Num, Button_CloseGrid
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, NumOfCols)
DIM Shared AS DOUBLE totalCols(NumOfRows, 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,270,20,"How many rows do you want to calculate",, Window_Main)
Edit_a = EditBox_New(300,10,30,20,"", ES_CENTER or WS_BORDER, Window_Main)
Button_Num = Button_New(350,10,100,20, "Enter",, Window_Main)
Button_CloseGrid = Button_New(500,10,100,20, "Close Grid",, Window_Main)

'Open console
'Screen 12
'open cons for output as #1

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

	'-------------------------------
	'  SET UP THE GRID
	'-------------------------------
sub setUpGrid(NumOfRows as long)
 	reDim As HWND Edit_Text(1 To NumOfRows, 1 To NumOfCols)
	reDIM AS DOUBLE numb(2 TO NumOfRows, 3 TO NumOfCols)
	reDIM AS DOUBLE totalRows(2 TO NumOfRows, NumOfCols)
	reDIM AS DOUBLE totalCols(NumOfRows, 3 TO NumOfCols)
	vPos = 90: bHeight = 20
	For row = 1 To NumOfRows
		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
		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))
	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(2)
'=============================================

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

DO
	WaitEvent(Window_Main,msg)
	SELECT CASE msg.message
		' CASE WM_LBUTTONDOWN
		'SELECT CASE msg.message
		CASE WM_TIMER
			'Check contents of the edit box every 300 millisecinds
			For row = 2 to NumOfRows
				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 msg.hwnd = Button_Num then
				text = EditBox_GetText(Edit_a)
				NumOfRows = val(text)
				NumOfRows = NumOfRows + 2
				setUpGrid(NumOfRows)
				print NumOfRows
            
			Else
            ' Click Close Grid button to close grid
            ' This closes all down except for column 2
				if msg.hwnd = Button_CloseGrid THEN
               for row = 1 to NumOfRows
                  for col = 1 to  5
                       SendMessage(Edit_Text(row,col), WM_CLOSE, 0, 0)
                  next
               Next
					
				Else
					'If Calculate! button is clicked then carry out calculation
					IF msg.hwnd = Button_Calc THEN
						totalCols(NumOfRows,col) = 0
						FOR row = 2 to NumOfRows
							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--->
								sTxt = EditBox_GetText(Edit_Text(row,col))
								numb(row,col) = val(sTxt)
								totalCols(NumOfRows,col) =  totalCols(NumOfRows,col) +  numb(row-1,col)
								'print row; "  "; col; "  "; numb(row,col)
								sTxt = STR(totalCols(NumOfRows,col))
								EditBox_SetText(Edit_Text(NumOfRows,col), sTxt)
								print row; "  "; col; "  "; numb(row,col)
							NEXT
						NEXT
					end if
				END IF
			End if
	END SELECT
LOOP UNTIL Window_Event_Close(Window_Main, msg)

End
Post Reply