Autor Thema: Hilfe! evnt_multi() ignoriert Mausklick  (Gelesen 317 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline Count

  • Benutzer
  • Beiträge: 190
Hilfe! evnt_multi() ignoriert Mausklick
« am: Mo 22.02.2021, 19:25:09 »
Hallo zusammen,

ich stehe mal wieder vor einem Rätsel und vielleicht kann mir einer von euch auf die Sprünge helfen, wonach ich suchen muss.

Und zwar habe ich ein GEM-Programm, um verschiedene Daten zu verwalten. Dafür gibt es unterschiedliche Eingabemasken, die in einem Fenster dargestellt werden. Die Masken können über das Pulldown-Menü aufgerufen werden oder auch über Hotkeys. Zu Beginn ist keine Maske geöffnet.

Rufe ich die erste Maske über das Pulldown-Menü auf, ist alles in Ordnung. Verwende ich dafür einen Hotkey, habe ich den Effekt, dass der erste Mausklick nicht erkannt wird. Dabei ist es unerheblich, ob ich vor dem Öffnen der Maske auf dem leeren Desktop rumgeklickt habe oder nicht.

Im Grunde ist es egal, ob ich die Maske über das Pulldown-Menü oder über den Hotkey aufrufe. Der Effekt tritt schlicht dann nicht auf, wenn ich vor dem ersten Öffnen einer Maske irgendwie das Pulldown-Menü aktiviert und die Maustaste gedrückt habe.

Das ganze passiert nur beim ersten Mal. D.h. wenn ich in eine andere Maske wechsle, tritt der Effekt nicht mehr auf.

Hier ist stark vereinfacht die Hauptschleife des Programms. Ich habe mir evnt_ret mal in eine Datei ausgeben lassen und es ist wirklich so, dass MU_BUTTON erst ab dem zweiten Drücken der Maustaste zurückgeliefert wird. Wie gesagt: Es sei denn, ich habe vorher das Pulldown-Menü verwendet und dort bereits einmal die Maustaste gedrückt.

do {
    short evnt_ret;
    short msg[8];
    short mx, my, mk, key, kstat;

    evnt_ret = evnt_multi(MU_MESAG | MU_TIMER | MU_BUTTON | MU_KEYBD,
                          1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, msg, CURSOR_BLINK_RATE,
                          &mx, &my, &mk, &kstat, &key, NULL
                         );

    if ((evnt_ret & MU_TIMER) == MU_TIMER) {
        cursor_blink();
        continue;
    }

    if ((evnt_ret & MU_MESAG) != 0) {
        event_handling(msg);
    }

    if ((evnt_ret & MU_KEYBD) != 0) {
        DO_SOMETHING
    }

    if ((evnt_ret & MU_BUTTON) != 0) {
        DO_SOMETHING
    }
} while (...);

Was kann die Ursache sein?

Offline KarlMüller

  • Benutzer
  • Beiträge: 351
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #1 am: Mo 22.02.2021, 19:56:52 »
Was kann die Ursache sein?
Ist ein wenig schwierig zu sagen. Was meinst Du mit "Pulldown-Menü"? Eine mit menu_bar angemeldete Menüzeile?

Welche Lib benutzt Du denn?
Die Zeit für ein MU_TIMER Ereignis wird normalerweise mit zwei Werten angeben. ev_mtlocount, ev_mthicount, wie bei evnt_timer. Bei Dir sehe ich nur CURSOR_BLINK_RATE.

Offline Chocco

  • Benutzer
  • Beiträge: 159
  • May the force be with you
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #2 am: Mo 22.02.2021, 20:06:49 »
Mir fällt nur auf, dass nach Abfrage des Timer Event mit continue ans Ende der Schleife gesprungen wird. Da in einem Event durchaus mehrere Ereignisse zurückgegeben werden können, wird ein zusätzlich zu MU_TIMER gegebenes Ereignis hier ignoriert.
Atari TT030 mit CrazyDots
Milan 040 (S3)
Apple MBP

Offline mfro

  • Benutzer
  • Beiträge: 1.483
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #3 am: Mo 22.02.2021, 20:14:26 »
Was kann die Ursache sein?
Ist ein wenig schwierig zu sagen. Was meinst Du mit "Pulldown-Menü"? Eine mit menu_bar angemeldete Menüzeile?

Welche Lib benutzt Du denn?
Die Zeit für ein MU_TIMER Ereignis wird normalerweise mit zwei Werten angeben. ev_mtlocount, ev_mthicount, wie bei evnt_timer. Bei Dir sehe ich nur CURSOR_BLINK_RATE.

die mintlib für gcc will an dieser Stelle einen LONG-Wert anstatt der zwei WORDs sehen. Das passt schon.

Mir fällt nur auf, dass nach Abfrage des Timer Event mit continue ans Ende der Schleife gesprungen wird. Da in einem Event durchaus mehrere Ereignisse zurückgegeben werden können, wird ein zusätzlich zu MU_TIMER gegebenes Ereignis hier ignoriert.
+1
And remember: Beethoven wrote his first symphony in C

Offline Count

  • Benutzer
  • Beiträge: 190
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #4 am: Mo 22.02.2021, 20:18:12 »
Das mit dem Timer-Event passt schon:

(evnt_ret & MU_TIMER) == MU_TIMER

Also nur, wenn ausschließlich das Timer-Event aufgetreten ist.

@KarlMüller: Wie @mfro erwähnt, verwende ich Mintlib.

Kann es vielleicht mit wind_update()-Aufrufen zusammenhängen? Vielleicht mehr Begins als Ends? Das könnte ich noch überprüfen.
« Letzte Änderung: Mo 22.02.2021, 20:20:09 von Count »

Offline KarlMüller

  • Benutzer
  • Beiträge: 351
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #5 am: Mo 22.02.2021, 20:42:05 »
@KarlMüller: Wie @mfro erwähnt, verwende ich Mintlib.
Nö die gemlib. Dann bitte in Zukunft dazu schreiben, dass niemand mühsam die Parameter abzählt, weil bei einer Lib was nicht zum offiziellen Aufruft passt.

Offline Chocco

  • Benutzer
  • Beiträge: 159
  • May the force be with you
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #6 am: Mo 22.02.2021, 20:43:46 »
Das mit dem Timer-Event passt schon:

(evnt_ret & MU_TIMER) == MU_TIMER

Also nur, wenn ausschließlich das Timer-Event aufgetreten ist.


Mit (event_ret & MU_TIMER) werden doch alle anderen Events ausgeblendet. Mit (event_ret == MU_TIMER) würden nur die ausschließlichen Timer Events abgegriffen.
 
Atari TT030 mit CrazyDots
Milan 040 (S3)
Apple MBP

Offline Chocco

  • Benutzer
  • Beiträge: 159
  • May the force be with you
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #7 am: Mo 22.02.2021, 21:08:46 »
Kann es vielleicht mit wind_update()-Aufrufen zusammenhängen? Vielleicht mehr Begins als Ends? Das könnte ich noch überprüfen.

Ich hatte es mir häufig einfach gemacht:

do
wind_update( END_UPDATE );
event_multi();
wind_update( BEG_UPDATE );

<Events bearbeiten>

while( !exit_program );
Atari TT030 mit CrazyDots
Milan 040 (S3)
Apple MBP

Offline Count

  • Benutzer
  • Beiträge: 190
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #8 am: Di 23.02.2021, 08:05:47 »
Mit (event_ret & MU_TIMER) werden doch alle anderen Events ausgeblendet. Mit (event_ret == MU_TIMER) würden nur die ausschließlichen Timer Events abgegriffen.
Nach einer Nacht darüber schlafen, hast du natürlich recht. ;)
Aber das ist leider nicht die Ursache. evnt_multi() liefert wirklich erst beim zweiten Klicken das richtige Event MU_BUTTON zurück.

