Author Topic: Trying to make a library. Demo using TYPE for variables...  (Read 3770 times)

0 Members and 1 Guest are viewing this topic.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Trying to make a library. Demo using TYPE for variables...
« on: July 24, 2019, 05:46:01 am »
Code: QB64: [Select]
  1. main:
  2.  
  3. DIM prompt$(4)
  4. prompt$(0) = "abc: "
  5. prompt$(1) = "def: "
  6. prompt$(2) = "ghi: "
  7. prompt$(3) = "jkl: "
  8.  
  9. PromptColumn% = 10
  10. PromptTopRow% = 5
  11. PromptRowSpacing% = 2
  12. MaxLengthResponse% = 40
  13. ForegroundColor% = 0
  14. BackgroundColor% = 7
  15. HighlightForgroundColor% = 15
  16. HighlightBackgroundColor% = 1
  17.  
  18. CALL ConsoleLibrary(prompt$(), PromptColumn%, PromptTopRow%, PromptRowSpacing%, MaxLengthResponse%, ForegroundColor%, BackgroundColor%, HighlightForgroundColor%, HighlightBackgroundColor%)
  19.  
  20. SUB ConsoleLibrary (ConsoleInput_prompt$(), ConsoleInput.prompt_column, ConsoleInput.vertpos, ConsoleInput.yyseparator, ConsoleInput.MAX_SIZE, ConsoleInput.c1f, ConsoleInput.c1b, ConsoleInput.c2f, ConsoleInput.c2b)
  21.  
  22.     PALETTE 7, 63
  23.  
  24.     TYPE ConsoleInput
  25.         ii AS INTEGER
  26.         vmax AS INTEGER
  27.         MAX_SIZE AS INTEGER
  28.         vertpos AS INTEGER
  29.         yyseparator AS INTEGER
  30.         prompt_column AS INTEGER
  31.         c1f AS INTEGER
  32.         c1b AS INTEGER
  33.         c2f AS INTEGER
  34.         c2b AS INTEGER
  35.     END TYPE
  36.  
  37.     DO UNTIL ConsoleInput_prompt$(ConsoleInput.vmax) = ""
  38.         ConsoleInput.vmax = ConsoleInput.vmax + 1
  39.     LOOP
  40.  
  41.     CALL ConsoleInput_demo(ConsoleInput_prompt$(), ConsoleInput.prompt_column, ConsoleInput.vmax, ConsoleInput.MAX_SIZE, ConsoleInput.vertpos, ConsoleInput.yyseparator, ConsoleInput.c1f, ConsoleInput.c1b, ConsoleInput.c2f, ConsoleInput.c2b)
  42.  
  43. SUB ConsoleInput_demo (ConsoleInput_prompt$(), ConsoleInput.prompt_column, ConsoleInput.vmax, ConsoleInput.MAX_SIZE, ConsoleInput.vertpos, ConsoleInput.yyseparator, ConsoleInput.c1f, ConsoleInput.c1b, ConsoleInput.c2f, ConsoleInput.c2b)
  44.     COLOR ConsoleInput.c1f, ConsoleInput.c1b
  45.     CLS
  46.     CALL b(ConsoleInput_prompt$(), ConsoleInput.prompt_column, ConsoleInput.vmax, ConsoleInput.MAX_SIZE, ConsoleInput.vertpos, ConsoleInput.yyseparator, ConsoleInput.c1f, ConsoleInput.c1b, ConsoleInput.c2f, ConsoleInput.c2b)
  47.  
  48.  
  49. SUB b (ConsoleInput_prompt$(), ConsoleInput.prompt_column, ConsoleInput.vmax, ConsoleInput.MAX_SIZE, ConsoleInput.vertpos, ConsoleInput.yyseparator, ConsoleInput.c1f, ConsoleInput.c1b, ConsoleInput.c2f, ConsoleInput.c2b)
  50.     FOR ConsoleInput.ii = 0 TO ConsoleInput.vmax - 1
  51.         LOCATE ConsoleInput.vertpos + ConsoleInput.ii * ConsoleInput.yyseparator, ConsoleInput.prompt_column
  52.         PRINT ConsoleInput.ii, ConsoleInput_prompt$(ConsoleInput.ii)
  53.     NEXT
  54.  
  55.  

By using TYPE, I can get unique variables, which helps conflicts with other users global variables.

I read this in the Wiki: "Type variables must be defined in every SUB or FUNCTION unless the type variable is DIMensioned as SHARED."

Really? I tried that, but I couldn't could up with a way to use SHARED in the initial SUB to pass the TYPE variables to other subs. Here is the code, without SHARED anywhere.

Code: QB64: [Select]
  1. main:
  2. ' I don't want to use this and otehrs like this in the main - DIM SHARED ConsoleInput.c1b AS INTEGER
  3.  
  4. DIM ConsoleInput_prompt$(4)
  5. ConsoleInput_prompt$(0) = "abc: "
  6. ConsoleInput_prompt$(1) = "def: "
  7. ConsoleInput_prompt$(2) = "ghi: "
  8. ConsoleInput_prompt$(3) = "jkl: "
  9.  
  10. ConsoleInput.promtp_column% = 10
  11. ConsoleInput.vertpos% = 5
  12. ConsoleInput.yyseparator% = 2
  13. ConsoleInput.MAX_SIZE% = 40
  14. ConsoleInput.c1f% = 0
  15. ConsoleInput.c1b% = 7
  16. ConsoleInput.c2f% = 15
  17. ConsoleInput.c2b% = 1
  18.  
  19. CALL ConsoleLibrary(ConsoleInput_prompt$())
  20.  
  21. SUB ConsoleLibrary (ConsoleInput_prompt$())
  22.  
  23.     PALETTE 7, 63
  24.  
  25.     TYPE ConsoleInput
  26.         ii AS INTEGER
  27.         vmax AS INTEGER
  28.         MAX_SIZE AS INTEGER
  29.         vertpos AS INTEGER
  30.         yyseparator AS INTEGER
  31.         prompt_column AS INTEGER
  32.         c1f AS INTEGER
  33.         c1b AS INTEGER
  34.         c2f AS INTEGER
  35.         c2b AS INTEGER
  36.     END TYPE
  37.  
  38.     DO UNTIL ConsoleInput_prompt$(ConsoleInput.vmax) = ""
  39.         ConsoleInput.vmax = ConsoleInput.vmax + 1
  40.     LOOP
  41.  
  42.     CALL ConsoleInput_demo(ConsoleInput_prompt$())
  43.  
  44. SUB ConsoleInput_demo (ConsoleInput_promt$())
  45.     COLOR ConsoleInput.c1f, ConsoleInput.c1b
  46.     CLS
  47.  
  48.     CALL b(ConsoleInput_prompt$())
  49.  
  50.  
  51. SUB b (ConsoleInput_prompt$())
  52.     FOR ConsoleInput.ii = 0 TO ConsoleInput.vmax - 1
  53.         LOCATE ConsoleInput.vertpos + ConsoleInput.ii * ConsoleInput.yyseparator, ConsoleInput.prompt_column
  54.         PRINT ConsoleInput.ii, ConsoleInput_prompt$(ConsoleInput.ii)
  55.     NEXT
  56.  
  57.  

Since this is a library, I don't want to use DIM SHARED or COMMON SHARED in the main. Is there a way to use SHARED to share the typ variable, or am I misunderstanding the Wiki information?

This post pertains to what I'm working on in: https://www.qb64.org/forum/index.php?topic=1524.msg107407#msg107407
Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #1 on: July 24, 2019, 07:36:24 am »
Is something like this what you're looking for?

Code: [Select]
main:
' I don't want to use this and otehrs like this in the main - DIM SHARED ConsoleInput.c1b AS INTEGER


CALL InitConsoleLibrary
CALL ConsoleLibrary(ConsoleInput_prompt$())
END

SUB InitConsoleLibrary
    SHARED ConsoleInput AS ConsoleInput
    SHARED ConsoleInput_prompt$()

    ConsoleInput_prompt$(0) = "abc: "
    ConsoleInput_prompt$(1) = "def: "
    ConsoleInput_prompt$(2) = "ghi: "
    ConsoleInput_prompt$(3) = "jkl: "

    ConsoleInput.prompt_column% = 10
    ConsoleInput.vertpos% = 5
    ConsoleInput.yyseparator% = 2
    ConsoleInput.MAX_SIZE% = 40
    ConsoleInput.c1f% = 0
    ConsoleInput.c1b% = 7
    ConsoleInput.c2f% = 15
    ConsoleInput.c2b% = 1

END SUB


SUB ConsoleLibrary (ConsoleInput_prompt$())
    SHARED ConsoleInput AS ConsoleInput
    SHARED ConsoleInput_prompt$()
    PALETTE 7, 63

    TYPE ConsoleInput
        ii AS INTEGER
        vmax AS INTEGER
        MAX_SIZE AS INTEGER
        vertpos AS INTEGER
        yyseparator AS INTEGER
        prompt_column AS INTEGER
        c1f AS INTEGER
        c1b AS INTEGER
        c2f AS INTEGER
        c2b AS INTEGER
    END TYPE

    DO UNTIL ConsoleInput_prompt$(ConsoleInput.vmax) = ""
        ConsoleInput.vmax = ConsoleInput.vmax + 1
    LOOP

    CALL ConsoleInput_demo(ConsoleInput_prompt$())
END SUB

SUB ConsoleInput_demo (ConsoleInput_prompt$())
    SHARED ConsoleInput AS ConsoleInput
    SHARED ConsoleInput_prompt$()
    COLOR ConsoleInput.c1f, ConsoleInput.c1b
    CLS

    CALL b(ConsoleInput_prompt$())

END SUB

SUB b (ConsoleInput_prompt$())
    SHARED ConsoleInput AS ConsoleInput
    SHARED ConsoleInput_prompt$()
    FOR ConsoleInput.ii = 0 TO ConsoleInput.vmax - 1
        LOCATE ConsoleInput.vertpos + ConsoleInput.ii * ConsoleInput.yyseparator, ConsoleInput.prompt_column
        PRINT ConsoleInput.ii, ConsoleInput_prompt$(ConsoleInput.ii)
    NEXT

END SUB
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #2 on: July 24, 2019, 02:24:12 pm »
Aha! That's how it's done. I tried a lot of SHARED combos in a few places, but I didn't think of that one.. SHARED ConsoleInput AS ConsoleInput

Thank you. This cuts down on the long lines of passing variables to subs. Other things I will be changing will be the names of the subs, so there is some consistency to associate the names with the library.

OK, so here is something strange I noticed with the SHARED approach. Did you know that the array gets shared with the main, as does the additional testing variable I created, called Pete%; however, the SHARED TYPE variables only get shared with the child subs, and not the main. Of course, I prefer this, but I'm surprised there is a difference as how shared type variables and shared string and numeric variables are handled by QB64. Anyway, here is the code, with comments, to illustrate this, and again, thank you for providing e with the way to share a TYPE variable. Maybe someday your example will make it into the Wiki and QB64 help....

Code: QB64: [Select]
  1. CALL InitConsoleLibrary
  2. CALL ConsoleLibrary(ConsoleInput_prompt$())
  3. PRINT: PRINT "Prompt$(0) = "; ConsoleInput_prompt$(0): PRINT: PRINT "Highlight Color (Consoleinput.c2f) should be 15, but ="; Consoleinput.c2f
  4. PRINT "Variable in SUB b, Pete% ="; Pete%
  5.  
  6. SUB InitConsoleLibrary
  7.     SHARED ConsoleInput AS ConsoleInput
  8.     SHARED ConsoleInput_prompt$()
  9.  
  10.     ConsoleInput_prompt$(0) = "abc: "
  11.     ConsoleInput_prompt$(1) = "def: "
  12.     ConsoleInput_prompt$(2) = "ghi: "
  13.     ConsoleInput_prompt$(3) = "jkl: "
  14.  
  15.     ConsoleInput.prompt_column% = 10
  16.     ConsoleInput.vertpos% = 5
  17.     ConsoleInput.yyseparator% = 2
  18.     ConsoleInput.MAX_SIZE% = 40
  19.     ConsoleInput.c1f% = 0
  20.     ConsoleInput.c1b% = 7
  21.     ConsoleInput.c2f% = 15
  22.     ConsoleInput.c2b% = 1
  23.  
  24.  
  25.  
  26. SUB ConsoleLibrary (ConsoleInput_prompt$())
  27.     SHARED ConsoleInput AS ConsoleInput ' Shared with child subs, BUT NOT main.
  28.     SHARED ConsoleInput_prompt$() ' Shared with child subs AND main.
  29.     PALETTE 7, 63
  30.  
  31.     TYPE ConsoleInput
  32.         ii AS INTEGER
  33.         vmax AS INTEGER
  34.         MAX_SIZE AS INTEGER
  35.         vertpos AS INTEGER
  36.         yyseparator AS INTEGER
  37.         prompt_column AS INTEGER
  38.         c1f AS INTEGER
  39.         c1b AS INTEGER
  40.         c2f AS INTEGER
  41.         c2b AS INTEGER
  42.     END TYPE
  43.  
  44.     DO UNTIL ConsoleInput_prompt$(ConsoleInput.vmax) = ""
  45.         ConsoleInput.vmax = ConsoleInput.vmax + 1
  46.     LOOP
  47.  
  48.     CALL ConsoleInput_demo(ConsoleInput_prompt$())
  49.  
  50. SUB ConsoleInput_demo (ConsoleInput_prompt$())
  51.     SHARED ConsoleInput AS ConsoleInput
  52.     SHARED ConsoleInput_prompt$()
  53.     COLOR ConsoleInput.c1f, ConsoleInput.c1b
  54.     CLS
  55.  
  56.     CALL b(ConsoleInput_prompt$())
  57.  
  58.  
  59. SUB b (ConsoleInput_prompt$())
  60.     SHARED ConsoleInput AS ConsoleInput
  61.     SHARED ConsoleInput_prompt$()
  62.     SHARED Pete%: Pete% = 100 ' This will also get shared in main. So will the string, ConsoleInput_promt$(), but NOT the shared TYPE variables.
  63.     FOR ConsoleInput.ii = 0 TO ConsoleInput.vmax - 1
  64.         LOCATE ConsoleInput.vertpos + ConsoleInput.ii * ConsoleInput.yyseparator, ConsoleInput.prompt_column
  65.         PRINT ConsoleInput.ii, ConsoleInput_prompt$(ConsoleInput.ii)
  66.     NEXT
  67.  
  68.  

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #3 on: July 24, 2019, 03:09:56 pm »
Quote
Did you know that the array gets shared with the main, as does the additional testing variable I created, called Pete%; however, the SHARED TYPE variables only get shared with the child subs, and not the main.

That’s only because you don’t have a corresponding variable to share the info with.  At the top of your code put a:

DIM ConsoleInput AS ConsoleInput

Then you can print/change any of the values in the main sub as you wish, and have those changes affect the relevant SUB/FUNCTIONS.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #4 on: July 24, 2019, 07:06:36 pm »
Sure, but then why don't we need to do the same in the main with Pete% and prompt$()? As in...

DIM Pete%
DIM SHARED ConsoleInput_prompt$(14)

We don't need those to get the values they represent back to the main at all. Simply having them shared in the subs is all that is ineeded, but TYPE acts differently. TYPE has to be DIM in the main. I just don't understand why TYPE is treated the same as the numeric, presumably string, and string arrays are treated and passed to the main without the need to be DIM in the main.

Also, and this is a biggie. QB64 allows for 10 elements to be in an array, before the array needs to be dimensioned, 11, actually, if you use zero to 1. Anyway, let's say we need 15 elements in the code as posted. So now we need...

    DIM ConsoleInput_prompt$(14)

