atari-home.de - Foren

Software => Coding => Thema gestartet von: Count am Sa 28.07.2018, 20:41:51

Titel: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: Count am Sa 28.07.2018, 20:41:51
Hallo zusammen,

ich möchte aus meinem Programm heraus alle geöffneten Desk-Accessories schließen, wenn ein anderes Programm gestartet wird. Es geht hier nicht um Multitasking-Betriebssysteme.

Ansich sind laufende Accessories kein Problem, aber sie erscheinen nach dem Start des anderen Programms als mit Desktop-Hintergrund gefüllte Rechtecke, bekommen also keine WM_REDRAW-Message. Erst wenn ein Programmfenster aktualisiert werden muss, bekommen auch die Accessories die Aufforderung sich zu aktualisieren.

Der Atari-Desktop (TOS 2.06) schließt geöffnete Accessories, wenn ein Programm gestartet wird. Gemini macht es ebenso. Also muss es doch eine Möglichkeit geben. appl_find() funktioniert nur, wenn man den Dateinamen kennt.

Ist der einzige Ausweg wirklich, das Wurzelverzeichnis des Boot-Laufwerks nach "*.ACC" und "*.CPX" zu durchsuchen und die Treffer mit appl_find() und appl_write() zu bearbeiten?

Ratlos...
Oliver
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: gh-baden am Sa 28.07.2018, 23:03:43
Der Atari-Desktop (TOS 2.06) schließt geöffnete Accessories, wenn ein Programm gestartet wird. Gemini macht es ebenso. Also muss es doch eine Möglichkeit geben. appl_find() funktioniert nur, wenn man den Dateinamen kennt.

Ist der einzige Ausweg wirklich, das Wurzelverzeichnis des Boot-Laufwerks nach "*.ACC" und "*.CPX" zu durchsuchen und die Treffer mit appl_find() und appl_write() zu bearbeiten?

Ich weiß nicht wie es geht, aber du kannst Gemini ja mal mit Sysmon o.ä. auf die Pelle rücken und alle OS-Calls mitschneiden. Dann siehst du ja, wie es vorgeht.
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: mfro am Sa 28.07.2018, 23:17:16
appl_search() (damit kann man laufende Applikationen finden) gibt's erst mit neueren AESen (XaAES, ...).
Wenn Du an jedes Element der Liste ein AC_CLOSE sendest (Applikationen sollte das nicht jucken), hast Du, was Du willst.

In Single-TOS werden GEM-Applikationen vom Desktop per shel_write() gestartet. Damit sie tatsächlich loslaufen, muss der Desktop sich aber erst selbst beenden und dabei werden die Accessories geschlossen (das ist also eigentlich ein Seiteneffekt).

Startest Du von deiner Anwendung aus weitere per Pexec()?
Dann ist das dein Problem. Verwende shel_write().
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: Thorsten Otto am So 29.07.2018, 04:41:44
In Single-TOS werden GEM-Applikationen vom Desktop per shel_write() gestartet. Damit sie tatsächlich loslaufen, muss der Desktop sich aber erst selbst beenden und dabei werden die Accessories geschlossen (das ist also eigentlich ein Seiteneffekt).

Das ist soweit richtig und gleichzeitig auch das Problem. Der "Desktop" ist ja in diesem Fall sein Programm, und müsste sich also beenden. Ich gehe aber mal davon aus daß sein Programm nachher wieder aktiv sein soll.

Hatte in ORCS auch mal das Problem, als ich es eingebaut habe dort beliebige Programme nachzustarten. Ist unter SingleTOS echt ein ziemlicher Krampf. Ua. musst du auch unbedingt ein appl_exit() machen, sonst kommt das AES gehörig aus dem Tritt.
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: mfro am Mo 30.07.2018, 22:21:47
Ich weiß nicht wie es geht, aber du kannst Gemini ja mal mit Sysmon o.ä. auf die Pelle rücken und alle OS-Calls mitschneiden. Dann siehst du ja, wie es vorgeht.

GEMINI macht sich's da einfach (aber da muss man auch erst mal drauf kommen): es startet nicht direkt die auszuführende Applikation, sondern ruft zunächst shel_write() für RUNNER2.APP (eine Mini-Applikation, die nur genau das kann) aus und beendet sich dann.