Offline mfro

  • Benutzer
  • Beiträge: 1.483
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #9 am: Di 23.02.2021, 08:08:06 »
Mit (event_ret & MU_TIMER) werden doch alle anderen Events ausgeblendet. Mit (event_ret == MU_TIMER) würden nur die ausschließlichen Timer Events abgegriffen.
Nach einer Nacht darüber schlafen, hast du natürlich recht. ;)
Aber das ist leider nicht die Ursache. evnt_multi() liefert wirklich erst beim zweiten Klicken das richtige Event MU_BUTTON zurück.

was hast Du konkret geändert?
And remember: Beethoven wrote his first symphony in C

Offline Count

  • Benutzer
  • Beiträge: 190
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #10 am: Di 23.02.2021, 08:13:28 »
Mit (event_ret & MU_TIMER) werden doch alle anderen Events ausgeblendet. Mit (event_ret == MU_TIMER) würden nur die ausschließlichen Timer Events abgegriffen.
Nach einer Nacht darüber schlafen, hast du natürlich recht. ;)
Aber das ist leider nicht die Ursache. evnt_multi() liefert wirklich erst beim zweiten Klicken das richtige Event MU_BUTTON zurück.

was hast Du konkret geändert?
Nichts. Ich schreibe das Ergebnis von evnt_multi() direkt in eine Datei und beobachte das. Und es wird alle 300 ms (CURSOR_BLINK_RATE) MU_TIMER (0x20) zurückgeliefert. Erst nach dem zweiten Mausklick MU_BUTTON (0x02).

