Results 1 to 40 of 83

Thread: How much do you trust the Collection class?

Threaded View

  1. #11
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    10,918

    Re: How much do you trust the Collection class?

    Alright, I'm just going to post my particular progress in figuring this out.

    Here's how I modified the code, just to consolidate it and also add my own debug functions:

    Code:
    
    Option Explicit
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)
    Private Declare Function OpenClipboard Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function EmptyClipboard Lib "user32.dll" () As Long
    Private Declare Function CloseClipboard Lib "user32.dll" () As Long
    Private Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
    Private Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
    Private Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
    Private Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyW" (ByVal lpString1 As Long, ByVal lpString2 As Long) As Long
    Private Declare Function SetClipboardData Lib "user32.dll" (ByVal wFormat As Long, ByVal hMem As Long) As Long
    '
    
    Private Sub Form_Load()
        Dim i As Long, j As Long
        Dim sKey As String
        Dim asKeys() As String
        Dim oColl As Collection
    
    
    
        Randomize 14
    
    
        ReDim asKeys(0 To 4837) As String
        Set oColl = New Collection
    
        'Generating ITEMS keys. 
        For i = 0 To 4837
            For j = 1 To 6
                asKeys(i) = asKeys(i) & ChrW(Int(Rnd() * 65535))
            Next j
        Next i
    
        'Adding ITEMS key into collection. 
        For i = 0 To 4836 ' <----------------------- it will crash on 4837. 
            oColl.Add i, asKeys(i)
        Next i
    
        '   NOW DELETE KEYS UNTIL THE ERROR GOES AWAY <--------- FINDING THE DUPLICATE!!!!!!!!!!! 
        On Error Resume Next
        Do
            oColl.Add 4837, asKeys(4837)
            If Err = 0 Then
                Debug.Print HexKey(asKeys(4837))
                Debug.Print HexKey(sKey)
                Debug.Print "The StrComp: " & StrComp(asKeys(4837), sKey, vbTextCompare)
                Stop
            End If
            sKey = CollectionItemKey(1, oColl)
            oColl.Remove 1
            Err.Clear
        Loop
    
        MsgBox "Done"
    End Sub
    
    Function HexKey(sKey As String) As String
        Dim j As Long
        For j = 1 To 6
            HexKey = HexKey & Right("000" & Hex$(AscW(Mid$(sKey, j, 1))), 4) & " "
        Next j
    End Function
    
    
    Public Function CollectionItemKey(idx As Long, Coll As Collection) As String
        ' Original by LaVolpe. 
        Dim i     As Long
        Dim ptr   As Long
        Dim sKey  As String
        '
        If Coll Is Nothing Then
            Err.Raise 91
            Exit Function
        End If
        '
        If idx < 1 Or idx > Coll.Count Then
            Err.Raise 9
            Exit Function
        End If
        '
        If idx <= Coll.Count / 2 Then                       ' Go from beginning or end. 
            CopyMemory ptr, ByVal ObjPtr(Coll) + &H18, 4    ' VbCollection.First 
            For i = 2 To idx
                CopyMemory ptr, ByVal ptr + &H18, 4         ' VbCollectionItem.Next 
            Next i
        Else                                                ' End is quicker. 
            CopyMemory ptr, ByVal ObjPtr(Coll) + &H1C, 4    ' VbCollection.Last 
            For i = Coll.Count - 1 To idx Step -1
                CopyMemory ptr, ByVal ptr + &H14, 4         ' VbCollectionItem.Prev 
            Next i
        End If
        '
        i = StrPtr(sKey)
        CopyMemory ByVal VarPtr(sKey), ByVal ptr + 16, 4
        CollectionItemKey = sKey
        CopyMemory ByVal VarPtr(sKey), i, 4
    End Function
    
    Public Property Let UniClipboard(sUniText As String)
        ' Puts a VB string in the clipboard without converting it to ASCII. 
        Dim iStrPtr As Long
        Dim iLen As Long
        Dim iLock As Long
        Const GMEM_MOVEABLE As Long = &H2
        Const GMEM_ZEROINIT As Long = &H40
        Const CF_UNICODETEXT As Long = &HD
        '
        OpenClipboard 0&
        EmptyClipboard
        iLen = LenB(sUniText) + 2&
        iStrPtr = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT, iLen)
        iLock = GlobalLock(iStrPtr)
        lstrcpy iLock, StrPtr(sUniText)
        GlobalUnlock iStrPtr
        SetClipboardData CF_UNICODETEXT, iStrPtr
        CloseClipboard
    End Property
    
    The code does stop and reports the following in my Immediate window:

    Code:
    1056 1060 0BFD 15F1 31B1 A19E 
    D9A2 2770 4DE5 1AF0 A28B 2F86 
    The StrComp: 0
    Just FYI, a StrComp=0 indicates it sees the two strings as equal.

    The first thing I noticed was that D9A2 is outside of the valid Unicode range, and it's also the first character of the key. Therefore, while still in "Stop" mode, I tried this in the Immediate window:

    Code:
    ? strcomp(asKeys(4837), left$(sKey, 1), vbTextCompare)
    Voila, it still reported equality between the strings. Notice that this was the value I deleted (and not the one I was trying to add).

    Now, I did more checking and found that the D9A2 2770 4DE5 1AF0 A28B 2F86 key was created in the key creation loop at i=3730.

    It's still a puzzle to me why adding this specific key didn't cause a problem, and that it waited until adding where i=4837 caused the problem.

    I must admit that it's still quite curious. The first thing I'm going to do is restrict the Unicode values to values between &h0020 and &hD7FF (the valid Unicode range).
    Last edited by Elroy; Aug 25th, 2016 at 10:39 PM.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width