Obligement - L'Amiga au maximum

Dimanche 24 septembre 2017 - 12:38  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

 · Accueil
 · A Propos
 · Articles
 · Galeries
 · Glossaire
 · Hit Parade
 · Liens
 · Liste jeux Amiga
 · Quizz
 · Téléchargements
 · Trucs et astuces


Articles

 · Actualité (récente)
 · Actualité (archive)
 · Comparatifs
 · Dossiers
 · Entrevues
 · Matériel (tests)
 · Matériel (bidouilles)
 · Points de vue
 · En pratique
 · Programmation
 · Reportages
 · Tests de jeux
 · Tests de logiciels
 · Tests de compilations
 · Articles divers

 · Articles in english
 · Articles in other languages


Twitter

Suivez-nous sur Twitter




Liens

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Moteurs de recherche
 · Pages de liens
 · Constructeurs matériels
 · Matériel
 · Autres sites de matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Développeurs logiciels
 · Logiciels
 · Développeurs de jeux
 · Jeux
 · Autres sites de jeux
 · Scène démo
 · Divers
 · Informatique générale


Jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Partenaires

Annuaire Amiga

Amedia Computer

Relec

Hit Parade


Contact

David Brunet

Courriel

 


Amiga E : Interfaces graphiques
(Article écrit par Damien Guichard - octobre 2004)


Troisième étape

Dans l'article précédent, on a introduit les structures fondamentales d'AmigaOS et notamment les signaux de tâche, les listes d'attributs et les listes Exec. Dans cet article, on utilise ces notions pour expliquer comment créer des interfaces graphiques interactives. Dans le prochain article on améliorera nos interfaces graphiques avec des raccourcis clavier, une interface Exchange et un port ARexx.

Intuition

Créer, gérer et fermer une fenêtre Intuition, se fait toujours selon le même procédé général :
  • Fournir les WA_FLAGS, qui spécifient l'équipement de la fenêtre.
  • Fournir les WA_IDCMP, qui spécifient quels événements sont notifiés.
  • Ouvrir la fenêtre via OpenWindowTagList().
  • Le port de message de la fenêtre est win.userport.
  • Le signal de tâche correspondant est Shl(1,win.userport.sigbit).
  • Attendre les signaux voulus, en plus du signal de port de fenêtre.
  • Lors de la réception d'un message par le port de fenêtre, il faut :
    • 1. Obtenir le message par imsg:=GetMsg(win.userport).
    • 2. L'événement de fenêtre est imsg.class.
    • 3. Eventuellement, le gadget concerné est imsg.iaddress.
    • 4. Répondre au message par ReplyMsg(imsg).
    • 5. Lors d'un événement IDCMP_REFRESHWINDOW il faut appeler BeginRefresh(), puis redessiner le contenu de la fenêtre, et ensuite appeler EndRefresh() avant de fermer la fenêtre, il faut vider le port de message.

OPT OSVERSION=37

MODULE 'exec/ports'
MODULE 'reqtools','intuition/intuition'

ENUM ERR_OK,ERR_NOREQTOOLS,ERR_NOWINDOW

CONST SIGNAL_BREAK=$1000

DEF win:PTR TO window
DEF iclass,icode,igad:PTR TO gadget

PROC main() HANDLE
  reqtoolsbase:=OpenLibrary('reqtools.library',37)
  IF reqtoolsbase=NIL THEN Raise(ERR_NOREQTOOLS)
  win:=OpenWindowTagList(NIL,
     [WA_TITLE, 'My Window',
      WA_FLAGS, WFLG_SIZEGADGET+WFLG_DEPTHGADGET+WFLG_CLOSEGADGET+
                WFLG_DRAGBAR+WFLG_SIMPLE_REFRESH+WFLG_ACTIVATE,
      WA_IDCMP, IDCMP_CLOSEWINDOW+IDCMP_REFRESHWINDOW,
      WA_MINWIDTH,  140,
      WA_MINHEIGHT, 35,
      NIL])
  IF win=NIL THEN Raise(ERR_NOWINDOW)
  handle()
EXCEPT DO
  SELECT exception
  CASE ERR_NOREQTOOLS
    PrintF('Could not open reqtools.library v37+ !\\n')
  CASE ERR_NOWINDOW
    RtEZRequestA('Could not open window!','Ok',0,0,0)
  ENDSELECT
  IF win THEN CloseWindow(win)
  IF reqtoolsbase THEN CloseLibrary(reqtoolsbase)
