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...

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

, 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
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