Mac-Programmierung: Menüs

Willemers Informatik-Ecke

Ressourcen definieren

Die Ressourcen für das Menü werden im ResEdit definiert. Die Vorgehensweise ist die, die einzelnen Klappmenüs als MENU zu definieren und ein Liste dieser MENUs in einer Ressource MBAR zusammenzustellen. Die Ressourcenummer von MBAR ist der Startpunkt für das Einbinden des Menüs in das Programm.

Initialisieren der Menüs

// --------------- Menue ----------------
#define mApple  128
#define         iAbout  1
#define mFile   129
#define         iQuit   1

static void MenuInit(void)
{
Handle menuBar;
MenuHandle menu;

    menuBar = GetNewMBar(128);
    SetMenuBar(menuBar);
    DisposeHandle(menuBar); // das Handle wird nicht mehr gebraucht

    // behandle die Deskaccessories extra!
    menu = GetMenuHandle(mApple);
    AppendResMenu(menu, 'DRVR');

    DrawMenuBar(); // Menueleiste zeichnen
}

In der Funktion MenuInit sind die üblichen Aufrufe zum Start eines Menüs. Mit dem Aufruf GetNewMBar wird die MBAR Ressource geladen. Der Rückgabewert ist ein Handle, dass von SetMenuBar verwendet wird, um die Menüleiste dem Programm zuzuführen. Da danach das Handle nicht mehr gebraucht wird, kann es dem System zur Freigabe zurückgegeben werden.

Das Apple-Menü braucht eine Sonderbehandlung, da hier die DeskAccessories angehängt werden müssen. Zu guter Letzt wird die Menüleiste gezeichnet.

Die Behandlung von Menüereignissen

An zwei Stellen werden die Menüereignisse in die Ereignisroutine eingehängt. Das eine betrifft die Tastenkürzel für die Menüs. Hier sind die Ereignisse keyDown bzw. autoKey relevant. Mit Hilfe von charCodeMask wird die Taste ausgefiltert. Durch AND mit cmdKey wird festgestellt, ob es überhaupt eine Kommandotaste ist. Dann kann die Taste der Funktion MenuKey zugeführt werden, die daraus eine Menüeintragkennung macht. Die Funktion BehandleMenue, die weiter unten aufgeführt ist, behandelt das Ereignis.

Das zweite Ereignis ist der Aufruf per Maus. Dadurch wird das mouseDown Ereignis ausgelöst. Das Ergebnis von FindWindow ist bei einem Menüaufruf inMenuBar. Die Funktion MenuSelect errechnet die Menüeintragskennung und wir können BehandleMenue aufrufen.

short thePart;
char tastenDruck;
long menuePunkt;

    switch (eventPtr->what) {
    case keyDown:
    case autoKey:
        tastenDruck = eventPtr->message & charCodeMask;
        if ( 0 != (eventPtr->modifiers & cmdKey)) {
            BehandleMenue( MenuKey(tastenDruck) );
        }
        break;
    case mouseDown:
        // in welchem Fensterbereich ist er niedergegangen?
        thePart = FindWindow(eventPtr->where, &window);
        switch (thePart) {
        case inMenuBar:
                menuePunkt = MenuSelect(eventPtr->where);
                BehandleMenue(menuePunkt);
                break;

Die Menüeintragkennung enthält in den höheren Bits die Kennung des Men&umml;s und in den niedrigeren die des Eintrags. Mit den Funktionen HiWord und LoWord werden sie ausgefiltert. Danach erfolgt eine Fallunterscheidung nach Menü und innerhalb der Menüs nach den Einträgen.

Eine Sonderrolle nimmt hier wieder das Apple-Menü ein. Hierin wird nach dem Menütext des Eintrages geforscht und per OpenDeskAcc aufgerufen.

Zuletzt wird der Eintrag in der Menüleiste, der durch die Aktivierung des Menüs invertiert wurde, wieder in normaler Farbgebung dargestellt.

static void BehandleMenue(long menuePunkt)
{
short menu, item;
Str255 accName;

    if (menuePunkt != 0)  {
        menu = HiWord(menuePunkt);
        item = LoWord(menuePunkt);
        switch (menu) {
        case mApple:
            switch(item) {
            case iAbout: //
                    break;
            default: // hier werden die Accessories angesprochen
                GetMenuItemText( GetMenuHandle(mApple), item, accName);
                OpenDeskAcc(accName);
                break;
            }
            break;
        case mFile:
            switch(item) {
            case iQuit:
                gDone = true;
                break;
            }
        }
        // Menue wurde aktiviert, jetzt muss die Auswahl optisch
        // wieder zurueckgesetzt werden.
        HiliteMenu(0);
    }
}

Namensänderungen

Einige Namen von Funktionen haben sich geändert. Ältere Listings werden gegebenenfalls nicht mehr kompiliert. Nähere Informationen finden sich auf den Apple Development Seiten

Neuer Name Bisheriger Name
AppendResMenu AddResMenu
DeleteMCEntries DelMCEntries
DeleteMenuItem DelMenuItem
DisposeMCInfo DispMCInfo
GetMenuHandle GetMHandle
GetMenuItemText GetItem
InsertMenuItem InsMenuItem
SetMenuItemText SetItem


Homepage (C) Copyright 1999, 2002 Arnold Willemer