ENDPROC

PROC handle() HANDLE
  DEF signals,winsig,imsg:PTR TO intuimessage
  winsig:=Shl(1,win.userport.sigbit)
  LOOP
    signals:=Wait(winsig+SIGNAL_BREAK)
    IF signals AND winsig
      WHILE imsg:=GetMsg(win.userport)
        iclass:=imsg.class
        icode:=imsg.code
        igad:=imsg.iaddress
        ReplyMsg(imsg)
        SELECT iclass
        CASE IDCMP_REFRESHWINDOW
          BeginRefresh(win)
          EndRefresh(win,TRUE)
        CASE IDCMP_CLOSEWINDOW
          Raise(0)
        ENDSELECT
      ENDWHILE
    ENDIF
    IF signals AND SIGNAL_BREAK
      Raise(0)
    ENDIF
  ENDLOOP
EXCEPT
  WHILE imsg:=GetMsg(win.userport)
    ReplyMsg(imsg)
  ENDWHILE
ENDPROC
Notez qu'il n'y a pas besoin d'ouvrir/fermer la intuition.library, c'est l'AmigaE qui s'en charge.

Pour plus d'information sur les drapeaux WA_FLAGS,WA_IDCMP, sur OpenWindowTagList(),intuimessage, BeginRefresh() et EndRefresh(), voir les Autodocs de la intuition.library ainsi que les Includes intuition/intuition.h.

Gadtools

Si nous voulons des gadgets tout prêts à utiliser et des menus faciles à créer, alors Intuition n'est pas suffisant, il faut en plus un kit de construction de GUI. Gadtools est un bon candidat pour démarrer, plus tard vous choisirez BOOPSI, MUI, Reaction ou Feelin, mais d'abord il faut apprendre les techniques de base avec Gadtools.

Gadtools fonctionne à peu près comme Intuition, les différences sont :
  • Vous devez ouvrir/fermer la gadtools.library.
  • GetMsg/ReplyMsg deviennent Gt_GetIMsg/Gt_ReplyIMsg.
  • BeginRefresh/EndRefresh deviennent Gt_BeginRefresh/Gt_EndRefresh.
  • Il y a une initialisation en plus à l'aide de GetVisualInfoA() et CreateContext().
  • Une fois la fenêtre ouverte il faut appeller Gt_RefreshWindow().
Comme nous voulons aussi profiter des facilités de Gatools en matière de menus :
  • On crée un menu à l'aide de CreateMenuA() et LayoutMenuA().
  • On libère ce menu avec ClearMenuStrip() et FreeMenus().
C'est quand même du code plutôt rébarbatif, c'est pourquoi il est habile de le placer dans un module "gt_window", ensuite il n'y aura plus qu'à le paramétrer avec les options voulues :

OPT MODULE
OPT EXPORT

MODULE 'exec/ports'
MODULE 'reqtools','intuition/intuition'
MODULE 'gadtools','libraries/gadtools'

ENUM ERR_OK,ERR_NOREQTOOLS,ERR_NOGADTOOLS,ERR_NOSCREEN,
     ERR_NOVISUAL,ERR_NOCONTEXT,ERR_NOMENU,ERR_NOGADGET,ERR_NOWINDOW

CONST SIGNAL_BREAK=$1000

PROC gt_openwindow(windef,newmenu,winhandler) HANDLE
  DEF win=NIL:PTR TO window,iclass,icode,igad
  DEF signals,winsig,imsg:PTR TO intuimessage
  DEF scr=NIL,visual=NIL,context,gadlist=NIL,menu=NIL
  reqtoolsbase:=OpenLibrary('reqtools.library',37)
  IF reqtoolsbase=NIL THEN Raise(ERR_NOREQTOOLS)
  gadtoolsbase:=OpenLibrary('gadtools.library',37)
  IF gadtoolsbase=NIL THEN Raise(ERR_NOGADTOOLS)
  IF (scr:=LockPubScreen('Workbench'))=NIL THEN Raise(ERR_NOSCREEN)
  IF (visual:=GetVisualInfoA(scr,NIL))=NIL THEN Raise(ERR_NOVISUAL)
  IF (context:=CreateContext({gadlist}))=NIL THEN Raise(ERR_NOCONTEXT)
  IF newmenu
    IF (menu:=CreateMenusA(newmenu,NIL))=NIL THEN Raise(ERR_NOMENU)
    IF LayoutMenusA(menu,visual,NIL)=FALSE THEN Raise(ERR_NOMENU)
  ENDIF
  IF (win:=windef(scr,context,visual,gadlist))=NIL THEN Raise(ERR_NOWINDOW)
  IF menu THEN IF SetMenuStrip(win,menu)=FALSE THEN Raise(ERR_NOMENU)
  Gt_RefreshWindow(win,NIL)
  winsig:=Shl(1,win.userport.sigbit)
  LOOP
    signals:=Wait(winsig+SIGNAL_BREAK)
    IF signals AND winsig
      WHILE imsg:=Gt_GetIMsg(win.userport)
        iclass:=imsg.class
        icode:=imsg.code
        igad:=imsg.iaddress
        winhandler(imsg,iclass,icode,igad)
      ENDWHILE
    ENDIF
    IF signals AND SIGNAL_BREAK
      Raise(ERR_OK)
    ENDIF
  ENDLOOP
