Entering Editbox Values Through the Program

Discussions about the BBC BASIC language, with particular reference to BB4W and BBCSDL
MattC
Posts: 114
Joined: Mon 16 Apr 2018, 06:17

Entering Editbox Values Through the Program

Post by MattC »

Hi.

I've written a 'DOS' based program through which values can be entered into a variable in, what looks like, an edit box (albeit, a character coded box).
I now wish to produce a more Windows looking version with dialog boxes, etc. Some of the values entered have to be in a numeric format, for which it is possible to set up an editbox: (e.g. PROC_editbox(dlg%, "", 100, 10, 10, 100, 12, ES_NUMBER)). However, the numbers displayed have to include a decimal point and a possible minus (negative) sign. The 'DOS' format I have, only accepts these 12 keystrokes. (In fact, the decimal point is not entered as it is permanently assigned - the figures represent a cost and only the digits and negative are entered.)

What I would like to do is use the keystrokes directly recorded in the program to enter the value into the editbox (NOT using ES_NUMBER) but removing the ability for direct entry. The style value &8000000 (not sure of the Windows Variable name) seems to allow the box to be clicked on, but not edited. However, even with this, the moment the box is clicked on, the focus is taken away from the main program and no keystrokes are recorded through the program, only the system - which doesn't show them in this case. I appreciate that this is not the normal way that the editbox is intended to work, but it's the way I need it to. I need the program to completely control what is put in the editbox, not the system.

Not sure if this is clear.

Matt
RNBW
Posts: 29
Joined: Thu 05 Apr 2018, 21:41

Re: Entering Editbox Values Through the Program

Post by RNBW »