Offline mfro

  • Benutzer
  • Beiträge: 1.483
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #11 am: Di 23.02.2021, 08:20:24 »
Hast Du das "continue" rausgemacht?
And remember: Beethoven wrote his first symphony in C

Offline Count

  • Benutzer
  • Beiträge: 190
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #12 am: Di 23.02.2021, 08:44:56 »
Hast Du das "continue" rausgemacht?
Nein, ich habe die Bedingung in (evnt_ret == MU_TIMER) geändert.

Offline Count

  • Benutzer
  • Beiträge: 190
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #13 am: Di 23.02.2021, 09:06:31 »
Ich habe jetzt mal in einer Header-Datei, die von jeder Quelldatei eingebunden wird, das wind_update()-Makro umgebogen. Meine eigenen Header-Dateien werden immer erst nach den System-Headerdateien eingebunden, also auch immer nach <gem.h>.
#undef wind_update
#define wind_update(a) my_wind_update(a)
void my_wind_update(short);

Die Funktion sieht so aus:
void my_wind_update(short a)
{
    static const char* what[] = { "END_UPDATE","BEG_UPDATE","END_MCTRL","BEG_MCTRL" };
    FILE*f=fopen("A.TXT","a");
    fprintf(f,"wind_update(%s)\n",what[a]);
    fclose(f);
#undef wind_update
#define wind_update(a) mt_wind_update(a,aes_global)
    wind_update(a);
}

Die Ausgabe in A.TXT zeigt keine Auffälligkeiten:
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)
wind_update(BEG_UPDATE)
wind_update(BEG_MCTRL)
wind_update(END_MCTRL)
wind_update(END_UPDATE)

Offline mfro

  • Benutzer
  • Beiträge: 1.483
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #14 am: Di 23.02.2021, 09:15:05 »
Hast Du das "continue" rausgemacht?
Nein, ich habe die Bedingung in (evnt_ret == MU_TIMER) geändert.

Das ist dann zwar nicht die Ursache für dein Problem, aber trotzdem falsch. Das "continue" hat da nichts verloren, das "==" auch nicht.