RUNNER2.APP startet die eigentliche Anwendung und verbleibt im Speicher (und braucht dabei - im Gegensatz zu GEMINI - nur ganz wenig davon). Wenn die eigentliche Applikation beendet wird, startet RUNNER2 wieder GEMINI.
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: Thorsten Otto am Di 31.07.2018, 05:14:37
GEMINI macht sich's da einfach (aber da muss man auch erst mal drauf kommen): es startet nicht direkt die auszuführende Applikation, sondern ruft zunächst shel_write() für RUNNER2.APP (eine Mini-Applikation, die nur genau das kann) aus und beendet sich dann.

Aber nur um Speicher  zu sparen, und auch nur wenn du es explizit gesagt hast (ging glaub ich durch irgendeine Einstellung in $GEMDEFAULT). Bei mir wird runner2.app jedenfalls nicht gestartet ;)
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: 1ST1 am Di 31.07.2018, 08:17:00
Ist die Funktionsweise von Runner2.app irgendwo genau dokumentiert, um das für Zwecke außerhalb von Gemini zu missbrauchen? Vielleicht könnte ich das für meinemn "progman" brauchen, der eine Erweiterung des Atari-Desktops darstellt, und dem eine Art Verknüpfung von Programmen nachrüstet. Dort habe ich nämlich das Problem, dass weder über pexec() noch über shel_write() gestartete Programme ihre Dateien (RSC usw.) finden. Bei manchen Programmen klappt es, das aktuelle Verzeichnis ist aber nicht das Programmverzeichnis, bei anderen aber nicht. Dabei habe ich damals auch versucht, den aktuellen Pfad auf den Pfad des aufgerufenen Programms zu verbiegen.
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: KarlMüller am Di 31.07.2018, 10:39:22
Ist die Funktionsweise von Runner2.app irgendwo genau dokumentiert
Musst Du in der Doku zu Gemini schauen. Ansonsten gibt es bei Thing etwas ähnliches nennt sich ThingRun. Falls es nicht so funktioniert wie gewünscht, kannst es ja umbauen, da der Quelltext vorhanden ist.

Aber zum Thema zurück:
Ich nehme an ein wind_new() ist zu brutal oder?
Titel: Re: Wie kann ich alle geöffneten Accessories schließen?
Beitrag von: Count am Di 31.07.2018, 16:19:51
wind_new() ist zumindest seltsam.

Kurz vorab: Ich habe im Quelltext von Teradesk eine Lösung gefunden. Und da sind wir auch schon bei wind_new().

Teradesk ruft andere Programme mit shel_write() auf, beendet sich aber nicht. Stattdessen werden alle Fenster geschlossen (ab AES 1.04 mit wind_new(), bei älteren Versionen in einer Schleife jeweils das oberste, bis alle geschlossen sind). Danach wird das Programm mit Pexec() gestartet und nach der Rückkehr noch einmal shel_write() mit leerem Programmnamen und zwei Null-Bytes als Kommandozeile aufgerufen.

Das funktioniert in meinem Programm auch wie gewünscht, hat aber bei Verwendung von wind_new() zwei seltsame Macken:

1. Das aufgerufene Programm lässt zunächst keine Eingabe zu (Passwort muss eingegeben werden). Erst nach einigem Herumklicken in der Menüleiste (die bis nach der Passworteingabe deaktiviert ist), sind Tastatureingaben möglich.
2. Wenn dieses Programm beendet wird, stürzt der Rechner mit einer scheinbar willkürlichen Zahl an Bomben ab.

Schließe ich die Fenster statt mit wind_new() einzeln in einer Schleife, funktioniert alles reibungslos.


...

shel_write(1, 1, 0, program, param);
wind_set(0, WF_NEWDESK, 0, 0, 0, 0);

appl_exit();
appl_init();

destroy_windows();

ret = Pexec(0, program, param, env);

shel_write(0, 1, 0, "", "\0\0");

...

void
destroy_windows()
{
    short win, dummy;

    wind_get(0, WF_TOP, &win, &dummy, &dummy, &dummy);

    while (win > 0) {
        close_window(win);
        wind_delete(win);
        wind_get(0, WF_TOP, &win, &dummy, &dummy, &dummy);
    }
}