Seite 1 von 2

EditorGadget - Bug oder Userproblem?

Verfasst: 12.08.2009 20:30
von netzer
Hallo zusammen,

ich habe ein Problem bei der Verwendung des EditorGadget:

In meinem Programm befindet sich eine PING-Funktion (ähnelt dem DOS-Befehl), bei Aufruf dieser Funktion soll jeder einzelne Ping an ein EditorGadget mittels AddGadgetItem zurückgegeben werden. Das funktioniert aber erst ab dem 20. Versuch. Um dieses Problem zu beheben, habe ich jetzt eine For-Next-Schleife mit 20x AddGadgetItem(ID, -1, Chr(10)) eingebaut. Sieht nicht schön aus aber funktioniert.

Ist das ein Bug oder ein Userproblem?

Danke und Gruß vom Netzer

PS: PB 4.30

Verfasst: 12.08.2009 20:43
von cxAlex
Hm, bei mir funzt das schön:

Nachdem du keinen Code gepostet hast hab ich schnell selbst ein Beispiel geschrieben, so sollte das gehen:

Code: Alles auswählen

EnableExplicit

Define Window, Edit, Address, Ping, Event, Host$

InitNetwork()

Procedure DNS_Lookup(Host$)
  Protected *host.hostent, ret.l
  *host = gethostbyname_(host$)
  If *host
    ret = PeekL(PeekL(*host\h_addr_list))
  Else
    ret = *host
  EndIf
  ProcedureReturn ret
EndProcedure

Procedure ICMP_Ping(ipAddress)
  Protected *Echo.ICMP_ECHO_REPLY, EchoMessage.s, ResultSize, ret, hFile, loop, rtt
  
  EchoMessage = RSet("ICMP ECHO MESSAGE ", 64, "X") ; 64 Bytes senden
  ResultSize = SizeOf(ICMP_ECHO_REPLY) + Len(EchoMessage)
  *Echo = AllocateMemory(ResultSize)
  
  hFile = IcmpCreateFile_()
  For loop = 1 To 3 ; Wie genau?
    If IcmpSendEcho_(hFile, ipAddress, EchoMessage, Len(EchoMessage), 0, *Echo, ResultSize, 1000)
      ret + 1
      rtt = rtt + *Echo\RoundTripTime
    EndIf
  Next
  IcmpCloseHandle_(hFile)
  FreeMemory(*Echo)
  
  If ret
    ret = rtt/ret
  Else
    ret = -1
  EndIf
  
  ProcedureReturn ret
  
EndProcedure

