[archimedes] Re: Wie richtig auf Reason-Codes reagieren?

  • From: Alexander Ausserstorfer <bavariasound@xxxxxxxxxxxxxxx>
  • To: archimedes@xxxxxxxxxxxxx
  • Date: Sun, 26 Oct 2014 06:18:38 +0100

In message <9cab225954.Toni@xxxxxxxxxxxxxxxxxxxxxxxx>
          "Anton Reiser" <anton-reiser@xxxxxxxxxxx> wrote:

>> In dem Code wird jetzt auf die entsprechende Nachricht der WIMP
>> gelauscht, die besagt, dass das Programm beendet werden soll. Das
>> ganze hätte ich ohne eure Hilfe vermutlich noch lange nicht
>> geschafft, vor allem auch, weil es (für mich) schwierig ist,
>> block.message.action aus dem StrongHelp-Manuell von OSLib zu finden
>> bzw. zu sehen.
>
> Ist auch in wimp.h zu finden.
>
> Dein Name für wimp_block ist 'block'.
> wimp_block ist als union definiert.
> Die Brille, durch die wir das ansehen (müssen) ist wimp_message.
> Diese hat in wimp_block den Namen 'message' bekommen
> Die MagicNumber für die Nachricht ist im Message Header zu finden.
> Der ist per #define angegeben.
> Dort ist 'action' für die entsprechende Strukturvariable angegeben.
>
> So kommt block.message.action zustande.

Vielen Dank für die Erklärung. Man muss sowas wohl direkt in Verbindung
mit den PRMs abklären.

Wenn ich per Task Manager mein Programm beende, funktioniert das
anscheinend so:

Der Task Manager teilt (über die WIMP) meinem Programm mit, dass dieses
beendet werden soll. Dabei handelt es sich um eine User_Message. (Er
gibt der WIMP quasi eine Nachricht, welche an mein Programm gerichtet
ist.)

Die Funktion / der SWI wimp_poll liefert dann laut PRMs in diesem Fall
die Ereignisnummer 17 (User_Message) zurück. Gleichzeitig beschreibt die
Funktion einen 256-Byte großen Datenblock, in dem nähere Angaben zum
aufgetretenen Ereignis stehen.

Diesen Datenblock muss man nun auswerten.

Dazu muss man wissen, wie der Datenblock aufgebaut ist. Der Aufbau des
Datenblockes ist aber ereignisabhängig - und genau dies alles steht in
den PRMs. Aus dem OSLib-Handbuch allein ist das nicht zu sehen.

Im Fall einer User_Message mit der Ereignisnummer 17 findet man dort:

User_Message 17

The returned block contains:

R1 + 0 size of block in bytes (20 - 256 in a multiple of four (i.e. words))
R1 + 4 task handle of message sender
R1 + 8 my_ref - the sender's reference for this message
R1 + 12 your_ref - a previous message's my_ref, or 0 if this isn't a reply
R1 + 16 message action code
R1 + 20 message data (dependent on message action)
...

Ab 16 Bytes Offset findet man den Message Action Code, der dem Programm
sagt, was es tun soll.

In C muss man also genau diese Stelle finden. Das hast du oben gemacht.

Leider werden in C statt Nummern und Zahlen Namen vergeben (welche für
diese Nummern und Zahlen stehen), und irgendwelche Definitionen stehen
wiederum für irgendwas anderes. Man muss also immer etwas finden und
dies an Stelle von irgendwas anderem einsetzen:

Ausgegangen von der Funktion

extern wimp_event_no wimp_poll ( wimp_poll_flags mask, wimp_block
*block, int *pollword);

welche im StrongHelp-Handbuch von OSLib zu finden ist, suche ich erstmal
nach wimp_block und finde in der Datei wimp im Verzeichnis h von OSLib:

union wimp_block
   {  wimp_draw redraw;
      wimp_open open;
      wimp_close close;
      wimp_leaving leaving;
      wimp_entering entering;
      wimp_pointer pointer;
      wimp_dragged dragged;
      wimp_key key;
      wimp_selection selection;
      wimp_scroll scroll;
      wimp_caret caret;
      wimp_pollword pollword;
      wimp_message message;
      byte reserved [256];
   };

(Je nachdem, welches Ereignis auftritt, wird der Datenblock entsprechend
formatiert, deshalb wohl die Union mit den verschiedenen Datentypen).

Jetzt suche ich nach dem Datentyp wimp_message und finde dort:

struct wimp_message
   {  wimp_MESSAGE_HEADER_MEMBERS
      union
      {  wimp_message_data_xfer data_xfer;
         wimp_message_ram_xfer ram_xfer;
         wimp_message_prequit prequit;
         wimp_message_save_desktop save_desktop;
         wimp_message_save_desktopw save_desktopw;
         wimp_message_device device;
         wimp_message_data_saved data_saved;
         wimp_message_shutdown shutdown;
         wimp_message_claim_entity claim_entity;
         wimp_message_data_request data_request;
         wimp_message_dragging dragging;
         wimp_message_drag_claim drag_claim;
         wimp_message_release_entity release_entity;
         wimp_message_app_control app_control;
         byte reserved [236];
      }
      data;
   };

und hier nach wimp_MESSAGE_HEADER_MEMBERS:

#define wimp_MESSAGE_HEADER_MEMBERS \
   int size; \
   wimp_t sender; \
   int my_ref; \
   int your_ref; \
   bits action;

In meinem Programm wiederum steht jetzt aber

block für wimp_block.

Also fängt man mit block an, setzt jeweils das rechte für das linke ein
und gelangt so schließlich zu:

block.message.action

Man, das ist ein Schlauch. In Assembler weiß man wenigstens noch, was
man tut.

Ciao,

A.

-- 
http://home.chiemgau-net.de/ausserstorfer/


Other related posts: