Mein Gadget spinnt... oder ist meinem Code schlecht?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Darkman1
Beiträge: 13
Registriert: 28.03.2008 10:02
Wohnort: Bad Vilbel

Mein Gadget spinnt... oder ist meinem Code schlecht?

Beitrag von Darkman1 »

...zumindest sehe ich in meinem Code keinen Fehler. Also, das Programm soll mal ein Terminalprogramm werden mit dem über die ser. Schnittstelle mit externen Geräten kommuniziert wird.
Im Augenblick werden (fast) alle Tastatureingaben direkt auf den Bildschirm (Listgadget) geleitet. Das Pgm füllt zunächst das Gadget mit Zeilen. Wird nun eine Taste gedrückt erscheint das Zeichen in der untersten Zeile. Soweit so gut. Wird nun Return gedrückt fängt das Gadget an zu spinnen. Nach wie vor sind Eingaben möglich, sie werden auch in der nächsten (unsichtbaren) Zeile angezeigt. Wird nun nochmals Return gedrückt kriegt sich alles wieder ein und das Ganze funktioniert als wäre nichts gewesen.
Hab schon alles mögliche probiert um den Fehler zu lokalisieren/zu umgehen, aber, ist irgendwie nicht. Daher ist meine Meinung, dass ein Fehler im Listgadget vorliegt und zwar genau im Übergang wenn die rechte Scrollbar erzeugt werden muss. Ich denke, da gibt's ein Counter-Problem :o - so in der Art mit 0 und 1 als ersten Wert.

Code: Alles auswählen

version$="Fehler ?"
;Festlegung der Position + Größe des Hauptfensters
main_xpos.w      =100
main_ypos.w      =100
main_xwidth.w    =600
main_ywidth.w    =600
;Festlegung der Position + Größe der COM-Window
com_xpos.w      =20
com_ypos.w      =40
com_xwidth.w    =main_xwidth-2*com_xpos
com_ywidth.w    =main_ywidth-com_ypos-40
mainwin.w       =0
Global comwin.w=10
Line$           =""
Line.l          =1
#lib_user       =1
Global GAKS.l  =0
carretcntr.w    =0
carretpos.w     =0
key.c           =0
shiftstatus.l   =0
len.w           =0

;Openlibrary[...]
;GetFunktion[...]
;Callfunctionfast[...] (oder prototyp) 