Die AES führen bei evnt_multi() unterschiedliche Events, die "quasi-zeitgleich" auftreten, zusammen. Deine Event-Behandlung sollte also immer den Event (mit einer Abfrage auf das gesetzte Bit, also
if (evnt & MU_....)
"rausfischen", den es bearbeiten möchte, aber weiterhin die Behandlung anderer Events *nicht* "abklemmen". Das "continue" macht aber genau das. Zusätzlich bearbeitest Du jetzt einen Timer-Event nur dann, wenn er alleine auftritt.

Mehr kann man erst sagen, wenn Du deinen angepassten Code noch mal zeigst.

And remember: Beethoven wrote his first symphony in C

Offline mfro

  • Benutzer
  • Beiträge: 1.483
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #15 am: Di 23.02.2021, 09:44:50 »
Darüber hinaus: zu viel (unnötiges) wind_update() bremst das Multitasking.

wind_update(BEG_UPDATE)
...
wind_update(END_UPDATE)

klammert Zeichenoperationen, wo Du (per VDI-Calls) selbst zeichnest (also die Rechteckliste abarbeitest). Der call sorgt (nur) dafür, dass die AES so lange die Rechteckliste "in Ruhe lassen".

wind_update(BEG_MCTRL)
...
wind_update(END_MCTRL)

klammert *nur* "lokale" Mausaktionen (also z.B. wenn Du einen Rahmen aufziehst oder eine Fenster-Formularaktion machst). Das verhindert, dass jemand anders als Du von den Aktionen was mitbekommt.

And remember: Beethoven wrote his first symphony in C

Offline Count

  • Benutzer
  • Beiträge: 190
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #16 am: Di 23.02.2021, 11:24:07 »
Danke, das war der entscheidende Tipp. Ich habe die ganzen wind_update()-Aufrufe nochmal kontrolliert und einiges rausgeschmissen. Jetzt funktioniert alles, wie es soll. Wo genau das Problem lag, kann ich leider nicht sagen.

Online Thorsten Otto

  • Benutzer
  • Beiträge: 880
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #17 am: Di 23.02.2021, 12:42:10 »
Das ist dann zwar nicht die Ursache für dein Problem, aber trotzdem falsch. Das "continue" hat da nichts verloren, das "==" auch nicht.

Das kann man so nicht sagen. Wenn der timer nur für Cursor-Blinken benutzt wird, dann möchte man im allgemeinen nicht daß der blinkt, wenn danach noch andere Aktionen wie redraw ausgeführt werden. Auch möchte man vlt nicht daß er blinkt, solange eine Maustaste gedrückt ist. Jedenfalls habe ich  in einigen meiner Programme was ähnliches drin. Auf jeden Fall dürfte, nach der Änderung auf ==, das keinen EInfluss mehr auf die Button-Events haben. Lässt sich einfach testen, indem man mal MU_TIMER aus der Maske der zu erwartenden Events entfernt.

Offline mfro

  • Benutzer
  • Beiträge: 1.483
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #18 am: Di 23.02.2021, 12:51:52 »
Über das == kann man streiten, auch wenn mir schwerfällt, mir eine Situation vorzustellen, wo ich einen Event nur dann bearbeite, wenn die AES gerade keinen anderen Event (mehr oder weniger zufällig) "dazugepackt" haben.
Wenn es so eine Situation gäbe (mir - soweit ich mich erinnere - noch nicht untergekommen), würde ich das jedenfalls expliziter hinschreiben.

Das continue ist m.E. jedenfalls verkehrt. Da wird potentiell ein (oder mehrere) Event(s) weggeschmissen, der/die so auch nicht wieder auftauch[t|en].
Wenn's beispielsweise das Loslassen einer Maustaste war (auf das man gerade sehnlichst wartet), kann das ziemlich blöd sein und nach dem Fehler kann man sich totsuchen.
And remember: Beethoven wrote his first symphony in C

Online Thorsten Otto

  • Benutzer
  • Beiträge: 880
Re: Hilfe! evnt_multi() ignoriert Mausklick
« Antwort #19 am: Di 23.02.2021, 14:44:47 »
Das continue ist m.E. jedenfalls verkehrt. Da wird potentiell ein (oder mehrere) Event(s) weggeschmissen

Nein. Wenn da steht
if (event_ret == MU_TIMER)
{
    do_something();
    continue;
}

dann ist das lediglich eine kleine Optimierung. In dem Fall waren ja keine anderen bits gesetzt und müssen auch nicht weiter getested werden.
Natürlich müsste man dann theoretisch nochmal extra testen, ob MU_TIMER zusammen mit anderen Events aufgetreten ist. Ob man das will hängt aber von der Anwendung ab. In vielen Fällen wird man MU_TIMER nur behandeln wollen, wenn sonst nichts zu tun war,

PS.: das Problem scheint ja auch gelöst zu sein, und mit MU_TIMER nichts zu tun zu habne.