EXCEPT DO
  WHILE imsg:=Gt_GetIMsg(win.userport)
    Gt_ReplyIMsg(imsg)
  ENDWHILE
  SELECT exception
  CASE ERR_NOREQTOOLS
    PrintF('Could not open reqtools.library v37+ !\\n')
  CASE ERR_NOGADTOOLS
    RtEZRequestA('Could not open gadtools.library v37+ !','Ok',0,0,0)
  CASE ERR_NOSCREEN
    RtEZRequestA('Could not lock Workbench screen!','Ok',0,0,0)
  CASE ERR_NOVISUAL
    RtEZRequestA('Could not get visual info!','Ok',0,0,0)
  CASE ERR_NOCONTEXT
    RtEZRequestA('Could not create window context!','Ok',0,0,0)
  CASE ERR_NOMENU
    RtEZRequestA('Could not create menu!','Ok',0,0,0)
  CASE ERR_NOGADGET
    RtEZRequestA('Could not create gadget!','Ok',0,0,0)
  CASE ERR_NOWINDOW
    RtEZRequestA('Could not open window!','Ok',0,0,0)
  ENDSELECT
  IF win THEN ClearMenuStrip(win)
  IF menu THEN FreeMenus(menu)
  IF win THEN CloseWindow(win)
  IF gadlist THEN FreeGadgets(gadlist)
  IF visual THEN FreeVisualInfo(visual)
  IF scr THEN UnlockPubScreen(NIL,scr)
  IF gadtoolsbase THEN CloseLibrary(gadtoolsbase)
  IF reqtoolsbase THEN CloseLibrary(reqtoolsbase)
  IF exception>ERR_NOWINDOW THEN ReThrow()
ENDPROC

Voilà, maintenant nous pouvons ouvrir une fenêtre en appelant la fonction gt_openwindow() avec la définition de fenêtre et le gestionnaire approprié :

OPT OSVERSION=37

MODULE 'intuition/intuition','gadtools'
MODULE '*gt_window'

DEF win

PROC main()
  gt_openwindow({windef},NIL,{winhandler})
ENDPROC

PROC windef(scr,context,visual,gadlist)
  RETURN win:=OpenWindowTagList(NIL,
    [WA_TITLE, 'My Window',
     WA_FLAGS, WFLG_SIZEGADGET+WFLG_DEPTHGADGET+WFLG_CLOSEGADGET+
               WFLG_DRAGBAR+WFLG_SIMPLE_REFRESH+WFLG_ACTIVATE,
     WA_IDCMP, IDCMP_CLOSEWINDOW+IDCMP_REFRESHWINDOW,
     WA_MINWIDTH,  140,
     WA_MINHEIGHT, 35,
     WA_GADGETS,   gadlist,
     NIL])
ENDPROC

PROC winhandler(imsg,iclass,icode,igad)
  SELECT iclass
  CASE IDCMP_REFRESHWINDOW
    Gt_BeginRefresh(win)
    Gt_EndRefresh(win,TRUE)
  CASE IDCMP_CLOSEWINDOW
    Raise(ERR_OK)
  ENDSELECT
ENDPROC

Les menus Gadtools

En premier il faut ajouter IDCMP_MENUPICK dans les WA_IDCMP de votre fenêtre. Ensuite, il faut fournir une structure newmenu complète. Alors, chaque fois qu'une entrée de menu est sélectionnée, le gestionnaire de fenêtre est appelé avec iclass qui vaut IDCMP_MENUPICK et icode qui désigne le numéro de menu sélectionné.

