Atari Logo
Programmieren

Hauptseite -
Welches System? -
Hardware -
Software -
Textverarbeitung -
Internet
MausNet
Programmieren
Verweise
Über

TOS - Algorithmen - Beispiele - weitere Informationen


Beispiel: GEM-Rumpf

Das folgende Beispiel stellt den Rumpf eines GEM-Programms dar und zeigt das Prinzip der GEM-Programmierung, kann aber auch als Template für das Erstellen eines neuen GEM-Programms dienen.

Sprache C
Beispiel gem.c

gem.c

#include 
#include 
#include 
#include 
#if GEMDOS
#include 
#endif
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MENUBAR 0
#define DESKTOP 1
#define OK      1
#define ABBRUCH 2
#define ENDE 1
#define DESK 0

BYTE *RscPfad="gem.rsc",
      *RscFehler="[2][Die Resourcedatei fehlt?][Abbruch]",
      ScrpPfad[80];
WORD WorkIn[16],WorkOut[57],AplId,VdiHandle,MsgBuff[8],
     AesHchar,AesWchar,AesHbox,AesWbox,AnzFarben,
     MausX,MausY,MausButton,SonderTaste,Taste,MausKlicks;
BOOL Fertig,IsFarbe;
OBJECT *MenuTree,*DeskTop;
GRECT Screen;

WORD DoDialog(OBJECT *dial)
{  GRECT size;
   WORD RetCode;

   /* Vorbereitung */
   wind_update(BEG_UPDATE);
   wind_update(BEG_MCTRL);
   form_center(ADDR(dial), ADDR(&size.g_x), ADDR(&size.g_y),
               ADDR(&size.g_w), ADDR(&size.g_h));
   form_dial(FMD_START, size.g_x, size.g_y, size.g_w, size.g_h,
             size.g_x, size.g_y, size.g_w, size.g_h);
   objc_draw(ADDR(dial), ROOT, MAX_DEPTH,
             size.g_x, size.g_y, size.g_w, size.g_h);
   /* Durchfhrung */
   RetCode=form_do(ADDR(dial), ROOT) & 0x7FFF;
   /* Nachbereitung */
   form_dial(FMD_FINISH, size.g_x, size.g_y, size.g_w, size.g_h,
             size.g_x, size.g_y, size.g_w, size.g_h);
   wind_update(END_MCTRL);
   wind_update(END_UPDATE);
   dial[RetCode].ob_state &= (~SELECTED); /* Knopf deselektieren */
   return(RetCode);
}

WORD DoDia2(OBJECT *dial)
{  GRECT size;
   WORD RetCode,DoppelKlick;

   /* Vorbereitung */
   wind_update(BEG_UPDATE);
   wind_update(BEG_MCTRL);
   form_center(ADDR(dial), ADDR(&size.g_x), ADDR(&size.g_y),
               ADDR(&size.g_w), ADDR(&size.g_h));
   form_dial(FMD_START, size.g_x, size.g_y, size.g_w, size.g_h,
             size.g_x, size.g_y, size.g_w, size.g_h);
   objc_draw(ADDR(dial), ROOT, MAX_DEPTH,
             size.g_x, size.g_y, size.g_w, size.g_h);
   /* Durchfhrung */
   for (;;)
   {
      RetCode=form_do(ADDR(dial), ROOT);
      DoppelKlick = RetCode&0x8000;
      RetCode &= 0x7FFF;
      if ((RetCode == OK) || (RetCode == ABBRUCH))
         break;
      /* weitere spezielle Auswertungen... */
   }
   /* Nachbereitung */
   form_dial(FMD_FINISH, size.g_x, size.g_y, size.g_w, size.g_h,
             size.g_x, size.g_y, size.g_w, size.g_h);
   wind_update(END_MCTRL);
   wind_update(END_UPDATE);
   dial[RetCode].ob_state &= (~SELECTED); /* Knopf deselektieren */
   return(RetCode);
}

