Seite 1 von 2
Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 15:57
von SBond
Hi Leute,
habe mal wieder eine Frage an euch. Ich arbeite gerade an einem Software-Oszilloskop (hier ein paar Bilder:
http://forum.arduino.cc/index.php?topic=160703.60).
Die Daten die ich auswerte, erhalte ich über die COM-Schnittstelle. An sich funktioniert alles gut. ...doch sobald ich mit der Maus die Titelleiste anklicke und den Maus-Button gedrückt halte, pausiert das Programm. Es führt nach wenigen Millisekunden zum Pufferüberlauf und die Daten sind somit inkonsistent.
Nach langem hin und her habe ich es nun über einen zweiten Thread gelöst, das soweit auch funktioniert. Das Problem ist aber immer wieder die Übergabe oder das Verwenden von Resourcen/Variablen, wenn mehrere Threads auf eine Resource zeitgleich zugreifen wollen. Ich kann das Problem zwar lösen, aber es ist irgendwie nicht das gelbe vom Ei. Schöner wäre es, wenn ich auf diese Threads verzichten könnte. Das würde viele Probleme im Keim ersticken.
Ist es möglich, dass das Programm immer läuft und niemals pausiert? Gibt es da irgendwo eine Einstellung oder ähnliches?
lg
SBond
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 17:05
von NicTheQuick
Wenn deine Ereignisschleife stehen bleibt, sobald du das Fenster verschiebst, kannst du das ändern, indem du den Timeout-Parameter von 'WaitWindowEvent()' verwendest oder einen Window-Timer mit 'AddWindowTimer()' benutzt. Beispiele dazu findest du in der Hilfe.
An deiner Stelle würde ich aber trotzdem die Thread-Variante bevorzugen. Allerdings musst du dann auch wissen wie du die Daten zwischen Thread und Hauptprogramm sauber austauschst. Dazu gibt es Mutex und Semaphoren. Bei den Semaphoren gibt es in der Hilfe ein schönes Beispiel zum Austausch von Daten zwischen Thread und Hauptprogramm.
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 17:17
von SBond
das mit den Parametern scheint aber nicht so recht zu klappen

Ich nutze WaitWindowEvent() mit 2ms TimeOut, aber das Pausieren lässt sich trotzdem nicht verhindern.
Hast du eventuell ein Code-Beispiel? Eventuell bin ich ja auch einfach nur zu blöd um es richtig anzuwenden.
Wahrscheinlich ist es wirklich besser mit Threads zu arbeiten.
lg
SBond
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 20:06
von HeX0R
SBond hat geschrieben:das mit den Parametern scheint aber nicht so recht zu klappen

Ich nutze WaitWindowEvent() mit 2ms TimeOut, aber das Pausieren lässt sich trotzdem nicht verhindern.
Das lässt sich in der Tat nur durch Threads verhindern.
Ich habe dieses Verhalten schon vor ewigen Zeiten offiziell bemängelt, es interessiert aber keinen.
Schlimm ist ja nicht nur, dass die Ereignisschleife einfriert, viel schlimmer ist, dass dabei Events verloren gehen.
Wenn man nun z.B. von Threads über Window-Events mit seiner Hauptschleife kommunizieren will, kann es passieren, dass ein Dir wichtiges Signal nicht ankommt, weil der Anwender die Frechheit besessen hat, das Fenster währenddessen herumzuschieben...
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 20:19
von ts-soft
Zumindest mit BindEvent() genutzte Events kommen auch beim verschieben an. So kann man sich dann doch
noch etwas behelfen.
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 21:27
von Lambda
Was du auf Windows benötigen würdest wäre #WM_MOVE.
Code: Alles auswählen
Procedure WinProc(hWnd, Msg, wParam, lParam)
Protected Old = GetProp_(hWnd, "PROC")
Static Count
Select Msg
Case #WM_MOVE
Count + 1
Debug "Move"+Str(Count)
EndSelect
ProcedureReturn CallWindowProc_(Old, hWnd, Msg, wParam, lParam)
EndProcedure
OpenWindow(0, 0, 0, 400, 300, "Move", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetProp_(WindowID(0), "PROC", SetWindowLongPtr_(WindowID(0), #GWL_WNDPROC, @WinProc()))
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
End
EndSelect
ForEver
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 09.08.2013 23:58
von HeX0R
ts-soft hat geschrieben:Zumindest mit BindEvent() genutzte Events kommen auch beim verschieben an. So kann man sich dann doch
noch etwas behelfen.
Ach, ist das tatsächlich so?
Ich habe das nie ausprobiert, weil ich dachte "geht bestimmt eh nicht".
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 10.08.2013 00:12
von ts-soft
HeX0R hat geschrieben:Ach, ist das tatsächlich so?
Ich habe das nie ausprobiert, weil ich dachte "geht bestimmt eh nicht".
Code: Alles auswählen
EnableExplicit
Procedure SetTime()
SetWindowTitle(0, FormatDate("%hh:%ii:%ss", Date()))
EndProcedure
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "")
AddWindowTimer(0, 1, 500)
BindEvent(#PB_Event_Timer, @SetTime())
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Uhr läuft auch beim verschieben des Fensters weiter

Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 10.08.2013 13:27
von SBond
ist natürlich interessant. So wie ich das sehe, ist die Funktion aber erst in der PB 5.20 enthalten. Ich warte aber erst noch etwas, bis die Version aus der Beta-Phase ist.
Ich denke mal, dass ich wohl bei den Threads bleiben muss. Ich habe da aber immernoch Probleme ein Array aus einem Thread in die Main-Schleife zu übertragen, ohne dass es zu Zugriffskonflikten kommt. Ich denke mal das Zauberwort wird Mutex sein.
Re: Problem: Programm pausiert beim Verschieben des Fensters
Verfasst: 10.08.2013 13:44
von Bisonte
Da das neue BindEvent() und seine Brüder eigentlich aus dem Callback des Windows direkt abgreifen, kannst du dir mit
einem eigenen WindowCallback behelfen.
Das Timer Beispiel von TS-Soft als Callback :
Code: Alles auswählen
EnableExplicit
#MeinTimer = 123 ; sollten ab 121 beginnen, um Konflikte zu vermeiden
Procedure WindowCallBack(hWnd, uMsg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_TIMER ; <-- Das Fenster erhält ein Timer Event
; --- Hier wird der Timer abgefragt
; --- in wParam steht die TimerEvent Nummer
If wParam = #MeinTimer
SetWindowTitle(0, FormatDate("%hh:%ii:%ss", Date()))
EndIf
; --- Sollte man den Timer nicht mehr brauchen
; KillTimer_(hWnd, #MeinTimer)
EndSelect
ProcedureReturn Result
EndProcedure
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "")
; --- Ersatz für
; AddWindowTimer(0, #MeinTimer, 500)
SetTimer_(WindowID(0), #MeinTimer, 500, #Null)
; --- Ersatz für
; BindEvent(#PB_Event_Timer, @SetTime())
SetWindowCallback(@WindowCallBack(), 0)
; --- Und die Auswertung erfolgt im Callback
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
Wenn man einige merkwürdige Logiken von MS geschnallt hat, ist WindowAPI gar nicht mehr so
rätselhaft ...