A partir de ce numéro de menu les deux fonctions suivantes extraient le numéro de l'article et le numéro du sous-article :

PROC itemnum(n)                // menu item
ENDPROC Shr(n,5) AND $3F

PROC subnum(n)                 // menu sub item
ENDPROC Shr(n,11) AND $1F

Voyez les Includes libraries/gadtools.h et intuition/intuition.h pour plus d'information sur les menus Gadtools.

Les gadgets Gadtools

La fonction CreateGadgetA() permet de créer et de lier un nouveau gadget Gadtools à une fenêtre. CreateGadgetA() attend comme arguments un type de gadget tel que SCROLLER_KIND ou LISTVIEW_KIND, ainsi qu'une structure newgadget initialisée et une liste d'attributs. La structure newgadget contient essentiellement les dimensions du gadget et le visual info. La liste d'attributs est spécifique au type de gadget, voyez les Includes libraries/gadtools.h pour davantage d'information. Vous n'avez pas à tester toutes les créations de gadgets, il suffit de tester la dernière création, car elle a échoué si l'une des précédentes a échoué.

Un gadget LISTVIEW_KIND peut recevoir une liste Exec comme contenu initial. Dans ce cas il nous incombe de créer la liste Exec avant la création du gadget LISTVIEW_KIND.

Autre chose, les coordonnées de gadgets sont données relativement au bord extérieur de la fenêtre, et non pas relativement au bord intérieur, c'est pourquoi il faut leur ajouter offx et offy tels qu'ils sont calculés.

Grâce à l'attribut WA_ZOOM notre fenêtre possède une position repliée.

Ce calendrier factice illustre la création d'une GUI complète, avec menu, à l'aide de Gadtools :

OPT OSVERSION=37

MODULE 'intuition/intuition','intuition/screens','intuition/gadgetclass'
MODULE 'gadtools','libraries/gadtools'
MODULE 'utility/tagitem','graphics/rastport'
MODULE 'exec/nodes','exec/lists'
MODULE '*gt_window'

DEF win

PROC main()
  DEF menu
  menu:=[NM_TITLE,0,'Project',0,0,0,0,
         NM_ITEM,0,'New','N',0,0,0,
         NM_ITEM,0,'Load...','L',0,0,0,
         NM_ITEM,0,'Save','S',0,0,0,
         NM_ITEM,0,'Babbling',0,0,0,0,
         NM_SUB,0,'aaargh','A',0,0,0,
         NM_SUB,0,'hmmm','H',0,0,0,
         NM_ITEM,0,NM_BARLABEL,0,0,0,0,
         NM_ITEM,0,'Quit','Q',0,0,0,
         0,0,0,0,0,0,0]:newmenu
  gt_openwindow({windef},menu,{winhandler})
ENDPROC

PROC newlist()
  DEF list:PTR TO mlh
  NEW list
  list.head:=list+4
  list.tailpred:=list
ENDPROC list

PROC insert(list,name)
  AddTail(list,NEW [0,0,0,0,name]:ln)
ENDPROC

PROC windef(scr:PTR TO screen,gad,visual,glist)
  DEF offx,offy,labels=NIL

  offx:=scr.wborleft
  offy:=scr.wbortop+scr.rastport.txheight+1

  gad:=CreateGadgetA(CYCLE_KIND,gad,
    [offx+20,offy+9,155,16,NIL,scr.font,0,0,visual,0]:newgadget,
    [GTCY_LABELS,
     ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday',
     NIL],
     TAG_DONE])

  gad:=CreateGadgetA(SLIDER_KIND,gad,
    [offx+40,offy+36,135,16,NIL,scr.font,0,0,visual,0]:newgadget,
    [GTSL_MIN,1,
     GTSL_MAX,31,
     GTSL_LEVELFORMAT,'\d[2]',
     GTSL_MAXLEVELLEN,2,
     TAG_DONE])

  labels:=newlist()
  insert(labels,'January')
  insert(labels,'February')
  insert(labels,'March')
  insert(labels,'April')
  insert(labels,'May')
  insert(labels,'June')
  insert(labels,'July')
  insert(labels,'August')
  insert(labels,'September')
  insert(labels,'October')
  insert(labels,'November')
  insert(labels,'December')

  gad:=CreateGadgetA(LISTVIEW_KIND,gad,
    [offx+20,offy+63,155,100,NIL,scr.font,0,0,visual,0]:newgadget,
    [GTLV_SCROLLWIDTH,20,
     GTLV_LABELS,labels,
     GTLV_SHOWSELECTED,NIL,
     TAG_DONE])

  IF gad=NIL THEN Raise(ERR_NOGADGET)

  RETURN win:=OpenWindowTagList(NIL,
    [WA_TITLE, 'Calendar Demo',
     WA_FLAGS,  WFLG_DEPTHGADGET+WFLG_CLOSEGADGET+WFLG_DRAGBAR+
                WFLG_SIMPLE_REFRESH+WFLG_ACTIVATE,
     WA_IDCMP,  IDCMP_CLOSEWINDOW+IDCMP_REFRESHWINDOW+
                IDCMP_GADGETDOWN+IDCMP_GADGETUP+IDCMP_MOUSEMOVE+IDCMP_MENUPICK,
     WA_WIDTH,  200,
     WA_HEIGHT, offy+176,
     WA_ZOOM,   [0,offy,130,offy]:INT,
     WA_GADGETS,      glist,
     WA_NEWLOOKMENUS, TRUE,
     WA_AUTOADJUST,   TRUE,
     TAG_DONE])