void WndRedraw(WORD win, WORD x, WORD y, WORD w, WORD h)
{  GRECT t1,t2;

   t2.g_x = x;
   t2.g_y = y;
   t2.g_w = w;
   t2.g_h = h;
   wind_get(win, WF_FIRSTXYWH,
            ADDR(&t1.g_x), ADDR(&t1.g_y)
            ADDR(&t1.g_w), ADDR(&t1.g_h));
   while ((t1.g_w != 0) && (t1.g_h != 0))
   {
      /* in Schleife die neuzumalenden Rechtecke aktualisieren */
      /* Ueberschneidung errechnen */
      if (rc_intersect(&t1, &t2))
      {
         /* Fensterbereich neu zeichnen */
      }
      wind_get(win, WF_NEXTXYWH,
               ADDR(&t1.g_x), ADDR(&t1.g_y),
               ADDR(&t1.g_w), ADDR(&t1.g_h));
   }
}

void WndTopped(WORD win)
{
#if TURBO_C
   wind_set(win, WF_TOP);
#else
   wind_set(win, WF_TOP, 0, 0, 0, 0);
#endif

}

void WndClosed(WORD win)
{
   wind_close(win);
}

void WndFulled(WORD win)
{
   wind_set(win, WF_CURRXYWH,
            Screen.g_x, Screen.g_y, Screen.g_w, Screen.g_h);
}

void WndArrowed(WORD win, WORD mode)
{
   switch (mode)
   {
      case 0:
         /* Seite nach oben */
         break;
      case 1:
         /* Seite nach unten */
         break;
      case 2:
         /* Zeile nach oben */
         break;
      case 3:
         /* Zeile nach unten */
         break;
      case 4:
         /* Seite nach links */
         break;
      case 5:
         /* Seite nach rechts */
         break;
      case 6:
         /* Spalte nach links */
         break;
      case 7:
         /* Spalte nach rechts */
         break;
   }
}

void WndHslid(WORD win, WORD pos)
{
#if TURBO_C
   wind_set(win, WF_HSLIDE, pos);
#else
   wind_set(win, WF_HSLIDE, pos, 0, 0, 0);
#endif
}

void WndVslid(WORD win, WORD pos)
{
#if TURBO_C
   wind_set(win, WF_VSLIDE, pos);
#else
   wind_set(win, WF_VSLIDE, pos, 0, 0, 0);
#endif
}

void WndSized(WORD win, WORD x, WORD y, WORD w, WORD h)
{
   wind_set(win, WF_CURRXYWH, x, y, w, h);
   /* Ausschnitt aktualisieren */
}

void WndMoved(WORD win, WORD x, WORD y, WORD w, WORD h)
{
   wind_set(win, WF_CURRXYWH, x, y, w, h);
}

void MenSelected(WORD Eintrag)
{
   switch (Eintrag)
   {
      case ENDE:
         Fertig = TRUE;
         break;
   }
}

void HdleKeybd(WORD Taste)
{
}

void HdleButton(WORD MausX, WORD MausY, WORD MausButton,
                WORD SonderTaste, WORD MausKlicks)
{
   /* Hier kann auch die Bewegung eines Desktop-Objekts erfolgen */
}

void HdleM1(WORD MausX, WORD MausY, WORD MausButton, WORD SonderTaste)
{
}

void HdleM2(WORD MausX, WORD MausY, WORD MausButton, WORD SonderTaste)
{
}

