home *** CD-ROM | disk | FTP | other *** search
/ Computer Music Interactif…cial Edition 1999 Winter / cd 3.iso / mac / Mac / Shares / Midishare™1.68 / Development Tools / Sources Examples / msBarGraph / msBarGraph.p < prev    next >
Encoding:
Text File  |  1992-03-08  |  26.5 KB  |  765 lines  |  [TEXT/MPS ]

  1. {••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
  2. {•                                BAR GRAPH                                         •}
  3. {•------------------------------------------------------------------------------•}
  4. {•                                                                                •}
  5. {• Le programme BARGRAPH présenté ici, fait partie d'une série d'exemples à         •}
  6. {• caractère pédagogique (enfin j'espère !) sur la façon d'utiliser MIDISHARE.    •}
  7. {•                                                                                •}
  8. {• BARGRAPH permet de visualiser l'activité Midi. Il comporte deux séries de 16 •}
  9. {• afficheurs à L.E.D. sensibles à la vélocité des notes reçues.                •}
  10. {•                                                                                •}
  11. {•------------------------------------------------------------------------------•}
  12. {•    Release 1.1 (Mars 90) (pour MPW 3.1)                                        •}
  13. {•                                                                                •}
  14. {•        - ajout du menu Edit pour DA ouvert dans l'application    elle-même        •}
  15. {•        - correction de bugs sous MultiFinder et/ou avec DA dans l'application    •}
  16. {•                                                                                •}
  17. {•------------------------------------------------------------------------------•}
  18. {•        © GRAME 1989, Yann Orlarey et Hervé Lequay                                •}
  19. {••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••}
  20.  
  21. {$D+} { MacsBug symbols on }
  22. {$R-} { No range checking  }
  23.  
  24. program BarGraph;
  25.  
  26. uses Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf, Traps, MIDIShareUnit;
  27.  
  28. const
  29.     AppleID        = 128;        AppleMenu    = 1;
  30.     FileID        = 129;        FileMenu    = 2;
  31.     EditID        = 130;        EditMenu    = 3;
  32.         UndoI    = 1;    CutI    = 3;    CopyI    = 4;    PasteI    = 5;    ClearI    = 6;
  33.  
  34.     WindowId    = 128;                                     { ID fenêtre de l'application }
  35.     AboutID        = 129;                                     { ID fenêtre de About }
  36.     AlertID        = 500;                                     { ID Alerte erreurs }
  37.  
  38.     resumeMask    = $01;                                     { suspend/resume mask }
  39.  
  40. type
  41.     TBarGraph     = record                                 { infos nécessaires à l'affichage }
  42.         portVal        : array [0..1] of integer;
  43.         portTarg    : array [0..1] of integer;
  44.         value        : array [0..1, 0..15] of integer;
  45.         target        : array [0..1, 0..15] of integer;
  46.         end;
  47.  
  48. var
  49.     myWindow        : WindowPtr;                        { ma fenêtre (qui est un Dialog) }
  50.     dragRect        : Rect;                                { limite les mouvmnt de la fenêtre }
  51.     myMenus            : array [AppleMenu..EditMenu] of MenuHandle;
  52.  
  53.     gMac            : SysEnvRec;                        { machine… }
  54.     eventPending    : boolean;                            { vrai si événement en attente }
  55.     hasWNE            : boolean;                            { vrai si WaitNextEvent implémenté }
  56.     foreGround        : boolean;                            { vrai si en foreGround }
  57.  
  58.     doneFlag        : boolean;                            { signale la fin de l'application }
  59.     myEvent            : EventRecord;                        { événement Macintosh }
  60.  
  61.     whichChar        : char;                                { caractère clavier Macintosh }
  62.     myNum            : integer;                            { ID unique de l'appl. donné par MS }
  63.     myBarGraph        : TBarGraph;                        { Afficheurs BarGraphs }
  64.  
  65. {*******************************************************************************}
  66. {                                UTILITAIRES                                        }
  67. {-------------------------------------------------------------------------------}
  68. {                                                                                }
  69. {*******************************************************************************}
  70.  
  71. {$S Initialize}
  72. Procedure PullToFront;
  73. var    i    : integer;
  74. begin
  75.     for i := 1 TO 3 DO
  76.         IF EventAvail(everyEvent,myEvent) THEN;    { pull application to front            }
  77. end;
  78.  
  79. {$S Initialize}
  80. function TrapAvailable(tNumber: integer; tType: trapType): boolean;
  81. {    Vérification de l'implémentation d'une trappe                                    }
  82. begin
  83.     TrapAvailable := NGetTrapAddress(tNumber, tType) <> GetTrapAddress(_Unimplemented)
  84. end;
  85.  
  86. {$S Main}
  87. function IsAppWindow(aWind: WindowPtr): boolean;
  88. { vérifie si la fenêtre appartient à l'application                                }
  89.  
  90. begin
  91.     if aWind = nil then
  92.         IsAppWindow := false
  93.     else
  94.         IsAppWindow := windowPeek(aWind)^.windowKind >= 0
  95. end;
  96.  
  97. {$S Main}
  98. function IsDAWindow(aWind: WindowPtr): boolean;
  99. { vérifie si la fenêtre appartient à un accessoire de bureau                        }
  100. begin
  101.     if aWind = nil then
  102.         IsDAWindow := false
  103.     else
  104.         IsDAWindow := windowPeek(aWind)^.windowKind < 0
  105. end;
  106.  
  107. {$S Main}
  108. Procedure CenterRectOnScreen (var aRect: Rect);
  109. { aRect rectangle global à centrer sur écran (dragRect)                    }
  110. var    screenSize    : Point;
  111.     rectSize    : Point;
  112. begin
  113.     with dragRect do
  114.         SetPt(screenSize,right - left,bottom - top);
  115.     with aRect do begin
  116.         SetPt(rectSize,right - left,bottom - top);
  117.         left:= dragRect.left + (screenSize.h - rectSize.h) div 2;
  118.         top:= dragRect.top + (screenSize.v - rectSize.v) div 5;
  119.         topLeft:= point(PinRect(dragRect,topLeft));
  120.         right:= left + rectSize.h;
  121.         bottom:= top + rectSize.v;
  122.         end;
  123. end;
  124.  
  125. {$S Main}
  126. Function GetNewCenteredDialog (dialogID: integer): DialogPtr;
  127. var    dlogTemplate    : DialogTHndl;
  128. begin
  129.     GetNewCenteredDialog := nil;
  130.     dlogTemplate := DialogTHndl(GetResource('DLOG', dialogID));
  131.     if dlogTemplate <> nil then begin
  132.         CenterRectOnScreen(dlogTemplate^^.boundsRect);
  133.         GetNewCenteredDialog:= GetNewDialog(dialogID, nil, pointer(-1));
  134.         end
  135.     else SysBeep(2)                                                { At least give some indication }
  136. end;
  137.  
  138. {$S Main}
  139. Procedure AlertUser (alertID: integer);
  140. var    alrtTemplate    : AlertTHndl;
  141.     temp            : integer;
  142. begin
  143.     alrtTemplate := AlertTHndl(GetResource('ALRT', alertID));
  144.     if alrtTemplate <> nil then begin
  145.         SetCursor(arrow);
  146.         CenterRectOnScreen(alrtTemplate^^.boundsRect);
  147.         temp:= Alert(alertID,nil)
  148.         end
  149.     else SysBeep(2)                                             { At least give some indication        }
  150. end;
  151.  
  152.  
  153. {*******************************************************************************}
  154. {                                INIT BAR GRAPH                                    }
  155. {-------------------------------------------------------------------------------}
  156. { Prépare les barGraphs en leur donnant un objectif maximal pour "allumer"        }
  157. { toutes les LEDs au démarrage de l'application.                                }
  158. {                                                                                }
  159. { Les paramètres de l'appel :                                                    }
  160. { ---------------------------                                                    }
  161. {                                                                                }
  162. {        aucun paramètre.                                                        }
  163. {                                                                                }
  164. {*******************************************************************************}
  165.  
  166. {$ Initialize}
  167. procedure InitBarGraph;
  168. var
  169.     p, i         : integer;
  170. begin
  171.     with myBarGraph do
  172.         for p := 0 to 1 do begin                    { Pour chaque ports Midi }
  173.             portVal[p] := 0;                        { LED actuellement éteinte }
  174.             portTarg[p] := 1;                        { objectif, allumée. }
  175.             for i := 0 to 15 do begin                { Pour chaque canal }
  176.                 value[p, i] := 0;                    { LEDs actuellement éteintes }
  177.                 target[p, i] := 8;                    { objectif, les 8 allumées. }
  178.                 end
  179.             end
  180. end;
  181.  
  182. {*******************************************************************************}
  183. {                                DOWN BAR GRAPH                                    }
  184. {-------------------------------------------------------------------------------}
  185. { Cette procédure a pour objectif de "rendre vivants" les barGraphs en les        }
  186. { ramenant doucement vers la valeur zéro à chaque fois qu'ils sont activés.        }
  187. {                                                                                }
  188. { DownBarGraph fonctionne comme une tâche de fond qui se réactive périodi-        }
  189. { quement toutes les 100 ms par le biais d'un MidiCall. Le premier lancement    }
  190. { est effectué à l'initialisation de l'application (voir MIDI SET UP).            }
  191. {                                                                                }
  192. { Comme DownBarGraph est appelée sous interruptions, elle ne fait aucun affi-    }
  193. { chage directement, mais elle prépare le travail pour RefreshBarGraph.            }
  194. {                                                                                }
  195. { Les paramètres d'un appel par le biais d'un MidiCall sont imposés, et sont    }
  196. { au nombre de cinq : la date de l'appel (longint), le numéro de référence de    }
  197. { l'application (integer), et trois paramètres dont l'usage est libre sous        }
  198. { réserve qu'ils soient de la taille d'un longint ou d'un pointeur.                }
  199. {                                                                                }
  200. { Les paramètres de l'appel :                                                    }
  201. { ---------------------------                                                    }
  202. {                                                                                }
  203. {        d:        date de l'appel (longint, en ms)                                }
  204. {        myNum:    numéro de référence unique de l'application (integer)            }
  205. {        delay:    delai entre les activations successives.                        }
  206. {        a2,a3:    paramètres obligatoires, mais non utilisés ici.                    }
  207. {                                                                                }
  208. {*******************************************************************************}
  209.  
  210. {$ Main}
  211. procedure downBarGraph(date: longint; refNum: integer; delay, a2, a3: longint);
  212. var
  213.     p, i         : integer;
  214. begin
  215.     with myBarGraph do
  216.         for p := 0 to 1 do begin                        { Pour chaque port Midi }
  217.             if (portTarg[p] > 0) &                        { Si la LED a un objectif et }
  218.                 (portVal[p] >= portTarg[p]) then        { Si elle l'a atteint : }
  219.                 portTarg[p] := portTarg[p] - 1;            { diminuer son objectif }
  220.             for i := 0 to 15 do                            { Pour tous les canaux Midi }
  221.                 if (target[p, i] > 0) &                    { Si le BarGraph à un objectif et }
  222.                     (value[p, i] >= target[p, i]) then    { Si il l'a atteint : }
  223.                     target[p, i] := target[p, i] - 1;    { diminuer son objectif }
  224.             end;
  225.     midiCall(@downBarGraph,date + delay,refNum,delay,a2,a3) { DownBarGraph se relance }
  226. end;                                                    { elle-même dans <Delay> ms }
  227.  
  228.  
  229. {*******************************************************************************}
  230. {                                REFRESH BAR GRAPH                                }
  231. {-------------------------------------------------------------------------------}
  232. { Cette procédure met à jour l'affichage de tous les objets qui doivent chan-    }
  233. { ger de valeur en dessinant les différences entre valeur courante et valeur    }
  234. { objectif.                                                                        }
  235. {                                                                                }
  236. { Les paramètres de l'appel :                                                    }
  237. { ---------------------------                                                    }
  238. {                                                                                }
  239. {        aucun paramètre.                                                        }
  240. {                                                                                }
  241. {*******************************************************************************}
  242.  
  243. {$ Main}
  244. procedure refreshBarGraph;
  245. var
  246.     x0, y0, x1, y1: integer;
  247.     i, p, n, v, t: integer;
  248.     r            : Rect;
  249. begin
  250.     SetPort(myWindow);
  251.     with myBarGraph do
  252.         for p := 0 to 1 do begin                            { Pour chaque ports Midi }
  253.             x0 := 10 + p * (16 * 13 + 5); y0 := 50;            { calcule la position du groupe, }
  254.             x1 := x0 + 130; y1 := y0 - 42;                    { celle de la LED du port Midi }
  255.             setRect(r, x1, y1, x1 + 8, y1 + 3);                { ainsi que son rectangle. }
  256.             if (portVal[p] = 0) & (portTarg[p] <> 0) then    { s'il faut allumer la LED }
  257.                 paintRect(r)                                { dessine la LED }
  258.             else if (portVal[p] <> 0) & (portTarg[p] = 0) then { s'il faut éteindre la LED }
  259.                 eraseRect(r);                                { efface la LED }
  260.             portVal[p] := portTarg[p];                        { l'objectif est réalisé }
  261.     
  262.             for i := 0 to 15 do begin                        { Pour chaque canal Midi }
  263.                 v := value[p, i];                            { v est la valeur du BarGraph }
  264.                 t := target[p, i];                            { t est son objectif }
  265.                 if v < t then                                { s'il faut monter la valeur }
  266.                     for n := 1 + v to t do begin            { on dessine les LED en plus }
  267.                         x1 := x0 + 13 * i; y1 := y0 - 4 * n;
  268.                         setRect(r, x1, y1, x1 + 8, y1 + 3);
  269.                         if n > 5 then ForeColor(redColor)
  270.                         else ForeColor(greenColor);
  271.                         paintRect(r);
  272.                         end
  273.                 else if v > t then                            { s'il faut descendre la valeur }
  274.                     for n := v downto 1 + t do begin        { on efface les LED en trop }
  275.                         x1 := x0 + 13 * i; y1 := y0 - 4 * n;
  276.                         setRect(r, x1, y1, x1 + 8, y1 + 3);
  277.                         eraseRect(r);
  278.                         end;
  279.                 value[p, i] := t;                            { l'objectif est réalisé }
  280.                 end;
  281.             ForeColor(blackColor)
  282.             end
  283. end;
  284.  
  285. {*******************************************************************************}
  286. {                                DRAW BAR GRAPH                                    }
  287. {-------------------------------------------------------------------------------}
  288. { Cette procédure redessine tous les objets.                                    }
  289. {                                                                                }
  290. { Les paramètres de l'appel :                                                    }
  291. { ---------------------------                                                    }
  292. {                                                                                }
  293. {        aucun paramètre.                                                        }
  294. {                                                                                }
  295. {*******************************************************************************}
  296.  
  297. {$ Main}
  298.  
  299. procedure drawBarGraph;
  300. var
  301.     x0, y0, x1, y1: integer;
  302.     i, p, n        : integer;
  303.     r            : Rect;
  304. begin
  305.     with myBarGraph do
  306.         for p := 0 to 1 do begin                            { Pour chaque port Midi }
  307.             x0 := 10 + p * (16 * 13 + 5); y0 := 50;            { calcule la position du groupe, }
  308.             if portVal[p] > 0 then begin                    { Si la LED est allumée : }
  309.                 x1 := x0 + 130; y1 := y0 - 42;                { calcule sa position }
  310.                 setRect(r, x1, y1, x1 + 8, y1 + 3);            { calcule son rectangle }
  311.                 paintRect(r);                                { et la dessine. }
  312.                 end;
  313.             for i := 0 to 15 do                                { Pour chaque canal Midi }
  314.                 for n := 1 to value[p, i] do begin            { Pour chaque LED allumée }
  315.                     x1 := x0 + 13 * i; y1 := y0 - 4 * n;    { calcule sa position }
  316.                     setRect(r, x1, y1, x1 + 8, y1 + 3);        { calcule son rectangle }
  317.                     if n > 5 then ForeColor(redColor)
  318.                     else ForeColor(greenColor);
  319.                     paintRect(r);                            { et la dessine }
  320.                     end;
  321.             ForeColor(blackColor)
  322.             end;
  323. end;
  324.  
  325. {*******************************************************************************}
  326. {                                DRAW MY WINDOW                                    }
  327. {-------------------------------------------------------------------------------}
  328. { Affiche la fenêtre (qui est un Dialog) avec son contenu.                         }
  329. {                                                                                }
  330. { Les paramètres de l'appel :                                                    }
  331. { ---------------------------                                                    }
  332. {                                                                                }
  333. {        aucun paramètre.                                                        }
  334. {                                                                                }
  335. {*******************************************************************************}
  336.  
  337. {$ Main}
  338. procedure DrawMyWindow;
  339. begin
  340.     DrawDialog(myWindow);
  341.     drawBarGraph;
  342. end;
  343.  
  344. {*******************************************************************************}
  345. {                            TREAT MIDI EVENTS                                    }
  346. {-------------------------------------------------------------------------------}
  347. { La procedure de réception des événements Midi. Elle est appelée automatique-     }
  348. { ment par MidiShare, sous interruptions, chaque fois que l'application            }
  349. { reçoit de nouveaux événements.                                                }
  350. {                                                                                }
  351. { Pour ce faire, l'adresse de cette routine à été fournie à MidiShare à            }
  352. { l'ouverture de l'application par un MidiSetRcvAlarm.                            }
  353. {                                                                                }
  354. { Cette procédure doit obligatoirement comporter un paramètre, qui est le        }
  355. { numéro de référence unique de l'application (integer).                        }
  356. {                                                                                }
  357. { Le principe de cette procédure est d'aller récupérer les événements reçus.    }
  358. { Lorsque ce sont des KeyOn, TreatMidiEvents ce sert de leur vélocité pour         }
  359. { assigner un objectif au BarGraph du canal correspondant. Dans les autres cas     }
  360. { TreatMidiEvents se contente de faire clignoter la LED du port de provenance.     }
  361. {                                                                                }
  362. { Les paramètres de l'appel :                                                    }
  363. { ---------------------------                                                    }
  364. {                                                                                }
  365. {        myNum:    numéro de référence Midi de l'application.                        }
  366. {                                                                                }
  367. {*******************************************************************************}
  368.  
  369. {$ Main}
  370. procedure TreatMidiEvents(refNum: integer);
  371. var
  372.     e            : midiEvPtr;
  373.     v            : integer;
  374.     n            : longint;
  375. begin
  376.     n := midiCountEvs(myNum);                        { compte les événements reçus }
  377.     while n > 0 do begin                            { Pour chaque événement : }
  378.         e := midiGetEv(refNum);                        { on récupère l'événement reçu }
  379.         with e^, myBarGraph do begin
  380.             portTarg[port] := 2;                    { on fixe à la LED l'objectif allumée }
  381.             if evType <= typeKeyOn then begin        { Si l'événement est une note ou un KeyOn: }
  382.                 v := (vel + 15) div 16;                { on calcul un objectif d'aprés sa vel. }
  383.                 if v > target[port, chan] then        { Si cet objectif est sup. à l'ancien : }
  384.                     target[port, chan] := v;        { il devient le nouvel objectif }
  385.                 end;
  386.             end;
  387.         midiFreeEv(e);                                { on n'a plus besoin de l'événement }
  388.         n := n - 1;                                    { un de moins à traiter }
  389.         end
  390. end;
  391.  
  392. {*******************************************************************************}
  393. {                                SET UP MIDI                                         }
  394. {-------------------------------------------------------------------------------}
  395. { Cette procédure définit les différents paramètres necessaires au fonction-    }
  396. { nement Midi de l'application. Tout d'abord, le MidiOpen de l'application         }
  397. { qui lui permet de se signaler à MidiShare, et d'obtenir un numèro de réfé-    }
  398. { rence unique pour la suite des opérations. La chaine de caractères passée en     }
  399. { argument sert au catalogue des applications ouvertes que maintient MidiShare.    }
  400. { Ensuite la définition de l'alarme de réception, une procédure appelée auto-    }
  401. { matiquement par MidiShare, à chaque fois que l'application va recevoir de        }
  402. { nouveaux événements. Troisièmement, le lancement d'une tâche de fond qui est     }
  403. { chargée, toutes les 100 ms, de faire descendre les BarGraphs. Enfin l'éta-    }
  404. { blissement d'une connection entre l'application et les port Midi d'entrées.    }
  405. {                                                                                }
  406. { Les paramètres de l'appel :                                                    }
  407. { ---------------------------                                                    }
  408. {                                                                                }
  409. {        aucun paramètre.                                                        }
  410. {                                                                                }
  411. {*******************************************************************************}
  412.  
  413. {$ Initialize}
  414. procedure SetUpMidi;
  415. var    name:        str255;
  416.     apRefNum:    integer;
  417.     apParam:    Handle;
  418.     aRefNum:    integer;
  419.  
  420.     Procedure FAILSETUP (strIndex: integer);
  421.     var    msgStr:    str255;
  422.     begin
  423.         GetIndString (msgStr,AlertID,strIndex);            { message d'alerte suivant erreur    }
  424.         ParamText(name,msgStr,'','');
  425.         AlertUser(AlertID);
  426.         ExitToShell                                        { et quitte                            }
  427.     end;
  428.     
  429. begin
  430.     GetAppParms(name,apRefNum,apParam);                    { récupérer le nom d'application    }
  431.     if not MidiShare then FailSetUp(1);                    { MidiShare n'est pas installé        }
  432.         
  433.     myNum:= MidiOpen(name);                                { ouverture en Midi                    }
  434.     if myNum = MidiErrSpace then FailSetUp(2);            { impossible, plus de place            }
  435.     
  436.     midiCall(@downBarGraph, midiGetTime + 400, myNum, 100, 0, 0); { appel à la tâche downBarGraph }
  437.     midiSetRcvAlarm(myNum, @TreatMidiEvents);            { définit la tâche temps-réel de réception }
  438.  
  439.     midiConnect(0, myNum, true);                        { connection avec les ports Midi d'entrées }
  440. end;
  441.  
  442. {*******************************************************************************}
  443. {                            SET UP WINDOWS                                        }
  444. {-------------------------------------------------------------------------------}
  445. { Procédure chargé d'ouvrir la fenêtre et de réaliser les initialisations        }
  446. { nécessaires.                                                                     }
  447. {                                                                                }
  448. { Les paramètres de l'appel :                                                    }
  449. { ---------------------------                                                    }
  450. {                                                                                }
  451. {        aucun paramètre.                                                        }
  452. {                                                                                }
  453. {*******************************************************************************}
  454.  
  455. {$ Initialize}
  456. procedure SetUpWindows;
  457. var    r    : rect;
  458. begin    
  459.     with screenBits.bounds do                                    { rect max de déplacmt de fenêtre    }
  460.         SetRect(dragRect, 4, 24, right - 4, bottom - 4);
  461.     myWindow := GetNewDialog(WindowID,nil,pointer(-1));
  462.     SetPort(myWindow);
  463.     r:= myWindow^.portRect;
  464.     with r do begin
  465.         LocalToGlobal(topLeft);
  466.         LocalToGlobal(botRight)
  467.         end;
  468.     if not RectInRgn(r,GetGrayRgn) then begin
  469.         CenterRectOnScreen(r);
  470.         MoveWindow(myWindow,r.left,r.top,true)
  471.         end;
  472.     InitBarGraph;
  473.  
  474.     ShowWindow(myWindow)
  475. end;
  476.  
  477.  
  478. {$S Main}
  479. Procedure SaveWindowPos;
  480. type    rectPtr  =     ^rect;
  481.         rectHdle =    ^rectPtr;
  482. var    windHdle:    handle;
  483. begin
  484.     windHdle:= Get1Resource('DLOG',WindowID);
  485.     rectHdle(windHdle)^^:= windowPeek(myWindow)^.contRgn^^.rgnBBox;
  486.     ChangedResource(windHdle);
  487.     if ResError = noErr then
  488.         WriteResource(windHdle)
  489. end;
  490.  
  491.  
  492. {*******************************************************************************}
  493. {                                SET UP MENUS                                    }
  494. {-------------------------------------------------------------------------------}
  495. { Définition de la barre des menus.                                                }
  496. {                                                                                }
  497. { Les paramètres de l'appel :                                                    }
  498. { ---------------------------                                                    }
  499. {                                                                                }
  500. {        aucun paramètre.                                                        }
  501. {                                                                                }
  502. {*******************************************************************************}
  503.  
  504. {$ Initialize}
  505. procedure SetUpMenus;
  506. var
  507.     i            : integer;
  508. begin
  509.     myMenus[AppleMenu] := GetMenu(AppleID);
  510.     AddResMenu(myMenus[AppleMenu], 'DRVR');
  511.     myMenus[FileMenu] := GetMenu(FileID);
  512.     myMenus[EditMenu] := GetMenu(EditID);
  513.     for i := AppleMenu to EditMenu do InsertMenu(myMenus[i], 0);
  514.     DrawMenuBar
  515. end;
  516.  
  517. {*******************************************************************************}
  518. {                                INITIALIZE                                        }
  519. {-------------------------------------------------------------------------------}
  520. { Initialisations générales (hasWNE, foreGround, managers, fenêtre, Midi)        }
  521. {                                                                                }
  522. { Les paramètres de l'appel :                                                    }
  523. { ---------------------------                                                    }
  524. {                                                                                }
  525. {        aucun                                                                    }
  526. {                                                                                }
  527. {*******************************************************************************}
  528.  
  529. {$ Initialize}
  530. procedure Initialize;
  531. var
  532.     err            : OSErr;
  533. begin
  534.     err := SysEnvirons(1, gMac);
  535.     hasWNE := (gMac.machineType >= 0) & TrapAvailable(_WaitNextEvent, ToolTrap);
  536.  
  537.     InitGraf(@thePort);                                    { initialisations standard }
  538.     InitFonts;
  539.     InitWindows;
  540.     InitMenus;
  541.     TEInit;
  542.     InitDialogs(nil);
  543.     InitCursor;
  544.     SetUpMenus;                                            { mise en place menus }
  545.     PullToFront;
  546.     SetUpMidi;                                            { ouverture MidiShare }
  547.     SetUpWindows;                                        { initialisations fenêtre }
  548. end;
  549.  
  550. {*******************************************************************************}
  551. {                                DO COMMAND                                        }
  552. {-------------------------------------------------------------------------------}
  553. { Execution des commandes du menu.                                                 }
  554. {                                                                                }
  555. { Les paramètres de l'appel :                                                    }
  556. { ---------------------------                                                    }
  557. {                                                                                }
  558. {        mResult     :     le menu et l'item sélectionnés                                }
  559. {                                                                                }
  560. {*******************************************************************************}
  561.  
  562. {$ Main}
  563. procedure DoCommand(mResult: longint);
  564. var
  565.     theItem        : integer;
  566.     name         : str255;
  567.     sysEdit        : boolean;
  568.     
  569.     Procedure SHOWABOUT;
  570.     var    myDialog    : dialogPtr;
  571.         hit            : integer;
  572.     begin
  573.         myDialog:= GetNewCenteredDialog(AboutID);
  574.         if myDialog <> nil then begin
  575.             ModalDialog(nil,hit);
  576.             DisposDialog(myDialog);
  577.             end
  578.     end;
  579.             
  580. begin
  581.     theItem := LoWord(mResult);
  582.     case HiWord(mResult) of
  583.         AppleID:
  584.             if theItem <> 1 then begin
  585.                 GetItem(myMenus[AppleMenu], theItem, name);
  586.                 theItem := OpenDeskAcc(name)
  587.                 end
  588.             else
  589.                 ShowAbout;
  590.         FileID:
  591.             doneFlag := true;
  592.         EditID:                                            { menu Edit: uniquement pour DAs }
  593.             sysEdit := SystemEdit(theItem - 1);
  594.         end;
  595.     HiliteMenu(0)
  596. end;
  597.  
  598. {*******************************************************************************}
  599. {                                ADJUST MENUS                                    }
  600. {-------------------------------------------------------------------------------}
  601. { Ajustement de la barre de menus suivant la fenêtre de premier plan, juste        }
  602. { lors d'un click dans la barre des menus                                        }
  603. {                                                                                }
  604. { Les paramètres de l'appel :                                                    }
  605. { ---------------------------                                                    }
  606. {                                                                                }
  607. {        aucun                                                                    }
  608. {                                                                                }
  609. {*******************************************************************************}
  610.  
  611. {$S Main}
  612. procedure AdjustMenus;
  613. begin
  614.     if IsAppWindow(FrontWindow) then begin
  615.         DisableItem(myMenus[EditMenu], UndoI);
  616.         DisableItem(myMenus[EditMenu], CutI);
  617.         DisableItem(myMenus[EditMenu], CopyI);
  618.         DisableItem(myMenus[EditMenu], PasteI);
  619.         DisableItem(myMenus[EditMenu], ClearI)
  620.         end
  621.     else if IsDAWindow(FrontWindow) then begin
  622.         EnableItem(myMenus[EditMenu], UndoI);
  623.         EnableItem(myMenus[EditMenu], CutI);
  624.         EnableItem(myMenus[EditMenu], CopyI);
  625.         EnableItem(myMenus[EditMenu], PasteI);
  626.         EnableItem(myMenus[EditMenu], ClearI)
  627.         end
  628. end;
  629.  
  630. {*******************************************************************************}
  631. {                                DO MOUSE DOWN                                    }
  632. {-------------------------------------------------------------------------------}
  633. { Gère les clicks souris                                                        }
  634. {                                                                                }
  635. { Les paramètres de l'appel :                                                    }
  636. { ---------------------------                                                    }
  637. {                                                                                }
  638. {        anEvent: l'événement                                                    }
  639. {                                                                                }
  640. {*******************************************************************************}
  641.  
  642. {$ Main}
  643.  
  644. procedure DoMouseDown(anEvent: EventRecord);
  645. var
  646.     whichWind    : WindowPtr;
  647.     part         : integer;
  648. begin
  649.     part := FindWindow(anEvent.where, whichWind);
  650.     case part of
  651.         inMenuBar:        begin
  652.                         AdjustMenus;
  653.                         DoCommand(MenuSelect(anEvent.where))
  654.                         end;
  655.         inSysWindow:    SystemClick(anEvent, whichWind);
  656.         inDrag:            DragWindow(whichWind, anEvent.where, dragRect);
  657.         inGoAway:        if IsAppWindow(whichWind) then
  658.                             doneFlag := TrackGoAway(whichWind, anEvent.where);
  659.         inContent:        if whichWind <> FrontWindow then
  660.                             SelectWindow(whichWind);
  661.         end
  662. end;
  663.  
  664. {*******************************************************************************}
  665. {                                ADJUST CURSOR                                    }
  666. {-------------------------------------------------------------------------------}
  667. { Ajuste le curseur suivant région et fenêtre                                    }
  668. {                                                                                }
  669. {*******************************************************************************}
  670.  
  671. {$S Main}
  672. procedure AdjustCursor;
  673. begin
  674.     if foreGround & IsAppWindow(FrontWindow) then SetCursor(arrow)
  675. end;
  676.  
  677. {*******************************************************************************}
  678. {                                CLOSE WINDOWS                                    }
  679. {-------------------------------------------------------------------------------}
  680. { Pour terminer correctement l'application: fermeture de toutes les fenêtres    }
  681. { (application et DA's)                                                            }
  682. {                                                                                }
  683. {*******************************************************************************}
  684.  
  685. {$S Main}
  686. procedure CloseWind(aWind: WindowPtr);
  687. { ferme une fenêtre                                                            }
  688. begin
  689.     if IsDAWindow(aWind) then
  690.         CloseDeskAcc(windowPeek(aWind)^.windowKind)
  691.     else
  692.         if IsAppWindow(aWind) then DisposeWindow(aWind)
  693. end;
  694.  
  695. Procedure CLOSEALLWINDS;
  696. { ferme toutes les fenêtres                                                    }
  697. var    window:    windowPtr;
  698. begin
  699.     repeat
  700.         window:= FrontWindow;
  701.         if window <> nil then
  702.             CloseWind(window);
  703.     until window = nil;
  704. end;
  705.  
  706.  
  707. procedure _DataInit;                    external;
  708.  
  709. {*******************************************************************************}
  710. {                        Corps principal du programme                            }
  711. {-------------------------------------------------------------------------------}
  712. { Ouverture des différents managers, Initialisations diverses et boucle prin-    }
  713. { cipale typique d'une application Macintosh.                                    }
  714. {*******************************************************************************}
  715.  
  716. {$ Main}
  717. begin
  718.     UnLoadSeg(@_DataInit);
  719.     MaxApplZone;
  720.     Initialize;
  721.     UnLoadSeg(@Initialize);
  722.  
  723.     doneFlag := false;                                     { flag de terminaison }
  724.     repeat
  725.         if hasWNE then
  726.             eventPending := WaitNextEvent(everyEvent, myEvent, 0, nil)
  727.         else begin
  728.             SystemTask;
  729.             eventPending := GetNextEvent(everyEvent, myEvent)
  730.             end;
  731.         AdjustCursor;
  732.         with myEvent do
  733.             case what of
  734.                 nullEvent:
  735.                     refreshBarGraph;                    { redessine les BarGraphs qui ont bougés }
  736.                 osEvt:
  737.                     case BSR(message, 24) of
  738.                         suspendResumeMessage:    foreGround := BAnd(message, resumeMask) <> 0;
  739.                         mouseMovedMessage:        refreshBarGraph;
  740.                         end;
  741.                 keyDown, autoKey:
  742.                     if IsAppWindow(FrontWindow) then begin
  743.                         whichChar := CHR(BAnd(myEvent.message, charCodeMask));
  744.                         if BAnd(myEvent.modifiers, cmdKey) <> 0 then
  745.                             DoCommand(MenuKey(whichChar))
  746.                         end;
  747.                 mouseDown:
  748.                     DoMouseDown(myEvent);
  749.                 updateEvt:
  750.                     if IsAppWindow(WindowPtr(message)) then begin
  751.                         BeginUpdate(WindowPtr(message));
  752.                         if not EmptyRgn(WindowPtr(message)^.visRgn) then begin
  753.                             SetPort(WindowPtr(message));
  754.                             DrawMyWindow
  755.                             end;
  756.                         EndUpdate(WindowPtr(message))
  757.                         end
  758.                 end
  759.     until doneFlag;
  760.     MidiClose(myNum);                                    { fermeture MidiShare }
  761.     SaveWindowPos;
  762.     CloseAllWinds;
  763.     ExitToShell
  764. end.
  765.