ENDPROC

PROC itemnum(n)
ENDPROC Shr(n,5) AND $3F

PROC winhandler(msg,iclass,icode,igad)
  SELECT iclass
  CASE IDCMP_CLOSEWINDOW
    Raise(ERR_OK)
  CASE IDCMP_REFRESHWINDOW
    Gt_BeginRefresh(win)
    Gt_EndRefresh(win,TRUE)
  CASE IDCMP_MENUPICK
    IF itemnum(icode)=5 THEN Raise(ERR_OK)
  ENDSELECT
ENDPROC

Voyez les Includes libraries/gadtools.h pour davantage d'information sur les gadgets Gadtools.

Interaction

L'interaction avec les gadgets Gadtools est similaire à l'interaction avec les menus sauf que class est généralement IDCMP_GADGETUP et que gad désigne le gadget concerné par l'événement.

Pour aider à l'identification de gad il est pratique de spécifier un gadgetid dans la structure newmenu. Ainsi la réaction à un événement IDCMP_GADGETUP peut être sélectionnée en fonction de la valeur de gad.gadgetid.

La lecture et la mise à jour des attributs de gadgets ne sont pas symétriques. Par exemple, dans gad.specialinfo.longint on peut lire la valeur d'un gadget INTEGER_KIND. Par contre, pour écrire cette même valeur, on doit passer par un appel à la fonction Gt_SetGadgetAttrsA() qui évaluera l'étiquette GTIN_NUMBER. C'est ce qui permet à Gadtools d'actualiser l'affichage en plus de modifier la valeur.

Cette calculatrice sommaire illustre l'interaction entre plusieurs gadgets d'une GUI gadtools :

OPT OSVERSION=37

MODULE 'intuition/intuition','intuition/screens'
MODULE 'reqtools','gadtools','libraries/gadtools'
MODULE 'utility/tagitem','graphics/rastport'
MODULE '*gt_window'

DEF win
DEF display:PTR TO gadget
DEF result=0
DEF value=0

PROC main()
  DEF newmenu
  newmenu:=[NM_TITLE,0,'Calculator',0,0,0,0,
            NM_ITEM,0,'Reset','R',0,0,0,
            NM_ITEM,0,'About','A',0,0,0,
            NM_ITEM,0,'Quit','Q',0,0,0,
            0,0,0,0,0,0,0]:newmenu
  gt_openwindow({windef},newmenu,{winhandler})
ENDPROC