... in the initial sub, but  adding the DIM here prevents SHARED from returning the values assigned to prompt$() in any of the other subs, and the main. Again, that's fine, it's just worth noting DIM also changes the behavior, because the variable is being further defined while in a SUB. Now, if we did want it back in the main, but not DIM in the main, all we would have to do is pass it by reference as...

CALL ConsoleLibrary(ConsoleInput_prompt$()) 

and do that for all of the subs; however, if we tried to pass it back to the main, we'd end up with a Duplicate Definition error.

Pete
« Last Edit: July 24, 2019, 07:27:48 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #5 on: July 24, 2019, 11:49:08 pm »
Since I can't figure out a way to deal with keeping a DIM for the string array out of the main with the two library sub calls, I decided to go back to the single sub call, and start designing a way for the user to input the variables. This demo works, so I'll use this as a start and see where it takes me...

Code: QB64: [Select]
  1. main:
  2. CALL ConsoleInputLibrary
  3.  
  4. SUB ConsoleInputLibrary
  5.     SHARED ConsoleInput AS ConsoleInput
  6.  
  7.     ConsoleInput_Data:
  8.     'Place Prompts as DATA statement, here...
  9.     DATA 1,2,3,4,5,6,7,8,9,10,11,12
  10.     DATA "EOF"
  11.  
  12.     TYPE ConsoleInput
  13.         i AS INTEGER ' Generic counter variable
  14.         vmax AS INTEGER ' Maximum number of prompts / responses. Must fit within the screen height, including spearator spaces.
  15.         MAX_SIZE AS INTEGER ' Maximum length of the reply to prompt. Must be within the screen width.
  16.         vertpos AS INTEGER ' Margin top (Number of spaces from the top to display the first prompt.)
  17.         yyseparator AS INTEGER ' The vertical row spacing between prompts. 1 to (n).
  18.         prompt_column AS INTEGER ' Margin left. The column to begin displaying prompts. Must be within screen width including maximum length of response.
  19.         mypalette AS INTEGER ' Only use to modify standard screen colors. -1 means this option is turned off.
  20.         c1f AS INTEGER ' Foreground text color (0 - 15)
  21.         c1b AS INTEGER ' Background text color (0 - 15)
  22.         c2f AS INTEGER ' Foreground highlight text color (0 - 15)
  23.         c2b AS INTEGER ' Background highlight text color (0 - 15)
  24.     END TYPE
  25.  
  26.     ' Assign your variables here...
  27.     ConsoleInput.MAX_SIZE = 40
  28.     ConsoleInput.vertpos = 5
  29.     ConsoleInput.yyseparator = 1
  30.     ConsoleInput.prompt_column = 10
  31.     ConsoleInput.mypalette = 63
  32.     ConsoleInput.c1f = 0
  33.     ConsoleInput.c1b = 7
  34.     ConsoleInput.c2f = 15
  35.     ConsoleInput.c2b = 1
  36.     '------------------------------
  37.  
  38.     IF ConsoleInput.mypalette <> -1 THEN
  39.         PALETTE ConsoleInput.c1b, ConsoleInput.mypalette
  40.     END IF
  41.  
  42.     COLOR c1f, c1b
  43.     CLS
  44.  
  45.     ' Get the number of prompts to assign to prompt$() array.
  46.     RESTORE ConsoleInput_Data
  47.     ConsoleInput.vmax = 0
  48.     DO
  49.         READ ConsoleInput_Data$
  50.         IF ConsoleInput_Data$ = "EOF" THEN EXIT DO
  51.         ConsoleInput.vmax = ConsoleInput.vmax + 1
  52.     LOOP
  53.  
  54.     DIM ConsoleInput_prompt$(ConsoleInput.vmax)
  55.  
  56.     RESTORE ConsoleInput_Data
  57.     ConsoleInput.i = 0
  58.     DO
  59.         READ ConsoleInput_Data$
  60.         IF ConsoleInput_Data$ = "EOF" THEN EXIT DO
  61.         ConsoleInput_prompt$(ConsoleInput.i) = ConsoleInput_Data$
  62.         ConsoleInput.i = ConsoleInput.i + 1
  63.     LOOP
  64.  
  65.     CALL ConsoleInput_demo(ConsoleInput_prompt$())
  66.  
  67.  
  68. SUB ConsoleInput_demo (ConsoleInput_prompt$())
  69.     SHARED ConsoleInput AS ConsoleInput
  70.     COLOR ConsoleInput.c1f, ConsoleInput.c1b
  71.     CLS
  72.  
  73.     CALL ConsoleInputDisplay(ConsoleInput_prompt$())
  74.  
  75.  
  76. SUB ConsoleInputDisplay (ConsoleInput_prompt$())
  77.     SHARED ConsoleInput AS ConsoleInput
  78.  
  79.     FOR ConsoleInput.i = 0 TO ConsoleInput.vmax - 1
  80.         LOCATE ConsoleInput.vertpos + ConsoleInput.i * ConsoleInput.yyseparator, ConsoleInput.prompt_column
  81.         PRINT ConsoleInput.i, ConsoleInput_prompt$(ConsoleInput.i)
  82.     NEXT
  83.  
  84.  

I also need to make some better variable names. I have used very short non-descriptive names in the distant past, especially when I had to save memory space in QuickBASIC. Now, I think I'll try longer, more descriptive names, so if anyone wants to alter the library, it will be easier to understand. I could get a lot better at names, that's for sure. Well, I'll see how it goes...

Pete
« Last Edit: July 25, 2019, 01:08:57 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #6 on: July 25, 2019, 08:22:43 pm »
Hi
about SHARED and TYPE in QBASIC vs QB64


declaring a TYPE into a SUB and then using it in another SUB or in the main is NOT possible in QBASIC....

See wiki content
Quote
SHARED (without DIM) can share a list of variables inside of SUB or FUNCTION procedures with the main module only.
Note: SHARED variables in sub-procedures will not be passed to other sub-procedures, only the main module.
Quote
"Type variables must be defined in every SUB or FUNCTION unless the type variable is DIMensioned as SHARED."
Quote
TYPE definitions should be placed in the main module before the start of the program code execution.
TYPE definitions CAN be placed in SUB or FUNCTION procedures using QB64 only!

please run the code examples both in Qbasic both in QB64
Code: QB64: [Select]
  1. DECLARE SUB inizializza ()
  2. DECLARE SUB mostra ()
  3.  a AS STRING * 3
  4.  
  5. inizializza
  6. mostra
  7.  
  8. SUB inizializza
  9. SHARED tipo AS s
  10. COLOR 0, INT(RND * 14) + 1
  11. tipo.a = STRING$(3, INT(RND * 25) + 65)
  12. tipo.b = INT(RND * 1000) + 1
  13. tipo.c = (RND * 150) + 5.7
  14.  
  15. SUB mostra
  16. SHARED tipo AS s
  17. PRINT tipo.a, tipo.b, tipo.c
  18.  
Code: QB64: [Select]
  1. DECLARE SUB dichiara ()
  2. DECLARE SUB inizializza ()
  3. DECLARE SUB mostra ()
  4.  
  5. dichiara
  6. inizializza
  7. mostra
  8.  
  9. SUB dichiara
  10.  a AS STRING * 3
  11.  
  12.  
  13. SUB inizializza
  14. SHARED tipo AS s
  15. COLOR 0, INT(RND * 14) + 1
  16. tipo.a = STRING$(3, INT(RND * 25) + 65)
  17. tipo.b = INT(RND * 1000) + 1
  18. tipo.c = (RND * 150) + 5.7
  19.  
  20. SUB mostra
  21. SHARED tipo AS s
  22. PRINT tipo.a, tipo.b, tipo.c
  23.  
  24.  

we consider this characteristic as a powered feature of SHARED of Qbasic.


About
Quote
Sure, but then why don't we need to do the same in the main with Pete% and prompt$()? As in...

DIM Pete%
DIM SHARED ConsoleInput_prompt$(14)

We don't need those to get the values they represent back to the main at all. Simply having them shared in the subs is all that is ineeded, but TYPE acts differently. TYPE has to be DIM in the main.

IMHO there is some overlapping declarations as these two examples show that Wiki info are right
Code: QB64: [Select]
  1. DECLARE SUB dichiara ()
  2. DECLARE SUB inizializza ()
  3. DECLARE SUB mostra ()
  4.  
  5.     dichiara
  6.     inizializza
  7.     mostra
  8.     PRINT copia, intero, "from main"
  9.     SLEEP 1
  10.     IF INKEY$ = CHR$(27) THEN END
  11.  
  12. SUB dichiara
  13.     TYPE s
  14.         a AS STRING * 3
  15.         b AS INTEGER
  16.         c AS DOUBLE
  17.     END TYPE
  18.  
  19.  
  20. SUB inizializza
  21.     SHARED tipo AS s, Copia AS STRING, Intero AS INTEGER
  22.     COLOR 0, INT(RND * 14) + 1
  23.     CLS
  24.     tipo.a = STRING$(3, INT(RND * 25) + 65)
  25.     tipo.b = INT(RND * 1000) + 1
  26.     tipo.c = (RND * 150) + 5.7
  27.     Copia = tipo.a
  28.     Intero = tipo.b
  29.  
  30. SUB mostra
  31.     SHARED tipo AS s
  32.     PRINT tipo.a, tipo.b, tipo.c
  33.     PRINT copia, intero, "from SUB"
  34.  
  35.  

Code: QB64: [Select]
  1. DECLARE SUB dichiara ()
  2. DECLARE SUB inizializza ()
  3. DECLARE SUB mostra ()
  4.  
  5.     dichiara
  6.     inizializza
  7.     mostra
  8.     PRINT copia, intero, "from main"
  9.     SLEEP 1
  10.     IF INKEY$ = CHR$(27) THEN END
  11.  
  12. SUB dichiara
  13.     TYPE s
  14.         a AS STRING * 3
  15.         b AS INTEGER
  16.         c AS DOUBLE
  17.     END TYPE
  18.  
  19.  
  20. SUB inizializza
  21.     SHARED tipo AS s, Copia AS STRING, Intero AS INTEGER
  22.     COLOR 0, INT(RND * 14) + 1
  23.     CLS
  24.     tipo.a = STRING$(3, INT(RND * 25) + 65)
  25.     tipo.b = INT(RND * 1000) + 1
  26.     tipo.c = (RND * 150) + 5.7
  27.     Copia = tipo.a
  28.     Intero = tipo.b
  29.  
  30. SUB mostra
  31.     SHARED tipo AS s, Copia AS STRING, Intero AS INTEGER
  32.     PRINT tipo.a, tipo.b, tipo.c
  33.     PRINT Copia, Intero, "from SUB"
  34.  
  35.  

and the visibility of each variable is defined by its declaration as the picture shows
  [ You are not allowed to view this attachment ]  


« Last Edit: July 25, 2019, 08:24:37 pm by TempodiBasic »
Programming isn't difficult, only it's  consuming time and coffee

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #7 on: July 25, 2019, 08:31:28 pm »
What I concluded is QB64 will pass default variables, single for numeric variables and any string with $ instead of DIM x as string, if you use SHARED in the subs with no DIM in the main. Now if you define those variables as SINGLE and STRING in the subs, then it will not pass them back to the main. Since TYPE variables are defined in the type, they don't get passed back to the main, unless they are defined in the main, as well.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #8 on: July 25, 2019, 08:54:16 pm »
Thanks Pete
now I can duplicate your experience.

Code: QB64: [Select]
  1. DECLARE SUB dichiara ()
  2. DECLARE SUB inizializza ()
  3. DECLARE SUB mostra ()
  4.  
  5.     dichiara
  6.     inizializza
  7.     mostra
  8.     PRINT copia$, intero%, "from main"
  9.     SLEEP 1
  10.     IF INKEY$ = CHR$(27) THEN END
  11.  
  12. SUB dichiara
  13.     TYPE s
  14.         a AS STRING * 3
  15.         b AS INTEGER
  16.         c AS DOUBLE
  17.     END TYPE
  18.  
  19.  
  20. SUB inizializza
  21.     SHARED tipo AS s, copia$, intero%
  22.     COLOR 0, INT(RND * 14) + 1
  23.     CLS
  24.     tipo.a = STRING$(3, INT(RND * 25) + 65)
  25.     tipo.b = INT(RND * 1000) + 1
  26.     tipo.c = (RND * 150) + 5.7
  27.     copia$ = tipo.a
  28.     intero% = tipo.b
  29.  
  30. SUB mostra
  31.     SHARED tipo AS s, copia$, intero%
  32.     PRINT tipo.a, tipo.b, tipo.c
  33.     PRINT copia$, intero%, "from SUB"
  34.  
  35.  

moreover it seems that Qb64 and QBASIC are identical about not use of %$!# for defining variables into TYPE ...END TYPE structure!
« Last Edit: July 25, 2019, 08:58:07 pm by TempodiBasic »
Programming isn't difficult, only it's  consuming time and coffee

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #9 on: July 26, 2019, 01:09:59 am »
Made some progress with the TYPE variable structure. Got the sub names and variable names changed. I do need to add some more user variable descriptions. This is new method seems to be proving out to be a winner. Now, I need to figure out how I want to call this from the main.

