Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Experimenting with a "StringList" type for simpler handling of string arrays/lists
#7
@Dimster

Yes, I think (in theory because I haven't tried this) either would work, but both get cumbersome in apps that reuire many variables.

Here is an example of using 2-dim arrays to track single-dim arrays over two screens. Each screen contains 5 numbers you can drag with the mouse. Flip to the other tab screen by pressing F1 for tab #1, or F2 for tab #2.

Notice that you can arrange the numbers on the screen like 1 to 5, flip tot he other screen and arrange those from 5 to 1, and when you flip back and forth these arrangements will be remembered and properly displayed, all using the same routine by just repopulating the variables from the memory subroutine.

Code: (Select All)
Type MouseVar
    x As Integer
    y As Integer
    lb As Integer
    rb As Integer
    mb As Integer
    mw As Integer
    clkcnt As Integer
    caps As Integer
    shift As Integer
    ctrl As Integer
    alt As Integer
    prevx As Integer
    prevy As Integer
    drag As Integer
    sbar As Integer
    sbRow As Integer
    oldsbRow As Integer
    ThumbTop As Integer
    ThumbSize As Integer
    ThumbDrag As Integer
    autokey As String
End Type
Dim m As MouseVar

Type ControlVars
    notbs As Integer ' Number of tabs.
    noc As Integer ' Number of characters
    oldtabx As Integer
    tabx As Integer
End Type
Dim c As ControlVars

c.tabx = 1: c.notbs = 2: c.noc = 5
ReDim tracker(c.notbs)
t$ = "Tab #1": _Title t$
Do
    If c.tabx <> c.oldtabx Then ' Print the tab number in the title bar
        If c.tabx = 1 Then t$ = "Tab #1" Else t$ = "Tab #2"
        _Title t$
    End If
    If tracker(c.tabx) = 0 Then ' Populate characters to screen when a tab is opened for the first time.
        Cls
        ReDim y(c.noc), x(c.noc)
        For i = 1 To c.noc
            i$ = LTrim$(Str$(i))
            Do
                y(i) = Int(Rnd * _Height) + 1: x(i) = Int(Rnd * _Width) + 1
                For j = 1 To i - 1
                    If y(j) = y(i) And x(j) = x(i) Then flag = 1: Exit For
                Next
                If flag = 0 Then Exit Do Else flag = 0
            Loop
            Locate y(i), x(i): Print i$;
        Next
        tracker(c.tabx) = 1
    Else ' Show the characters on tab screen, which are now in array memory.
        Cls
        For i = 1 To c.noc
            i$ = LTrim$(Str$(i))
            Locate y(i), x(i): Print i$;
        Next
    End If
    Do
        _Limit 60
        Mouse_Keyboard m, b$
        Select Case b$
            Case Chr$(0) + Chr$(59) ' F1 Switch to tab #1
                c.tabx = 1
            Case Chr$(0) + Chr$(60) ' F2 Switch to tab #2
                c.tabx = 2
            Case Chr$(27)
                System
        End Select
        Select Case m.lb
            Case -1 ' Left mouse button clicked.
                For i = 1 To c.noc
                    If m.y = y(i) And m.x = x(i) Then k = i: Exit For
                Next
            Case 2: If k Then k = 0 ' Left mouse button released.
        End Select
        If m.drag And k <> 0 Then
            For i = 1 To c.noc
                If i <> k Then
                    If m.y = y(i) And m.x = x(i) Then flag = 1: Sound 500, .1: Exit For ' Do not allow numbers to overlap on drag.
                End If
            Next
            If flag = 0 Then ' Move character.
                Locate y(k), x(k): Print " ";
                Locate m.y, m.x: Print LTrim$(Str$(k));
                y(k) = m.y: x(k) = m.x
            Else
                flag = 0
            End If
        End If
        If c.oldtabx And c.oldtabx <> c.tabx Then ' Switch tabs (F1 or F2 key was pressed).
            My_PITA_Routine c, y(), x()
            c.oldtabx = 0
            Exit Do
        End If
        c.oldtabx = c.tabx
    Loop
Loop

Sub My_PITA_Routine (c As ControlVars, y(), x()) ' Memory subroutine.
    Static memy(2, 5), memx(2, 5)
    For i = 1 To c.noc
        memy(c.oldtabx, i) = y(i)
        memx(c.oldtabx, i) = x(i)
    Next
    For i = 1 To c.noc
        y(i) = memy(c.tabx, i)
        x(i) = memx(c.tabx, i)
    Next
End Sub

Sub Mouse_Keyboard (m As MouseVar, b$)
    Static z1
    If Len(m.autokey) Then
        b$ = Mid$(m.autokey + ",", 1, InStr(m.autokey$ + ",", ",") - 1)
        m.autokey = Mid$(m.autokey, InStr(m.autokey$ + ",", ",") + 1) ' Don't add "," tomid$() portion or the last key will always be a comma.
    Else
        b$ = InKey$
    End If
    m.prevx = m.x: m.prevy = m.y
    If m.mw Then m.mw = 0
    While _MouseInput
        m.mw = m.mw + _MouseWheel: If m.mw Then m.mw = m.mw \ Abs(m.mw) ' Limit to 1 or -1 for up or down.
    Wend
    m.x = _MouseX
    m.y = _MouseY
    If z1 Then If Abs(Timer - z1) > .25 Then z1 = 0: m.clkcnt = 0
    Select Case m.lb
        Case 2: m.lb = 0 ' Click cycle completed.
        Case 1: If _MouseButton(1) = 0 Then m.lb = 2: m.drag = 0: m.ThumbDrag = 0 ' Button released.
        Case -1: m.lb = 1 ' Button held down.
        Case 0: m.lb = _MouseButton(1)
    End Select
    Select Case m.rb
        Case 2: m.rb = 0 ' Click cycle completed.
        Case 1: If _MouseButton(2) = 0 Then m.rb = 2 ' Button released.
        Case -1: m.rb = 1 ' Button held down.
        Case 0: m.rb = _MouseButton(2)
    End Select
    Select Case m.mb
        Case 2: m.mb = 0 ' Click cycle completed.
        Case 1: If _MouseButton(3) = 0 Then m.mb = 2 ' Button released.
        Case -1: m.mb = 1 ' Button held down.
        Case 0: m.mb = _MouseButton(3)
    End Select
    If Abs(m.lb) = 1 Then
        If m.lb = -1 Then z1 = Timer: m.clkcnt = m.clkcnt + 1
        If m.prevx And m.prevx <> m.x Or m.prevy And m.prevy <> m.y Then
            If m.x <> m.prevx Then m.drag = Sgn(m.x - m.prevx) ' Prevent zero which can occur if mouse moves off row when being draged horizontally.
        End If
    End If
    If _KeyDown(100301) Then m.caps = -1 Else If m.caps Then m.caps = 0
    If _KeyDown(100303) Or _KeyDown(100304) Then m.shift = -1 Else If m.shift Then m.shift = 0
    If _KeyDown(100305) Or _KeyDown(100306) Then m.ctrl = -1 Else If m.ctrl Then m.ctrl = 0
    If _KeyDown(100307) Or _KeyDown(100308) Then m.alt = -1 Else If m.alt Then m.alt = 0
End Sub

Now a gripe of mine is this:

Because it uses STATIC in the memory sub, we can't do anything to modify the array. Hell, we can't even use variables in the ( ) or a c++ compilation error will occur. That because STATIC means static! The other option, for greater flexibility, would be to dim the two-dim memory arrays in the main as global or shared. That's a bitch, because we will only be using them in one sub. Now other than using _Mem, yes, I might be missing some other angle, as I hardly ever work with multi-dim arrays.

EDIT:

Okay, just for fun. How to change the size of a two-dim array without using the dysfunctional _Preserve statement...

Code: (Select All)
ind1 = 1: noa = 5
ReDim array$(ind1, noa)
For i = 1 To 5
    array$(ind1, i) = "Pete-" + LTrim$(Str$(i))
Next
GoSub display
Do
    Print "Press 1 to add to an array or 2 to delete from an array: ";
    Do
        _Limit 30
        b$ = InKey$
        If Len(b$) Then
            If b$ = "1" Then AddDelete = 1: Print b$
            If b$ = "2" Then AddDelete = -1: Print b$
            If b$ = Chr$(27) Then End
        End If
        If AddDelete Then
            If AddDelete = 1 Then Line Input "Name of array element: "; MyInput$
            If AddDelete = -1 Then
                Line Input "Press 0 to delete last added array or pick a number: "; MyInput$
                If Val(MyInput$) Then ArrayNumber = Val(MyInput$): AddDelete = -2
            End If
            GoSub Add_Delete
            GoSub display
            Exit Do
        End If
    Loop
    AddDelete = 0: Print
Loop

Add_Delete:
Select Case AddDelete
    Case 1 ' Add.
        noa = noa + 1: x$ = ""
        ReDim temp$(ind1, noa)
        For i = 1 To noa - 1
            temp$(ind1, i) = array$(ind1, i)
        Next
        ReDim array$(ind1, noa)
        For i = 1 To noa
            hold$ = temp$(ind1, i)
            array$(ind1, i) = x$
            x$ = hold$
        Next
        x$ = "": array$(ind1, 1) = MyInput$: Erase temp$
    Case -1 ' Delete.
        If noa > 0 Then
            ReDim temp$(ind1, noa - 1)
            For i = 1 To noa
                temp$(ind1, i - 1) = array$(ind1, i)
            Next
            noa = noa - 1
            ReDim array$(ind1, noa)
            For i = 1 To noa
                array$(ind1, i) = temp$(ind1, i)
            Next
            Erase temp$
        End If
    Case -2 ' Delete numbered array.
        noa = noa - 1
        ReDim temp$(ind1, noa)
        For i = 1 To noa
            If i >= ArrayNumber Then temp$(ind1, i) = array$(ind1, i + 1) Else temp$(ind1, i) = array$(ind1, i)
        Next
        ReDim array$(ind1, noa)
        For i = 1 To noa
            array$(ind1, i) = temp$(ind1, i)
        Next
        Erase temp$
End Select
Return

display:
Cls
For i = 1 To noa
    Print i; array$(ind1, i)
Next
Return

Other algorithms would need to be added to add and subtract to the end, or add to the middle, but this lesser demo should be good enough to show how it's basically achievable. I could also show you guys single-dim arrays, using preserve, and you'd see what a nice little code saver it is.

Pete
Reply


Messages In This Thread
RE: Experimenting with a "StringList" type for simpler handling of string arrays/lists - by Pete - 12-16-2025, 07:33 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Sub not Reconizing Dim as String pmackay 18 1,476 10-16-2025, 03:32 PM
Last Post: pmackay
  for performance, what's the best variable type to use for boolean _TRUE & _FALSE ? madscijr 12 1,257 09-29-2025, 02:59 PM
Last Post: dakra137
  Using modulo to loop through lists fistfullofnails 3 723 09-03-2025, 11:50 PM
Last Post: fistfullofnails
  Loading from file into _MEM? and LEN a TYPE... Unseen Machine 9 976 08-03-2025, 02:55 AM
Last Post: SMcNeill
  Illegal string-number conversion Herve 7 774 07-07-2025, 09:53 AM
Last Post: a740g

Forum Jump:


Users browsing this thread: 1 Guest(s)