I have not had the inclination or opportunity to convert the following code to BBC Basic. I wrote it in LBB (Richard's version of Liberty Basic), but it may give you an idea how to achieve what you are after. I've also written it in FreeBasic, but this requires you to use FreeBasic GUI libraries, but I can post the code if you like. Unfortunately, it will probably be winter before I get back to any coding.

Code: Select all

'==============================================
' Numeric entry into a textbox.
' This permits the entry of numbers including
' "-" and ".".  It also prevents more than one
' "-" and "." from being entered.
' Filename: NumericInputByChar_6
'==============================================

nomainwin
Stylebits #main.textbox, _ES_RIGHT, _WS_BORDER, 0, 0
textbox #main.textbox, 10, 50, 100, 25  
WindowWidth = 350  
WindowHeight = 150

open "Filtered Numeric Input" for window as #main  
print #main, "Font Arial 12 Bold"
#main.textbox "!contents? txt$"    
#main.textbox "!setfocus"
#main "trapclose [quit]"     

[CheckInput]       
timer 0
    
    #main.textbox "!contents? txt$"   'text in textbox
     oldtxt$ = txt$    ' make text the oldtext
    txt$ = num$(txt$)  ' gets new text from function num$(text$) which does the checking
    if oldtxt$ <> txt$ then
        #main.textbox txt$      ' if old text is not the same as the new text then use new text
        handle = hWnd(#main.textbox)   ' get the handle of the textbox
        pos = len(txt$)    ' position of character is the length of the current text
        calldll #user32, "SendMessageA", _   ' call EM_SETSEL
            handle as ulong, _
            _EM_SETSEL as long, _
            pos as long, _
            pos as long, _
            result as void
    end if

timer 5, [CheckInput]  ' short delay then last char is deleted if not 0-9, - or .
wait   ' wait for event

' Function to check that character input is 0-9, - or .
function num$(d$)
    t = 0
    for i=1 to len(d$)
        a=asc(mid$(d$,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 will do, not just 8 (for backspace)
        if a = 46 and i = 1 then num$ = "0" + num$
        if a = 45 or a = 46 or a>47 and a<58 then num$=num$+chr$(a)
    next
    a=asc(mid$(num$,1,1))
    if a = 45 and mid$(num$,2,1) = "." then num$ = "-0" + num$

end function

[quit]
close #main   ' close window
end
I hope it's of use to you.
RNBW
Posts: 29
Joined: Thu 05 Apr 2018, 21:41

Re: Entering Editbox Values Through the Program

Post by RNBW »

Just had a thought after my last post, Richard's LBB editor does a translation from Liberty Basic to BBC Basic. There's all sorts of Procs in there, but it may be a little clearer for you.

Code: Select all

    1 REM Automatically translated from Liberty BASIC to BBC BASIC
      REM by 'LB Booster' version 3.10, Mon. 13 May 2019, 18:55:40
      REM!Crunch spaces,rems
      REM!Embed @lib$+"LBLIB.BBCC", @lib$+"LBprompt.tpl"
    1 HIMEM=PAGE+&1F400000:INSTALL @lib$+"LBLIB.BBCC":PROC_LBinit
      Version$ = "4.04 (LBB 3.10)":Err$ = "":erl%=0:lc%=0:io&=&F
      
      REM!WC Windows Constants:
      _EM_SETSEL=&B1
      _ES_RIGHT=2
      _WS_BORDER=&800000
      
      REM Initialise string variables:
      txt$ = "" : oldtxt$ = ""
      
    1 REM ==============================================
    2 REM  Numeric entry into a textbox.
    3 REM  This permits the entry of numbers including
    4 REM  "-" and ".".  It also prevents more than one
    5 REM  "-" and "." from being entered.
    6 REM  Filename: NumericInputByChar_6
    7 REM ----------------------------------------------
    8 REM  Still to resolve: zeros after decimal
    9 REM  point if it is the last character.
   10 REM ==============================================
   11 
   12 SYS "ShowWindow", @hwnd%, 0
   13 PROC_stylebits(`main, `main`textbox, 1, FN_32(_ES_RIGHT), FN_32(_WS_BORDER), 0, 0)
   14 PROC_textbox(`main, `main`textbox, "#main.textbox", 10, 50, 100, 25)
   15 WindowWidth = 350
   16 WindowHeight = 150
   17 
   18 PROC_open("Filtered Numeric Input", "window", "#main", `main)
   19 PROC_gui(`main, "Font Arial 12 Bold")
   20 PROC_gui(`main`textbox, "!contents? txt$")
   21 PROC_gui(`main`textbox, "!setfocus")
   22 PROC_gui(`main, "trapclose [quit]")
   23 
   24 (CheckInput_)
   25 PROC_timer(0, 0)
   26 
   27 PROC_gui(`main`textbox, "!contents? txt$") : REM text in textbox
   28 oldtxt$ = txt$ : REM  make text the oldtext
   29 txt$ = FNnum$(txt$) : REM  gets new text from function num$(text$) which does the checking
   30 IF oldtxt$ <> txt$ THEN
   31   PROC_gui(`main`textbox, txt$) : REM  if old text is not the same as the new text then use new text
   32   handle = !`main`textbox : REM  get the handle of the textbox
   33   pos = LEN(txt$) : REM  position of character is the length of the current text
   34   SYS "SendMessageA", FN_32(handle), FN_32(_EM_SETSEL), FN_32(pos), FN_32(pos) TO tmp_%
   40 ENDIF
   41 
   42 PROC_timer(5, (CheckInput_)) : REM  short delay then last char is deleted if not 0-9, - or .
   43 PROC_wait : REM  wait for event
   44 
   45 REM  Function to check that character input is 0-9, - or .
      PROC_end
      
   46 DEF FNnum$(d$)
      LOCAL num$, t, i, a
   47 t = 0
   48 FOR i = 1 TO LEN(d$) : WHILE 1 > (LEN(d$)) EXIT FOR : ENDWHILE
   49   a = ASC(MID$(d$, i, 1)+CHR$0)
   50   IF a = 46 THEN t = t + 1
   51   IF (-(a = 46)) AND (-(t > 1)) THEN a = 0 : REM only DOT after FIRST is cleared
   52   IF -(a = 45) AND -(i > 1) THEN a = 0 : REM so really almost anything do, not just 8
   53   IF -(a = 46) AND -(i = 1) THEN num$ = "0" + num$
   54   IF (-(a = 45) OR -(a = 46) OR -(a > 47)) AND -(a < 58) THEN num$ = num$ + CHR$(a)
   55 NEXT
   56 a = ASC(MID$(num$, 1, 1)+CHR$0)
   57 IF -(a = 45) AND -(MID$(num$, 2, 1) = ".") THEN num$ = "-0" + num$
   58 
   59 = num$
   60 
   61 (quit_)
   62 PROC_close(`main) : REM  close window
   63 PROC_end
   64 
Hope you can make it out.
MattC
Posts: 114
Joined: Mon 16 Apr 2018, 06:17

Re: Entering Editbox Values Through the Program

Post by MattC »

Thanks RNBW. Never looked into LBB so analysing this is difficult and the BBCBasic version seems to use subs that are not listed. Having said that, I very much appreciate the information and the time you spent.

I decided to look into a slightly different route, by using 'Boxes and Buttons' (WINLIB5(A)) onto a separate window acting as a 'dialog box'. These give returned handles and may be of more use. Preliminary testing suggests more likelihood of attaining my goal, but still not an easy option.

Thanks again.

Matt