Toon posts:

[vb6] Probleem met strings overschrijven

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik gebruik een door een derde gemaakte class om dragdrop-events vanuit windows explorer op te vangen. Zo wordt het dus mogelijk dat een gebruiker een aantal bestanden selecteert vanuit explorer en die vervolgens in een listbox dropt op mijn form. Door middel van de FileName variabele (een array) kun je achterhalen welke bestanden zijn gedropt:
Visual Basic:
1
HetEersteBestand = iclass.FileName(0)

Welnu, het gekke is dat elke string in die array exact uit 256 karakters bestaat. Als de bestandsnaam korter is dan 256, dan bestaat de rest van de string uit spaties:
Visual Basic:
1
a = Len(iclass.FileName(0)) 'a = 256

Door middel van de functie TrimComplete die ik elders op het web vond, kan ik eenvoudig alle non-printing characters verwijderen. Nadat ik die functie heb toegepast, geeft Len wél de verwachte lengte weer.

Eind goed al goed zou je zeggen, maar in een loop gaat het mis. Dit gebeurt er met de volgende code:
Visual Basic:
1
2
3
4
5
strSource(0) = TrimComplete(iclass.FileName(0))      'is "pepsi-pepsi-pepsi-pepsi-pepsi"
strSource(1) = TrimComplete(iclass.FileName(1))      'is "cola-cola"

strTest = iclass.FileName(0) 'strTest is "pepsi-pepsi-pepsi-pepsi-pepsi"
strTest = iclass.FileName(1) 'strTest is ineens "cola-cola i-pepsi-pepsi-pepsi"

Op een of andere manier blijft er een restje van de vorige string over! Heeft iemand enig idee waar dit aan kan liggen? Ik heb me echt rotgezocht op het web, maar ik kan geen oplossing vinden. Zelf heb ik het vermoeden dat dit te maken heeft met het ontbreken van een Null Characte of zo (dus dat die class dat niet goed afhandelt. Maar ook iets als
Visual Basic:
1
strTest = iclass.Filename(0) & vbNullString
brengt geen verbetering.

In een loop is het toevoegen van een groot aantal bestanden aan bijvoorbeeld een sql-database dus een ramp. Alleen strings met een bestandsnaam die langer is dan die van een vorige string [dus len(bestand(i)) < len(bestand(i+1))] gaan goed, maar daar heb ik natuurlijk niets aan...

Ik kan me voorstellen dat de bug in de volgende code zit, omdat daar iets gebeurt met vbNullString en het getal 256 naar voren komt en er zelfs trimming plaatsvindt, maar ik kan er niets geks aan ontdekken:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Public Function WndProc(ByVal Hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    'Dim obj As New CDrag_Drop
    
    Dim n As Long, iLoop As Long, FileInfo As Long
    Dim Buffer As String * 256, tmp As String
    Dim length As Long
    If msg = WM_DROPFILES Then
        obj.ClearFileNames
        FileInfo = wParam
        n = DragQueryFile(FileInfo, -1&, vbNullString, 0)
        For iLoop = 0 To n - 1
            length = DragQueryFile(FileInfo, iLoop, ByVal Buffer, 256)
            Buffer = Trim(Buffer)
            obj.AddInFileNames Buffer
        Next
        
        obj.NowRaiseEvent
        
        DragFinish FileInfo 'wParam
        WndProc = 0
    Else
        WndProc = CallWindowProc(PrevWndFunc, Hwnd, msg, wParam, lParam)
    End If


Iemand enig idee...? :)

Voor de volledigheid:
- De code van TrimComplete: http://www.freevbcode.com/ShowCode.Asp?ID=104
- De code van de dragdrop-class moet hier staan: http://go.to/abubakar

Verwijderd

Je probleem zit hem in je declaratie. Als je een string met een expliciete lengte declareerd ( hier dus String * 256 ), dan zal die string TEN ALLEN TIJDE 256 karakters groot zijn.

[edit]
Ik zie dat je hier met API functies aan het werken bent. Deze geven meestal C-stijl string terug ( null-terminated dus ), vandaar dat de buffer een vaste lengte heeft. Je zult het null karakter ( chr$(0) ) moeten opzoeken, en alles DAARVOOR moeten kopieren Dan heb je je uiteindelijke resultaat.

[ Voor 46% gewijzigd door Verwijderd op 09-11-2005 00:44 ]


  • TallManNL
  • Registratie: Oktober 2005
  • Laatst online: 21-04 14:52
Wat je ook kan doen is in je WndProc voor regel 13 (je API call) je buffer vullen met chr(0) d.m.v.

Visual Basic:
1
  Buffer = String(256, Chr(0))


Dan wordt je buffer gecleared want die API zal je buffer waarschijnlijk niet verder aanvullen dus blijft je restant uit de vorige call over in je buffer.

geheelonthouder met geheugenverlies


Verwijderd

kun je niet gewoon hetvolgende doen:
obj.AddInFileNames left(Buffer,lenght)