void HdleMesag(WORD *MsgBuff)
{
   switch (MsgBuff[0])
   {
      case AC_OPEN:
         /* ein Accessory wurde angew„hlt... */
         /* MsgBuff[3]  Identifikator des Accessories */
         break;
      case AC_CLOSE:
         /* Accessory wurde geschlossen */
         /* MsgBuff[3]  Identifikator des Accessories */
         break;
      case MN_SELECTED:
         /* Menverwaltung... */
         MenSelected(MsgBuff[4]);
         menu_tnormal(ADDR(MenuTree), MsgBuff[3], 1);
         break;
      case WM_REDRAW:
         /* Redraw-Meldung ID und Koordinaten uebergeben */
         WndRedraw(MsgBuff[3], MsgBuff[4], MsgBuff[5],
                   MsgBuff[6], MsgBuff[7]);
         break;
      case WM_TOPPED:
         /* falls Fenster aktiviert werden soll */
         WndTopped(MsgBuff[3]); /* ID des Fensters */
         break;
      case WM_CLOSED:
         /* falls Fenster geschlossen werden soll */
         WndClosed(MsgBuff[3]); /* ID des Fensters */
         break;
      case WM_FULLED:
         /* falls Fensters auf volle Gr”že gebracht werden soll */
         WndFulled(MsgBuff[3]); /* ID des Fensters */
         break;
      case WM_ARROWED:
         /* falls einer der Pfeile angeklickt wurde... */
         WndArrowed(MsgBuff[3],  /* ID des Fensters */
                    MsgBuff[4]); /* Art der Ver„nderung */
         break;
      case WM_HSLID:
         /* falls der horizontale Slider bewegt wurde... */
         WndHslid(MsgBuff[3],  /* ID des Fensters */
                  MsgBuff[4]); /* Position in Promille */
         break;
      case WM_VSLID:
         /* falls der vertikale Slider bewegt wurde */
         WndVslid(MsgBuff[3],  /* ID des Fensters */
                  MsgBuff[4]); /* Position in Promille */
         break;
      case WM_SIZED:
         /* falls die Fenstergr”že ver„ndert wurde... */
         WndSized(MsgBuff[3],  /* ID des Fensters */
                  MsgBuff[4],  /* X-Koordinate des Fensters */
                  MsgBuff[5],  /* Y-Koordinate des Fensters */
                  MsgBuff[6],  /* neue Breite */
                  MsgBuff[7]); /* neue H”he */
         break;
      case WM_MOVED:
         /* falls das ganze Fenster bewegt wurde */
         WndMoved(MsgBuff[3],  /* ID des Fensters */
                  MsgBuff[4],  /* neue x-Koordinate */
                  MsgBuff[5],  /* neue y_Koordinate */
                  MsgBuff[6],  /* Breite */
                  MsgBuff[7]); /* H”he */
         break;
      case WM_NEWTOP:
         /* falls Fenster aktiviert werden soll */
         WndTopped(MsgBuff[3]); /* ID des Fensters */
         break;
      /* Ab Falcon AES */
      case WM_UNTOPPED:
         break;
      case WM_ONTOP:
         break;
      case AP_TERM:
         break;
      case AP_TFAIL:
         break;
      case AP_RESCHG:
         break;
      case SHUT_COMPLETED:
         break;
      case RESCH_COMPLETED:
         break;
      case AP_DRAGDROP:
         break;
      case SH_EXIT:
         break;
      case SH_START:
         break;
      case CH_EXIT:
         break;
   }
}

#if GEMDOS

MLOCAL WORD BootDev(VOID)
{  VOID *OldSuperStack;
   WORD RetWert;

   OldSuperStack=(VOID *)Super(NULL);
   RetWert=*(WORD *)0x446;
   Super(OldSuperStack);
   return(RetWert);
}

MLOCAL VOID GetScrapPath(char *Path)
{  int OldDrv;

   OldDrv = Dgetdrv(); /* aktuelles Laufwerk merken */
   /* zuerst wird versucht, C: zu setzen */
   Dsetdrv(2);
   if (Dgetdrv()==2)
      Path[0]='C';
   else
   {
      /* C existiert nicht, Bootlaufwerk ermitteln */
      Path[0]='A'+(char)BootDev();
      Dsetdrv(Path[0]-'A');
   }
   /* Klemmbrett anlegen */
   Dcreate("\\CLIPBRD");
   Path[1]='\0';
   strcat(Path,":\\CLIPBRD");
   Dsetdrv(OldDrv);
}

#else

/* nur ein dummy, sollte noch sinnvoll gefuellt werden */
MLOCAL VOID GetScrapPath(char *Path)
{
   strcpy(Path, "C:\\GEMSYS\\CLIPBRD");
}

#endif