Window = OpenWindow(#PB_Any, 0, 0, 400, 390, "Ping", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
Edit = EditorGadget(#PB_Any, 5, 5, 390, 350, #PB_Editor_ReadOnly)
Address = StringGadget(#PB_Any, 5, 360, 315, 20, "www.google.de")
Ping = ButtonGadget(#PB_Any, 325, 360, 70, 20, "Ping")


Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case Ping
          Host$ = GetGadgetText(Address)
          AddGadgetItem(Edit, -1, "Host: " + Host$ + ", IP: " + IPString(DNS_Lookup(Host$)) + ", Ping: " + Str(ICMP_Ping(DNS_Lookup(Host$)))+" ms")
      EndSelect
  EndSelect
Until Event = #PB_Event_CloseWindow

Verfasst: 12.08.2009 23:06
von netzer
Habe jetzt mal in Kurzform gecodet:

Code: Alles auswählen

 Procedure action()
 
 For i = 1 To 20
    AddGadgetItem(0, -1, "Zeile " + Str(i))
    Debug i
    SendMessage_(GadgetID(0),#EM_SCROLL,#SB_BOTTOM,0)
    Delay(200)
 Next
 
 EndProcedure
 
 
  If OpenWindow(0, 0, 0, 200, 170, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    EditorGadget(0, 10, 10, 180, 100)
    ButtonGadget(1, 10, 140, 50, 20, "Action!", #PB_Button_MultiLine)
 
    Repeat
    EventID = WaitWindowEvent()
    
    If EventID = #PB_Event_Gadget

      Select EventGadget()
        Case 1
          action()       

          
      EndSelect

    EndIf

  Until EventID = #PB_Event_CloseWindow

EndIf


Wenn man den Button drückt, vergeht eine gewisse Zeit, bis etwas passiert (siehe Debugger). Nach wiederholtem Drücken funktioniert es einwandfrei. :?
In meinem eigentlichen Programm geschieht es erst nach 20 Durchläufen.

Gruß vom Netzer

Verfasst: 12.08.2009 23:13
von netzer
Es hängt mit der Größe des Gadgets zusammen. Habe soeben das EditorGadget vergrößert -> Zeitspanne wird größer... :evil:

Verfasst: 12.08.2009 23:19
von ts-soft
> Ist das ein Bug oder ein Userproblem?
Naja, ein Problem des Codes. Solange sich Dein Programm in action()
befindet, werden keine WindowEvents bearbeitet, AddGadgetItem wird zwar
ausgeführt, aber nicht gezeichnet.

Das Delay ist dort vollkommen deplaciert. Du solltest Timer einsetzen,
entweder per API oder ein bissel warten, bis PB4.40 beta erscneint, da gibts
die Timer nativ.

Da Dein Beitrag unter Allgemein gepostet wurde, denke ich mal, das
bekommste jetzt alleine hin.

Gruß

Thomas

Verfasst: 12.08.2009 23:35
von netzer
OK, also ein Userproblem :oops: , danke für die klaren Worte...

Das Delay sollte die pings ein bißchen sanfter ausführen.

Gruß
Netzer

Verfasst: 13.08.2009 06:55
von netzer
Solange sich Dein Programm in action() befindet, werden keine WindowEvents bearbeitet, AddGadgetItem wird zwar ausgeführt, aber nicht gezeichnet.
Die WindowEvents werden ausgeführt, aber erst nach einem bestimmten Durchlauf. Bei erneutem Klicken des Buttons läuft es einwandfrei.
Habe jetzt die Größe noch einmal geändert und das Delay sogar hochgesetzt. Beachtet dabei das EditorGadget und zeitgleich den Debugger. Nach Durchlauf noch einmal action drücken...

Gruß vom Netzer

Code: Alles auswählen

 Procedure action()
 
 For i = 1 To 30
    AddGadgetItem(0, -1, "Zeile " + Str(i))
    Debug i
    SendMessage_(GadgetID(0),#EM_SCROLL,#SB_BOTTOM,0)
    Delay(500)
 Next
 
 EndProcedure
 
 
  If OpenWindow(0, 0, 0, 200, 250, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    EditorGadget(0, 10, 10, 180, 190)
    ButtonGadget(1, 10, 210, 50, 20, "Action!", #PB_Button_MultiLine)
 
    Repeat
    EventID = WaitWindowEvent()
    
    If EventID = #PB_Event_Gadget

      Select EventGadget()
        Case 1
          action()       

          
      EndSelect

    EndIf

  Until EventID = #PB_Event_CloseWindow

EndIf

Verfasst: 13.08.2009 07:17
von ts-soft
> Die WindowEvents werden ausgeführt, aber erst nach einem bestimmten Durchlauf
Anfangs fallen mehr Events an, die in Deinem Code nicht richtig
abgearbeitet werden, deshalb fällts dort mehr auf.

Delay ist in jeder GUI Anwendung böse :mrgreen:

Per Timer im Eventloop rufste die Procedure auf und fürst nur einen Schritt
der Schleife aus, zählst stattdessen eine statische Variable hoch.

Schon sollte alles laufen wie geschmiert.

Gruß

Thomas

Verfasst: 13.08.2009 23:20
von netzer
Hmm, jetzt habe ich den ganzen Tag ohne Erfolg rumgebastelt :(

Habe den Gedankenanstoß von Thomas verstanden (auch die Funktionsweise), aber es scheitert bei der Umsetzung:
EventGadget (Case 1) und Timer im Eventloop zu vereinen, ist für mich der größte Stolperstein.

Code: Alles auswählen

 Procedure action(i)
 
 
    AddGadgetItem(0, -1, "Zeile " + Str(i))
    Debug i
    SendMessage_(GadgetID(0),#EM_SCROLL,#SB_BOTTOM,0)
    
 
 
 EndProcedure
 
 
  If OpenWindow(0, 0, 0, 200, 250, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    SetTimer_(WindowID(0), 0, 500, 0)
    EditorGadget(0, 10, 10, 180, 190)
    ButtonGadget(1, 10, 210, 50, 20, "Action!", #PB_Button_MultiLine)
 
    Repeat
    EventID = WaitWindowEvent()
    
    
    
    
    If EventID = #PB_Event_Gadget

      Select EventGadget()
        Case 1
          action(k) 
                 
      Case #WM_TIMER
        ;Hier wachsen mir die grauen Haare
        ;Timer und Case 1 sollen zusammen arbeiten
          
      EndSelect

    EndIf

  Until EventID = #PB_Event_CloseWindow

EndIf
Vielen Dank für Eure Unterstützung
Gruß
Netzer

Verfasst: 13.08.2009 23:31
von HeX0R
netzer hat geschrieben:Hmm, jetzt habe ich den ganzen Tag ohne Erfolg rumgebastelt :(
Hmm... also, das ist ja nun wirklich ein triviales Problem, was machst du denn, wenn es wirklich mal komplex wird?

Egal, hier:

Code: Alles auswählen

Procedure action(i)

	AddGadgetItem(0, -1, "Zeile " + Str(i))
	Debug i
	SendMessage_(GadgetID(0), #EM_SCROLL, #SB_BOTTOM, 0)

EndProcedure


If OpenWindow(0, 0, 0, 200, 250, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	SetTimer_(WindowID(0), 1, 500, 0)
	EditorGadget(0, 10, 10, 180, 190)
	ButtonGadget(1, 10, 210, 50, 20, "Action!", #PB_Button_MultiLine)

	Repeat
		EventID = WaitWindowEvent()

		If EventID = #PB_Event_Gadget
			Select EventGadget()
				Case 1
					If Not Start
						SetGadgetText(1, "Stop!")
					Else
						SetGadgetText(1, "Action!")
					EndIf
					Start ! 1
			EndSelect
		ElseIf EventID = #WM_TIMER
			If Start
				action(k)
				k + 1
			EndIf
		EndIf

	Until EventID = #PB_Event_CloseWindow

EndIf