Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von ts-soft »

SebastianJu2 hat geschrieben:

Code: Alles auswählen

Procedure.s test(*string.String)
  Debug PeekS(*string)
  ProcedureReturn "Proc fertig"
EndProcedure

string2.s = "Hallo"
Debug test(@string2)
Allerdings wollte ich eigentlich Debug *string\s benutzen. Funktioniert aber nicht.
So, so, funktioniert also nicht.

Code: Alles auswählen

rocedure.s test(*string.String)
  *string\s = "Hallo Welt"
EndProcedure

string2.string
string2\s = "Hallo"

test(@string2) 
Debug string2\s
:mrgreen:
Wenn Du gleich einen Pointer verwendest, wurde kein Platz für den String geschaffen und
der Stringmanager weiß nichts davon, das an dieser Adresse ein String ist und verwaltet
den auch nicht. Allocatememory wäre ein Möglichkeit, wobei dann aber die Grösse weiterhin
von Dir verwaltet werden müßte, wäre wahrscheinlich mehr Code und langsamer.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von SebastianJu2 »

Gleiche Struktur... ja... :)

Übrigens ist GetGadgetItemText() keine Alternative für das was ich vorhab. Ich habe das Ganze mal testweise so umgesetzt:

Code: Alles auswählen

       Define s.s, start.i
       x = 0
       start=ElapsedMilliseconds()
       Repeat
         
         s = GetGadgetItemText(*InputEditorHandle,x)
         AddGadgetItem(*InputListIconHandle, 0, s)
         x + 1
       Until Not s
       MessageRequester("",Str(ElapsedMilliseconds()-start))
Ohne Debugger und mit einer Liste aus 20.000 URLs brauchte es 21 Sekunden um die Zeilen von einem Editorgadget ins andere zu schieben.
Wenn ich die neuen Zeilen am unteren Ende des Editors anfügte brauchte es für 20.000 URLs sogar 300Sekunden/5min. Aber das muss ja nicht sein.

Mit der Pointerversion sind es mit 200.000 URLs, also 10 mal so viel, zwischen 1,5 und 2 Sekunden.

Scheint als wenn die Benutzung von Pointern in dem Fall alternativlos ist.
Ich müsste auch noch mal schauen wie sich sqlite in so einem Fall schlagen würde.

ABER... ein Problem vor dem du gewarnt hast ist aufgetreten... es versteht kein kyrillisch... :)
Ich muss mal suchen wie man das lösen kann. Wenn mehrere Codierungen gleichzeitig im ersten Editorfenster vorhanden sind wirds wahrscheinlich richtig spaßig...
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von edel »

Dass das ganze sehr langsam ist, liegt nicht an Purebasic, sondern an den Windows Controls. Bei dem ListIconGadget gibt es eine Moeglichkeit die Daten, mit Hilfe der Windows Api, anders einzufuegen, das ist ein sehr schneller Weg und sollte bei sehr vielen Daten benutzt werden.

Code: Alles auswählen

#Count = 1000000
#lig = 0