int main(int argc, char *argv[])
{  WORD i, Event, OldDrv;
   int Ret;

   AplId = appl_init();
   if (AplId >= 0)
   {
      VdiHandle = graf_handle(ADDR(&AesWchar), ADDR(&AesHchar),
                              ADDR(&AesWbox), ADDR(&AesHbox));
      WorkIn[0] = 1; /* Geraet = Monitor, Standardaufloesung */
      for (i=1; i<10; i++)
         WorkIn[i] = 1;
      WorkIn[10] = 2; /* Raster-Koordinaten */
      for (i=11; i<16; i++)
         WorkIn[i] = 0;
      v_opnvwk(WorkIn, ADDR(&VdiHandle), ADDR(WorkOut));
      AnzFarben = WorkOut[13];
      IsFarbe = WorkOut[35] == 1;
      /* Desktop-Groesse ermitteln */
      wind_get(DESK, WF_WORKXYWH,
               ADDR(&Screen.g_x), ADDR(&Screen.g_y),
               ADDR(&Screen.g_w), ADDR(&Screen.g_h));
      graf_mouse(BUSYBEE, NULL);
      if (rsrc_load(ADDR(RscPfad)) != 0)
      {
         /* Desktop */
         rsrc_gaddr(R_TREE, DESKTOP, ADDR(&DeskTop));
         DeskTop[ROOT].ob_x = Screen.g_x;
         DeskTop[ROOT].ob_y = Screen.g_y;
         DeskTop[ROOT].ob_width = Screen.g_w;
         DeskTop[ROOT].ob_height = Screen.g_h;
         objc_draw(ADDR(DeskTop), ROOT, MAX_DEPTH,
                   Screen.g_x, Screen.g_y, Screen.g_w, Screen.g_h);
#if TURBO_C
         wind_set(DESK, WF_NEWDESK, (LONG)DeskTop, 0);
#else
         wind_set(DESK, WF_NEWDESK, HW(DeskTop), LW(DeskTop), 0, 0);
#endif
         /* Klemmbrett */
         scrp_read(ScrpPfad);
         if (ScrpPfad[0] == '\0')
         {
            GetScrapPath(ScrpPfad);
            scrp_write(ScrpPfad);
         }
         /* Menue */
         rsrc_gaddr(R_TREE, MENUBAR, ADDR(&MenuTree));
         graf_mouse(M_OFF, NULL);
         menu_bar(ADDR(MenuTree), 1);
         graf_mouse(M_ON, NULL);
         graf_mouse(ARROW, NULL);
         Fertig = FALSE;
         while (!Fertig)
         {
            Event=evnt_multi(MU_KEYBD|MU_BUTTON|MU_M1|MU_M2|MU_MESAG|MU_TIMER,
                             1,0x01,0x01, 0,0,0,0,0, 0,0,0,0,0,
                             ADDR(MsgBuff), 0,0,
                             ADDR(&MausX), ADDR(&MausY),
                             ADDR(&MausButton),
                             ADDR(&SonderTaste), ADDR(&Taste),
                             ADDR(&MausKlicks));
            if (Event&MU_KEYBD)
               HdleKeybd(Taste); /* gedrueckte Taste */
            if (Event&MU_BUTTON)
               HdleButton(MausX,MausY, /* Position des Mauszeigers */
                          MausButton,  /* Status der Maustasten */
                          SonderTaste, /* Status der Umschalttasten */
                          MausKlicks); /* Anzahl der Mausklicks */
            if (Event&MU_M1)
               HdleM1(MausX,MausY,  /* Position des Mauszeigers */
                      MausButton,   /* Status der Maustasten */
                      SonderTaste); /* Status der Umschalttasten */
            if (Event&MU_M2)
               HdleM2(MausX,MausY,  /* Position des Mauszeigers */
                      MausButton,   /* Status der Maustasten */
                      SonderTaste); /* Status der Umschalttasten */
            if (Event&MU_MESAG)
               HdleMesag(MsgBuff); /* Adresse des Messagepuffers */
         }
         graf_mouse(M_OFF, NULL);
         menu_bar(MenuTree, 0);
         wind_set(DESK, WF_NEWDESK, 0, 0, 0);
         graf_mouse(M_ON, NULL);
         rsrc_free();
         Ret = 0;
      }
      else
      {
         graf_mouse(ARROW, NULL);
         form_alert(1, ADDR(RscFehler));
         Ret = 2;
      }
      v_clsvwk(VdiHandle);
      appl_exit();
   }
   else
      Ret = 1;
   return(Ret);
}

Best viewed with any browser English version not yet available.

Änderungen und Irrtümer vorbehalten. Letzte Änderung:
13 September 2005.
Home - Mail an den Webmaster - Impressum