Mac-Programmierung: Dialoge

Willemers Informatik-Ecke

Ressourcen definieren

Die Ressourcen für die Dialoge werden im ResEdit definiert. Die Vorgehensweise beginnt mit der Erstellung eines DITL. Darin wird das Aussehen des Dialogs und seine Kontrollelemente definiert. Dann wird für einen Dialog ein DLOG-Element definiert. Der Dialog erinnert an den WIND-Dialog. Darin gibt es einen Verweis auf das zugehörige DITL.

Modaler Dialog

Ein modaler Dialog sperrt die Anwendung für die Dauer seiner Bearbeitung. Ein nichtmodaler Dialog ähnelt in seinem Verhalten eher einem Fenster. Man kann es also während der Bearbeitung in den Hintergrund stellen.

#define kDia 128	// DLOG-ID, nicht DITL-ID!
#define kOk 1

static void DialogStart(void)
{
DialogPtr diaHandle;
short itemHit;

    diaHandle = GetNewDialog( kDia, nil, (WindowPtr)-1L);
    if (diaHandle) {
        SetDialogDefaultItem(diaHandle, kOk);
        do {
            ModalDialog(nil, &itemHit);
        } while (itemHit !=kOk);
        DisposeDialog(diaHandle);
    }
}

Mit der Funktion GetNewDialog werden die Ressourcedefinitionen geladen. In einer Schleife wird Modaldialog aufgerufen. Dabei wird aus Sicht der Anwendung der Dialog jedesmal verlassen, wenn ein Kontrollelement bedient wird. Im Beispiel oben wird die Schleife erst verlassen, wenn das angewählte Dialogelement der Ok-Button ist (sofern dieser als Element#1 im DITL definiert wurde).

Die Behandlung der Kontrollelementereignisse

Um ein Kontrollelement anzusprechen, verwendet man die Funktion GetDialogItem (vormals GetDItem). Sie ermittelt anhand des Dialogzeigers und der Elementnummer das Handle des Kontrollelements, dessen Typs und Ausdehnung.

Eingabefelder

Die Eingabefelder müssen vor dem Start der Dialogbox vorbesetzt werden und nach dem Ende der Dialogbox mit Ok ausgelesen werden. Dazu kann man folgende Funktionen verwenden, die die meist unnötigen Parameter von GetDialogItem kapseln.

static void diaGetItemString(DialogPtr Dialog, int Item, Str255 myString)
{
short itemType;
Rect itemRect;
Handle lHandle;

    GetDialogItem(Dialog, Item, &itemType, &lHandle, &itemRect);
    GetDialogItemText(lHandle, myString);
}

static void diaPutItemString(DialogPtr Dialog, int Item, Str255 myString)
{
short itemType;
Rect itemRect;
Handle lHandle;

    GetDialogItem(Dialog, Item, &itemType, &lHandle, &itemRect);
    SetDialogItemText(lHandle, myString);
}

In der Aufrufsequenz der Dialogbox sieht das dann so aus:

static Str255 EingabeString = "\pVorgabe";

    diaHandle = GetNewDialog( kDia, nil, (WindowPtr)-1L);
    if (diaHandle) {
        SetDialogDefaultItem(diaHandle, kOk);
        diaPutItemString(diaHandle, kInput, EingabeString);
        do {
            ModalDialog(nil, &itemHit);
        } while (itemHit !=kOk && itemHit !=kCancel);
        if (itemHit==kOk) {
            diaGetItemString(diaHandle, kInput, EingabeString);
        }
        DisposeDialog(diaHandle);
    }

Die Konstante kInput ist die Elementnummer des Eingabeitems, wie es in ResEdit angelegt wurde.

Alarmboxen

Alarmboxen sind vordefinierte Dialogboxen. Sie werden durch einen einfachen Aufruf gestartet und enthalten je ein Symbol. Die Ressourcen werden als ALRM und der Inhalt der Alarmbox als DITL definiert.

    case mApple:
        switch(item) {
        case iAbout: //
            NoteAlert(kAboutID, NULL);

kAboutID ist die ID der Ressource ALRM.

Dateiselektorbox

Es gibt zwei Standarddialoge für den Umgang mit Dateien. Sie werden durch StandardGetFile und StandardPutFile aufgerufen. Das Ergebnis der Anfrage findet sich dann in der Struktur StandardFileReply.

static Boolean diaOpen()
{
StandardFileReply answer;
SFTypeList	typeList;
Boolean ok = false;

    typeList[0] = kVokFile;
    typeList[1] = kOldFile;
    typeList[2] = kTextFile;
    StandardGetFile( nil, 3, typeList, &answer);
    if (answer.sfGood) {
        switch(answer.sfType) {
        case kVokFile:
            // Lade Dateien des Typs VOKD
            break;
        case kOldFile:
            // Lade Dateien des Typs VOKF
            break;
        case kTextFile:
            // Importiere Dateien des Typs TEXT
            break;
        }
    }
    return ok;
}

StandardGetFile verwendet eine Liste von Dateikennungen, die bei der Auswahl angezeigt werden. Als zweiter Parameter wird die Anzahl dieser Typen angegeben. Ist dieser Parameter -1, werden alle Dateitypen angezeigt. In dem Strukturelement sfType steht der tatsächlich ausgewählte Typ der Datei, so dass jeder Typ entsprechend behandelt werden kann. Die im obigen Beispiel verwendeten Typen sind so definiert:

#define kVokFile	'VOKD'
#define kOldFile	'VOKF'
#define kTextFile	'TEXT'

Weitere Elemente der StandardFileReply sind sfGood als Kennzeichnung, dass der Open mit Ok beendet wurde und sfFile vom Typ FSSpec, die von den Dateifunktionen des MacOS als Parameter gebraucht werden.

static Boolean diaSaveAs()
{
StandardFileReply answer;
OSErr	err;

    StandardPutFile("\psichern als", "\pDateiname", &answer);
    if (answer.sfGood) { // auf sichern geklickt
        if (answer.sfReplacing) { // ersetzen
            err = FSpDelete(&answer.sfFile);
        }
        if (noErr!=FSpCreate(&answer.sfFile, kCreator, kVokFile, answer.sfScript)) {
            return false;
        }
        // sichern der Daten....
        return true;
    }
    return false;
}

Namensänderungen

Einige Namen von Funktionen haben sich geändert. Ältere Listings werden gegebenenfalls nicht mehr kompiliert.

Neuer Name Bisheriger Name
GetDialogItem GetDItem
SetDialogItemText SetIText
GetDialgoItemText GetIText
DisposeDialog DisposDialog


Homepage (C) Copyright 1999, 2002 Arnold Willemer