GLOBAL DIM MeineDaten.s(#Count -1)

PROCEDURE FillData()
  
  FOR i = 0 TO #Count-1
    MeineDaten(i) = "Zeile :" + Str(i)
  NEXT
  
ENDPROCEDURE

PROCEDURE WinCallback(hWnd, msg, wparam, lparam)
  PROTECTED *notifyh.NMHDR
  PROTECTED *notiitem.NMLVDISPINFO
  
  
  IF msg = #WM_NOTIFY
    
    *notifyh = lparam
    
    IF *notifyh\code = #LVN_GETDISPINFO AND *notifyh\idFrom = #lig
      
      *notiitem = lparam
      
      *notiitem\item\pszText = @MeineDaten(*notiitem\item\iItem)
      
    ENDIF
    
  ENDIF
  
  PROCEDURERETURN #PB_ProcessPureBasicEvents
ENDPROCEDURE


PROCEDURE Main()
  
  FillData()
  
  win = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 400, 400, "Test")
  
  IF win
    
    SetWindowCallback(@WinCallback(), win)
    
    ListIconGadget(#lig, 5, 5, 390, 390, "Zeile", 375, #LVS_OWNERDATA)
    
    SendMessage_(GadgetID(#lig), #LVM_SETITEMCOUNT, #Count, 0)
    
    REPEAT
      
    UNTIL WaitWindowEvent() = #PB_Event_CloseWindow
    
  ENDIF
  
ENDPROCEDURE:Main()


END
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von SebastianJu2 »

Wow... sehr schnell... ich habe es mal mit der 200.000 URL-Datei versucht die ich erst eingelesen habe in das Array und dann ausgeben ließ in das ListIconGadget. Sehr fix... Das dürfte auch noch für weit größere Listen reichen. Wie findet man solche Möglichkeiten eigentlich?

Die Standard-Stringfunktionen von PB verstehen auch kein kyrillisch. Einlesen, schreiben und es ist Müll. Es gibt wohl nur die Möglichkeit mit PeekS und PokeS zu arbeiten wenn man UTF-8 verarbeitet. Aber dann muss man wiederum vorher wissen ob es UTF8 ist weil man wohl nicht wirklich herausfinden kann was es ist wenn man nur den String hat.
Man kann es vermutlich nur erkennen wenn die Daten aus einer Datei ausgelesen werden und man den BOM ausliest. Oder man läßt es sich von demjenigen sagen der die Daten einfügt.
Sortierungen werden dann auch nicht mit den Standardfunktionen klappen da die wohl kein UTF8 unterscheiden. Bleibt dann wohl nur eine eigene Routine unter Nutzung von CompareMemoryString wenn man sortieren will.
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von DarkDragon »

Hallo,

Das naheliegendste wurde glaube ich vergessen, nämlich die Beobachtungsliste/Watchlist. Die ist ja exakt das was er aus seiner VBA geschichte kennt:
Ich kenne das von VBA, da gab es ein Fenster in dem man Variablen oder Ausdrücke definieren konnte und während der Code unterbrochen war für die Fehlersuche konnte man immer genau sehen welche Werte die Variablen gerade enthielten.
Außerdem sollte man das hier nicht vergessen zu erwähnen:
Bei "Examining variables during runtime" in der Hilfedatei unter "Benutzen des Debuggers" sieht man dass man lediglich über die Variablen mit dem Mauszeiger fahren muss, schon sieht man den Inhalt.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von SebastianJu2 »

@DarkDragon

Die Beobachtungsliste hatte ich dann auch schnell gefunden. Aber leider sind diese ganzen Tools nicht so weit entwickelt worden wie ich das von VBA kenne. Von negativsten zum weniger negativen ist das:
  • * Die Variablen in der Beobachtungsliste sind nur einmal pro Programmaufruf da. Bei einem neuen Aufruf muss man alles wieder neu eintragen.
    * (Bei diesem Punkt weiß ich nicht ob es vielleicht bei VBA auch so ist weil ich da nie mit Pointern gearbeitet habe.) Man kann nicht alle Variablen überwachen. ZB *c.Character. Man kann hier nur den Pointer beobachten und im Code bekommt man statt des Pointers immer den Wert von *c\c auch wenn die Maus über *c steht. Man kommt also an die Werte aber nicht komfortabel und auf einen Blick, was gut wäre wenn man mit F8 durch den Code geht.
    * Es können keine komplexeren Ausdrücke beobachtet werden sondern wirklich nur Variablen. (Also (i.i **Restzeit) geht nicht)
    * In VBA konnte man während der Pause auch einfach eine Teilbedingung oder einen Ausdruck wie gerade beschrieben mit der Maus markieren und beim Tooltip erschien dann die Rechnung samt Ergebnis
    * Einen Speicherbereichdarsteller hatte VBA glaube ich nicht aber es ist nicht gut dass es nur ein Fenster gibt bzw dieses Fenster immer nur einen Speicherbereich darstellen kann
Also insgesamt ist es schon eine Hilfe aber es ist noch nicht so gut wie bei VBA finde ich. Vielleicht irre ich mich auch bei dem einen oder anderen Punkt.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von ts-soft »

SebastianJu2 hat geschrieben: Also insgesamt ist es schon eine Hilfe aber es ist noch nicht so gut wie bei VBA finde ich. Vielleicht irre ich mich auch bei dem einen oder anderen Punkt.
In VBA gibts ja auch keine Pointer. Sollte man also die Pointer abschaffen, damit die Anzeige genauso
vollständig ist :freak: Das ist ja schlimmer als mit Äppel und Birnen (VBA :freak: )
Wenn Du mit Pointern arbeitest, solltest Du Wissen, was Du machst, da bedarf es keiner Tools.
Wenn doch, dann Finger weg von den Pointern, die sowieso nur selten benötigt und nur selten
Vorteile bringen. Etwas benutzen, um es zu lernen ist blödsinn. Erst musst Du Wissen, wann und
wie ist es sinnvoll nutzbar und brauche ich das wirklich.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von SebastianJu2 »

In VBA gibts ja auch keine Pointer.
Dann ist das vermutlich der Grund wieso ich sie dort nicht benutzt habe... :) Ist schon länger her dass ich an VBA saß...

Aber mal angenommen ich will auf Pointer verzichten. Wie könnte ich in kurzer Zeit viele Daten aus einem Editorfeld in eine List() übertragen und dabei auf Pointer verzichten?

Alle anderen Methoden die ich bisher probiert habe sind sehr langsam. Eine große Anzahl von URLs in eine Liste einzuscannen würde so lange dauern dass es sinnlos wird. Egal ob ich die Daten mit getgadgettext und stringfield oder getgadgetitemtext abrufe.
Das Einlesen aus einer Textdatei geht schneller. Aber deswegen die Daten erst eine temporäre Datei schreiben klingt umständlich.

Vorschläge?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von ts-soft »

SebastianJu2 hat geschrieben:Vorschläge?
Nimm den Code von edel:

Code: Alles auswählen

EnableExplicit

Global Dim MeineDaten.s(0)

Procedure WinCallback(hWnd, msg, wparam, lparam)
  Protected *notifyh.NMHDR
  Protected *notiitem.NMLVDISPINFO
 
  If msg = #WM_NOTIFY
    If ArraySize(MeineDaten())
      *notifyh = lparam
      If *notifyh\code = #LVN_GETDISPINFO And *notifyh\idFrom = 1
        *notiitem = lparam
        *notiitem\item\pszText = @MeineDaten(*notiitem\item\iItem)
      EndIf
    EndIf
  EndIf
 
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Define.s Text, tmp
Define i, count
If OpenWindow(0, 0, 0, 640, 480, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EditorGadget(0, 10, 10, 620, 200) 
  ListIconGadget(1, 10, 220, 620, 200, "Zeile:", 600, #LVS_OWNERDATA)
  ButtonGadget(2, 10, 430, 80, 20, "test")
  SetWindowCallback(@WinCallback(), 0)

  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow : Break
      Case #PB_Event_Gadget
        If EventGadget() = 2
          Text = GetGadgetText(0)
          If Text 
            ClearGadgetItems(1)
            count = CountString(Text, #CRLF$) + 1
            ReDim MeineDaten.s(count)
            For i = 1 To count
              tmp = Trim(StringField(Text, i, #CRLF$))
              If tmp
                MeineDaten(i - 1) = tmp
              EndIf
            Next
            SendMessage_(GadgetID(1), #LVM_SETITEMCOUNT, count, 0)
          EndIf
        EndIf
    EndSelect
  ForEver 
EndIf 


PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
SebastianJu2
Beiträge: 180
Registriert: 24.09.2010 10:39

Re: Unterbrechungsmodus Variablenwerte komfortabel ablesen?

Beitrag von SebastianJu2 »

@edel

Um dein Skript mal zu verstehen... du nutzt ein WindowCallback damit du von Windows Parameter geliefert bekommst die du brauchst. Dann sendest du eine Nachricht an das Gadget dass es die Anzahl der Zeilen auf #Count setzen soll. Damit wird vermutlich das dahinterliegende Array/Structure erweitert. Durch die Anfrage wird dann auch das Callback aufgerufen und liefert Parameter. Und dann ordnest du mit einem Befehl das ganze eigene Array dem internen Windowsarray zu dass die Daten für das Gadget enthält. Es werden also keine Strings ausgetauscht. Und wahrscheinlich auch gerade mal der sichtbare Bereich abgerufen.
Hab ich das so richtig verstanden?

Wie kommt man auf solche Funktionen? Nur durch Studium der Windows API und austesten?

@ts-soft

Der Code von edel trägt aber nichts zur Einlesegeschwindigkeit bei. Und das Einlesen ins Array, also mit rausgeklemmtem Schreiben ins listicongadget, dauert da noch länger als mit getgadgetitemtext:

Code: Alles auswählen

      Define lines.i
      lines = CountString(GetGadgetText(*InputEditorHandle), #CRLF$) + 1
      Dim Array_.s(lines)
      For x = 0 To lines-1
        Array_(x) = GetGadgetItemText(*InputEditorHandle,x)
      Next
Und... wenn ich den Code von edel nicht falsch verstanden habe wird dort auch nichts anderes gemacht als die Pointer des ListIcon-Arrays auf diejenigen des eigenen Arrays zu verdrehen. Also reine Pointerarbeit.
Antworten