;VB: GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
;Library "user32" öffnen:
If OpenLibrary(#lib_user, "user32")
  GAKS = GetFunction(#lib_user, "GetAsyncKeyState")
EndIf


If OpenWindow(mainwin, main_xpos, main_ypos, main_xwidth, main_ywidth, version$)And CreateGadgetList(WindowID(mainwin))And InitKeyboard() 
  
  ;Font festlegen:
  If LoadFont(100,"Courier new",10)
    SetGadgetFont(#PB_Default, FontID(100))   ; geladenen Courier 10 Zeichensatz als neuen Standard festlegen
  EndIf
  
  ;List-Gadget öffnen:
  ListViewGadget(comwin, com_xpos, com_ypos, com_xwidth, com_ywidth) ;<--------------------
  SetGadgetColor(comwin, #PB_Gadget_BackColor,RGB(230,230,255))
  SetGadgetColor(comwin, #PB_Gadget_FrontColor,RGB(0,0,255))
  ;...und 32 Zeilen anlegen + ausfüllen
  For Line=1 To 32
    AddGadgetItem(comwin, Line-1, "Line "+Str(Line-1)) 
  Next
  Line=32
  SetGadgetState(comwin, CountGadgetItems(comwin)-1) ;<------------------------------------
  SetGadgetState(comwin, -1) ;<------------------------------------------------------------
  ; The event loop. A ToolBar event is like a Menu event (as tools are shortcut for menu the most
  ; of the time). This is handy, as if the ToolBar buttons and the MenuItem have the same ID, then
  ; the same operation can be done on both action without any adds..
  ;
 
  Repeat
    Delay(20)
    EventID = WindowEvent()
    If EventID
      Select EventID
;-----------------------------------------------------------------------------------------
;-----------------------------------------------------------------------------------------
        Case #PB_Event_CloseWindow  ; If the user has pressed on the close button
          Quit = 1
;-----------------------------------------------------------------------------------------
        Case 256
            ; Keyboard -------------------------------------------------------------------
          key=EventwParam() ;Value of the key in ascii/scancode
          ;SHIFT-Taste ermitteln
          If GAKS
            shiftstatus=CallFunctionFast(GAKS, 16):;16=SHIFT-Taste
            ;SetGadgetItemText(mainwin, 1,RSet(Bin(shiftstatus),32,"0")+"  $"+Hex(shiftstatus))
          EndIf
          Select key
            Case $0d : ;------------------------------------------ CR --------------------
              ;Finde _ und entferne es
              If FindString(s$,"_",0) > 0
                len=Len(s$)
                s$=Left(s$,len-1)
              EndIf
              SetGadgetItemText(comwin, Line-1, s$)
              Line=Line+1
              AddGadgetItem(comwin, Line-1, "Line "+Str(Line-1)) 
              SetGadgetState(comwin, Line-1) ;<------------------------------------
              SetGadgetState(comwin, -1)     ;<------------------------------------
              carretcntr=0
              key=0
            Case $30 To $39 : ;----------------------------------- 0..9 ------------------
              If (shiftstatus&$8000)>0 : ;SHIFT ist gedrückt
                key=0
              EndIf
            Case $41 To $5A : ;----------------------------------- A..Z a..z -------------
              If (shiftstatus&$8000)=0 : ;SHIFT ist nicht gedrückt
                key=key+$20
              EndIf
            Default
              key=0
          EndSelect
          If key>0
            s$=GetGadgetItemText(comwin, Line-1)
            ;Finde _ und entferne es
            If FindString(s$,"_",0) > 0
              len=Len(s$)
              s$=Left(s$,len-1)
            EndIf
            SetGadgetItemText(comwin, Line-1, s$+Chr(key))
          EndIf
;-----------------------------------------------------------------------------------------
      EndSelect
    EndIf

    ;Stelle fest ob vor einem Buchstaben ein _ ist:
    s$=GetGadgetItemText(comwin, Line-1)
    len=Len(GetGadgetItemText(comwin, Line-1))
    p.w=FindString(s$,"_",0)
    If (p>0)And(l>p)
      s$=Mid(s$,0,p-1)+Right(s$,1)
      SetGadgetItemText(comwin, Line-1, s$+" ")
      SetGadgetItemText(comwin, Line-1, s$)
      carretcntr=0
    EndIf
    ; Bei carretcntr=0 ein _ anhängen
    If carretcntr=0
      s$=GetGadgetItemText(comwin, Line-1)
      p=FindString(s$,"_",0)
      If p=0
        SetGadgetItemText(comwin, Line-1, s$+"_")
      EndIf
    EndIf
    ; Ein vorhandenes _ löschen
    If carretcntr=15
      s$=GetGadgetItemText(comwin, Line-1)
      p.w=FindString(s$,"_",0)
      If p>0
        s$=Mid(s$,0,p-1)
        SetGadgetItemText(comwin, Line-1, s$+" ")
        SetGadgetItemText(comwin, Line-1, s$)
      EndIf
    EndIf
    ; Zähler inkrementieren
    carretcntr=carretcntr+1
    ; ...und begrenzen
    If carretcntr>29 
      carretcntr=0
    EndIf

  Until Quit = 1

EndIf
Titel geändert - Kaeru fecit - sorry ICNR
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Ich glaube, ich habe einen Fehler gefunden.

Beitrag von Kiffi »

Darkman1 hat geschrieben:...zumindest sehe ich in meinem Code keinen Fehler.
Die SetGadget*()-Befehle lösen u.U. auch wiederum Events aus, so dass
Du beim ersten CR in eine sich nicht von selber beendende Event-Schleife
gerätst

alles, was zwischen

Code: Alles auswählen

;Stelle fest ob vor einem Buchstaben ein _ ist:
und

Code: Alles auswählen

Until Quit = 1
solltest Du innerhalb eines geeigneten Events platzieren. Ich glaube nicht,
dass Du die Abfragen alle 20 Millisekunden durchlaufen willst.

Grüße ... Kiffi

P.S.: Bitte einen aussagekräftigeren Betreff wählen!
a²+b²=mc²
Darkman1
Beiträge: 13
Registriert: 28.03.2008 10:02
Wohnort: Bad Vilbel

Beitrag von Darkman1 »

alles, was zwischen
.
.
solltest Du innerhalb eines geeigneten Events platzieren. Ich glaube nicht,
dass Du die Abfragen alle 20 Millisekunden durchlaufen willst.


Der Code wird nicht wirklich alle 20ms durchlaufen, dafür sorgt der Zähler carretcntr.

Zu Testzwecken habe ich ein GOTO eingefügt um den gesamten Code zur Cursor-Erzeugung zu übergehen. Tatsächlich ist ein weniger chaotisches Verhalten festzustellen. Trotzdem bleibt ein Fehler der auftritt wenn die Scrollbar soeben erzeugt wurde und die Befehle
SetGadgetState(comwin, Line-1)
SetGadgetState(comwin, -1)
nicht wirksam sind wenn Line den Wert 33 annimmt. Alles funktioniert jedoch zufriedenstellend sobald Line>33 wird.
Olaf Scholz, BM f. Arbeit u. Soziales: ...das ist mehr als wenn es weniger gewesen wäre.
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

@Darkman1:

Der von mir angemerkte Code wird durchlaufen. Da hilft auch Dein
ominöses carretcntr nichts. Einfach mal ein Debug "!" einfügen und
schauen, was passiert.

Ich habe grade ein paar Minuten investiert um Deinen Code zu kapieren,
aber sorry, da muss ich wohl das Handtuch werfen. Liegt unter anderem
auch an solchen Sachen wie:

Code: Alles auswählen

        SetGadgetItemText(comwin, Line-1, s$+" ")
        SetGadgetItemText(comwin, Line-1, s$) 
Was machst Du da eigentlich? :?

Ich persönlich bin nicht der Meinung, dass das ein PB-Bug ist, sondern das
Resultat Deiner seltsamen Programmierung (die ich nicht verstehe).

Grüße ... Kiffi
Kiffi hat geschrieben:P.S.: Bitte einen aussagekräftigeren Betreff wählen!
a²+b²=mc²
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

der code ist leider wirklich ungeeignet um über pb-bugs zu spekulieren.
versuche ihn mal besser zu strukturieren. vor allem solltest du operationen ausführen wenn sie nötig sind, und wenn sie nicht nötig sind, sie nicht ausführen. klingt logisch, aber genau das machst du nicht.
ich glaube auch wie k!ff!, dein hauptproblem ist, dass deine event-queue nicht sauber bleibt, weill du einerseits die abarbeitung mit delay bremst, andererseit eben auch zusätzliche events generierst, wenn es der zustand deines programms nicht unbedingt erfordert (z.b. aller 30-schleifendurchgänge durch diesen zähler).

wenn du beschreibst, was dein programm machen soll, codet dir bestimmmt jemand was zusammen, in funktionierendem pb.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

ohne deinen Code zu verstehen etc. sind mir 2 Dinge aufgefallen.

1. in der Repeatschleife sind SetGadgetstate Befehle enthalten und jedes SetGadget... erzeugt in der Regel ein Event. Kann, muß aber nicht komische Sachen auslösen.

2. Du benutzt EventwParam(). Nicht ohne Grund ist das eine undokumentierte Funktion. Die funktioniert schon mit WaitWindowEvent nicht 100 Prozentig. So fragst du z.B. den Shift Status ab. Dies meldet EventwParam() nicht immer sofort habe ich die Erfahrung gemacht.

Vielleicht solltest du das ganze in einen Callback packen.
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

hjbremer hat geschrieben:2. Du benutzt EventwParam(). Nicht ohne Grund ist das eine undokumentierte Funktion. Die funktioniert schon mit WaitWindowEvent nicht 100 Prozentig. So fragst du z.B. den Shift Status ab. Dies meldet EventwParam() nicht immer sofort habe ich die Erfahrung gemacht.
EventwParam und EventlParam funktionieren so wie man es erwartet.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag von hjbremer »

:mrgreen:
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Du kannst EventwParam() überhaupt nicht in Verbinding bringen. Beide beziehen auf den PB-internen Event-Loop und nicht auf den plattformabhängigen Event-Loop von Windows den man reinem API bzw. Callbacks bearbeitet.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Antworten