Code: QB64: [Select]
  1. main:
  2. ' The next two lines can be removed to use this library with other programs.
  3. LINE INPUT "Input 1 for debug mode with variable display, any other to keep debug off. "; a$
  4. IF a$ = "1" THEN DIM SHARED ConsoleInput_debug: ConsoleInput_debug = -1
  5.  
  6. ' Place the routine that will use this library above and/or ConsoleInput.CursorAppearanceide this loop...
  7. WHILE (1)
  8.     CALL ConsoleInputLibrary
  9.  
  10. '=============================CONSOLE INPUT LIBRARY===========================
  11.  
  12. SUB ConsoleInputLibrary
  13.     STATIC UserInputSetup AS INTEGER
  14.     STATIC ConsoleInput_prompt$(), entry$(), ConsoleInput_entryrow() AS INTEGER
  15.  
  16.     SHARED ConsoleInput AS ConsoleInput
  17.  
  18.     IF UserInputSetup = 0 THEN
  19.         TYPE ConsoleInput
  20.             ' User Defined Variable Types--------------------------------------------------------
  21.             MarginTop AS INTEGER ' Margin top (Number of spaces from the top to display the first prompt.)
  22.             PromptMarginLeft AS INTEGER ' Margin left. The column to begin displaying prompts. Must be within screen width including maximum length of response.
  23.             PromptSpacing AS INTEGER ' The vertical row spacing between prompts. 1 to (n).
  24.             ResponseLength AS INTEGER ' Maximum length of the reply to prompt. Must be within the screen width.
  25.             MyPalette AS INTEGER ' Only use to modify standard screen colors. -1 means this option is turned off.
  26.             ColorTextForeground AS INTEGER ' Foreground text color (0 - 15)
  27.             ColorTextBackground AS INTEGER ' Background text color (0 - 15)
  28.             ColorHighlightForeground AS INTEGER ' Foreground highlight text color (0 - 15)
  29.             ColorHighlightBackground AS INTEGER ' Background highlight text color (0 - 15)
  30.             CursorAppearance AS INTEGER ' Default is 7 for text insert and 30 for text overwrite. Insert key changes mode.
  31.             ' ------------------------------------------------------------------------------------
  32.  
  33.             PromptLength AS INTEGER ' Automatically determined by library function.
  34.             PromptsDisplayed AS INTEGER ' Automatically determined by library function.
  35.             ResponsemarginLeft AS INTEGER ' Automatically determined by library function.
  36.             ResponseMarginRight AS INTEGER ' Automatically determined by library function.
  37.             yy AS INTEGER
  38.             xx AS INTEGER
  39.             drag AS INTEGER
  40.             dir AS INTEGER
  41.             hl AS INTEGER
  42.             shift AS INTEGER
  43.             ctrl AS INTEGER
  44.             hmrk AS INTEGER
  45.         END TYPE
  46.  
  47.         ConsoleInput_Data:
  48.         ' User Defined Prompts Go Here. Leave the DATA EOF.--------------------------------
  49.         DATA "Example Prompt 1: ","Example Prompt 2: ","Example Prompt 3: "
  50.         ' ---------------------------------------------------------------------------------
  51.         DATA EOF
  52.  
  53.         ' User Defined Prompts Go Here. Keep DATA EOF.-------------------------------------
  54.         ConsoleInput.MarginTop = 5
  55.         ConsoleInput.PromptMarginLeft = 10
  56.         ConsoleInput.PromptSpacing = 2 'Number of blank rows, less 1, between prompts. Do not set lower than 1.
  57.         ConsoleInput.ResponseLength = 50
  58.         ConsoleInput_MyPalette = 63
  59.         ConsoleInput.ColorTextForeground = 0
  60.         ConsoleInput.ColorTextBackground = 7
  61.         ConsoleInput.ColorHighlightForeground = 7
  62.         ConsoleInput.ColorHighlightBackground = 1
  63.         ConsoleInput.CursorAppearance = 7 'Cursor vertical height for default ConsoleInput.CursorAppearanceert text mode.
  64.         ' ---------------------------------------------------------------------------------
  65.  
  66.         IF ConsoleInput_MyPalette >= 0 THEN
  67.             PALETTE ConsoleInput.ColorTextBackground, ConsoleInput_MyPalette
  68.         END IF
  69.  
  70.         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  71.         CLS
  72.  
  73.         CALL ConsoleInputGetPrompts(ConsoleInput_entryrow(), ConsoleInput_prompt$())
  74.  
  75.         DIM entry$(ConsoleInput.PromptsDisplayed) 'Text entry array.
  76.         LOCATE , , 1, 7, ConsoleInput.CursorAppearance
  77.  
  78.         UserInputSetup = -1
  79.     END IF
  80.  
  81.     CALL ConsoleInputResponse(ConsoleInput_entryrow(), entry$())
  82.  
  83.  
  84. SUB ConsoleInputGetPrompts (ConsoleInput_entryrow() AS INTEGER, ConsoleInput_prompt$())
  85.     SHARED ConsoleInput AS ConsoleInput
  86.  
  87.     ' Get the number of prompts to assign to ConsoleInput_prompt$() array.
  88.     RESTORE ConsoleInput_Data
  89.     ConsoleInput.PromptsDisplayed = 0
  90.     DO
  91.         READ ConsoleInput_Data$
  92.         IF ConsoleInput_Data$ = "EOF" THEN EXIT DO
  93.         IF LEN(ConsoleInput_Data$) > ConsoleInput.PromptLength THEN ConsoleInput.PromptLength = LEN(ConsoleInput_Data$)
  94.         ConsoleInput.PromptsDisplayed = ConsoleInput.PromptsDisplayed + 1
  95.     LOOP
  96.  
  97.     REDIM ConsoleInput_prompt$(ConsoleInput.PromptsDisplayed)
  98.     REDIM ConsoleInput_prompt$(ConsoleInput.PromptsDisplayed) 'Prompt array.
  99.     REDIM ConsoleInput_entryrow(ConsoleInput.PromptsDisplayed) AS INTEGER 'Tracks row location of each prompt.
  100.  
  101.     ConsoleInput.ResponsemarginLeft = ConsoleInput.PromptMarginLeft + ConsoleInput.PromptLength
  102.     ConsoleInput.ResponseMarginRight = ConsoleInput.ResponsemarginLeft + ConsoleInput.ResponseLength
  103.  
  104.     RESTORE ConsoleInput_Data
  105.     ConsoleInput_i = 0
  106.     DO
  107.         READ ConsoleInput_Data$
  108.         IF ConsoleInput_Data$ = "EOF" THEN EXIT DO
  109.         ConsoleInput_prompt$(ConsoleInput_i) = ConsoleInput_Data$
  110.         ConsoleInput_i = ConsoleInput_i + 1
  111.     LOOP
  112.  
  113.     ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  114.     ConsoleInput.yy = ConsoleInput.MarginTop
  115.  
  116.     FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed - 1
  117.         LOCATE ConsoleInput.yy, ConsoleInput.PromptMarginLeft
  118.         PRINT ConsoleInput_prompt$(ConsoleInput_i);
  119.         ConsoleInput_entryrow(ConsoleInput_i) = ConsoleInput.yy
  120.         ConsoleInput.yy = ConsoleInput.yy + ConsoleInput.PromptSpacing
  121.     NEXT
  122.  
  123.     LOCATE ConsoleInput.MarginTop, ConsoleInput.ResponsemarginLeft
  124.     ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  125.     ConsoleInput.yy = ConsoleInput.MarginTop
  126.  
  127. SUB ConsoleInputCopyText (ConsoleInput_xntry$, entry$())
  128.     DIM ConsoleInput_m1 AS INTEGER, ConsoleInput_m2 AS INTEGER
  129.  
  130.     SHARED ConsoleInput AS ConsoleInput
  131.  
  132.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 < ConsoleInput.hmrk THEN
  133.         ConsoleInput_m2 = ConsoleInput.hmrk
  134.         ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  135.     ELSE
  136.         ConsoleInput_m1 = ConsoleInput.hmrk
  137.         ConsoleInput_m2 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  138.     END IF
  139.     ConsoleInput_xntry$ = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m1, ConsoleInput_m2 - ConsoleInput_m1)
  140.  
  141. SUB ConsoleInputReplace (entry$())
  142.     DIM ConsoleInput_j AS INTEGER, ConsoleInput_m1 AS INTEGER, ConsoleInput_m2 AS INTEGER
  143.  
  144.     SHARED ConsoleInput AS ConsoleInput
  145.  
  146.     ConsoleInput_j = LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  147.     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  148.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 < ConsoleInput.hmrk THEN
  149.         ConsoleInput_m2 = ConsoleInput.hmrk
  150.         ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft
  151.     ELSE
  152.         ConsoleInput_m1 = ConsoleInput.hmrk - 1
  153.         ConsoleInput_m2 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  154.     END IF
  155.     entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput_m1) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m2)
  156.     LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  157.     PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  158.     PRINT STRING$(ConsoleInput_j - LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)), 32);
  159.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 > ConsoleInput.hmrk THEN
  160.         ConsoleInput.xx = ConsoleInput.hmrk - 1 + ConsoleInput.ResponsemarginLeft
  161.     END IF
  162.     LOCATE ConsoleInput.yy, ConsoleInput.xx
  163.     ConsoleInput.hmrk = 0
  164.     ConsoleInput.hl = 0
  165.     ConsoleInput.dir = 0
  166.  
  167. SUB ConsoleInputResponse (ConsoleInput_entryrow() AS INTEGER, entry$())
  168.     STATIC ConsoleInput_xntry$
  169.     SHARED ConsoleInput AS ConsoleInput
  170.  
  171.     DIM ConsoleInput_oldyy AS INTEGER
  172.  
  173.     IF ConsoleInput.ctrl THEN ConsoleInput.ctrl = 0
  174.     IF ConsoleInput.shift < 0 THEN ConsoleInput.shift = 0
  175.     DEF SEG = 0
  176.     ConsoleInput_i = PEEK(&H417) MOD 16
  177.     SELECT CASE ConsoleInput_i
  178.         CASE 1, 2
  179.             ConsoleInput.shift = -1
  180.         CASE 4
  181.             ConsoleInput.ctrl = -1
  182.     END SELECT
  183.     DEF SEG
  184.  
  185.     ConsoleInput_oldyy = ConsoleInput.yy
  186.  
  187.     IF ConsoleInput.drag = 0 THEN
  188.         IF ConsoleInput.hl AND ConsoleInput.shift = 0 AND ConsoleInput.hmrk = 0 THEN
  189.             ConsoleInput.hl = 0 ' Disable ConsoleInput.hl so character value isn't printed after a shift / release event without highlighting.
  190.         END IF
  191.     END IF
  192.  
  193.     CALL ConsoleInputMouse(ConsoleInput_entryrow(), entry$(), ConsoleInput_ch$)
  194.  
  195.     IF ConsoleInput.drag = 0 THEN
  196.         IF ConsoleInput_ch$ = "" THEN ConsoleInput_ch$ = INKEY$
  197.         IF ConsoleInput_ch$ <> "" THEN
  198.             IF ConsoleInput.ctrl THEN
  199.                 SELECT CASE LCASE$(ConsoleInput_ch$)
  200.                     CASE CHR$(1) ' Select All
  201.                         LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  202.                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  203.                         PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  204.                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  205.                         ConsoleInput.hmrk = 1
  206.                         ConsoleInput.hl = -1
  207.                         ConsoleInput.dir = LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  208.                         ConsoleInput.xx = ConsoleInput.ResponsemarginLeft + ConsoleInput.dir
  209.                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  210.  
  211.                     CASE CHR$(3) ' Copy
  212.                         IF ConsoleInput.hmrk THEN
  213.                             CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  214.                         END IF
  215.  
  216.                     CASE CHR$(24) ' Cut
  217.                         IF ConsoleInput.hmrk THEN
  218.                             CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  219.                             CALL ConsoleInputReplace(entry$())
  220.                         END IF
  221.  
  222.                     CASE CHR$(22) ' Paste
  223.                         IF ConsoleInput_xntry$ <> "" THEN
  224.                             IF ConsoleInput.hmrk THEN
  225.                                 CALL ConsoleInputReplace(entry$())
  226.                             END IF
  227.                             ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft
  228.                             ConsoleInput_m2 = ConsoleInput_m1 + 1
  229.                             IF LEN(ConsoleInput_xntry$) + LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) - (ConsoleInput_m2 - ConsoleInput_m1) <= ConsoleInput.ResponseLength - 1 THEN
  230.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput_m1) + ConsoleInput_xntry$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m2)
  231.                                 LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  232.                                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  233.                                 PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  234.                                 ConsoleInput.xx = ConsoleInput.xx + LEN(ConsoleInput_xntry$)
  235.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  236.                             ELSE
  237.                                 BEEP ' Contents too large to paste.
  238.                             END IF
  239.                         END IF
  240.                 END SELECT
  241.             ELSE
  242.                 SELECT CASE ConsoleInput_ch$
  243.                     CASE CHR$(8) ' Backspace
  244.                         ConsoleInput_ch$ = CHR$(0)
  245.                         IF ConsoleInput.hmrk > 0 THEN
  246.                             CALL ConsoleInputReplace(entry$())
  247.                         ELSE
  248.                             IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  249.                                 ConsoleInput.xx = ConsoleInput.xx - 1
  250.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  251.                                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2); " ";
  252.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2)
  253.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  254.                             END IF
  255.                         END IF
  256.                     CASE CHR$(0) + "S" ' Delete
  257.                         IF ConsoleInput.shift THEN
  258.                             IF ConsoleInput.hmrk THEN
  259.                                 CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  260.                                 CALL ConsoleInputReplace(entry$())
  261.                             END IF
  262.                         ELSE
  263.                             ConsoleInput_ch$ = CHR$(0)
  264.                             IF ConsoleInput.hmrk > 0 THEN
  265.                                 CALL ConsoleInputReplace(entry$())
  266.                             ELSE
  267.                                 IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) > 0 AND ConsoleInput.xx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  268.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2); " ";
  269.                                     entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2)
  270.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  271.                                 END IF
  272.                             END IF
  273.                         END IF
  274.  
  275.                     CASE CHR$(0) + "H" ' Arrow up
  276.                         ConsoleInput_ch$ = CHR$(0)
  277.                         IF ConsoleInput.yy > ConsoleInput.MarginTop THEN
  278.                             ConsoleInput.yy = ConsoleInput.yy - ConsoleInput.PromptSpacing
  279.                             ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  280.                             LOCATE ConsoleInput.yy, ConsoleInput.xx
  281.                         END IF
  282.  
  283.                     CASE CHR$(0) + "P", CHR$(13) ' Arrow down, Enter
  284.                         ConsoleInput_ch$ = CHR$(0)
  285.                         IF (ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing + 1 < ConsoleInput.PromptsDisplayed THEN
  286.                             ConsoleInput.yy = ConsoleInput.yy + ConsoleInput.PromptSpacing
  287.                             ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  288.                             LOCATE ConsoleInput.yy, ConsoleInput.xx
  289.                         END IF
  290.  
  291.                     CASE CHR$(0) + "K" ' Arrow left
  292.                         ConsoleInput_ch$ = CHR$(0)
  293.                         IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  294.                             IF ConsoleInput.shift THEN
  295.                                 IF ConsoleInput.dir <= 0 THEN
  296.                                     IF ConsoleInput.dir = 0 THEN
  297.                                         ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  298.                                         ConsoleInput.hl = -1
  299.                                     END IF
  300.                                     ConsoleInput.xx = ConsoleInput.xx - 1
  301.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  302.                                     COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  303.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  304.                                     ConsoleInput.dir = ConsoleInput.dir - 1
  305.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  306.                                 ELSE
  307.                                     ConsoleInput.xx = ConsoleInput.xx - 1
  308.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  309.                                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  310.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  311.                                     ConsoleInput.dir = ConsoleInput.dir - 1
  312.                                     IF ConsoleInput.dir = 0 THEN
  313.                                         ConsoleInput.hmrk = 0
  314.                                     END IF
  315.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  316.                                 END IF
  317.  
  318.                             ELSE
  319.                                 ConsoleInput.xx = ConsoleInput.xx - 1
  320.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  321.                             END IF
  322.                         END IF
  323.  
  324.                     CASE CHR$(0) + "M" ' Arrow right
  325.                         ConsoleInput_ch$ = CHR$(0)
  326.                         IF ConsoleInput.xx < ConsoleInput.ResponseMarginRight - 1 AND ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  327.                             IF ConsoleInput.shift THEN
  328.                                 IF ConsoleInput.dir >= 0 THEN
  329.                                     IF ConsoleInput.dir = 0 THEN
  330.                                         ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  331.                                         ConsoleInput.hl = -1
  332.                                     END IF
  333.                                     COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  334.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  335.                                     ConsoleInput.xx = ConsoleInput.xx + 1
  336.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  337.                                     ConsoleInput.dir = ConsoleInput.dir + 1
  338.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  339.                                 ELSE
  340.                                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  341.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  342.                                     ConsoleInput.xx = ConsoleInput.xx + 1
  343.                                     ConsoleInput.dir = ConsoleInput.dir + 1
  344.                                     IF ConsoleInput.dir = 0 THEN
  345.                                         ConsoleInput.hmrk = 0
  346.                                         ConsoleInput.hl = 0
  347.                                     END IF
  348.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  349.                                 END IF
  350.                             ELSE
  351.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  352.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  353.                             END IF
  354.                         END IF
  355.  
  356.                     CASE CHR$(0) + "G" ' Home
  357.                         ConsoleInput_ch$ = CHR$(0)
  358.                         IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  359.                             IF ConsoleInput.shift THEN
  360.                                 WHILE ConsoleInput.xx > ConsoleInput.ResponsemarginLeft
  361.                                     IF ConsoleInput.dir <= 0 THEN
  362.                                         IF ConsoleInput.dir = 0 THEN
  363.                                             ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  364.                                             ' ConsoleInput.hl is already set.
  365.                                         END IF
  366.                                         ConsoleInput.xx = ConsoleInput.xx - 1
  367.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  368.                                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  369.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  370.                                         ConsoleInput.dir = ConsoleInput.dir - 1
  371.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  372.                                     ELSE
  373.                                         ConsoleInput.xx = ConsoleInput.xx - 1
  374.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  375.                                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  376.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  377.                                         ConsoleInput.dir = ConsoleInput.dir - 1
  378.                                         IF ConsoleInput.dir = 0 THEN
  379.                                             ConsoleInput.hmrk = 0
  380.                                             ConsoleInput.hl = 0
  381.                                         END IF
  382.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  383.                                     END IF
  384.                                 WEND
  385.                             ELSE
  386.                                 ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  387.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  388.                             END IF
  389.                         END IF
  390.  
  391.                     CASE CHR$(0) + "O" ' End
  392.                         ConsoleInput_ch$ = CHR$(0)
  393.                         IF ConsoleInput.xx < ConsoleInput.ResponseMarginRight - 1 THEN
  394.                             IF ConsoleInput.shift THEN
  395.                                 WHILE ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  396.                                     IF ConsoleInput.dir >= 0 THEN
  397.                                         IF ConsoleInput.dir = 0 THEN
  398.                                             ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  399.                                             ConsoleInput.hl = -1
  400.                                         END IF
  401.                                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  402.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  403.                                         ConsoleInput.xx = ConsoleInput.xx + 1
  404.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  405.                                         ConsoleInput.dir = ConsoleInput.dir + 1
  406.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  407.                                     ELSE
  408.                                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  409.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  410.                                         ConsoleInput.xx = ConsoleInput.xx + 1
  411.                                         ConsoleInput.dir = ConsoleInput.dir + 1
  412.                                         IF ConsoleInput.dir = 0 THEN
  413.                                             ConsoleInput.hmrk = 0
  414.                                         END IF
  415.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  416.                                     END IF
  417.                                 WEND
  418.                             ELSE
  419.                                 ConsoleInput.xx = ConsoleInput.ResponsemarginLeft + LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  420.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  421.                             END IF
  422.                         END IF
  423.  
  424.                     CASE CHR$(27)
  425.                         ConsoleInput_ch$ = CHR$(0)
  426.                         SYSTEM
  427.  
  428.                     CASE CHR$(0) + CHR$(82) ' ConsoleInput.CursorAppearanceert
  429.                         ConsoleInput_ch$ = CHR$(0)
  430.                         IF ConsoleInput.CursorAppearance = 7 THEN ConsoleInput.CursorAppearance = 30 ELSE ConsoleInput.CursorAppearance = 7
  431.                         LOCATE , , 1, 7, ConsoleInput.CursorAppearance
  432.  
  433.                     CASE CHR$(32) TO CHR$(126)
  434.                         IF ConsoleInput.hmrk > 0 THEN
  435.                             CALL ConsoleInputReplace(entry$())
  436.                         END IF
  437.                         IF ConsoleInput.CursorAppearance = 30 THEN
  438.                             IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < ConsoleInput.ResponseLength - 1 THEN
  439.                                 MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1) = ConsoleInput_ch$
  440.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  441.                                 PRINT ConsoleInput_ch$;
  442.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  443.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  444.                             END IF
  445.                         ELSE
  446.                             IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) < ConsoleInput.ResponseLength - 1 THEN
  447.                                 PRINT ConsoleInput_ch$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1);
  448.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + ConsoleInput_ch$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1)
  449.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  450.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  451.                             END IF
  452.                         END IF
  453.                 END SELECT
  454.             END IF
  455.         END IF
  456.  
  457.         IF ConsoleInput.shift THEN
  458.             IF ConsoleInput.hl = 0 AND ConsoleInput.dir <> 0 THEN
  459.                 ConsoleInput.hl = -1 ' When ConsoleInput.dir <> 0 the first character has been highlighted.
  460.             END IF
  461.         ELSE
  462.             IF ConsoleInput_ch$ <> "" THEN
  463.                 IF ConsoleInput.hl AND ConsoleInput.shift = 0 AND LCASE$(ConsoleInput_ch$) <> "x" AND ConsoleInput.ctrl = 0 AND ConsoleInput_ch$ <> CHR$(8) AND ConsoleInput_ch$ <> CHR$(0) + "S" THEN
  464.                     ' ROutine to remove highlighting from text.
  465.                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  466.                     LOCATE ConsoleInput_oldyy, ConsoleInput.ResponsemarginLeft
  467.                     IF ConsoleInput_ch$ <> CHR$(0) THEN
  468.                         PRINT ConsoleInput_ch$;
  469.                     END IF
  470.                     PRINT entry$((ConsoleInput_oldyy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  471.                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  472.                     ConsoleInput.hmrk = 0
  473.                     ConsoleInput.hl = 0
  474.                     ConsoleInput.dir = 0
  475.                 END IF
  476.             END IF
  477.         END IF
  478.         ConsoleInput_ch$ = ""
  479.     END IF
  480.  
  481. SUB ConsoleInputMouse (ConsoleInput_entryrow() AS INTEGER, entry$(), ConsoleInput_ch$)
  482.     STATIC ConsoleInput_doubleclick AS INTEGER, ConsoleInput_lb AS INTEGER, ConsoleInput_lbdn AS INTEGER, ConsoleInput_z1
  483.     STATIC ConsoleInput_mx AS INTEGER, ConsoleInput_my AS INTEGER, ConsoleInput_oldmx AS INTEGER, ConsoleInput_oldmy AS INTEGER, ConsoleInput_mhl AS INTEGER
  484.  
  485.     SHARED ConsoleInput AS ConsoleInput
  486.  
  487.     IF ConsoleInput_debug THEN
  488.         LOCATE 18, 1
  489.         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  490.         PRINT " oldmx"; ConsoleInput_oldmx; "  oldmy"; ConsoleInput_oldmy; "  mx"; ConsoleInput_mx; "  my"; ConsoleInput_my; "  xx"; ConsoleInput.xx; "  yy"; ConsoleInput.yy; "  lb"; ConsoleInput_lb; "  lbdn"; ConsoleInput_lbdn; "      "
  491.         PRINT " shift"; ConsoleInput.shift; "  drag"; ConsoleInput.drag; "  mhl"; mhl; "  hmrk"; ConsoleInput.hmrk; "  dir"; ConsoleInput.dir; "  dblclk"; ConsoleInput_doubleclick; "        "
  492.         PRINT " mx"; ConsoleInput_mx - ConsoleInput.ResponsemarginLeft + 1; "  my"; (ConsoleInput_my - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing; "  xx"; ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1; "  yy"; (ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing; " hl"; ConsoleInput.hl; "  Response Margin"; ConsoleInput.ResponsemarginLeft; "     ";
  493.         LOCATE ConsoleInput.yy, ConsoleInput.xx
  494.     END IF
  495.  
  496.     ConsoleInput_mx = _MOUSEX
  497.     ConsoleInput_my = _MOUSEY
  498.     ConsoleInput_lb = _MOUSEBUTTON(1)
  499.  
  500.     IF ConsoleInput_lb AND ConsoleInput.hl AND ConsoleInput.shift = 0 AND ConsoleInput.drag = 0 AND ConsoleInput_mhl = 0 THEN ' Allows highlighting caused by mouse click to be removed in parent sub.
  501.         ConsoleInput_ch$ = CHR$(0)
  502.         EXIT SUB
  503.     END IF
  504.  
  505.     IF ConsoleInput.shift AND ConsoleInput_lb AND ConsoleInput.drag = 0 OR ConsoleInput_mhl THEN
  506.         IF ConsoleInput_mhl = 0 THEN ' Shift + click highlighting.
  507.             IF ConsoleInput_my = ConsoleInput.yy AND ConsoleInput_mx <> ConsoleInput.xx AND ConsoleInput_mx >= ConsoleInput.ResponsemarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  508.                 ConsoleInput_mhl = ConsoleInput_mx - ConsoleInput.ResponsemarginLeft + 1
  509.             END IF
  510.         ELSE ' Terminal point reached, end highlighting.
  511.             IF ConsoleInput_mhl = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 THEN ConsoleInput_mhl = 0: ConsoleInput.drag = 0: EXIT SUB
  512.         END IF
  513.     END IF
  514.  
  515.     IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  516.         IF ConsoleInput_lbdn AND ConsoleInput.xx <> ConsoleInput_mx AND ConsoleInput.shift = 0 OR ConsoleInput_mhl THEN ' Combined drag and shift + click highlighting.
  517.             IF ConsoleInput_my = ConsoleInput.yy THEN ' Restrict to active text line.
  518.                 IF ConsoleInput_lb OR ConsoleInput_mhl THEN
  519.                     IF ConsoleInput.xx > ConsoleInput_mx THEN
  520.                         ConsoleInput.drag = -1
  521.                     ELSE
  522.                         ConsoleInput.drag = 1
  523.                     END IF
  524.                     GOSUB mouseConsoleInput.drag
  525.                     EXIT SUB
  526.                 ELSE
  527.                     ConsoleInput.drag = 0
  528.                 END IF
  529.             END IF
  530.         END IF
  531.     END IF
  532.  
  533.     IF ConsoleInput_lb THEN
  534.         IF ConsoleInput_debug THEN COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground: LOCATE 2, 1: PRINT "left button down    "
  535.         IF ConsoleInput_lbdn = 0 THEN ConsoleInput_lbdn = -1
  536.         IF ConsoleInput_my = ConsoleInput.yy THEN
  537.             IF ConsoleInput_mx >= ConsoleInput.ResponsemarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  538.                 IF ConsoleInput.drag = 0 AND ConsoleInput.shift = 0 THEN ConsoleInput.yy = ConsoleInput_my ' Prevents changing rows if a ConsoleInput.drag is in progress.
  539.                 ConsoleInput.xx = ConsoleInput_mx
  540.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  541.                 ConsoleInput_oldmx = ConsoleInput_mx: ConsoleInput_oldmy = ConsoleInput_my
  542.             END IF
  543.         ELSEIF ConsoleInput.shift = 0 THEN
  544.             FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed - 1
  545.                 IF ConsoleInput_my = ConsoleInput_entryrow(ConsoleInput_i) THEN EXIT FOR
  546.             NEXT
  547.  
  548.             IF ConsoleInput_my = ConsoleInput_entryrow(ConsoleInput_i) AND ConsoleInput.drag = 0 THEN
  549.                 IF ConsoleInput_mx >= ConsoleInput.PromptMarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= ConsoleInput.ResponseLength THEN
  550.                     IF ConsoleInput_mx - ConsoleInput.ResponsemarginLeft > 0 AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$(ConsoleInput_i)) THEN
  551.                         ConsoleInput.yy = ConsoleInput_my: ConsoleInput.xx = ConsoleInput_mx
  552.                     ELSE
  553.                         ConsoleInput.yy = ConsoleInput_my: ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  554.                     END IF
  555.                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  556.                 END IF
  557.             END IF
  558.         END IF
  559.     ELSE
  560.         IF ConsoleInput_lbdn THEN
  561.             ConsoleInput_z1 = TIMER
  562.             IF ConsoleInput_debug THEN COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground: LOCATE 2, 1: PRINT "left button released"
  563.             ConsoleInput_doubleclick = ConsoleInput_doubleclick + 1
  564.             ConsoleInput_lbdn = 0
  565.             ConsoleInput.drag = 0
  566.         END IF
  567.     END IF
  568.  
  569.     IF ConsoleInput_doubleclick = 1 THEN
  570.         IF ABS(ConsoleInput_z1 - TIMER) > .33 THEN ConsoleInput_doubleclick = 0
  571.     END IF
  572.  
  573.     IF ConsoleInput_doubleclick = 2 THEN
  574.         ' Any double click events go here...
  575.         IF ConsoleInput_debug THEN LOCATE 2, 1: PRINT "double click         ";
  576.         ConsoleInput_doubleclick = 0
  577.     END IF
  578.     LOCATE ConsoleInput.yy, ConsoleInput.xx
  579.  
  580.     EXIT SUB
  581.  
  582.     mouseConsoleInput.drag:
  583.     SELECT CASE ConsoleInput.drag
  584.         CASE IS < 0
  585.             IF ConsoleInput.dir <= 0 THEN ' highlight to left
  586.                 IF ConsoleInput.dir = 0 THEN
  587.                     ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  588.                     ' Do not emulate shift here.
  589.                     ConsoleInput.hl = -1
  590.                 END IF
  591.                 ConsoleInput.xx = ConsoleInput.xx - 1
  592.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  593.                 COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  594.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  595.                 ConsoleInput.dir = ConsoleInput.dir - 1
  596.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  597.             ELSE ' unhighlight to left
  598.                 ConsoleInput.xx = ConsoleInput.xx - 1
  599.                 ConsoleInput.dir = ConsoleInput.dir - 1
  600.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  601.                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  602.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  603.                 IF ConsoleInput.dir = 0 THEN
  604.                     ConsoleInput.hmrk = 0
  605.                     ConsoleInput.hl = 0
  606.                     ConsoleInput.shift = 0
  607.                 END IF
  608.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  609.             END IF
  610.         CASE IS > 0
  611.             IF ConsoleInput.dir >= 0 THEN
  612.                 COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  613.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  614.                 IF ConsoleInput.dir = 0 THEN
  615.                     ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  616.                     ConsoleInput.hl = -1
  617.                     ' Do not emulate shift here.
  618.                 END IF
  619.                 ConsoleInput.xx = ConsoleInput.xx + 1
  620.                 ConsoleInput.dir = ConsoleInput.dir + 1
  621.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  622.             ELSE
  623.                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  624.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  625.                 ConsoleInput.xx = ConsoleInput.xx + 1
  626.                 ConsoleInput.dir = ConsoleInput.dir + 1
  627.                 IF ConsoleInput.dir = 0 THEN
  628.                     ConsoleInput.hmrk = 0
  629.                     ConsoleInput.hl = 0
  630.                     ConsoleInput.shift = 0
  631.                 END IF
  632.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  633.             END IF
  634.     END SELECT
  635.     RETURN
  636.  
  637.  


Pete
« Last Edit: July 26, 2019, 01:36:25 pm by Pete »
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Trying to make a library. Demo using TYPE for variables...
« Reply #10 on: July 26, 2019, 10:48:38 pm »
OK, which method is better? Method 1 is pretty standard. You pass variables to the library and add your own prompts in the main. Method 2 is the same, except you place your prompts as DATA statements.

Method 1

Code: QB64: [Select]
  1. 'DIM SHARED ConsoleInput_debug AS INTEGER: ConsoleInput_debug = 1
  2. main:
  3. 'PARAMETERS------------------------------------------------------------------
  4. 'Prompts.
  5. 'Margin top.
  6. 'Margin left.
  7. 'Spacing.
  8. 'Response length.
  9. 'Palette screen color modifier. Set to -1 for none.
  10. 'Foreground text color.
  11. 'Screen color.
  12. 'Highlight text foreground.
  13. 'Highlight text background.
  14. '-----------------------------------------------------------------------------
  15. DIM CI_Prompt$(3)
  16. CI_Prompt$(0) = "Example 1: "
  17. CI_Prompt$(1) = "Example 2: "
  18. CI_Prompt$(2) = "Example 3: "
  19. WHILE (1)
  20.     CALL ConsoleInputLibrary(CI_Prompt$(), 10, 15, 2, 50, 63, 0, 7, 7, 1, 7)
  21.  
  22. '=============================CONSOLE INPUT LIBRARY===========================
  23.  
  24. SUB ConsoleInputLibrary (ConsoleInput_Prompt$(), CI_1 AS INTEGER, CI_2 AS INTEGER, CI_3 AS INTEGER, CI_4 AS INTEGER, CI_5 AS INTEGER, CI_6 AS INTEGER, CI_7 AS INTEGER, CI_8 AS INTEGER, CI_9 AS INTEGER, CI_10 AS INTEGER)
  25.     STATIC UserInputSetup AS INTEGER
  26.     STATIC entry$(), ConsoleInput_entryrow() AS INTEGER
  27.  
  28.     SHARED ConsoleInput AS ConsoleInput
  29.  
  30.     IF UserInputSetup = 0 THEN
  31.         TYPE ConsoleInput
  32.             ' User Defined Variable Types--------------------------------------------------------
  33.             MarginTop AS INTEGER ' Margin top (Number of spaces from the top to display the first prompt.)
  34.             PromptMarginLeft AS INTEGER ' Margin left. The column to begin displaying prompts. Must be within screen width including maximum length of response.
  35.             PromptSpacing AS INTEGER ' The vertical row spacing between prompts. 1 to (n).
  36.             ResponseLength AS INTEGER ' Maximum length of the reply to prompt. Must be within the screen width.
  37.             MyPalette AS INTEGER ' Only use to modify standard screen colors. -1 means this option is turned off.
  38.             ColorTextForeground AS INTEGER ' Foreground text color (0 - 15)
  39.             ColorTextBackground AS INTEGER ' Background text color (0 - 15)
  40.             ColorHighlightForeground AS INTEGER ' Foreground highlight text color (0 - 15)
  41.             ColorHighlightBackground AS INTEGER ' Background highlight text color (0 - 15)
  42.             CursorAppearance AS INTEGER ' Default is 7 for text insert and 30 for text overwrite. Insert key changes mode.
  43.             ' ------------------------------------------------------------------------------------
  44.             PromptLength AS INTEGER ' Automatically determined by library function.
  45.             PromptsDisplayed AS INTEGER ' Automatically determined by library function.
  46.             ResponsemarginLeft AS INTEGER ' Automatically determined by library function.
  47.             ResponseMarginRight AS INTEGER ' Automatically determined by library function.
  48.             yy AS INTEGER
  49.             xx AS INTEGER
  50.             drag AS INTEGER
  51.             dir AS INTEGER
  52.             hl AS INTEGER
  53.             shift AS INTEGER
  54.             ctrl AS INTEGER
  55.             hmrk AS INTEGER
  56.         END TYPE
  57.  
  58.         ConsoleInput.MarginTop = CI_1
  59.         ConsoleInput.PromptMarginLeft = CI_2
  60.         ConsoleInput.PromptSpacing = CI_3
  61.         ConsoleInput.ResponseLength = CI_4
  62.         ConsoleInput_MyPalette = CI_5
  63.         ConsoleInput.ColorTextForeground = CI_6
  64.         ConsoleInput.ColorTextBackground = CI_7
  65.         ConsoleInput.ColorHighlightForeground = CI_8
  66.         ConsoleInput.ColorHighlightBackground = CI_9
  67.         ConsoleInput.CursorAppearance = CI_10
  68.  
  69.         ConsoleInput.PromptsDisplayed = UBOUND(ConsoleInput_Prompt$)
  70.  
  71.         FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed
  72.             IF LEN(ConsoleInput_Prompt$(ConsoleInput_i)) > ConsoleInput.PromptLength THEN ConsoleInput.PromptLength = LEN(ConsoleInput_Prompt$(ConsoleInput_i))
  73.         NEXT
  74.  
  75.         IF ConsoleInput_MyPalette >= 0 THEN
  76.             PALETTE ConsoleInput.ColorTextBackground, ConsoleInput_MyPalette
  77.         END IF
  78.  
  79.         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  80.         CLS
  81.  
  82.         CALL ConsoleInputGetPrompts(ConsoleInput_entryrow(), ConsoleInput_Prompt$())
  83.  
  84.         DIM entry$(ConsoleInput.PromptsDisplayed) 'Text entry array.
  85.         LOCATE , , 1, 7, ConsoleInput.CursorAppearance
  86.  
  87.         UserInputSetup = -1
  88.     END IF
  89.  
  90.     CALL ConsoleInputResponse(ConsoleInput_entryrow(), entry$())
  91.  
  92.  
  93. SUB ConsoleInputGetPrompts (ConsoleInput_entryrow() AS INTEGER, ConsoleInput_prompt$())
  94.     SHARED ConsoleInput AS ConsoleInput
  95.  
  96.     REDIM ConsoleInput_entryrow(ConsoleInput.PromptsDisplayed) AS INTEGER 'Tracks row location of each prompt.
  97.  
  98.     ConsoleInput.ResponsemarginLeft = ConsoleInput.PromptMarginLeft + ConsoleInput.PromptLength
  99.     ConsoleInput.ResponseMarginRight = ConsoleInput.ResponsemarginLeft + ConsoleInput.ResponseLength
  100.     ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  101.     ConsoleInput.yy = ConsoleInput.MarginTop
  102.  
  103.     FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed - 1
  104.         LOCATE ConsoleInput.yy, ConsoleInput.PromptMarginLeft
  105.         PRINT ConsoleInput_prompt$(ConsoleInput_i);
  106.         ConsoleInput_entryrow(ConsoleInput_i) = ConsoleInput.yy
  107.         ConsoleInput.yy = ConsoleInput.yy + ConsoleInput.PromptSpacing
  108.     NEXT
  109.  
  110.     LOCATE ConsoleInput.MarginTop, ConsoleInput.ResponsemarginLeft
  111.     ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  112.     ConsoleInput.yy = ConsoleInput.MarginTop
  113.  
  114. SUB ConsoleInputCopyText (ConsoleInput_xntry$, entry$())
  115.     DIM ConsoleInput_m1 AS INTEGER, ConsoleInput_m2 AS INTEGER
  116.  
  117.     SHARED ConsoleInput AS ConsoleInput
  118.  
  119.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 < ConsoleInput.hmrk THEN
  120.         ConsoleInput_m2 = ConsoleInput.hmrk
  121.         ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  122.     ELSE
  123.         ConsoleInput_m1 = ConsoleInput.hmrk
  124.         ConsoleInput_m2 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  125.     END IF
  126.     ConsoleInput_xntry$ = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m1, ConsoleInput_m2 - ConsoleInput_m1)
  127.  
  128. SUB ConsoleInputReplace (entry$())
  129.     DIM ConsoleInput_j AS INTEGER, ConsoleInput_m1 AS INTEGER, ConsoleInput_m2 AS INTEGER
  130.  
  131.     SHARED ConsoleInput AS ConsoleInput
  132.  
  133.     ConsoleInput_j = LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  134.     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  135.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 < ConsoleInput.hmrk THEN
  136.         ConsoleInput_m2 = ConsoleInput.hmrk
  137.         ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft
  138.     ELSE
  139.         ConsoleInput_m1 = ConsoleInput.hmrk - 1
  140.         ConsoleInput_m2 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  141.     END IF
  142.     entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput_m1) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m2)
  143.     LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  144.     PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  145.     PRINT STRING$(ConsoleInput_j - LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)), 32);
  146.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 > ConsoleInput.hmrk THEN
  147.         ConsoleInput.xx = ConsoleInput.hmrk - 1 + ConsoleInput.ResponsemarginLeft
  148.     END IF
  149.     LOCATE ConsoleInput.yy, ConsoleInput.xx
  150.     ConsoleInput.hmrk = 0
  151.     ConsoleInput.hl = 0
  152.     ConsoleInput.dir = 0
  153.  
  154. SUB ConsoleInputResponse (ConsoleInput_entryrow() AS INTEGER, entry$())
  155.     STATIC ConsoleInput_xntry$
  156.     SHARED ConsoleInput AS ConsoleInput
  157.  
  158.     DIM ConsoleInput_oldyy AS INTEGER
  159.  
  160.     IF ConsoleInput.ctrl THEN ConsoleInput.ctrl = 0
  161.     IF ConsoleInput.shift < 0 THEN ConsoleInput.shift = 0
  162.     DEF SEG = 0
  163.     ConsoleInput_i = PEEK(&H417) MOD 16
  164.     SELECT CASE ConsoleInput_i
  165.         CASE 1, 2
  166.             ConsoleInput.shift = -1
  167.         CASE 4
  168.             ConsoleInput.ctrl = -1
  169.     END SELECT
  170.     DEF SEG
  171.  
  172.     ConsoleInput_oldyy = ConsoleInput.yy
  173.  
  174.     IF ConsoleInput.drag = 0 THEN
  175.         IF ConsoleInput.hl AND ConsoleInput.shift = 0 AND ConsoleInput.hmrk = 0 THEN
  176.             ConsoleInput.hl = 0 ' Disable ConsoleInput.hl so character value isn't printed after a shift / release event without highlighting.
  177.         END IF
  178.     END IF
  179.  
  180.     CALL ConsoleInputMouse(ConsoleInput_entryrow(), entry$(), ConsoleInput_ch$)
  181.  
  182.     IF ConsoleInput.drag = 0 THEN
  183.         IF ConsoleInput_ch$ = "" THEN ConsoleInput_ch$ = INKEY$
  184.         IF ConsoleInput_ch$ <> "" THEN
  185.             IF ConsoleInput.ctrl THEN
  186.                 SELECT CASE LCASE$(ConsoleInput_ch$)
  187.                     CASE CHR$(1) ' Select All
  188.                         LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  189.                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  190.                         PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  191.                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  192.                         ConsoleInput.hmrk = 1
  193.                         ConsoleInput.hl = -1
  194.                         ConsoleInput.dir = LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  195.                         ConsoleInput.xx = ConsoleInput.ResponsemarginLeft + ConsoleInput.dir
  196.                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  197.  
  198.                     CASE CHR$(3) ' Copy
  199.                         IF ConsoleInput.hmrk THEN
  200.                             CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  201.                         END IF
  202.  
  203.                     CASE CHR$(24) ' Cut
  204.                         IF ConsoleInput.hmrk THEN
  205.                             CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  206.                             CALL ConsoleInputReplace(entry$())
  207.                         END IF
  208.  
  209.                     CASE CHR$(22) ' Paste
  210.                         IF ConsoleInput_xntry$ <> "" THEN
  211.                             IF ConsoleInput.hmrk THEN
  212.                                 CALL ConsoleInputReplace(entry$())
  213.                             END IF
  214.                             ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft
  215.                             ConsoleInput_m2 = ConsoleInput_m1 + 1
  216.                             IF LEN(ConsoleInput_xntry$) + LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) - (ConsoleInput_m2 - ConsoleInput_m1) <= ConsoleInput.ResponseLength - 1 THEN
  217.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput_m1) + ConsoleInput_xntry$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m2)
  218.                                 LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  219.                                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  220.                                 PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  221.                                 ConsoleInput.xx = ConsoleInput.xx + LEN(ConsoleInput_xntry$)
  222.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  223.                             ELSE
  224.                                 BEEP ' Contents too large to paste.
  225.                             END IF
  226.                         END IF
  227.                 END SELECT
  228.             ELSE
  229.                 SELECT CASE ConsoleInput_ch$
  230.                     CASE CHR$(8) ' Backspace
  231.                         ConsoleInput_ch$ = CHR$(0)
  232.                         IF ConsoleInput.hmrk > 0 THEN
  233.                             CALL ConsoleInputReplace(entry$())
  234.                         ELSE
  235.                             IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  236.                                 ConsoleInput.xx = ConsoleInput.xx - 1
  237.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  238.                                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2); " ";
  239.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2)
  240.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  241.                             END IF
  242.                         END IF
  243.                     CASE CHR$(0) + "S" ' Delete
  244.                         IF ConsoleInput.shift THEN
  245.                             IF ConsoleInput.hmrk THEN
  246.                                 CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  247.                                 CALL ConsoleInputReplace(entry$())
  248.                             END IF
  249.                         ELSE
  250.                             ConsoleInput_ch$ = CHR$(0)
  251.                             IF ConsoleInput.hmrk > 0 THEN
  252.                                 CALL ConsoleInputReplace(entry$())
  253.                             ELSE
  254.                                 IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) > 0 AND ConsoleInput.xx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  255.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2); " ";
  256.                                     entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2)
  257.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  258.                                 END IF
  259.                             END IF
  260.                         END IF
  261.  
  262.                     CASE CHR$(0) + "H" ' Arrow up
  263.                         ConsoleInput_ch$ = CHR$(0)
  264.                         IF ConsoleInput.yy > ConsoleInput.MarginTop THEN
  265.                             ConsoleInput.yy = ConsoleInput.yy - ConsoleInput.PromptSpacing
  266.                             ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  267.                             LOCATE ConsoleInput.yy, ConsoleInput.xx
  268.                         END IF
  269.  
  270.                     CASE CHR$(0) + "P", CHR$(13) ' Arrow down, Enter
  271.                         ConsoleInput_ch$ = CHR$(0)
  272.                         IF (ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing + 1 < ConsoleInput.PromptsDisplayed THEN
  273.                             ConsoleInput.yy = ConsoleInput.yy + ConsoleInput.PromptSpacing
  274.                             ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  275.                             LOCATE ConsoleInput.yy, ConsoleInput.xx
  276.                         END IF
  277.  
  278.                     CASE CHR$(0) + "K" ' Arrow left
  279.                         ConsoleInput_ch$ = CHR$(0)
  280.                         IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  281.                             IF ConsoleInput.shift THEN
  282.                                 IF ConsoleInput.dir <= 0 THEN
  283.                                     IF ConsoleInput.dir = 0 THEN
  284.                                         ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  285.                                         ConsoleInput.hl = -1
  286.                                     END IF
  287.                                     ConsoleInput.xx = ConsoleInput.xx - 1
  288.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  289.                                     COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  290.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  291.                                     ConsoleInput.dir = ConsoleInput.dir - 1
  292.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  293.                                 ELSE
  294.                                     ConsoleInput.xx = ConsoleInput.xx - 1
  295.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  296.                                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  297.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  298.                                     ConsoleInput.dir = ConsoleInput.dir - 1
  299.                                     IF ConsoleInput.dir = 0 THEN
  300.                                         ConsoleInput.hmrk = 0
  301.                                     END IF
  302.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  303.                                 END IF
  304.  
  305.                             ELSE
  306.                                 ConsoleInput.xx = ConsoleInput.xx - 1
  307.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  308.                             END IF
  309.                         END IF
  310.  
  311.                     CASE CHR$(0) + "M" ' Arrow right
  312.                         ConsoleInput_ch$ = CHR$(0)
  313.                         IF ConsoleInput.xx < ConsoleInput.ResponseMarginRight - 1 AND ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  314.                             IF ConsoleInput.shift THEN
  315.                                 IF ConsoleInput.dir >= 0 THEN
  316.                                     IF ConsoleInput.dir = 0 THEN
  317.                                         ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  318.                                         ConsoleInput.hl = -1
  319.                                     END IF
  320.                                     COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  321.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  322.                                     ConsoleInput.xx = ConsoleInput.xx + 1
  323.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  324.                                     ConsoleInput.dir = ConsoleInput.dir + 1
  325.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  326.                                 ELSE
  327.                                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  328.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  329.                                     ConsoleInput.xx = ConsoleInput.xx + 1
  330.                                     ConsoleInput.dir = ConsoleInput.dir + 1
  331.                                     IF ConsoleInput.dir = 0 THEN
  332.                                         ConsoleInput.hmrk = 0
  333.                                         ConsoleInput.hl = 0
  334.                                     END IF
  335.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  336.                                 END IF
  337.                             ELSE
  338.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  339.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  340.                             END IF
  341.                         END IF
  342.  
  343.                     CASE CHR$(0) + "G" ' Home
  344.                         ConsoleInput_ch$ = CHR$(0)
  345.                         IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  346.                             IF ConsoleInput.shift THEN
  347.                                 WHILE ConsoleInput.xx > ConsoleInput.ResponsemarginLeft
  348.                                     IF ConsoleInput.dir <= 0 THEN
  349.                                         IF ConsoleInput.dir = 0 THEN
  350.                                             ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  351.                                             ' ConsoleInput.hl is already set.
  352.                                         END IF
  353.                                         ConsoleInput.xx = ConsoleInput.xx - 1
  354.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  355.                                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  356.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  357.                                         ConsoleInput.dir = ConsoleInput.dir - 1
  358.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  359.                                     ELSE
  360.                                         ConsoleInput.xx = ConsoleInput.xx - 1
  361.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  362.                                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  363.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  364.                                         ConsoleInput.dir = ConsoleInput.dir - 1
  365.                                         IF ConsoleInput.dir = 0 THEN
  366.                                             ConsoleInput.hmrk = 0
  367.                                             ConsoleInput.hl = 0
  368.                                         END IF
  369.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  370.                                     END IF
  371.                                 WEND
  372.                             ELSE
  373.                                 ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  374.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  375.                             END IF
  376.                         END IF
  377.  
  378.                     CASE CHR$(0) + "O" ' End
  379.                         ConsoleInput_ch$ = CHR$(0)
  380.                         IF ConsoleInput.xx < ConsoleInput.ResponseMarginRight - 1 THEN
  381.                             IF ConsoleInput.shift THEN
  382.                                 WHILE ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  383.                                     IF ConsoleInput.dir >= 0 THEN
  384.                                         IF ConsoleInput.dir = 0 THEN
  385.                                             ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  386.                                             ConsoleInput.hl = -1
  387.                                         END IF
  388.                                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  389.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  390.                                         ConsoleInput.xx = ConsoleInput.xx + 1
  391.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  392.                                         ConsoleInput.dir = ConsoleInput.dir + 1
  393.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  394.                                     ELSE
  395.                                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  396.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  397.                                         ConsoleInput.xx = ConsoleInput.xx + 1
  398.                                         ConsoleInput.dir = ConsoleInput.dir + 1
  399.                                         IF ConsoleInput.dir = 0 THEN
  400.                                             ConsoleInput.hmrk = 0
  401.                                         END IF
  402.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  403.                                     END IF
  404.                                 WEND
  405.                             ELSE
  406.                                 ConsoleInput.xx = ConsoleInput.ResponsemarginLeft + LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  407.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  408.                             END IF
  409.                         END IF
  410.  
  411.                     CASE CHR$(27)
  412.                         ConsoleInput_ch$ = CHR$(0)
  413.                         SYSTEM
  414.  
  415.                     CASE CHR$(0) + CHR$(82) ' ConsoleInput.CursorAppearanceert
  416.                         ConsoleInput_ch$ = CHR$(0)
  417.                         IF ConsoleInput.CursorAppearance = 7 THEN ConsoleInput.CursorAppearance = 30 ELSE ConsoleInput.CursorAppearance = 7
  418.                         LOCATE , , 1, 7, ConsoleInput.CursorAppearance
  419.  
  420.                     CASE CHR$(32) TO CHR$(126)
  421.                         IF ConsoleInput.hmrk > 0 THEN
  422.                             CALL ConsoleInputReplace(entry$())
  423.                         END IF
  424.                         IF ConsoleInput.CursorAppearance = 30 THEN
  425.                             IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < ConsoleInput.ResponseLength - 1 THEN
  426.                                 MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1) = ConsoleInput_ch$
  427.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  428.                                 PRINT ConsoleInput_ch$;
  429.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  430.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  431.                             END IF
  432.                         ELSE
  433.                             IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) < ConsoleInput.ResponseLength - 1 THEN
  434.                                 PRINT ConsoleInput_ch$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1);
  435.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + ConsoleInput_ch$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1)
  436.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  437.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  438.                             END IF
  439.                         END IF
  440.                 END SELECT
  441.             END IF
  442.         END IF
  443.  
  444.         IF ConsoleInput.shift THEN
  445.             IF ConsoleInput.hl = 0 AND ConsoleInput.dir <> 0 THEN
  446.                 ConsoleInput.hl = -1 ' When ConsoleInput.dir <> 0 the first character has been highlighted.
  447.             END IF
  448.         ELSE
  449.             IF ConsoleInput_ch$ <> "" THEN
  450.                 IF ConsoleInput.hl AND ConsoleInput.shift = 0 AND LCASE$(ConsoleInput_ch$) <> "x" AND ConsoleInput.ctrl = 0 AND ConsoleInput_ch$ <> CHR$(8) AND ConsoleInput_ch$ <> CHR$(0) + "S" THEN
  451.                     ' ROutine to remove highlighting from text.
  452.                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  453.                     LOCATE ConsoleInput_oldyy, ConsoleInput.ResponsemarginLeft
  454.                     IF ConsoleInput_ch$ <> CHR$(0) THEN
  455.                         PRINT ConsoleInput_ch$;
  456.                     END IF
  457.                     PRINT entry$((ConsoleInput_oldyy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  458.                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  459.                     ConsoleInput.hmrk = 0
  460.                     ConsoleInput.hl = 0
  461.                     ConsoleInput.dir = 0
  462.                 END IF
  463.             END IF
  464.         END IF
  465.         ConsoleInput_ch$ = ""
  466.     END IF
  467.  
  468. SUB ConsoleInputMouse (ConsoleInput_entryrow() AS INTEGER, entry$(), ConsoleInput_ch$)
  469.     STATIC ConsoleInput_doubleclick AS INTEGER, ConsoleInput_lb AS INTEGER, ConsoleInput_lbdn AS INTEGER, ConsoleInput_z1
  470.     STATIC ConsoleInput_mx AS INTEGER, ConsoleInput_my AS INTEGER, ConsoleInput_oldmx AS INTEGER, ConsoleInput_oldmy AS INTEGER, ConsoleInput_mhl AS INTEGER
  471.  
  472.     SHARED ConsoleInput AS ConsoleInput
  473.  
  474.     IF ConsoleInput_debug THEN
  475.         LOCATE 18, 1
  476.         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  477.         PRINT " oldmx"; ConsoleInput_oldmx; "  oldmy"; ConsoleInput_oldmy; "  mx"; ConsoleInput_mx; "  my"; ConsoleInput_my; "  xx"; ConsoleInput.xx; "  yy"; ConsoleInput.yy; "  lb"; ConsoleInput_lb; "  lbdn"; ConsoleInput_lbdn; "      "
  478.         PRINT " shift"; ConsoleInput.shift; "  drag"; ConsoleInput.drag; "  mhl"; mhl; "  hmrk"; ConsoleInput.hmrk; "  dir"; ConsoleInput.dir; "  dblclk"; ConsoleInput_doubleclick; "        "
  479.         PRINT " mx"; ConsoleInput_mx - ConsoleInput.ResponsemarginLeft + 1; "  my"; (ConsoleInput_my - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing; "  xx"; ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1; "  yy"; (ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing; " hl"; ConsoleInput.hl; "  Response Margin"; ConsoleInput.ResponsemarginLeft; "     ";
  480.         LOCATE ConsoleInput.yy, ConsoleInput.xx
  481.     END IF
  482.  
  483.     ConsoleInput_mx = _MOUSEX
  484.     ConsoleInput_my = _MOUSEY
  485.     ConsoleInput_lb = _MOUSEBUTTON(1)
  486.  
  487.     IF ConsoleInput_lb AND ConsoleInput.hl AND ConsoleInput.shift = 0 AND ConsoleInput.drag = 0 AND ConsoleInput_mhl = 0 THEN ' Allows highlighting caused by mouse click to be removed in parent sub.
  488.         ConsoleInput_ch$ = CHR$(0)
  489.         EXIT SUB
  490.     END IF
  491.  
  492.     IF ConsoleInput.shift AND ConsoleInput_lb AND ConsoleInput.drag = 0 OR ConsoleInput_mhl THEN
  493.         IF ConsoleInput_mhl = 0 THEN ' Shift + click highlighting.
  494.             IF ConsoleInput_my = ConsoleInput.yy AND ConsoleInput_mx <> ConsoleInput.xx AND ConsoleInput_mx >= ConsoleInput.ResponsemarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  495.                 ConsoleInput_mhl = ConsoleInput_mx - ConsoleInput.ResponsemarginLeft + 1
  496.             END IF
  497.         ELSE ' Terminal point reached, end highlighting.
  498.             IF ConsoleInput_mhl = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 THEN ConsoleInput_mhl = 0: ConsoleInput.drag = 0: EXIT SUB
  499.         END IF
  500.     END IF
  501.  
  502.     IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  503.         IF ConsoleInput_lbdn AND ConsoleInput.xx <> ConsoleInput_mx AND ConsoleInput.shift = 0 OR ConsoleInput_mhl THEN ' Combined drag and shift + click highlighting.
  504.             IF ConsoleInput_my = ConsoleInput.yy THEN ' Restrict to active text line.
  505.                 IF ConsoleInput_lb OR ConsoleInput_mhl THEN
  506.                     IF ConsoleInput.xx > ConsoleInput_mx THEN
  507.                         ConsoleInput.drag = -1
  508.                     ELSE
  509.                         ConsoleInput.drag = 1
  510.                     END IF
  511.                     GOSUB mouseConsoleInput.drag
  512.                     EXIT SUB
  513.                 ELSE
  514.                     ConsoleInput.drag = 0
  515.                 END IF
  516.             END IF
  517.         END IF
  518.     END IF
  519.  
  520.     IF ConsoleInput_lb THEN
  521.         IF ConsoleInput_debug THEN COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground: LOCATE 2, 1: PRINT "left button down    "
  522.         IF ConsoleInput_lbdn = 0 THEN ConsoleInput_lbdn = -1
  523.         IF ConsoleInput_my = ConsoleInput.yy THEN
  524.             IF ConsoleInput_mx >= ConsoleInput.ResponsemarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  525.                 IF ConsoleInput.drag = 0 AND ConsoleInput.shift = 0 THEN ConsoleInput.yy = ConsoleInput_my ' Prevents changing rows if a ConsoleInput.drag is in progress.
  526.                 ConsoleInput.xx = ConsoleInput_mx
  527.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  528.                 ConsoleInput_oldmx = ConsoleInput_mx: ConsoleInput_oldmy = ConsoleInput_my
  529.             END IF
  530.         ELSEIF ConsoleInput.shift = 0 THEN
  531.             FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed - 1
  532.                 IF ConsoleInput_my = ConsoleInput_entryrow(ConsoleInput_i) THEN EXIT FOR
  533.             NEXT
  534.  
  535.             IF ConsoleInput_my = ConsoleInput_entryrow(ConsoleInput_i) AND ConsoleInput.drag = 0 THEN
  536.                 IF ConsoleInput_mx >= ConsoleInput.PromptMarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= ConsoleInput.ResponseLength THEN
  537.                     IF ConsoleInput_mx - ConsoleInput.ResponsemarginLeft > 0 AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$(ConsoleInput_i)) THEN
  538.                         ConsoleInput.yy = ConsoleInput_my: ConsoleInput.xx = ConsoleInput_mx
  539.                     ELSE
  540.                         ConsoleInput.yy = ConsoleInput_my: ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  541.                     END IF
  542.                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  543.                 END IF
  544.             END IF
  545.         END IF
  546.     ELSE
  547.         IF ConsoleInput_lbdn THEN
  548.             ConsoleInput_z1 = TIMER
  549.             IF ConsoleInput_debug THEN COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground: LOCATE 2, 1: PRINT "left button released"
  550.             ConsoleInput_doubleclick = ConsoleInput_doubleclick + 1
  551.             ConsoleInput_lbdn = 0
  552.             ConsoleInput.drag = 0
  553.         END IF
  554.     END IF
  555.  
  556.     IF ConsoleInput_doubleclick = 1 THEN
  557.         IF ABS(ConsoleInput_z1 - TIMER) > .33 THEN ConsoleInput_doubleclick = 0
  558.     END IF
  559.  
  560.     IF ConsoleInput_doubleclick = 2 THEN
  561.         ' Any double click events go here...
  562.         IF ConsoleInput_debug THEN LOCATE 2, 1: PRINT "double click         ";
  563.         ConsoleInput_doubleclick = 0
  564.     END IF
  565.     LOCATE ConsoleInput.yy, ConsoleInput.xx
  566.  
  567.     EXIT SUB
  568.  
  569.     mouseConsoleInput.drag:
  570.     SELECT CASE ConsoleInput.drag
  571.         CASE IS < 0
  572.             IF ConsoleInput.dir <= 0 THEN ' highlight to left
  573.                 IF ConsoleInput.dir = 0 THEN
  574.                     ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  575.                     ' Do not emulate shift here.
  576.                     ConsoleInput.hl = -1
  577.                 END IF
  578.                 ConsoleInput.xx = ConsoleInput.xx - 1
  579.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  580.                 COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  581.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  582.                 ConsoleInput.dir = ConsoleInput.dir - 1
  583.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  584.             ELSE ' unhighlight to left
  585.                 ConsoleInput.xx = ConsoleInput.xx - 1
  586.                 ConsoleInput.dir = ConsoleInput.dir - 1
  587.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  588.                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  589.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  590.                 IF ConsoleInput.dir = 0 THEN
  591.                     ConsoleInput.hmrk = 0
  592.                     ConsoleInput.hl = 0
  593.                     ConsoleInput.shift = 0
  594.                 END IF
  595.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  596.             END IF
  597.         CASE IS > 0
  598.             IF ConsoleInput.dir >= 0 THEN
  599.                 COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  600.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  601.                 IF ConsoleInput.dir = 0 THEN
  602.                     ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  603.                     ConsoleInput.hl = -1
  604.                     ' Do not emulate shift here.
  605.                 END IF
  606.                 ConsoleInput.xx = ConsoleInput.xx + 1
  607.                 ConsoleInput.dir = ConsoleInput.dir + 1
  608.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  609.             ELSE
  610.                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  611.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  612.                 ConsoleInput.xx = ConsoleInput.xx + 1
  613.                 ConsoleInput.dir = ConsoleInput.dir + 1
  614.                 IF ConsoleInput.dir = 0 THEN
  615.                     ConsoleInput.hmrk = 0
  616.                     ConsoleInput.hl = 0
  617.                     ConsoleInput.shift = 0
  618.                 END IF
  619.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  620.             END IF
  621.     END SELECT
  622.     RETURN
  623.  

Method 2

Code: QB64: [Select]
  1. main:
  2. ConsoleInput_Data:
  3. ' User Defined Prompts Go Here. Leave the DATA EOF.--------------------------------
  4. DATA "Example Prompt 1: ","Example Prompt 2: ","Example Prompt 3: "
  5. 'PARAMETERS------------------------------------------------------------------
  6. 'Margin top.
  7. 'Margin left.
  8. 'Spacing.
  9. 'Response length.
  10. 'Palette screen color modifier. Set to -1 for none.
  11. 'Foreground text color.
  12. 'Screen color.
  13. 'Highlight text foreground.
  14. 'Highlight text background.
  15. '-----------------------------------------------------------------------------
  16. WHILE (1)
  17.     CALL ConsoleInputLibrary(10, 15, 2, 50, 63, 0, 7, 7, 1, 7)
  18.  
  19. '=============================CONSOLE INPUT LIBRARY===========================
  20.  
  21. SUB ConsoleInputLibrary (CI_1 AS INTEGER, CI_2 AS INTEGER, CI_3 AS INTEGER, CI_4 AS INTEGER, CI_5 AS INTEGER, CI_6 AS INTEGER, CI_7 AS INTEGER, CI_8 AS INTEGER, CI_9 AS INTEGER, CI_10 AS INTEGER)
  22.     STATIC UserInputSetup AS INTEGER
  23.     STATIC ConsoleInput_prompt$(), entry$(), ConsoleInput_entryrow() AS INTEGER
  24.  
  25.     SHARED ConsoleInput AS ConsoleInput
  26.  
  27.     IF UserInputSetup = 0 THEN
  28.         TYPE ConsoleInput
  29.             ' User Defined Variable Types--------------------------------------------------------
  30.             MarginTop AS INTEGER ' Margin top (Number of spaces from the top to display the first prompt.)
  31.             PromptMarginLeft AS INTEGER ' Margin left. The column to begin displaying prompts. Must be within screen width including maximum length of response.
  32.             PromptSpacing AS INTEGER ' The vertical row spacing between prompts. 1 to (n).
  33.             ResponseLength AS INTEGER ' Maximum length of the reply to prompt. Must be within the screen width.
  34.             MyPalette AS INTEGER ' Only use to modify standard screen colors. -1 means this option is turned off.
  35.             ColorTextForeground AS INTEGER ' Foreground text color (0 - 15)
  36.             ColorTextBackground AS INTEGER ' Background text color (0 - 15)
  37.             ColorHighlightForeground AS INTEGER ' Foreground highlight text color (0 - 15)
  38.             ColorHighlightBackground AS INTEGER ' Background highlight text color (0 - 15)
  39.             CursorAppearance AS INTEGER ' Default is 7 for text insert and 30 for text overwrite. Insert key changes mode.
  40.             ' ------------------------------------------------------------------------------------
  41.             PromptLength AS INTEGER ' Automatically determined by library function.
  42.             PromptsDisplayed AS INTEGER ' Automatically determined by library function.
  43.             ResponsemarginLeft AS INTEGER ' Automatically determined by library function.
  44.             ResponseMarginRight AS INTEGER ' Automatically determined by library function.
  45.             yy AS INTEGER
  46.             xx AS INTEGER
  47.             drag AS INTEGER
  48.             dir AS INTEGER
  49.             hl AS INTEGER
  50.             shift AS INTEGER
  51.             ctrl AS INTEGER
  52.             hmrk AS INTEGER
  53.         END TYPE
  54.  
  55.         ConsoleInput.MarginTop = CI_1
  56.         ConsoleInput.PromptMarginLeft = CI_2
  57.         ConsoleInput.PromptSpacing = CI_3
  58.         ConsoleInput.ResponseLength = CI_4
  59.         ConsoleInput_MyPalette = CI_5
  60.         ConsoleInput.ColorTextForeground = CI_6
  61.         ConsoleInput.ColorTextBackground = CI_7
  62.         ConsoleInput.ColorHighlightForeground = CI_8
  63.         ConsoleInput.ColorHighlightBackground = CI_9
  64.         ConsoleInput.CursorAppearance = CI_10
  65.  
  66.         IF ConsoleInput_MyPalette >= 0 THEN
  67.             PALETTE ConsoleInput.ColorTextBackground, ConsoleInput_MyPalette
  68.         END IF
  69.  
  70.         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  71.         CLS
  72.  
  73.         CALL ConsoleInputGetPrompts(ConsoleInput_entryrow(), ConsoleInput_prompt$())
  74.  
  75.         DIM entry$(ConsoleInput.PromptsDisplayed) 'Text entry array.
  76.         LOCATE , , 1, 7, ConsoleInput.CursorAppearance
  77.  
  78.         UserInputSetup = -1
  79.     END IF
  80.  
  81.     CALL ConsoleInputResponse(ConsoleInput_entryrow(), entry$())
  82.  
  83.  
  84. SUB ConsoleInputGetPrompts (ConsoleInput_entryrow() AS INTEGER, ConsoleInput_prompt$())
  85.     SHARED ConsoleInput AS ConsoleInput
  86.  
  87.     ' Get the number of prompts to assign to ConsoleInput_prompt$() array.
  88.     RESTORE ConsoleInput_Data
  89.     ConsoleInput.PromptsDisplayed = 0
  90.     DO
  91.         READ ConsoleInput_Data$
  92.         IF ConsoleInput_Data$ = "EOF" THEN EXIT DO
  93.         IF LEN(ConsoleInput_Data$) > ConsoleInput.PromptLength THEN ConsoleInput.PromptLength = LEN(ConsoleInput_Data$)
  94.         ConsoleInput.PromptsDisplayed = ConsoleInput.PromptsDisplayed + 1
  95.     LOOP
  96.  
  97.     REDIM ConsoleInput_prompt$(ConsoleInput.PromptsDisplayed) 'Prompt array.
  98.     REDIM ConsoleInput_entryrow(ConsoleInput.PromptsDisplayed) AS INTEGER 'Tracks row location of each prompt.
  99.  
  100.     ConsoleInput.ResponsemarginLeft = ConsoleInput.PromptMarginLeft + ConsoleInput.PromptLength
  101.     ConsoleInput.ResponseMarginRight = ConsoleInput.ResponsemarginLeft + ConsoleInput.ResponseLength
  102.  
  103.     RESTORE ConsoleInput_Data
  104.     ConsoleInput_i = 0
  105.     DO
  106.         READ ConsoleInput_Data$
  107.         IF ConsoleInput_Data$ = "EOF" THEN EXIT DO
  108.         ConsoleInput_prompt$(ConsoleInput_i) = ConsoleInput_Data$
  109.         ConsoleInput_i = ConsoleInput_i + 1
  110.     LOOP
  111.  
  112.     ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  113.     ConsoleInput.yy = ConsoleInput.MarginTop
  114.  
  115.     FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed - 1
  116.         LOCATE ConsoleInput.yy, ConsoleInput.PromptMarginLeft
  117.         PRINT ConsoleInput_prompt$(ConsoleInput_i);
  118.         ConsoleInput_entryrow(ConsoleInput_i) = ConsoleInput.yy
  119.         ConsoleInput.yy = ConsoleInput.yy + ConsoleInput.PromptSpacing
  120.     NEXT
  121.  
  122.     LOCATE ConsoleInput.MarginTop, ConsoleInput.ResponsemarginLeft
  123.     ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  124.     ConsoleInput.yy = ConsoleInput.MarginTop
  125.  
  126. SUB ConsoleInputCopyText (ConsoleInput_xntry$, entry$())
  127.     DIM ConsoleInput_m1 AS INTEGER, ConsoleInput_m2 AS INTEGER
  128.  
  129.     SHARED ConsoleInput AS ConsoleInput
  130.  
  131.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 < ConsoleInput.hmrk THEN
  132.         ConsoleInput_m2 = ConsoleInput.hmrk
  133.         ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  134.     ELSE
  135.         ConsoleInput_m1 = ConsoleInput.hmrk
  136.         ConsoleInput_m2 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  137.     END IF
  138.     ConsoleInput_xntry$ = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m1, ConsoleInput_m2 - ConsoleInput_m1)
  139.  
  140. SUB ConsoleInputReplace (entry$())
  141.     DIM ConsoleInput_j AS INTEGER, ConsoleInput_m1 AS INTEGER, ConsoleInput_m2 AS INTEGER
  142.  
  143.     SHARED ConsoleInput AS ConsoleInput
  144.  
  145.     ConsoleInput_j = LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  146.     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  147.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 < ConsoleInput.hmrk THEN
  148.         ConsoleInput_m2 = ConsoleInput.hmrk
  149.         ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft
  150.     ELSE
  151.         ConsoleInput_m1 = ConsoleInput.hmrk - 1
  152.         ConsoleInput_m2 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  153.     END IF
  154.     entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput_m1) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m2)
  155.     LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  156.     PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  157.     PRINT STRING$(ConsoleInput_j - LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)), 32);
  158.     IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 > ConsoleInput.hmrk THEN
  159.         ConsoleInput.xx = ConsoleInput.hmrk - 1 + ConsoleInput.ResponsemarginLeft
  160.     END IF
  161.     LOCATE ConsoleInput.yy, ConsoleInput.xx
  162.     ConsoleInput.hmrk = 0
  163.     ConsoleInput.hl = 0
  164.     ConsoleInput.dir = 0
  165.  
  166. SUB ConsoleInputResponse (ConsoleInput_entryrow() AS INTEGER, entry$())
  167.     STATIC ConsoleInput_xntry$
  168.     SHARED ConsoleInput AS ConsoleInput
  169.  
  170.     DIM ConsoleInput_oldyy AS INTEGER
  171.  
  172.     IF ConsoleInput.ctrl THEN ConsoleInput.ctrl = 0
  173.     IF ConsoleInput.shift < 0 THEN ConsoleInput.shift = 0
  174.     DEF SEG = 0
  175.     ConsoleInput_i = PEEK(&H417) MOD 16
  176.     SELECT CASE ConsoleInput_i
  177.         CASE 1, 2
  178.             ConsoleInput.shift = -1
  179.         CASE 4
  180.             ConsoleInput.ctrl = -1
  181.     END SELECT
  182.     DEF SEG
  183.  
  184.     ConsoleInput_oldyy = ConsoleInput.yy
  185.  
  186.     IF ConsoleInput.drag = 0 THEN
  187.         IF ConsoleInput.hl AND ConsoleInput.shift = 0 AND ConsoleInput.hmrk = 0 THEN
  188.             ConsoleInput.hl = 0 ' Disable ConsoleInput.hl so character value isn't printed after a shift / release event without highlighting.
  189.         END IF
  190.     END IF
  191.  
  192.     CALL ConsoleInputMouse(ConsoleInput_entryrow(), entry$(), ConsoleInput_ch$)
  193.  
  194.     IF ConsoleInput.drag = 0 THEN
  195.         IF ConsoleInput_ch$ = "" THEN ConsoleInput_ch$ = INKEY$
  196.         IF ConsoleInput_ch$ <> "" THEN
  197.             IF ConsoleInput.ctrl THEN
  198.                 SELECT CASE LCASE$(ConsoleInput_ch$)
  199.                     CASE CHR$(1) ' Select All
  200.                         LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  201.                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  202.                         PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  203.                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  204.                         ConsoleInput.hmrk = 1
  205.                         ConsoleInput.hl = -1
  206.                         ConsoleInput.dir = LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  207.                         ConsoleInput.xx = ConsoleInput.ResponsemarginLeft + ConsoleInput.dir
  208.                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  209.  
  210.                     CASE CHR$(3) ' Copy
  211.                         IF ConsoleInput.hmrk THEN
  212.                             CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  213.                         END IF
  214.  
  215.                     CASE CHR$(24) ' Cut
  216.                         IF ConsoleInput.hmrk THEN
  217.                             CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  218.                             CALL ConsoleInputReplace(entry$())
  219.                         END IF
  220.  
  221.                     CASE CHR$(22) ' Paste
  222.                         IF ConsoleInput_xntry$ <> "" THEN
  223.                             IF ConsoleInput.hmrk THEN
  224.                                 CALL ConsoleInputReplace(entry$())
  225.                             END IF
  226.                             ConsoleInput_m1 = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft
  227.                             ConsoleInput_m2 = ConsoleInput_m1 + 1
  228.                             IF LEN(ConsoleInput_xntry$) + LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) - (ConsoleInput_m2 - ConsoleInput_m1) <= ConsoleInput.ResponseLength - 1 THEN
  229.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput_m1) + ConsoleInput_xntry$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput_m2)
  230.                                 LOCATE ConsoleInput.yy, ConsoleInput.ResponsemarginLeft
  231.                                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  232.                                 PRINT entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  233.                                 ConsoleInput.xx = ConsoleInput.xx + LEN(ConsoleInput_xntry$)
  234.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  235.                             ELSE
  236.                                 BEEP ' Contents too large to paste.
  237.                             END IF
  238.                         END IF
  239.                 END SELECT
  240.             ELSE
  241.                 SELECT CASE ConsoleInput_ch$
  242.                     CASE CHR$(8) ' Backspace
  243.                         ConsoleInput_ch$ = CHR$(0)
  244.                         IF ConsoleInput.hmrk > 0 THEN
  245.                             CALL ConsoleInputReplace(entry$())
  246.                         ELSE
  247.                             IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  248.                                 ConsoleInput.xx = ConsoleInput.xx - 1
  249.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  250.                                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2); " ";
  251.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2)
  252.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  253.                             END IF
  254.                         END IF
  255.                     CASE CHR$(0) + "S" ' Delete
  256.                         IF ConsoleInput.shift THEN
  257.                             IF ConsoleInput.hmrk THEN
  258.                                 CALL ConsoleInputCopyText(ConsoleInput_xntry$, entry$())
  259.                                 CALL ConsoleInputReplace(entry$())
  260.                             END IF
  261.                         ELSE
  262.                             ConsoleInput_ch$ = CHR$(0)
  263.                             IF ConsoleInput.hmrk > 0 THEN
  264.                                 CALL ConsoleInputReplace(entry$())
  265.                             ELSE
  266.                                 IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) > 0 AND ConsoleInput.xx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  267.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2); " ";
  268.                                     entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 2)
  269.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  270.                                 END IF
  271.                             END IF
  272.                         END IF
  273.  
  274.                     CASE CHR$(0) + "H" ' Arrow up
  275.                         ConsoleInput_ch$ = CHR$(0)
  276.                         IF ConsoleInput.yy > ConsoleInput.MarginTop THEN
  277.                             ConsoleInput.yy = ConsoleInput.yy - ConsoleInput.PromptSpacing
  278.                             ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  279.                             LOCATE ConsoleInput.yy, ConsoleInput.xx
  280.                         END IF
  281.  
  282.                     CASE CHR$(0) + "P", CHR$(13) ' Arrow down, Enter
  283.                         ConsoleInput_ch$ = CHR$(0)
  284.                         IF (ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing + 1 < ConsoleInput.PromptsDisplayed THEN
  285.                             ConsoleInput.yy = ConsoleInput.yy + ConsoleInput.PromptSpacing
  286.                             ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  287.                             LOCATE ConsoleInput.yy, ConsoleInput.xx
  288.                         END IF
  289.  
  290.                     CASE CHR$(0) + "K" ' Arrow left
  291.                         ConsoleInput_ch$ = CHR$(0)
  292.                         IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  293.                             IF ConsoleInput.shift THEN
  294.                                 IF ConsoleInput.dir <= 0 THEN
  295.                                     IF ConsoleInput.dir = 0 THEN
  296.                                         ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  297.                                         ConsoleInput.hl = -1
  298.                                     END IF
  299.                                     ConsoleInput.xx = ConsoleInput.xx - 1
  300.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  301.                                     COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  302.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  303.                                     ConsoleInput.dir = ConsoleInput.dir - 1
  304.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  305.                                 ELSE
  306.                                     ConsoleInput.xx = ConsoleInput.xx - 1
  307.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  308.                                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  309.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  310.                                     ConsoleInput.dir = ConsoleInput.dir - 1
  311.                                     IF ConsoleInput.dir = 0 THEN
  312.                                         ConsoleInput.hmrk = 0
  313.                                     END IF
  314.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  315.                                 END IF
  316.  
  317.                             ELSE
  318.                                 ConsoleInput.xx = ConsoleInput.xx - 1
  319.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  320.                             END IF
  321.                         END IF
  322.  
  323.                     CASE CHR$(0) + "M" ' Arrow right
  324.                         ConsoleInput_ch$ = CHR$(0)
  325.                         IF ConsoleInput.xx < ConsoleInput.ResponseMarginRight - 1 AND ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  326.                             IF ConsoleInput.shift THEN
  327.                                 IF ConsoleInput.dir >= 0 THEN
  328.                                     IF ConsoleInput.dir = 0 THEN
  329.                                         ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  330.                                         ConsoleInput.hl = -1
  331.                                     END IF
  332.                                     COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  333.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  334.                                     ConsoleInput.xx = ConsoleInput.xx + 1
  335.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  336.                                     ConsoleInput.dir = ConsoleInput.dir + 1
  337.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  338.                                 ELSE
  339.                                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  340.                                     PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  341.                                     ConsoleInput.xx = ConsoleInput.xx + 1
  342.                                     ConsoleInput.dir = ConsoleInput.dir + 1
  343.                                     IF ConsoleInput.dir = 0 THEN
  344.                                         ConsoleInput.hmrk = 0
  345.                                         ConsoleInput.hl = 0
  346.                                     END IF
  347.                                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  348.                                 END IF
  349.                             ELSE
  350.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  351.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  352.                             END IF
  353.                         END IF
  354.  
  355.                     CASE CHR$(0) + "G" ' Home
  356.                         ConsoleInput_ch$ = CHR$(0)
  357.                         IF ConsoleInput.xx > ConsoleInput.ResponsemarginLeft THEN
  358.                             IF ConsoleInput.shift THEN
  359.                                 WHILE ConsoleInput.xx > ConsoleInput.ResponsemarginLeft
  360.                                     IF ConsoleInput.dir <= 0 THEN
  361.                                         IF ConsoleInput.dir = 0 THEN
  362.                                             ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  363.                                             ' ConsoleInput.hl is already set.
  364.                                         END IF
  365.                                         ConsoleInput.xx = ConsoleInput.xx - 1
  366.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  367.                                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  368.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  369.                                         ConsoleInput.dir = ConsoleInput.dir - 1
  370.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  371.                                     ELSE
  372.                                         ConsoleInput.xx = ConsoleInput.xx - 1
  373.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  374.                                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  375.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  376.                                         ConsoleInput.dir = ConsoleInput.dir - 1
  377.                                         IF ConsoleInput.dir = 0 THEN
  378.                                             ConsoleInput.hmrk = 0
  379.                                             ConsoleInput.hl = 0
  380.                                         END IF
  381.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  382.                                     END IF
  383.                                 WEND
  384.                             ELSE
  385.                                 ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  386.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  387.                             END IF
  388.                         END IF
  389.  
  390.                     CASE CHR$(0) + "O" ' End
  391.                         ConsoleInput_ch$ = CHR$(0)
  392.                         IF ConsoleInput.xx < ConsoleInput.ResponseMarginRight - 1 THEN
  393.                             IF ConsoleInput.shift THEN
  394.                                 WHILE ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  395.                                     IF ConsoleInput.dir >= 0 THEN
  396.                                         IF ConsoleInput.dir = 0 THEN
  397.                                             ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  398.                                             ConsoleInput.hl = -1
  399.                                         END IF
  400.                                         COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  401.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  402.                                         ConsoleInput.xx = ConsoleInput.xx + 1
  403.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  404.                                         ConsoleInput.dir = ConsoleInput.dir + 1
  405.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  406.                                     ELSE
  407.                                         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  408.                                         PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1);
  409.                                         ConsoleInput.xx = ConsoleInput.xx + 1
  410.                                         ConsoleInput.dir = ConsoleInput.dir + 1
  411.                                         IF ConsoleInput.dir = 0 THEN
  412.                                             ConsoleInput.hmrk = 0
  413.                                         END IF
  414.                                         LOCATE ConsoleInput.yy, ConsoleInput.xx
  415.                                     END IF
  416.                                 WEND
  417.                             ELSE
  418.                                 ConsoleInput.xx = ConsoleInput.ResponsemarginLeft + LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing))
  419.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  420.                             END IF
  421.                         END IF
  422.  
  423.                     CASE CHR$(27)
  424.                         ConsoleInput_ch$ = CHR$(0)
  425.                         SYSTEM
  426.  
  427.                     CASE CHR$(0) + CHR$(82) ' ConsoleInput.CursorAppearanceert
  428.                         ConsoleInput_ch$ = CHR$(0)
  429.                         IF ConsoleInput.CursorAppearance = 7 THEN ConsoleInput.CursorAppearance = 30 ELSE ConsoleInput.CursorAppearance = 7
  430.                         LOCATE , , 1, 7, ConsoleInput.CursorAppearance
  431.  
  432.                     CASE CHR$(32) TO CHR$(126)
  433.                         IF ConsoleInput.hmrk > 0 THEN
  434.                             CALL ConsoleInputReplace(entry$())
  435.                         END IF
  436.                         IF ConsoleInput.CursorAppearance = 30 THEN
  437.                             IF ConsoleInput.xx - ConsoleInput.ResponsemarginLeft < ConsoleInput.ResponseLength - 1 THEN
  438.                                 MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1) = ConsoleInput_ch$
  439.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  440.                                 PRINT ConsoleInput_ch$;
  441.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  442.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  443.                             END IF
  444.                         ELSE
  445.                             IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) < ConsoleInput.ResponseLength - 1 THEN
  446.                                 PRINT ConsoleInput_ch$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1);
  447.                                 entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing) = MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), 1, ConsoleInput.xx - ConsoleInput.ResponsemarginLeft) + ConsoleInput_ch$ + MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1)
  448.                                 ConsoleInput.xx = ConsoleInput.xx + 1
  449.                                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  450.                             END IF
  451.                         END IF
  452.                 END SELECT
  453.             END IF
  454.         END IF
  455.  
  456.         IF ConsoleInput.shift THEN
  457.             IF ConsoleInput.hl = 0 AND ConsoleInput.dir <> 0 THEN
  458.                 ConsoleInput.hl = -1 ' When ConsoleInput.dir <> 0 the first character has been highlighted.
  459.             END IF
  460.         ELSE
  461.             IF ConsoleInput_ch$ <> "" THEN
  462.                 IF ConsoleInput.hl AND ConsoleInput.shift = 0 AND LCASE$(ConsoleInput_ch$) <> "x" AND ConsoleInput.ctrl = 0 AND ConsoleInput_ch$ <> CHR$(8) AND ConsoleInput_ch$ <> CHR$(0) + "S" THEN
  463.                     ' ROutine to remove highlighting from text.
  464.                     COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  465.                     LOCATE ConsoleInput_oldyy, ConsoleInput.ResponsemarginLeft
  466.                     IF ConsoleInput_ch$ <> CHR$(0) THEN
  467.                         PRINT ConsoleInput_ch$;
  468.                     END IF
  469.                     PRINT entry$((ConsoleInput_oldyy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing);
  470.                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  471.                     ConsoleInput.hmrk = 0
  472.                     ConsoleInput.hl = 0
  473.                     ConsoleInput.dir = 0
  474.                 END IF
  475.             END IF
  476.         END IF
  477.         ConsoleInput_ch$ = ""
  478.     END IF
  479.  
  480. SUB ConsoleInputMouse (ConsoleInput_entryrow() AS INTEGER, entry$(), ConsoleInput_ch$)
  481.     STATIC ConsoleInput_doubleclick AS INTEGER, ConsoleInput_lb AS INTEGER, ConsoleInput_lbdn AS INTEGER, ConsoleInput_z1
  482.     STATIC ConsoleInput_mx AS INTEGER, ConsoleInput_my AS INTEGER, ConsoleInput_oldmx AS INTEGER, ConsoleInput_oldmy AS INTEGER, ConsoleInput_mhl AS INTEGER
  483.  
  484.     SHARED ConsoleInput AS ConsoleInput
  485.  
  486.     IF ConsoleInput_debug THEN
  487.         LOCATE 18, 1
  488.         COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  489.         PRINT " oldmx"; ConsoleInput_oldmx; "  oldmy"; ConsoleInput_oldmy; "  mx"; ConsoleInput_mx; "  my"; ConsoleInput_my; "  xx"; ConsoleInput.xx; "  yy"; ConsoleInput.yy; "  lb"; ConsoleInput_lb; "  lbdn"; ConsoleInput_lbdn; "      "
  490.         PRINT " shift"; ConsoleInput.shift; "  drag"; ConsoleInput.drag; "  mhl"; mhl; "  hmrk"; ConsoleInput.hmrk; "  dir"; ConsoleInput.dir; "  dblclk"; ConsoleInput_doubleclick; "        "
  491.         PRINT " mx"; ConsoleInput_mx - ConsoleInput.ResponsemarginLeft + 1; "  my"; (ConsoleInput_my - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing; "  xx"; ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1; "  yy"; (ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing; " hl"; ConsoleInput.hl; "  Response Margin"; ConsoleInput.ResponsemarginLeft; "     ";
  492.         LOCATE ConsoleInput.yy, ConsoleInput.xx
  493.     END IF
  494.  
  495.     ConsoleInput_mx = _MOUSEX
  496.     ConsoleInput_my = _MOUSEY
  497.     ConsoleInput_lb = _MOUSEBUTTON(1)
  498.  
  499.     IF ConsoleInput_lb AND ConsoleInput.hl AND ConsoleInput.shift = 0 AND ConsoleInput.drag = 0 AND ConsoleInput_mhl = 0 THEN ' Allows highlighting caused by mouse click to be removed in parent sub.
  500.         ConsoleInput_ch$ = CHR$(0)
  501.         EXIT SUB
  502.     END IF
  503.  
  504.     IF ConsoleInput.shift AND ConsoleInput_lb AND ConsoleInput.drag = 0 OR ConsoleInput_mhl THEN
  505.         IF ConsoleInput_mhl = 0 THEN ' Shift + click highlighting.
  506.             IF ConsoleInput_my = ConsoleInput.yy AND ConsoleInput_mx <> ConsoleInput.xx AND ConsoleInput_mx >= ConsoleInput.ResponsemarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  507.                 ConsoleInput_mhl = ConsoleInput_mx - ConsoleInput.ResponsemarginLeft + 1
  508.             END IF
  509.         ELSE ' Terminal point reached, end highlighting.
  510.             IF ConsoleInput_mhl = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1 THEN ConsoleInput_mhl = 0: ConsoleInput.drag = 0: EXIT SUB
  511.         END IF
  512.     END IF
  513.  
  514.     IF LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  515.         IF ConsoleInput_lbdn AND ConsoleInput.xx <> ConsoleInput_mx AND ConsoleInput.shift = 0 OR ConsoleInput_mhl THEN ' Combined drag and shift + click highlighting.
  516.             IF ConsoleInput_my = ConsoleInput.yy THEN ' Restrict to active text line.
  517.                 IF ConsoleInput_lb OR ConsoleInput_mhl THEN
  518.                     IF ConsoleInput.xx > ConsoleInput_mx THEN
  519.                         ConsoleInput.drag = -1
  520.                     ELSE
  521.                         ConsoleInput.drag = 1
  522.                     END IF
  523.                     GOSUB mouseConsoleInput.drag
  524.                     EXIT SUB
  525.                 ELSE
  526.                     ConsoleInput.drag = 0
  527.                 END IF
  528.             END IF
  529.         END IF
  530.     END IF
  531.  
  532.     IF ConsoleInput_lb THEN
  533.         IF ConsoleInput_debug THEN COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground: LOCATE 2, 1: PRINT "left button down    "
  534.         IF ConsoleInput_lbdn = 0 THEN ConsoleInput_lbdn = -1
  535.         IF ConsoleInput_my = ConsoleInput.yy THEN
  536.             IF ConsoleInput_mx >= ConsoleInput.ResponsemarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing)) THEN
  537.                 IF ConsoleInput.drag = 0 AND ConsoleInput.shift = 0 THEN ConsoleInput.yy = ConsoleInput_my ' Prevents changing rows if a ConsoleInput.drag is in progress.
  538.                 ConsoleInput.xx = ConsoleInput_mx
  539.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  540.                 ConsoleInput_oldmx = ConsoleInput_mx: ConsoleInput_oldmy = ConsoleInput_my
  541.             END IF
  542.         ELSEIF ConsoleInput.shift = 0 THEN
  543.             FOR ConsoleInput_i = 0 TO ConsoleInput.PromptsDisplayed - 1
  544.                 IF ConsoleInput_my = ConsoleInput_entryrow(ConsoleInput_i) THEN EXIT FOR
  545.             NEXT
  546.  
  547.             IF ConsoleInput_my = ConsoleInput_entryrow(ConsoleInput_i) AND ConsoleInput.drag = 0 THEN
  548.                 IF ConsoleInput_mx >= ConsoleInput.PromptMarginLeft AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= ConsoleInput.ResponseLength THEN
  549.                     IF ConsoleInput_mx - ConsoleInput.ResponsemarginLeft > 0 AND ConsoleInput_mx - ConsoleInput.ResponsemarginLeft <= LEN(entry$(ConsoleInput_i)) THEN
  550.                         ConsoleInput.yy = ConsoleInput_my: ConsoleInput.xx = ConsoleInput_mx
  551.                     ELSE
  552.                         ConsoleInput.yy = ConsoleInput_my: ConsoleInput.xx = ConsoleInput.ResponsemarginLeft
  553.                     END IF
  554.                     LOCATE ConsoleInput.yy, ConsoleInput.xx
  555.                 END IF
  556.             END IF
  557.         END IF
  558.     ELSE
  559.         IF ConsoleInput_lbdn THEN
  560.             ConsoleInput_z1 = TIMER
  561.             IF ConsoleInput_debug THEN COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground: LOCATE 2, 1: PRINT "left button released"
  562.             ConsoleInput_doubleclick = ConsoleInput_doubleclick + 1
  563.             ConsoleInput_lbdn = 0
  564.             ConsoleInput.drag = 0
  565.         END IF
  566.     END IF
  567.  
  568.     IF ConsoleInput_doubleclick = 1 THEN
  569.         IF ABS(ConsoleInput_z1 - TIMER) > .33 THEN ConsoleInput_doubleclick = 0
  570.     END IF
  571.  
  572.     IF ConsoleInput_doubleclick = 2 THEN
  573.         ' Any double click events go here...
  574.         IF ConsoleInput_debug THEN LOCATE 2, 1: PRINT "double click         ";
  575.         ConsoleInput_doubleclick = 0
  576.     END IF
  577.     LOCATE ConsoleInput.yy, ConsoleInput.xx
  578.  
  579.     EXIT SUB
  580.  
  581.     mouseConsoleInput.drag:
  582.     SELECT CASE ConsoleInput.drag
  583.         CASE IS < 0
  584.             IF ConsoleInput.dir <= 0 THEN ' highlight to left
  585.                 IF ConsoleInput.dir = 0 THEN
  586.                     ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  587.                     ' Do not emulate shift here.
  588.                     ConsoleInput.hl = -1
  589.                 END IF
  590.                 ConsoleInput.xx = ConsoleInput.xx - 1
  591.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  592.                 COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  593.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  594.                 ConsoleInput.dir = ConsoleInput.dir - 1
  595.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  596.             ELSE ' unhighlight to left
  597.                 ConsoleInput.xx = ConsoleInput.xx - 1
  598.                 ConsoleInput.dir = ConsoleInput.dir - 1
  599.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  600.                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  601.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  602.                 IF ConsoleInput.dir = 0 THEN
  603.                     ConsoleInput.hmrk = 0
  604.                     ConsoleInput.hl = 0
  605.                     ConsoleInput.shift = 0
  606.                 END IF
  607.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  608.             END IF
  609.         CASE IS > 0
  610.             IF ConsoleInput.dir >= 0 THEN
  611.                 COLOR ConsoleInput.ColorHighlightForeground, ConsoleInput.ColorHighlightBackground
  612.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  613.                 IF ConsoleInput.dir = 0 THEN
  614.                     ConsoleInput.hmrk = ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1
  615.                     ConsoleInput.hl = -1
  616.                     ' Do not emulate shift here.
  617.                 END IF
  618.                 ConsoleInput.xx = ConsoleInput.xx + 1
  619.                 ConsoleInput.dir = ConsoleInput.dir + 1
  620.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  621.             ELSE
  622.                 COLOR ConsoleInput.ColorTextForeground, ConsoleInput.ColorTextBackground
  623.                 PRINT MID$(entry$((ConsoleInput.yy - ConsoleInput.MarginTop) \ ConsoleInput.PromptSpacing), ConsoleInput.xx - ConsoleInput.ResponsemarginLeft + 1, 1)
  624.                 ConsoleInput.xx = ConsoleInput.xx + 1
  625.                 ConsoleInput.dir = ConsoleInput.dir + 1
  626.                 IF ConsoleInput.dir = 0 THEN
  627.                     ConsoleInput.hmrk = 0
  628.                     ConsoleInput.hl = 0
  629.                     ConsoleInput.shift = 0
  630.                 END IF
  631.                 LOCATE ConsoleInput.yy, ConsoleInput.xx
  632.             END IF
  633.     END SELECT
  634.     RETURN
  635.  

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/