PROC windef(scr:PTR TO screen,gad,visual,glist)
  DEF offx,offy

  offx:=scr.wborleft
  offy:=scr.wbortop+scr.rastport.txheight+1

  gad:=display:=CreateGadgetA(INTEGER_KIND,gad,
    [offx+10,offy+8,124,22,NIL,scr.font,0,0,visual,0]:newgadget,
    NIL)

  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+10,offy+36,40,20,'7',scr.font,7,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+52,offy+36,40,20,'8',scr.font,8,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+94,offy+36,40,20,'9',scr.font,9,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+10,offy+58,40,20,'4',scr.font,4,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+52,offy+58,40,20,'5',scr.font,5,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+94,offy+58,40,20,'6',scr.font,6,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+10,offy+80,40,20,'1',scr.font,1,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+52,offy+80,40,20,'2',scr.font,2,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+94,offy+80,40,20,'3',scr.font,3,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+10,offy+102,40,20,'0',scr.font,0,0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+52,offy+102,40,20,'+',scr.font,"+",0,visual,0]:newgadget,
    NIL)
  gad:=CreateGadgetA(BUTTON_KIND,gad,
    [offx+94,offy+102,40,20,'=',scr.font,"=",0,visual,0]:newgadget,
    NIL)

  IF gad=NIL THEN Raise(ERR_NOGADGET)

  RETURN win:=OpenWindowTagList(NIL,
    [WA_TITLE, 'Minicalc Demo',
     WA_FLAGS,  WFLG_DEPTHGADGET+WFLG_CLOSEGADGET+WFLG_DRAGBAR+
                WFLG_SIMPLE_REFRESH+WFLG_ACTIVATE,
     WA_IDCMP,  IDCMP_CLOSEWINDOW+IDCMP_REFRESHWINDOW+
                IDCMP_GADGETUP+IDCMP_MENUPICK,
     WA_WIDTH,  150,
     WA_HEIGHT, offy+136,
     WA_ZOOM,   [0,offy,136,offy]:INT,
     WA_GADGETS,      glist,
     WA_NEWLOOKMENUS, TRUE,
     WA_AUTOADJUST,   TRUE,
     TAG_DONE])

ENDPROC

PROC itemnum(n)
ENDPROC Shr(n,5) AND $3F

PROC winhandler(msg,class,code,gad:PTR TO gadget)
  SELECT class
  CASE IDCMP_CLOSEWINDOW
    Raise(ERR_OK)
  CASE IDCMP_REFRESHWINDOW
    Gt_BeginRefresh(win)
    Gt_EndRefresh(win,TRUE)
  CASE IDCMP_GADGETUP
    IF gad=display
      result:=result+gad.specialinfo::stringinfo.longint
      Gt_SetGadgetAttrsA(display,win,NIL,[GTIN_NUMBER,result,0])
      value:=0
    ELSEIF (gad.gadgetid>=0) AND (gad.gadgetid<=9)
      value:=Mul(10,value)+gad.gadgetid
      Gt_SetGadgetAttrsA(display,win,NIL,[GTIN_NUMBER,value,0])
    ELSEIF gad.gadgetid="+"
      result:=result+value; value:=0
      Gt_SetGadgetAttrsA(display,win,NIL,[GTIN_NUMBER,0,0])
    ELSEIF gad.gadgetid="="
      result:=result+value
      Gt_SetGadgetAttrsA(display,win,NIL,[GTIN_NUMBER,result,0])
      value:=0; result:=0
    ENDIF
  CASE IDCMP_MENUPICK
    IF itemnum(code)=0
      value:=0; result:=0
      Gt_SetGadgetAttrsA(display,win,NIL,[GTIN_NUMBER,0,0])
    ELSEIF itemnum(code)=1
      RtEZRequestA('Demo: Mini Calculator\\nAuthor: Damien Guichard\\n','Ok',0,0,0)
    ELSEIF itemnum(code)=2
      Raise(ERR_OK)
    ENDIF
  ENDSELECT
ENDPROC

Pour aller plus loin

Un tutoriel n'est ni exhaustif ni une référence. Un programme AmigaOS réaliste est fait de mille autres choses, non abordées ici, comme les écrans, les datatypes, les memory-pools, les processus, les devices, les fichiers IFF et bien d'autres encore. Savoir programmer c'est donc aussi savoir trouver de la documentation, et des exemples, le plus souvent en anglais. Voici quelques liens pour démarrer.

La documentation indispensable c'est les Autodocs de Commodore, et c'est encore mieux dans le format AmigaGuide : de.aminet.net/pub/aminet/dev/misc/AmigaOS_guides.lha.

Les non moins indispensables AmigaOS Includes : obligement.free.fr/files/ndk_amigaos39.lzx.

Le compilateur EC v3.3a de Wouter van Oortmerssen (version complète) : www.aminet.net/dev/e/amigae33a.lha et www.aminet.net/dev/e/ec33a.lha.

Le compilateur ECX de Leif Salomonsson (version démo) : home.swipnet.se/blubbe/ECX.

La liste de diffusion Amiga-E : www.freelists.org/list/positron.


[Retour en haut] / [Retour aux articles] [Article précédent] / [Article suivant]